From 48c5451b6ca64124db540d68fa68808ca2787892 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Thu, 25 Jul 2024 21:12:10 +0200
Subject: [PATCH 01/12] WIP WUP

---
 src/backends/extrae/extrae_partial_tracer.cpp | 50 +++++++++++++++++++
 src/backends/extrae/extrae_partial_tracer.hpp | 48 ++++++++++++++++++
 src/utils/environment_variable.cpp            | 38 ++++++++++++++
 src/utils/environment_variable.hpp            |  8 +++
 4 files changed, 144 insertions(+)
 create mode 100644 src/backends/extrae/extrae_partial_tracer.cpp
 create mode 100644 src/backends/extrae/extrae_partial_tracer.hpp

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
new file mode 100644
index 0000000..04e8769
--- /dev/null
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -0,0 +1,50 @@
+#include "extrae_partial_tracer.hpp"
+
+#include <memory>
+#include <string>
+
+extern "C" {
+#include <extrae.h>
+}
+#include <utils/terminator.hpp>
+
+ExtraePartialTracer::ExtraePartialTracer() : mpi_helper_{} {
+  parallelism_descriptor_ = {
+      .mpi_descriptor_ = MPIDescriptor::Aware,
+      .thread_descriptor_ = ThreadDescriptor::Unsupported};
+  type_stack_strategy_ = std::make_unique<ExtraeTypeStackStrategy>();
+}
+
+void ExtraePartialTracer::shutdown() noexcept {
+  type_stack_strategy_->RegionStart({"Extrae OFF", {}});
+  Extrae_shutdown();
+}
+
+void ExtraePartialTracer::start() noexcept {
+  Extrae_restart();
+  type_stack_strategy_->RegionStopLast({"Extrae OFF", {}});
+}
+
+void ExtraePartialTracer::Init() noexcept {
+  // First init the type stack
+  type_stack_strategy_->Init();
+  shutdown();
+
+  // then we check the env
+  const auto number_of_names = region_names_env_.getValue().value().size();
+
+  if (number_of_names != regions_start_at_env_.getValue().value().size() ||
+      number_of_names != regions_stop_at_env_.getValue().value().size()) {
+    std::cout << "neSmiK Fatal: Please make sure to specify same amounts of "
+                 "names as well as starts and stops using e.g. "
+              << regions_stop_at_env_.getEnvName() << "=4,66,89" << std::endl;
+    Terminator::exit();
+  }
+}
+
+void ExtraePartialTracer::RegionStart(
+    const ProperlyNestedRegionInformation &region) noexcept {}
+void ExtraePartialTracer::RegionStopLast(
+    const ProperlyNestedRegionInformation &region) noexcept {}
+
+void ExtraePartialTracer::Finalize() noexcept {}
diff --git a/src/backends/extrae/extrae_partial_tracer.hpp b/src/backends/extrae/extrae_partial_tracer.hpp
new file mode 100644
index 0000000..9382565
--- /dev/null
+++ b/src/backends/extrae/extrae_partial_tracer.hpp
@@ -0,0 +1,48 @@
+#include <extrae_type_stack.hpp>
+#include <strategies.hpp>
+#include <string>
+#include <utils/environment_variable.hpp>
+#include <utils/parallelism_helper.hpp>
+#include <vector>
+
+class ExtraePartialTracer : public ProperlyNestedAnnotationStrategy {
+ private:
+  EnvironmentVariable<std::vector<std::string>> region_names_env_ =
+      EnvironmentVariable<std::vector<std::string>>(
+          "PARTIAL_TRACER_REGION_NAMES",
+          "A comma separated list of names of regions which are disjunct to "
+          "partially trace.",
+          true);
+  EnvironmentVariable<std::vector<unsigned int>> regions_start_at_env_ =
+      EnvironmentVariable<std::vector<unsigned int>>(
+          "PARTIAL_TRACER_START_AT_CALL",
+          "A comma separated list of at which encounter of the region tracing "
+          "should start",
+          true);
+
+  EnvironmentVariable<std::vector<unsigned int>> regions_stop_at_env_ =
+      EnvironmentVariable<std::vector<unsigned int>>(
+          "PARTIAL_TRACER_STOP_AT_CALL",
+          "A comma separated list of at which encounter of the region tracing "
+          "should stop",
+          true);
+
+  MPIHelper mpi_helper_;
+  std::unordered_map<std::string, unsigned int> region_counter_;
+  std::unordered_map<std::string, unsigned int> region_on_off_jobs;
+
+  std::unique_ptr<ExtraeTypeStackStrategy> type_stack_strategy_;
+  void shutdown();
+  void start();
+
+ public:
+  ExtraePartialTracer();
+  inline static const std::string name = "Extrae::PartialTracer";
+
+  virtual void RegionStart(
+      const ProperlyNestedRegionInformation &region) noexcept override;
+  virtual void RegionStopLast(
+      const ProperlyNestedRegionInformation &region) noexcept override;
+  virtual void Init() noexcept override;
+  virtual void Finalize() noexcept override;
+};
diff --git a/src/utils/environment_variable.cpp b/src/utils/environment_variable.cpp
index 979be29..bf1ac27 100644
--- a/src/utils/environment_variable.cpp
+++ b/src/utils/environment_variable.cpp
@@ -4,8 +4,10 @@
 #include <cctype>
 #include <cstdlib>
 #include <optional>
+#include <sstream>
 #include <string>
 #include <utils/string_helpers.hpp>
+#include <vector>
 
 template <>
 std::optional<bool> fromEnvString(const std::string &env_string) {
@@ -26,3 +28,39 @@ template <>
 std::optional<std::string> fromEnvString(const std::string &env_string) {
   return std::optional<std::string>{env_string};
 }
+
+template <>
+std::optional<std::vector<std::string>> fromEnvString(
+    const std::string &env_string) {
+  const char delimiter = ',';
+  std::vector<std::string> result;
+  std::stringstream stream(env_string);
+
+  while (stream.good()) {
+    std::string entry;
+    std::getline(stream, entry, delimiter);
+    if (!entry.empty()) {
+      result.push_back(entry);
+    }
+  }
+
+  if (result.size() > 0) {
+    return result;
+  } else {
+    return std::nullopt;
+  }
+}
+
+std::optional<std::vector<unsigned int>> fromEnvString(
+    const std::string &env_string) {
+  const auto &strings = fromEnvString<std::vector<std::string>>(env_string);
+
+  if (!strings.has_value()) {
+    return std::nullopt;
+  }
+  std::vector<unsigned int> result;
+  for (const auto &string : strings.value()) {
+    result.push_back(std::stoul(string));
+  }
+  return result;
+}
diff --git a/src/utils/environment_variable.hpp b/src/utils/environment_variable.hpp
index f071d98..3f6f3f4 100644
--- a/src/utils/environment_variable.hpp
+++ b/src/utils/environment_variable.hpp
@@ -6,6 +6,7 @@
 #include <iostream>
 #include <optional>
 #include <string>
+#include <vector>
 
 // dont allow the compiler to guess, but force user to implement conversion
 template <typename T>
@@ -15,6 +16,13 @@ template <>
 std::optional<bool> fromEnvString(const std::string &env_string);
 template <>
 std::optional<std::string> fromEnvString(const std::string &env_string);
+template <>
+std::optional<std::vector<std::string>> fromEnvString(
+    const std::string &env_string);
+
+template <>
+std::optional<std::vector<unsigned int>> fromEnvString(
+    const std::string &env_string);
 
 template <typename T>
 class EnvironmentVariable {
-- 
GitLab


From a7d509a084d442924990a1c6325bd7ab7d42df17 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Fri, 26 Jul 2024 11:47:06 +0200
Subject: [PATCH 02/12] Add partial tracer

---
 src/backends/extrae/CMakeLists.txt            |   2 +-
 src/backends/extrae/extrae_partial_tracer.cpp | 106 +++++++++++++++++-
 src/backends/extrae/extrae_partial_tracer.hpp |  20 +++-
 src/backends/extrae/extrae_type_stack.hpp     |   3 +
 src/delegator.cpp                             |  10 +-
 src/utils/environment_variable.cpp            |   2 +-
 6 files changed, 129 insertions(+), 14 deletions(-)

diff --git a/src/backends/extrae/CMakeLists.txt b/src/backends/extrae/CMakeLists.txt
index 319ef9c..2512a61 100644
--- a/src/backends/extrae/CMakeLists.txt
+++ b/src/backends/extrae/CMakeLists.txt
@@ -1 +1 @@
-target_sources(nesmik PRIVATE extrae_type_stack.cpp)
+target_sources(nesmik PRIVATE extrae_partial_tracer.cpp extrae_type_stack.cpp)
diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index 04e8769..765de0d 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -1,8 +1,8 @@
 #include "extrae_partial_tracer.hpp"
 
+#include <algorithm>
 #include <memory>
 #include <string>
-
 extern "C" {
 #include <extrae.h>
 }
@@ -18,11 +18,13 @@ ExtraePartialTracer::ExtraePartialTracer() : mpi_helper_{} {
 void ExtraePartialTracer::shutdown() noexcept {
   type_stack_strategy_->RegionStart({"Extrae OFF", {}});
   Extrae_shutdown();
+  is_shutdown_ = true;
 }
 
 void ExtraePartialTracer::start() noexcept {
   Extrae_restart();
   type_stack_strategy_->RegionStopLast({"Extrae OFF", {}});
+  is_shutdown_ = false;
 }
 
 void ExtraePartialTracer::Init() noexcept {
@@ -32,6 +34,12 @@ void ExtraePartialTracer::Init() noexcept {
 
   // then we check the env
   const auto number_of_names = region_names_env_.getValue().value().size();
+  if (number_of_names == 0) {
+    std::cout << "neSmiK Fatal: Please make sure to specify minimum one region "
+                 "to partiallys trace"
+              << std::endl;
+    Terminator::exit();
+  }
 
   if (number_of_names != regions_start_at_env_.getValue().value().size() ||
       number_of_names != regions_stop_at_env_.getValue().value().size()) {
@@ -40,11 +48,101 @@ void ExtraePartialTracer::Init() noexcept {
               << regions_stop_at_env_.getEnvName() << "=4,66,89" << std::endl;
     Terminator::exit();
   }
+
+  jobs_.reserve(number_of_names);
+
+  // now create the start stop jobs
+  for (std::size_t i = 0; i < number_of_names; i++) {
+    StartStopJob job{.region_name = region_names_env_.getValue().value()[i],
+                     .start_at = regions_start_at_env_.getValue().value()[i],
+                     .stop_at = regions_stop_at_env_.getValue().value()[i]};
+    jobs_.push_back(job);
+  }
 }
 
 void ExtraePartialTracer::RegionStart(
-    const ProperlyNestedRegionInformation &region) noexcept {}
+    const ProperlyNestedRegionInformation &region) noexcept {
+  const std::string region_name = std::string(region.name);
+  // A bit costly maybe if there is a lot of jobs, but much easier than keeping
+  // a tree or hashmap around
+
+  std::vector<StartStopJob> matching_jobs;
+  for (const auto &job : jobs_) {
+    if ((job.region_name.compare(region_name) == 0) &&
+        region_counter_starts_[region_name] == job.start_at) {
+      // nice we found a matching one
+      matching_jobs.push_back(job);
+    }
+  }
+
+  if (matching_jobs.size() > 1) {
+    std::cout
+        << "neSmiK Extrae::PartialTracer: Found multiple matching jobs, please "
+           "dont duplicate region names with the same start iteration"
+        << std::endl;
+    Terminator::exit();
+  }
+  if (!matching_jobs.empty()) {
+    if (!is_shutdown_) {
+      std::cout
+          << "neSmiK Extrae::PartialTracer: The regions you selected are "
+             "overlapping. The tracer is already running for "
+          << region_name
+          << ". Please make sure to select non overlapping regions and restart"
+          << std::endl;
+    }
+    // We need to startup extrae and emit the region_start event
+    start();
+  }
+
+  region_counter_starts_[region_name]++;
+
+  // if were running call extrae backend
+  if (!is_shutdown_) {
+    type_stack_strategy_->RegionStart(region);
+  }
+}
 void ExtraePartialTracer::RegionStopLast(
-    const ProperlyNestedRegionInformation &region) noexcept {}
+    const ProperlyNestedRegionInformation &region) noexcept {
+  const std::string region_name = std::string(region.name);
+
+  if (!is_shutdown_) {
+    type_stack_strategy_->RegionStopLast(region);
+  }
+
+  std::vector<StartStopJob> matching_jobs;
+  for (const auto &job : jobs_) {
+    if ((job.region_name.compare(region_name) == 0) &&
+        region_counter_stops_[region_name] == job.stop_at) {
+      // nice we found a matching one
+      matching_jobs.push_back(job);
+    }
+  }
+
+  if (matching_jobs.size() > 1) {
+    std::cout
+        << "neSmiK Extrae::PartialTracer: Found multiple matching jobs, please "
+           "dont duplicate region names with the same stop iteration"
+        << std::endl;
+    Terminator::exit();
+  }
+
+  if (!matching_jobs.empty()) {
+    if (is_shutdown_) {
+      std::cout
+          << "neSmiK Extrae::PartialTracer: The regions you selected are "
+             "overlapping. The tracer is already stopped for "
+          << region_name
+          << ". Please make sure to select non overlapping regions and restart"
+          << std::endl;
+    }
+    // We need to stop extrae
+    shutdown();
+  }
 
-void ExtraePartialTracer::Finalize() noexcept {}
+  region_counter_stops_[region_name]++;
+}
+
+void ExtraePartialTracer::Finalize() noexcept {
+  type_stack_strategy_->Finalize();
+}
diff --git a/src/backends/extrae/extrae_partial_tracer.hpp b/src/backends/extrae/extrae_partial_tracer.hpp
index 9382565..6f2093b 100644
--- a/src/backends/extrae/extrae_partial_tracer.hpp
+++ b/src/backends/extrae/extrae_partial_tracer.hpp
@@ -1,10 +1,17 @@
-#include <extrae_type_stack.hpp>
 #include <strategies.hpp>
 #include <string>
 #include <utils/environment_variable.hpp>
 #include <utils/parallelism_helper.hpp>
 #include <vector>
 
+#include "extrae_type_stack.hpp"
+
+struct StartStopJob {
+  std::string region_name;
+  unsigned int start_at;
+  unsigned int stop_at;
+};
+
 class ExtraePartialTracer : public ProperlyNestedAnnotationStrategy {
  private:
   EnvironmentVariable<std::vector<std::string>> region_names_env_ =
@@ -28,12 +35,13 @@ class ExtraePartialTracer : public ProperlyNestedAnnotationStrategy {
           true);
 
   MPIHelper mpi_helper_;
-  std::unordered_map<std::string, unsigned int> region_counter_;
-  std::unordered_map<std::string, unsigned int> region_on_off_jobs;
-
+  std::unordered_map<std::string, unsigned int> region_counter_starts_;
+  std::unordered_map<std::string, unsigned int> region_counter_stops_;
+  std::vector<StartStopJob> jobs_;
+  bool is_shutdown_{true};
   std::unique_ptr<ExtraeTypeStackStrategy> type_stack_strategy_;
-  void shutdown();
-  void start();
+  void shutdown() noexcept;
+  void start() noexcept;
 
  public:
   ExtraePartialTracer();
diff --git a/src/backends/extrae/extrae_type_stack.hpp b/src/backends/extrae/extrae_type_stack.hpp
index 02370f8..b66bd55 100644
--- a/src/backends/extrae/extrae_type_stack.hpp
+++ b/src/backends/extrae/extrae_type_stack.hpp
@@ -1,3 +1,5 @@
+#ifndef NESMIK_EXTRAE_TYPE_STACK_HPP
+#define NESMIK_EXTRAE_TYPE_STACK_HPP
 #include <stack>
 #include <string>
 #include <unordered_map>
@@ -52,3 +54,4 @@ class ExtraeTypeStackStrategy : public ProperlyNestedAnnotationStrategy {
   virtual void Init() noexcept override;
   virtual void Finalize() noexcept override;
 };
+#endif  // NESMIK_EXTRAE_TYPE_STACK_HPP
diff --git a/src/delegator.cpp b/src/delegator.cpp
index 2439203..bb7a54f 100644
--- a/src/delegator.cpp
+++ b/src/delegator.cpp
@@ -18,6 +18,7 @@
 #endif
 
 #ifdef ENABLE_EXTRAE
+#include "backends/extrae/extrae_partial_tracer.hpp"
 #include "backends/extrae/extrae_type_stack.hpp"
 #endif
 
@@ -41,6 +42,8 @@ void Delegator::TryInitProperlyNestedBackend(const std::string &backend) {
 #ifdef ENABLE_EXTRAE
   else if (backend.compare(ExtraeTypeStackStrategy::name) == 0) {
     pn_annotation_strategy_ = std::make_unique<ExtraeTypeStackStrategy>();
+  } else if (backend.compare(ExtraePartialTracer::name) == 0) {
+    pn_annotation_strategy_ = std::make_unique<ExtraePartialTracer>();
   }
 #endif
 #ifdef ENABLE_DLB
@@ -52,12 +55,15 @@ void Delegator::TryInitProperlyNestedBackend(const std::string &backend) {
 
 const std::vector<std::string> Delegator::available_backends = {
 #ifdef ENABLE_DLB
-    DLBTalpTreeStrategy::name, DLBTalpStrategy::name,
+    DLBTalpTreeStrategy::name,
+    DLBTalpStrategy::name,
 #endif
 #ifdef ENABLE_EXTRAE
     ExtraeTypeStackStrategy::name,
+    ExtraePartialTracer::name,
 #endif
-    "Default", "Detection"};
+    "Default",
+    "Detection"};
 
 bool Delegator::checkIfBackendAvailable(const std::string &backend) {
   bool found_backend{false};
diff --git a/src/utils/environment_variable.cpp b/src/utils/environment_variable.cpp
index bf1ac27..e00cbd5 100644
--- a/src/utils/environment_variable.cpp
+++ b/src/utils/environment_variable.cpp
@@ -50,7 +50,7 @@ std::optional<std::vector<std::string>> fromEnvString(
     return std::nullopt;
   }
 }
-
+template <>
 std::optional<std::vector<unsigned int>> fromEnvString(
     const std::string &env_string) {
   const auto &strings = fromEnvString<std::vector<std::string>>(env_string);
-- 
GitLab


From 49bbd40776328b83de9e3ef7642414a1313c6d6a Mon Sep 17 00:00:00 2001
From: VALENTIN SEITZ <valentin.seitz@bsc.es>
Date: Fri, 26 Jul 2024 19:43:45 +0200
Subject: [PATCH 03/12] Apply 1 suggestion(s) to 1 file(s)

Co-authored-by: JOAN VINYALS YLLA CATALA <joan.vinyals@bsc.es>
---
 src/backends/extrae/extrae_partial_tracer.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index 765de0d..c2c47b6 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -30,6 +30,7 @@ void ExtraePartialTracer::start() noexcept {
 void ExtraePartialTracer::Init() noexcept {
   // First init the type stack
   type_stack_strategy_->Init();
+  // And pause extrae
   shutdown();
 
   // then we check the env
-- 
GitLab


From 182ca555759853e53fe56d46b542bc0681d61d70 Mon Sep 17 00:00:00 2001
From: VALENTIN SEITZ <valentin.seitz@bsc.es>
Date: Fri, 26 Jul 2024 19:44:05 +0200
Subject: [PATCH 04/12] Apply 1 suggestion(s) to 1 file(s)

Co-authored-by: JOAN VINYALS YLLA CATALA <joan.vinyals@bsc.es>
---
 src/backends/extrae/extrae_partial_tracer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index c2c47b6..99eb1ec 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -64,9 +64,9 @@ void ExtraePartialTracer::Init() noexcept {
 void ExtraePartialTracer::RegionStart(
     const ProperlyNestedRegionInformation &region) noexcept {
   const std::string region_name = std::string(region.name);
+
   // A bit costly maybe if there is a lot of jobs, but much easier than keeping
   // a tree or hashmap around
-
   std::vector<StartStopJob> matching_jobs;
   for (const auto &job : jobs_) {
     if ((job.region_name.compare(region_name) == 0) &&
-- 
GitLab


From 8c875125bcb7670038d6a7f254670f2d4536a44c Mon Sep 17 00:00:00 2001
From: VALENTIN SEITZ <valentin.seitz@bsc.es>
Date: Fri, 26 Jul 2024 19:53:38 +0200
Subject: [PATCH 05/12] Apply 1 suggestion(s) to 1 file(s)

Co-authored-by: JOAN VINYALS YLLA CATALA <joan.vinyals@bsc.es>
---
 src/backends/extrae/extrae_partial_tracer.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index 99eb1ec..a16c386 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -103,6 +103,7 @@ void ExtraePartialTracer::RegionStart(
     type_stack_strategy_->RegionStart(region);
   }
 }
+
 void ExtraePartialTracer::RegionStopLast(
     const ProperlyNestedRegionInformation &region) noexcept {
   const std::string region_name = std::string(region.name);
-- 
GitLab


From a8e62567df1649bb3df3a3016f40483e82c4f44d Mon Sep 17 00:00:00 2001
From: VALENTIN SEITZ <valentin.seitz@bsc.es>
Date: Fri, 26 Jul 2024 19:56:32 +0200
Subject: [PATCH 06/12] Apply 1 suggestion(s) to 1 file(s)

Co-authored-by: JOAN VINYALS YLLA CATALA <joan.vinyals@bsc.es>
---
 src/utils/environment_variable.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/utils/environment_variable.cpp b/src/utils/environment_variable.cpp
index e00cbd5..822867a 100644
--- a/src/utils/environment_variable.cpp
+++ b/src/utils/environment_variable.cpp
@@ -50,6 +50,7 @@ std::optional<std::vector<std::string>> fromEnvString(
     return std::nullopt;
   }
 }
+
 template <>
 std::optional<std::vector<unsigned int>> fromEnvString(
     const std::string &env_string) {
-- 
GitLab


From d6fbd8bd1af15d84e6c9e7ae07647ba0f7804034 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Mon, 29 Jul 2024 14:14:51 +0200
Subject: [PATCH 07/12] Remove static threadlocal stuff as not needed

---
 src/backends/extrae/extrae_type_stack.hpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/backends/extrae/extrae_type_stack.hpp b/src/backends/extrae/extrae_type_stack.hpp
index b66bd55..cef9657 100644
--- a/src/backends/extrae/extrae_type_stack.hpp
+++ b/src/backends/extrae/extrae_type_stack.hpp
@@ -28,19 +28,19 @@ class ExtraeTypeStackStrategy : public ProperlyNestedAnnotationStrategy {
   static const std::string paraverConfigOverviewWindow;
   static const std::string paraverConfigLevelWindow;
 
+  inline static const int paraverConfigWindowHeight_ = 115;
+  inline static const int paraverConfigWindowHeightPad_ = 35;
+
   EnvironmentVariable<bool> write_config_file_ = EnvironmentVariable<bool>(
       "EXTRAE_WRITE_CONFIG_FILE",
       "Write corresponding Paraver .cfg file if set to True", false);
 
-  inline static const int paraverConfigWindowHeight_ = 115;
-  inline static const int paraverConfigWindowHeightPad_ = 35;
-
   MPIHelper mpi_helper_;
 
-  inline static bool didInitialize{false};
+  bool didInitialize{false};
 
-  inline static thread_local RegionStackData regionStackData;
-  inline static thread_local RegionMapData regionMapData;
+  RegionStackData regionStackData;
+  RegionMapData regionMapData;
   extrae_value get_value_by_region_name(const std::string &name);
 
  public:
-- 
GitLab


From b4bc01da7e0025cca3fb8714cffa0642ffd196c6 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Tue, 30 Jul 2024 17:18:26 +0200
Subject: [PATCH 08/12] add some debug statements

---
 src/backends/extrae/extrae_partial_tracer.cpp | 30 +++++++++++++++++++
 src/backends/extrae/extrae_partial_tracer.hpp |  3 ++
 2 files changed, 33 insertions(+)

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index a16c386..e71d425 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -16,12 +16,18 @@ ExtraePartialTracer::ExtraePartialTracer() : mpi_helper_{} {
 }
 
 void ExtraePartialTracer::shutdown() noexcept {
+  if (debug_output_.getValue().value_or(false) && mpi_helper_.IsRankNumber(0)) {
+    std::cout << "neSmiK Partial Tracer: Shutting down" << std::endl;
+  }
   type_stack_strategy_->RegionStart({"Extrae OFF", {}});
   Extrae_shutdown();
   is_shutdown_ = true;
 }
 
 void ExtraePartialTracer::start() noexcept {
+  if (debug_output_.getValue().value_or(false) && mpi_helper_.IsRankNumber(0)) {
+    std::cout << "neSmiK Partial Tracer: Starting up" << std::endl;
+  }
   Extrae_restart();
   type_stack_strategy_->RegionStopLast({"Extrae OFF", {}});
   is_shutdown_ = false;
@@ -59,6 +65,18 @@ void ExtraePartialTracer::Init() noexcept {
                      .stop_at = regions_stop_at_env_.getValue().value()[i]};
     jobs_.push_back(job);
   }
+
+  if (debug_output_.getValue().value_or(false) && mpi_helper_.IsRankNumber(0)) {
+    std::cout << "neSmiK Partial Tracer: Read the following jobs from env:"
+              << std::endl;
+    std::cout << "neSmiK Partial Tracer: {name,start_at,stop_at}" << std::endl;
+    for (std::size_t i = 0; i < jobs_.size(); i++) {
+      const auto &job = jobs_[i];
+      std::cout << "neSmiK Partial Tracer: Jobs: " << i << "{\""
+                << job.region_name << "\"," << job.start_at << ","
+                << job.stop_at << "}" << std::endl;
+    }
+  }
 }
 
 void ExtraePartialTracer::RegionStart(
@@ -94,6 +112,12 @@ void ExtraePartialTracer::RegionStart(
     }
     // We need to startup extrae and emit the region_start event
     start();
+  } else {
+    if (debug_output_.getValue().value_or(false) &&
+        mpi_helper_.IsRankNumber(0)) {
+      std::cout << "neSmiK Extrae::PartialTracer: No Start found for "
+                << region_name << std::endl;
+    }
   }
 
   region_counter_starts_[region_name]++;
@@ -140,6 +164,12 @@ void ExtraePartialTracer::RegionStopLast(
     }
     // We need to stop extrae
     shutdown();
+  } else {
+    if (debug_output_.getValue().value_or(false) &&
+        mpi_helper_.IsRankNumber(0)) {
+      std::cout << "neSmiK Extrae::PartialTracer: No Stop found for "
+                << region_name << std::endl;
+    }
   }
 
   region_counter_stops_[region_name]++;
diff --git a/src/backends/extrae/extrae_partial_tracer.hpp b/src/backends/extrae/extrae_partial_tracer.hpp
index 6f2093b..64f8dd3 100644
--- a/src/backends/extrae/extrae_partial_tracer.hpp
+++ b/src/backends/extrae/extrae_partial_tracer.hpp
@@ -34,6 +34,9 @@ class ExtraePartialTracer : public ProperlyNestedAnnotationStrategy {
           "should stop",
           true);
 
+  EnvironmentVariable<bool> debug_output_ =
+      EnvironmentVariable<bool>("PARTIAL_TRACER_DEBUG", "DEBUG output", false);
+
   MPIHelper mpi_helper_;
   std::unordered_map<std::string, unsigned int> region_counter_starts_;
   std::unordered_map<std::string, unsigned int> region_counter_stops_;
-- 
GitLab


From ef28ed0ecf4cd971f8929ff402fd63cd006eac46 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Thu, 1 Aug 2024 15:00:08 +0200
Subject: [PATCH 09/12] Massive refactor of extrae infrastructure

---
 src/backends/extrae/CMakeLists.txt            |   2 +-
 src/backends/extrae/extrae_partial_tracer.cpp |  25 +-
 src/backends/extrae/extrae_partial_tracer.hpp |   8 +
 src/backends/extrae/extrae_type_stack.cpp     | 268 ++----------------
 src/backends/extrae/extrae_type_stack.hpp     |  21 +-
 src/backends/extrae/extrae_types.hpp          |   5 +
 src/backends/extrae/extrae_wrapper.cpp        | 142 ++++++++++
 src/backends/extrae/extrae_wrapper.hpp        |  39 +++
 src/backends/extrae/paraver_config.cpp        | 134 +++++++++
 src/backends/extrae/paraver_config.hpp        |  29 ++
 10 files changed, 413 insertions(+), 260 deletions(-)
 create mode 100644 src/backends/extrae/extrae_types.hpp
 create mode 100644 src/backends/extrae/extrae_wrapper.cpp
 create mode 100644 src/backends/extrae/extrae_wrapper.hpp
 create mode 100644 src/backends/extrae/paraver_config.cpp
 create mode 100644 src/backends/extrae/paraver_config.hpp

diff --git a/src/backends/extrae/CMakeLists.txt b/src/backends/extrae/CMakeLists.txt
index 2512a61..e8ec467 100644
--- a/src/backends/extrae/CMakeLists.txt
+++ b/src/backends/extrae/CMakeLists.txt
@@ -1 +1 @@
-target_sources(nesmik PRIVATE extrae_partial_tracer.cpp extrae_type_stack.cpp)
+target_sources(nesmik PRIVATE extrae_partial_tracer.cpp extrae_type_stack.cpp extrae_wrapper.cpp paraver_config.cpp)
diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index e71d425..3c262e7 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -1,6 +1,7 @@
 #include "extrae_partial_tracer.hpp"
 
 #include <algorithm>
+#include <fstream>
 #include <memory>
 #include <string>
 extern "C" {
@@ -12,14 +13,16 @@ ExtraePartialTracer::ExtraePartialTracer() : mpi_helper_{} {
   parallelism_descriptor_ = {
       .mpi_descriptor_ = MPIDescriptor::Aware,
       .thread_descriptor_ = ThreadDescriptor::Unsupported};
+  extrae_wrapper_ = std::make_unique<ExtraeWrapper>(state_type_);
   type_stack_strategy_ = std::make_unique<ExtraeTypeStackStrategy>();
+  extrae_wrapper_->RegisterTypeWithDescription(type_description, state_type_);
 }
 
 void ExtraePartialTracer::shutdown() noexcept {
   if (debug_output_.getValue().value_or(false) && mpi_helper_.IsRankNumber(0)) {
     std::cout << "neSmiK Partial Tracer: Shutting down" << std::endl;
   }
-  type_stack_strategy_->RegionStart({"Extrae OFF", {}});
+  extrae_wrapper_->StopWithTypeAndRegionName(state_type_, "ON");
   Extrae_shutdown();
   is_shutdown_ = true;
 }
@@ -29,13 +32,11 @@ void ExtraePartialTracer::start() noexcept {
     std::cout << "neSmiK Partial Tracer: Starting up" << std::endl;
   }
   Extrae_restart();
-  type_stack_strategy_->RegionStopLast({"Extrae OFF", {}});
+  extrae_wrapper_->StartWithTypeAndRegionName(state_type_, "ON");
   is_shutdown_ = false;
 }
 
 void ExtraePartialTracer::Init() noexcept {
-  // First init the type stack
-  type_stack_strategy_->Init();
   // And pause extrae
   shutdown();
 
@@ -77,6 +78,8 @@ void ExtraePartialTracer::Init() noexcept {
                 << job.stop_at << "}" << std::endl;
     }
   }
+
+  is_initialized_ = true;
 }
 
 void ExtraePartialTracer::RegionStart(
@@ -133,6 +136,7 @@ void ExtraePartialTracer::RegionStopLast(
   const std::string region_name = std::string(region.name);
 
   if (!is_shutdown_) {
+    std::cout << "Region stop last " << region.name << std::endl;
     type_stack_strategy_->RegionStopLast(region);
   }
 
@@ -176,5 +180,18 @@ void ExtraePartialTracer::RegionStopLast(
 }
 
 void ExtraePartialTracer::Finalize() noexcept {
+  if (write_config_file_.getValue().value_or(true) &&
+      mpi_helper_.IsRankNumber(0)) {
+    std::string fileName = "nesmik_running.cfg";
+    std::ofstream out_file;
+    out_file.open(fileName);
+    ExtraeParaverConfig paraver_config{
+        .stacked_window_name = std::nullopt,
+        .description = "neSmiK Partial Tracer state"};
+    // write config
+    out_file << extrae_wrapper_->getParaverConfig(paraver_config) << std::endl;
+  }
+
+  extrae_wrapper_->Finalize();
   type_stack_strategy_->Finalize();
 }
diff --git a/src/backends/extrae/extrae_partial_tracer.hpp b/src/backends/extrae/extrae_partial_tracer.hpp
index 64f8dd3..22c2037 100644
--- a/src/backends/extrae/extrae_partial_tracer.hpp
+++ b/src/backends/extrae/extrae_partial_tracer.hpp
@@ -37,14 +37,22 @@ class ExtraePartialTracer : public ProperlyNestedAnnotationStrategy {
   EnvironmentVariable<bool> debug_output_ =
       EnvironmentVariable<bool>("PARTIAL_TRACER_DEBUG", "DEBUG output", false);
 
+  EnvironmentVariable<bool> write_config_file_ = EnvironmentVariable<bool>(
+      "EXTRAE_WRITE_CONFIG_FILE",
+      "Write corresponding Paraver .cfg file if set to True", false);
+
   MPIHelper mpi_helper_;
   std::unordered_map<std::string, unsigned int> region_counter_starts_;
   std::unordered_map<std::string, unsigned int> region_counter_stops_;
   std::vector<StartStopJob> jobs_;
   bool is_shutdown_{true};
+  bool is_initialized_{false};
+  std::unique_ptr<ExtraeWrapper> extrae_wrapper_;
   std::unique_ptr<ExtraeTypeStackStrategy> type_stack_strategy_;
   void shutdown() noexcept;
   void start() noexcept;
+  const extrae_type state_type_{9780};
+  const std::string type_description = "Extrae::PartialTracer State";
 
  public:
   ExtraePartialTracer();
diff --git a/src/backends/extrae/extrae_type_stack.cpp b/src/backends/extrae/extrae_type_stack.cpp
index be8be21..57714a4 100644
--- a/src/backends/extrae/extrae_type_stack.cpp
+++ b/src/backends/extrae/extrae_type_stack.cpp
@@ -5,6 +5,7 @@
 #include <fstream>
 #include <iostream>
 #include <numeric>
+#include <optional>
 #include <regex>
 #include <string>
 #include <vector>
@@ -17,121 +18,15 @@ ExtraeTypeStackStrategy::ExtraeTypeStackStrategy() : mpi_helper_{} {
   parallelism_descriptor_ = {
       .mpi_descriptor_ = MPIDescriptor::Aware,
       .thread_descriptor_ = ThreadDescriptor::Unsupported};
-}
-
-const std::string ExtraeTypeStackStrategy::paraverConfigHead = R"(
-#ParaverCFG
-ConfigFile.Version: 3.4
-ConfigFile.NumWindows: 2
-ConfigFile.BeginDescription
-Configuration to visualize the annotation done by neSmiK in Paraver
-ConfigFile.EndDescription
-)";
-
-const std::string ExtraeTypeStackStrategy::paraverConfigOverviewWindow = R"(
-################################################################################
-< NEW DISPLAYING WINDOW neSmiK Annotation Overview >
-################################################################################
-window_name neSmiK Annotation Overview
-window_type single
-window_position_x 400
-window_position_y 150
-window_width 600
-window_height NESMIK_REPLACE_WINDOW_HEIGHT
-window_comm_lines_enabled false
-window_flags_enabled false
-window_noncolor_mode true
-window_custom_color_enabled false
-window_semantic_scale_min_at_zero false
-window_logical_filtered true
-window_physical_filtered false
-window_intracomms_enabled true
-window_intercomms_enabled true
-window_comm_fromto true
-window_comm_tagsize true
-window_comm_typeval true
-window_maximum_y NESMIK_REPLACE_SEMANTIC_MAX
-window_minimum_y 0
-window_compute_y_max false
-window_level thread
-window_scale_relative 1.000000000000
-window_end_time_relative 1.000000000000
-window_object appl { 1, { All } }
-window_begin_time_relative 0.000000000000
-window_open true
-window_drawmode draw_maximum
-window_drawmode_rows draw_maximum
-window_pixel_size 1
-window_labels_to_draw 1
-window_object_axis_position 0
-window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } }
-window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, Stacked Val}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } }
-window_filter_module evt_type NESMIK_REPLACE_NUM_LEVELS NESMIK_REPLACE_LEVELS
-)";
-
-const std::string ExtraeTypeStackStrategy::paraverConfigLevelWindow = R"(
-################################################################################
-< NEW DISPLAYING WINDOW NESMIK_REPLACE_WINDOW_NAME >
-################################################################################
-window_name NESMIK_REPLACE_WINDOW_NAME
-window_type single
-window_position_x 400
-window_position_y NESMIK_REPLACE_WINDOW_Y_POSITION
-window_width 600
-window_height NESMIK_REPLACE_WINDOW_HEIGHT
-window_comm_lines_enabled false
-window_flags_enabled false
-window_noncolor_mode true
-window_custom_color_enabled false
-window_semantic_scale_min_at_zero false
-window_logical_filtered true
-window_physical_filtered false
-window_intracomms_enabled true
-window_intercomms_enabled true
-window_comm_fromto true
-window_comm_tagsize true
-window_comm_typeval true
-window_maximum_y NESMIK_REPLACE_SEMANTIC_MAX
-window_minimum_y 0
-window_compute_y_max false
-window_level thread
-window_scale_relative 1.000000000000
-window_end_time_relative 1.000000000000
-window_object appl { 1, { All } }
-window_begin_time_relative 0.000000000000
-window_open true
-window_drawmode draw_maximum
-window_drawmode_rows draw_maximum
-window_pixel_size 1
-window_labels_to_draw 1
-window_object_axis_position 0
-window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } }
-window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } }
-window_filter_module evt_type 1 NESMIK_REPLACE_EVENT_TYPE
-)";
 
-void ExtraeTypeStackStrategy::Init() noexcept {
-  auto isInitializedVal = Extrae_is_initialized();
-  if (isInitializedVal == 0) {
-    // Extrae is not initialized yet see
-    // https://github.com/bsc-performance-tools/extrae/blob/daee11a2f98e301eb146608f51df0c844e1ff381/include/extrae_types.h#L33
-    Extrae_init();
-    didInitialize = true;
-    std::cout << "NESMIK forced to Initialize extrae" << std::endl;
-  }
+  extrae_wrapper_ = std::make_unique<ExtraeWrapper>(base_type_);
 }
 
-extrae_value ExtraeTypeStackStrategy::get_value_by_region_name(
-    const std::string &name) {
-  // maybe insert
-  if (regionMapData.regionNameToValue.count(name) > 0) {
-    return regionMapData.regionNameToValue[name];
-  } else
-  // if not allocate new entry
-  {
-    const auto newValue = regionMapData.regionNameToValue.size() + 1;
-    regionMapData.regionNameToValue[name] = newValue;
-    return newValue;
+void ExtraeTypeStackStrategy::Init() noexcept {
+  // initialize the stack levels up to MAX_STACK_LEVELS
+  for (std::size_t i = 0; i < MAX_STACK_LEVELS; i++) {
+    std::string description = "Level: " + std::to_string(i);
+    extrae_wrapper_->RegisterTypeWithDescription(description, base_type_ + i);
   }
 }
 
@@ -139,142 +34,35 @@ void ExtraeTypeStackStrategy::RegionStart(
     const ProperlyNestedRegionInformation &region) noexcept {
   // First push to stack
   const auto regionName = std::string(region.name);
-  auto typeOffset = regionStackData.regionNameStack.size();
-  regionStackData.regionNameStack.push(regionName);
-
-  regionStackData.historicMaxStackSize =
-      std::max(typeOffset, regionStackData.historicMaxStackSize);
-
-  auto value = get_value_by_region_name(regionName);
-
-  auto type = baseType + typeOffset;
-
-  Extrae_eventandcounters(type, value);
+  const auto level = region.stack_.size();
+  max_stack_size = std::max(level, max_stack_size);
+  std::string description = "Level: " + std::to_string(level);
+  extrae_wrapper_->StartWithTypeNameAndRegionName(description, regionName);
 }
 void ExtraeTypeStackStrategy::RegionStopLast(
     const ProperlyNestedRegionInformation &region) noexcept {
-  if (regionStackData.regionNameStack.empty()) {
-    // whoops
-    std::cout << "imbalanced region stop REASON: Empty stack " << region.name
-              << std::endl;
-    return;
-  }
-
-  const auto &lastRegionName = regionStackData.regionNameStack.top();
-
-  if (lastRegionName.compare(region.name) == 0) {
-    // its the same -> we pop it and end that stack level with a 0
-    regionStackData.regionNameStack.pop();
-    auto typeOffset = regionStackData.regionNameStack.size();
-    auto type = baseType + typeOffset;
-    Extrae_eventandcounters(type, 0);
-    return;
-  } else {
-    std::cout << "imbalanced region stop " << region.name << std::endl;
-  }
+  const auto regionName = std::string(region.name);
+  const auto level = region.stack_.size();
+  max_stack_size = std::max(level, max_stack_size);
+  std::string description = "Level: " + std::to_string(level);
+  extrae_wrapper_->StopWithTypeNameAndRegionName(description, regionName);
 }
 
 void ExtraeTypeStackStrategy::Finalize() noexcept {
-  unsigned int numberOfRegionsRegistered =
-      regionMapData.regionNameToValue.size();
-  std::vector<extrae_value_t> values{};
-  std::vector<std::string> routine_names{};
-
-  for (const auto &item : regionMapData.regionNameToValue) {
-    const auto &routine_name = item.first;
-    const auto &value = item.second;
-    routine_names.push_back(routine_name);
-    values.push_back(value);
-  }
-  // leaking memory a bit, but c vs c++ strings are not worth making it not
-  // leaky?
-  char **routine_c_names = new char *[numberOfRegionsRegistered];
-  for (unsigned int i = 0; i < numberOfRegionsRegistered; i++) {
-    routine_c_names[i] = new char[routine_names[i].size() + 1];
-    std::strcpy(routine_c_names[i], routine_names[i].c_str());
-  }
-
-  for (unsigned int level = 0; level <= regionStackData.historicMaxStackSize;
-       level++) {
-    extrae_type_t type = baseType + level;
-    std::string description = "Level: " + std::to_string(level);
-    Extrae_define_event_type(&type, const_cast<char *>(description.c_str()),
-                             &numberOfRegionsRegistered, values.data(),
-                             routine_c_names);
-  }
-
   if (write_config_file_.getValue().value_or(write_config_file_default_) &&
       mpi_helper_.IsRankNumber(0)) {
     std::string fileName = "nesmik_annotations.cfg";
-    std::ofstream outputFile;
-    outputFile.open(fileName);
-
-    // write header
-    outputFile << paraverConfigHead;
-
-    // compute overview
-    auto numberOfEventTypes =
-        regionStackData.historicMaxStackSize + 1;  // 0 based so plus 1
-    auto allTypes = std::vector<extrae_type>(numberOfEventTypes);
-    std::iota(std::begin(allTypes), std::end(allTypes),
-              baseType);  // Fill with baseType baseType+1 ..
-
-    // Build a small list of all types
-    std::string allTypesString = "";
-    for (const auto &type : allTypes) {
-      allTypesString += std::to_string(type) + " ";
-    }
-
-    auto overviewReplacedNumLevels = std::regex_replace(
-        paraverConfigOverviewWindow, std::regex("NESMIK_REPLACE_NUM_LEVELS"),
-        std::to_string(numberOfEventTypes));
-    auto replacedWindowHeightOverview = std::regex_replace(
-        overviewReplacedNumLevels, std::regex("NESMIK_REPLACE_WINDOW_HEIGHT"),
-        std::to_string(paraverConfigWindowHeight_));
-    auto replacedWindowSemanticMaxOverview = std::regex_replace(
-        replacedWindowHeightOverview, std::regex("NESMIK_REPLACE_SEMANTIC_MAX"),
-        std::to_string(numberOfRegionsRegistered));
-    auto overviewReplacedAllTypes =
-        std::regex_replace(replacedWindowSemanticMaxOverview,
-                           std::regex("NESMIK_REPLACE_LEVELS"), allTypesString);
-
-    // write Overview
-    outputFile << overviewReplacedAllTypes;
-    outputFile << std::endl;
-
-    // write separate windows
-    for (unsigned int level = 0; level <= regionStackData.historicMaxStackSize;
-         level++) {
-      std::string windowName =
-          "neSmiK Instrumentation Level: " + std::to_string(level);
-
-      auto replacedEventType = std::regex_replace(
-          paraverConfigLevelWindow, std::regex("NESMIK_REPLACE_EVENT_TYPE"),
-          std::to_string(baseType + level));
-      auto replacedWindowHeight = std::regex_replace(
-          replacedEventType, std::regex("NESMIK_REPLACE_WINDOW_HEIGHT"),
-          std::to_string(paraverConfigWindowHeight_));
-      auto replacedWindowYPosition = std::regex_replace(
-          replacedWindowHeight, std::regex("NESMIK_REPLACE_WINDOW_Y_POSITION"),
-          std::to_string(
-              (paraverConfigWindowHeight_ + paraverConfigWindowHeightPad_) *
-              (level + 2 /* offset with overview window */)));
-      auto replacedWindowSemanticMax = std::regex_replace(
-          replacedWindowYPosition, std::regex("NESMIK_REPLACE_SEMANTIC_MAX"),
-          std::to_string(numberOfRegionsRegistered));
-      auto replacedWindowName = std::regex_replace(
-          replacedWindowSemanticMax, std::regex("NESMIK_REPLACE_WINDOW_NAME"),
-          windowName);
-
-      // write Overview
-      outputFile << replacedWindowName;
-      outputFile << std::endl;
-    }
-  }
-
-  if (didInitialize) {
-    // Assumption is that if we needed to initialize the lib we also need to
-    // Finalize it
-    Extrae_fini();
+    std::ofstream out_file;
+    out_file.open(fileName);
+    ExtraeParaverConfig paraver_config{
+        .stacked_window_name =
+            std::optional<std::string>("neSmiK Annotation Overview"),
+        .description =
+            "neSmiK annotation regions using the Extrae::TypeStack Backend"
+
+    };
+    // write config
+    out_file << extrae_wrapper_->getParaverConfig(paraver_config) << std::endl;
   }
+  extrae_wrapper_->Finalize();
 }
diff --git a/src/backends/extrae/extrae_type_stack.hpp b/src/backends/extrae/extrae_type_stack.hpp
index cef9657..dc1277b 100644
--- a/src/backends/extrae/extrae_type_stack.hpp
+++ b/src/backends/extrae/extrae_type_stack.hpp
@@ -6,15 +6,10 @@
 #include <utils/environment_variable.hpp>
 #include <utils/parallelism_helper.hpp>
 
+#include "extrae_types.hpp"
+#include "extrae_wrapper.hpp"
 #include "strategies.hpp"
 // #include <mutex>
-typedef unsigned long extrae_value;
-typedef unsigned long extrae_type;
-
-struct RegionStackData {
-  std::stack<std::string> regionNameStack;
-  std::size_t historicMaxStackSize;
-};
 
 struct RegionMapData {
   std::unordered_map<std::string, extrae_value> regionNameToValue;
@@ -23,23 +18,19 @@ struct RegionMapData {
 class ExtraeTypeStackStrategy : public ProperlyNestedAnnotationStrategy {
  private:
   const bool write_config_file_default_{true};
-  const unsigned long baseType{81000};
-  static const std::string paraverConfigHead;
-  static const std::string paraverConfigOverviewWindow;
-  static const std::string paraverConfigLevelWindow;
-
-  inline static const int paraverConfigWindowHeight_ = 115;
-  inline static const int paraverConfigWindowHeightPad_ = 35;
+  const extrae_type base_type_{81000};      // base event for the MPI wrapper
+  const std::size_t MAX_STACK_LEVELS = 50;  // maximum of supported stack levels
 
   EnvironmentVariable<bool> write_config_file_ = EnvironmentVariable<bool>(
       "EXTRAE_WRITE_CONFIG_FILE",
       "Write corresponding Paraver .cfg file if set to True", false);
 
   MPIHelper mpi_helper_;
+  std::unique_ptr<ExtraeWrapper> extrae_wrapper_;
 
   bool didInitialize{false};
 
-  RegionStackData regionStackData;
+  std::size_t max_stack_size{0};
   RegionMapData regionMapData;
   extrae_value get_value_by_region_name(const std::string &name);
 
diff --git a/src/backends/extrae/extrae_types.hpp b/src/backends/extrae/extrae_types.hpp
new file mode 100644
index 0000000..35c5025
--- /dev/null
+++ b/src/backends/extrae/extrae_types.hpp
@@ -0,0 +1,5 @@
+#ifndef NESMIK_EXTRAE_TYPES_HPP
+#define NESMIK_EXTRAE_TYPES_HPP
+typedef unsigned long extrae_value;
+typedef unsigned long extrae_type;
+#endif  // NESMIK_EXTRAE_TYPES_HPP
diff --git a/src/backends/extrae/extrae_wrapper.cpp b/src/backends/extrae/extrae_wrapper.cpp
new file mode 100644
index 0000000..25f664e
--- /dev/null
+++ b/src/backends/extrae/extrae_wrapper.cpp
@@ -0,0 +1,142 @@
+#include "extrae_wrapper.hpp"
+
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "extrae_types.hpp"
+#include "paraver_config.hpp"
+
+extern "C" {
+#include <extrae.h>
+}
+ExtraeWrapper::ExtraeWrapper(extrae_type base_type) : base_type_(base_type) {
+  auto isInitializedVal = Extrae_is_initialized();
+  if (isInitializedVal == 0) {
+    // Extrae is not initialized yet see
+    // https://github.com/bsc-performance-tools/extrae/blob/daee11a2f98e301eb146608f51df0c844e1ff381/include/extrae_types.h#L33
+    Extrae_init();
+    did_init_extrae_ = true;
+    std::cout << "neSmiK forced to Initialize extrae" << std::endl;
+  }
+}
+
+extrae_value ExtraeWrapper::getValueByName(extrae_type type,
+                                           const std::string &name) {
+  value_map_t &value_map = string_to_value_;
+  if (value_map.count(name) > 0) {
+    return value_map[name];
+  } else
+  // if not allocate new entry
+  {
+    const auto newValue = value_map.size() + 1;
+    value_map[name] = newValue;
+    return newValue;
+  }
+}
+
+void ExtraeWrapper::RegisterTypeWithDescription(
+    const std::string &type_description, extrae_type type) {
+  type_map_[type_description] = type;
+}
+void ExtraeWrapper::StartWithTypeAndRegionName(extrae_type type,
+                                               const std::string &value_str) {
+  const auto value = getValueByName(type, value_str);
+  // write it in type specific map
+  type_to_value_map_[type][value_str] = value;
+  Extrae_eventandcounters(static_cast<extrae_type_t>(type),
+                          static_cast<extrae_value_t>(value));
+}
+
+void ExtraeWrapper::StopWithTypeAndRegionName(extrae_type type,
+                                              const std::string &value_str) {
+  Extrae_eventandcounters(static_cast<extrae_type_t>(type), 0);
+}
+
+void ExtraeWrapper::StopWithTypeNameAndRegionName(
+    const std::string type_description, const std::string &value_str) {
+  // if this assertion fails, the type with that description has not been
+  // registered before and not started.
+  assert(type_map_.count(type_description) > 0);
+  return StopWithTypeAndRegionName(type_map_[type_description], value_str);
+}
+
+void ExtraeWrapper::StartWithTypeNameAndRegionName(
+    const std::string type_description, const std::string &value_str) {
+  if (type_map_.count(type_description) == 0) {
+    const auto new_type = type_map_.size();
+    type_map_[type_description] = base_type_ + new_type;
+  }
+  return StartWithTypeAndRegionName(type_map_[type_description], value_str);
+}
+
+void ExtraeWrapper::Finalize() {
+  // now for ever type define the event types:
+  for (const auto &[description, type_from_map] : type_map_) {
+    // For every type registered:
+    extrae_type_t type = static_cast<extrae_type_t>(type_from_map);
+    const value_map_t &value_map = type_to_value_map_[type];
+    unsigned number_of_regions = value_map.size();
+
+    char **routine_c_names = new char *[number_of_regions];
+    std::vector<extrae_value_t> values;
+
+    values.reserve(number_of_regions);
+    std::size_t i = 0;
+    for (const auto &[name, value] : value_map) {
+      values.push_back(static_cast<extrae_value_t>(value));
+      routine_c_names[i] =
+          new char[name.size() + 1];  // +1 for null terminiation
+      std::strcpy(routine_c_names[i], name.c_str());
+      i++;
+    }
+
+    Extrae_define_event_type(&type, const_cast<char *>(description.c_str()),
+                             &number_of_regions, values.data(),
+                             routine_c_names);
+
+    // free up the memory, long live std::vector
+    for (std::size_t n; n < number_of_regions; n++) {
+      delete[] routine_c_names[n];
+    }
+    delete[] routine_c_names;
+  }
+
+  if (did_init_extrae_) {
+    // Assumption is that if we needed to initialize the lib we also need to
+    // Finalize it
+    Extrae_fini();
+  }
+}
+
+std::string ExtraeWrapper::getParaverConfig(ExtraeParaverConfig config) {
+  ParaverConfig paraver_config(config.description);
+
+  // create arrays
+  std::vector<extrae_type> types;
+  std::vector<std::string> window_names;
+  std::vector<extrae_value> semantic_maximums;
+  for (const auto &[name, type] : type_map_) {
+    types.push_back(type);
+    window_names.push_back(name);
+    // now the ugly search for the semantic maximum
+    extrae_value semantic_maximum{0};
+    for (const auto &[value_name, value] : type_to_value_map_[type]) {
+      semantic_maximum = std::max(value, semantic_maximum);
+    }
+    semantic_maximums.push_back(semantic_maximum);
+  }
+
+  ParaverTimelineWindow window{
+      .window_names = window_names,
+      .types = types,
+      .semantic_maximums = semantic_maximums,
+      .stacked_window_name = config.stacked_window_name};
+
+  paraver_config.addTimeline(window);
+
+  return paraver_config.getString();
+}
diff --git a/src/backends/extrae/extrae_wrapper.hpp b/src/backends/extrae/extrae_wrapper.hpp
new file mode 100644
index 0000000..125668f
--- /dev/null
+++ b/src/backends/extrae/extrae_wrapper.hpp
@@ -0,0 +1,39 @@
+#include <optional>
+#include <string>
+#include <unordered_map>
+
+#include "extrae_types.hpp"
+
+struct ExtraeParaverConfig {
+  std::optional<std::string> stacked_window_name;
+  std::string description;
+};
+
+using value_map_t = std::unordered_map<std::string, extrae_value>;
+class ExtraeWrapper {
+  const extrae_type base_type_;
+
+ private:
+  std::unordered_map<std::string, extrae_type> type_map_;
+  std::unordered_map<extrae_type, value_map_t> type_to_value_map_;
+  std::unordered_map<std::string, extrae_value> string_to_value_;
+  bool did_init_extrae_{false};
+
+  extrae_value getValueByName(extrae_type type, const std::string &name);
+
+ public:
+  ExtraeWrapper(extrae_type base_type);
+  void RegisterTypeWithDescription(const std::string &type_description,
+                                   extrae_type type);
+  void StartWithTypeNameAndRegionName(const std::string type_description,
+                                      const std::string &value_str);
+  void StartWithTypeAndRegionName(extrae_type type,
+                                  const std::string &value_str);
+  void StopWithTypeAndRegionName(extrae_type type,
+                                 const std::string &value_str);
+  void StopWithTypeNameAndRegionName(const std::string type_description,
+                                     const std::string &value_str);
+
+  std::string getParaverConfig(ExtraeParaverConfig config);
+  void Finalize();
+};
diff --git a/src/backends/extrae/paraver_config.cpp b/src/backends/extrae/paraver_config.cpp
new file mode 100644
index 0000000..a04799e
--- /dev/null
+++ b/src/backends/extrae/paraver_config.cpp
@@ -0,0 +1,134 @@
+
+#include "paraver_config.hpp"
+
+#include <cassert>
+#include <numeric>
+#include <regex>
+#include <string>
+
+const std::string ParaverConfig::config_head_ = R"(
+#ParaverCFG
+ConfigFile.Version: 3.4
+ConfigFile.NumWindows: 2
+ConfigFile.BeginDescription
+NESMIK_REPLACE_DESCRIPTION
+ConfigFile.EndDescription
+)";
+const std::string ParaverConfig::time_line_window_template_ = R"(
+################################################################################
+< NEW DISPLAYING WINDOW NESMIK_REPLACE_WINDOW_NAME >
+################################################################################
+window_name NESMIK_REPLACE_WINDOW_NAME
+window_type single
+window_position_x 400
+window_position_y NESMIK_REPLACE_WINDOW_Y_POSITION
+window_width 600
+window_height NESMIK_REPLACE_WINDOW_HEIGHT
+window_comm_lines_enabled false
+window_flags_enabled false
+window_noncolor_mode true
+window_custom_color_enabled false
+window_semantic_scale_min_at_zero false
+window_logical_filtered true
+window_physical_filtered false
+window_intracomms_enabled true
+window_intercomms_enabled true
+window_comm_fromto true
+window_comm_tagsize true
+window_comm_typeval true
+window_maximum_y NESMIK_REPLACE_SEMANTIC_MAX
+window_minimum_y 0
+window_compute_y_max false
+window_level thread
+window_scale_relative 1.000000000000
+window_end_time_relative 1.000000000000
+window_object appl { 1, { All } }
+window_begin_time_relative 0.000000000000
+window_open true
+window_drawmode draw_maximum
+window_drawmode_rows draw_maximum
+window_pixel_size 1
+window_labels_to_draw 1
+window_object_axis_position 0
+window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } }
+window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, Stacked Val}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } }
+window_filter_module evt_type NESMIK_REPLACE_NUM_EVENTTYPES NESMIK_REPLACE_EVENTTYPES
+)";
+
+ParaverConfig::ParaverConfig(const std::string &description) {
+  auto head_with_description = std::regex_replace(
+      config_head_, std::regex("NESMIK_REPLACE_DESCRIPTION"), description);
+
+  config_ << head_with_description << "\n";
+}
+
+void ParaverConfig::addTimeline(ParaverTimelineWindow window_config) {
+  assert(window_config.types.size() == window_config.semantic_maximums.size() &&
+         window_config.types.size() == window_config.window_names.size());
+
+  // replace window height
+  auto repalaced_window_height = std::regex_replace(
+      time_line_window_template_, std::regex("NESMIK_REPLACE_WINDOW_HEIGHT"),
+      std::to_string(window_height_));
+
+  if (window_config.stacked_window_name.has_value()) {
+    // Build a small list of all types
+    std::string allTypesString = "";
+    for (const auto &type : window_config.types) {
+      allTypesString += std::to_string(type) + " ";
+    }
+
+    auto replace_window_name = std::regex_replace(
+        repalaced_window_height, std::regex("NESMIK_REPLACE_WINDOW_NAME"),
+        window_config.stacked_window_name.value());
+
+    auto replaced_event_type = std::regex_replace(
+        replace_window_name, std::regex("NESMIK_REPLACE_EVENTTYPES"),
+        allTypesString);
+
+    auto replaced_event_num = std::regex_replace(
+        replaced_event_type, std::regex("NESMIK_REPLACE_NUM_EVENTTYPES"),
+        std::to_string(window_config.types.size()));
+
+    auto replaced_window_y_pos = std::regex_replace(
+        replaced_event_num, std::regex("NESMIK_REPLACE_WINDOW_Y_POSITION"),
+        std::to_string(150));
+
+    const extrae_type max_value_in_array =
+        *std::max_element(window_config.semantic_maximums.begin(),
+                          window_config.semantic_maximums.end());
+    auto replaced_semantic_max = std::regex_replace(
+        replaced_window_y_pos, std::regex("NESMIK_REPLACE_SEMANTIC_MAX"),
+        std::to_string(max_value_in_array));
+
+    config_ << replaced_semantic_max << "\n";
+  }
+
+  std::size_t number_of_types = window_config.types.size();
+  // now iterate over the types
+  for (std::size_t i = 0; i < number_of_types; i++) {
+    auto replace_window_name = std::regex_replace(
+        repalaced_window_height, std::regex("NESMIK_REPLACE_WINDOW_NAME"),
+        window_config.window_names[i]);
+
+    auto replaced_event_type = std::regex_replace(
+        replace_window_name, std::regex("NESMIK_REPLACE_EVENTTYPES"),
+        std::to_string(window_config.types[i]));
+
+    auto replaced_event_num = std::regex_replace(
+        replaced_event_type, std::regex("NESMIK_REPLACE_NUM_EVENTTYPES"),
+        std::to_string(1));
+
+    auto replaced_window_y_pos = std::regex_replace(
+        replaced_event_num, std::regex("NESMIK_REPLACE_WINDOW_Y_POSITION"),
+        std::to_string((window_height_ + window_height_pad_) * (i + 2)));
+
+    auto replaced_semantic_max = std::regex_replace(
+        replaced_window_y_pos, std::regex("NESMIK_REPLACE_SEMANTIC_MAX"),
+        std::to_string(window_config.semantic_maximums[i]));
+
+    config_ << replaced_semantic_max << "\n";
+  }
+}
+
+std::string ParaverConfig::getString() { return config_.str(); }
diff --git a/src/backends/extrae/paraver_config.hpp b/src/backends/extrae/paraver_config.hpp
new file mode 100644
index 0000000..91d609f
--- /dev/null
+++ b/src/backends/extrae/paraver_config.hpp
@@ -0,0 +1,29 @@
+
+#include <optional>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "extrae_types.hpp"
+
+struct ParaverTimelineWindow {
+  const std::vector<std::string> &window_names;
+  const std::vector<extrae_type> &types;
+  const std::vector<extrae_value> semantic_maximums;
+  std::optional<std::string> stacked_window_name;
+};
+
+class ParaverConfig {
+ private:
+  std::stringstream config_;
+  static const std::string config_head_;
+  static const std::string time_line_window_template_;
+
+  const unsigned int window_height_ = 115;
+  const unsigned int window_height_pad_ = 35;
+
+ public:
+  ParaverConfig(const std::string &description);
+  void addTimeline(ParaverTimelineWindow window_config);
+  std::string getString();
+};
-- 
GitLab


From f859300441621424c87e6c7839c4fe68eff6cc95 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Thu, 1 Aug 2024 17:10:33 +0200
Subject: [PATCH 10/12] Fix small unitited value problem

---
 src/backends/extrae/extrae_wrapper.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/backends/extrae/extrae_wrapper.cpp b/src/backends/extrae/extrae_wrapper.cpp
index 25f664e..45fe235 100644
--- a/src/backends/extrae/extrae_wrapper.cpp
+++ b/src/backends/extrae/extrae_wrapper.cpp
@@ -99,7 +99,7 @@ void ExtraeWrapper::Finalize() {
                              routine_c_names);
 
     // free up the memory, long live std::vector
-    for (std::size_t n; n < number_of_regions; n++) {
+    for (std::size_t n = 0; n < number_of_regions; n++) {
       delete[] routine_c_names[n];
     }
     delete[] routine_c_names;
-- 
GitLab


From 4126645f8ab4bfefb9e53e90a7c4e8feab2b1df8 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Mon, 5 Aug 2024 12:22:05 +0200
Subject: [PATCH 11/12] - removed some dead code - moved to stack allocation

---
 src/backends/extrae/extrae_partial_tracer.cpp | 17 ++++++++---------
 src/backends/extrae/extrae_partial_tracer.hpp |  7 +++----
 src/backends/extrae/extrae_type_stack.cpp     | 15 +++++++--------
 src/backends/extrae/extrae_type_stack.hpp     |  9 +--------
 4 files changed, 19 insertions(+), 29 deletions(-)

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index 3c262e7..b473159 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -9,20 +9,21 @@ extern "C" {
 }
 #include <utils/terminator.hpp>
 
-ExtraePartialTracer::ExtraePartialTracer() : mpi_helper_{} {
+ExtraePartialTracer::ExtraePartialTracer()
+    : mpi_helper_{}, extrae_wrapper_{state_type_} {
   parallelism_descriptor_ = {
       .mpi_descriptor_ = MPIDescriptor::Aware,
       .thread_descriptor_ = ThreadDescriptor::Unsupported};
-  extrae_wrapper_ = std::make_unique<ExtraeWrapper>(state_type_);
+
   type_stack_strategy_ = std::make_unique<ExtraeTypeStackStrategy>();
-  extrae_wrapper_->RegisterTypeWithDescription(type_description, state_type_);
+  extrae_wrapper_.RegisterTypeWithDescription(type_description_, state_type_);
 }
 
 void ExtraePartialTracer::shutdown() noexcept {
   if (debug_output_.getValue().value_or(false) && mpi_helper_.IsRankNumber(0)) {
     std::cout << "neSmiK Partial Tracer: Shutting down" << std::endl;
   }
-  extrae_wrapper_->StopWithTypeAndRegionName(state_type_, "ON");
+  extrae_wrapper_.StopWithTypeAndRegionName(state_type_, "ON");
   Extrae_shutdown();
   is_shutdown_ = true;
 }
@@ -32,7 +33,7 @@ void ExtraePartialTracer::start() noexcept {
     std::cout << "neSmiK Partial Tracer: Starting up" << std::endl;
   }
   Extrae_restart();
-  extrae_wrapper_->StartWithTypeAndRegionName(state_type_, "ON");
+  extrae_wrapper_.StartWithTypeAndRegionName(state_type_, "ON");
   is_shutdown_ = false;
 }
 
@@ -78,8 +79,6 @@ void ExtraePartialTracer::Init() noexcept {
                 << job.stop_at << "}" << std::endl;
     }
   }
-
-  is_initialized_ = true;
 }
 
 void ExtraePartialTracer::RegionStart(
@@ -189,9 +188,9 @@ void ExtraePartialTracer::Finalize() noexcept {
         .stacked_window_name = std::nullopt,
         .description = "neSmiK Partial Tracer state"};
     // write config
-    out_file << extrae_wrapper_->getParaverConfig(paraver_config) << std::endl;
+    out_file << extrae_wrapper_.getParaverConfig(paraver_config) << std::endl;
   }
 
-  extrae_wrapper_->Finalize();
+  extrae_wrapper_.Finalize();
   type_stack_strategy_->Finalize();
 }
diff --git a/src/backends/extrae/extrae_partial_tracer.hpp b/src/backends/extrae/extrae_partial_tracer.hpp
index 22c2037..b4b0a3a 100644
--- a/src/backends/extrae/extrae_partial_tracer.hpp
+++ b/src/backends/extrae/extrae_partial_tracer.hpp
@@ -46,13 +46,12 @@ class ExtraePartialTracer : public ProperlyNestedAnnotationStrategy {
   std::unordered_map<std::string, unsigned int> region_counter_stops_;
   std::vector<StartStopJob> jobs_;
   bool is_shutdown_{true};
-  bool is_initialized_{false};
-  std::unique_ptr<ExtraeWrapper> extrae_wrapper_;
+  ExtraeWrapper extrae_wrapper_;
   std::unique_ptr<ExtraeTypeStackStrategy> type_stack_strategy_;
   void shutdown() noexcept;
   void start() noexcept;
-  const extrae_type state_type_{9780};
-  const std::string type_description = "Extrae::PartialTracer State";
+  const extrae_type state_type_{82000};
+  const std::string type_description_ = "Extrae::PartialTracer State";
 
  public:
   ExtraePartialTracer();
diff --git a/src/backends/extrae/extrae_type_stack.cpp b/src/backends/extrae/extrae_type_stack.cpp
index 57714a4..43b816f 100644
--- a/src/backends/extrae/extrae_type_stack.cpp
+++ b/src/backends/extrae/extrae_type_stack.cpp
@@ -14,19 +14,18 @@ extern "C" {
 #include <extrae.h>
 }
 
-ExtraeTypeStackStrategy::ExtraeTypeStackStrategy() : mpi_helper_{} {
+ExtraeTypeStackStrategy::ExtraeTypeStackStrategy()
+    : mpi_helper_{}, extrae_wrapper_{base_type_} {
   parallelism_descriptor_ = {
       .mpi_descriptor_ = MPIDescriptor::Aware,
       .thread_descriptor_ = ThreadDescriptor::Unsupported};
-
-  extrae_wrapper_ = std::make_unique<ExtraeWrapper>(base_type_);
 }
 
 void ExtraeTypeStackStrategy::Init() noexcept {
   // initialize the stack levels up to MAX_STACK_LEVELS
   for (std::size_t i = 0; i < MAX_STACK_LEVELS; i++) {
     std::string description = "Level: " + std::to_string(i);
-    extrae_wrapper_->RegisterTypeWithDescription(description, base_type_ + i);
+    extrae_wrapper_.RegisterTypeWithDescription(description, base_type_ + i);
   }
 }
 
@@ -37,7 +36,7 @@ void ExtraeTypeStackStrategy::RegionStart(
   const auto level = region.stack_.size();
   max_stack_size = std::max(level, max_stack_size);
   std::string description = "Level: " + std::to_string(level);
-  extrae_wrapper_->StartWithTypeNameAndRegionName(description, regionName);
+  extrae_wrapper_.StartWithTypeNameAndRegionName(description, regionName);
 }
 void ExtraeTypeStackStrategy::RegionStopLast(
     const ProperlyNestedRegionInformation &region) noexcept {
@@ -45,7 +44,7 @@ void ExtraeTypeStackStrategy::RegionStopLast(
   const auto level = region.stack_.size();
   max_stack_size = std::max(level, max_stack_size);
   std::string description = "Level: " + std::to_string(level);
-  extrae_wrapper_->StopWithTypeNameAndRegionName(description, regionName);
+  extrae_wrapper_.StopWithTypeNameAndRegionName(description, regionName);
 }
 
 void ExtraeTypeStackStrategy::Finalize() noexcept {
@@ -62,7 +61,7 @@ void ExtraeTypeStackStrategy::Finalize() noexcept {
 
     };
     // write config
-    out_file << extrae_wrapper_->getParaverConfig(paraver_config) << std::endl;
+    out_file << extrae_wrapper_.getParaverConfig(paraver_config) << std::endl;
   }
-  extrae_wrapper_->Finalize();
+  extrae_wrapper_.Finalize();
 }
diff --git a/src/backends/extrae/extrae_type_stack.hpp b/src/backends/extrae/extrae_type_stack.hpp
index dc1277b..3cd2ee8 100644
--- a/src/backends/extrae/extrae_type_stack.hpp
+++ b/src/backends/extrae/extrae_type_stack.hpp
@@ -9,11 +9,6 @@
 #include "extrae_types.hpp"
 #include "extrae_wrapper.hpp"
 #include "strategies.hpp"
-// #include <mutex>
-
-struct RegionMapData {
-  std::unordered_map<std::string, extrae_value> regionNameToValue;
-};
 
 class ExtraeTypeStackStrategy : public ProperlyNestedAnnotationStrategy {
  private:
@@ -26,13 +21,11 @@ class ExtraeTypeStackStrategy : public ProperlyNestedAnnotationStrategy {
       "Write corresponding Paraver .cfg file if set to True", false);
 
   MPIHelper mpi_helper_;
-  std::unique_ptr<ExtraeWrapper> extrae_wrapper_;
+  ExtraeWrapper extrae_wrapper_;
 
   bool didInitialize{false};
 
   std::size_t max_stack_size{0};
-  RegionMapData regionMapData;
-  extrae_value get_value_by_region_name(const std::string &name);
 
  public:
   ExtraeTypeStackStrategy();
-- 
GitLab


From c103b6608a1b8f4d745c2410cf8f04297f417914 Mon Sep 17 00:00:00 2001
From: Valentin Seitz <valentin.seitz@bsc.es>
Date: Mon, 5 Aug 2024 12:24:48 +0200
Subject: [PATCH 12/12] remove verrbosity on other ranks for partial tracer

---
 src/backends/extrae/extrae_partial_tracer.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/backends/extrae/extrae_partial_tracer.cpp b/src/backends/extrae/extrae_partial_tracer.cpp
index b473159..d2efb16 100644
--- a/src/backends/extrae/extrae_partial_tracer.cpp
+++ b/src/backends/extrae/extrae_partial_tracer.cpp
@@ -104,7 +104,7 @@ void ExtraePartialTracer::RegionStart(
     Terminator::exit();
   }
   if (!matching_jobs.empty()) {
-    if (!is_shutdown_) {
+    if (!is_shutdown_ && mpi_helper_.IsRankNumber(0)) {
       std::cout
           << "neSmiK Extrae::PartialTracer: The regions you selected are "
              "overlapping. The tracer is already running for "
@@ -148,7 +148,7 @@ void ExtraePartialTracer::RegionStopLast(
     }
   }
 
-  if (matching_jobs.size() > 1) {
+  if (matching_jobs.size() > 1 && mpi_helper_.IsRankNumber(0)) {
     std::cout
         << "neSmiK Extrae::PartialTracer: Found multiple matching jobs, please "
            "dont duplicate region names with the same stop iteration"
@@ -157,7 +157,7 @@ void ExtraePartialTracer::RegionStopLast(
   }
 
   if (!matching_jobs.empty()) {
-    if (is_shutdown_) {
+    if (is_shutdown_ && mpi_helper_.IsRankNumber(0)) {
       std::cout
           << "neSmiK Extrae::PartialTracer: The regions you selected are "
              "overlapping. The tracer is already stopped for "
-- 
GitLab