diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4e1bcc43f7..8e92343fa1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ set ( LIB_SRC ${LIB_DIR}/core/proxy_queue.cpp ${LIB_DIR}/core/simple_proxy_queue.cpp ${LIB_DIR}/core/intercept_queue.cpp + ${LIB_DIR}/core/metrics.cpp ${LIB_DIR}/util/hsa_rsrc_factory.cpp ) add_library ( ${TARGET_LIB} SHARED ${LIB_SRC} ) diff --git a/src/core/context.h b/src/core/context.h index 15a85166d0..cb32064717 100644 --- a/src/core/context.h +++ b/src/core/context.h @@ -129,9 +129,10 @@ class Context { agent_info_(agent_info), queue_(queue), hsa_rsrc_(&util::HsaRsrcFactory::Instance()), - api_(hsa_rsrc_->AqlProfileApi()), - metrics_(agent_info) + api_(hsa_rsrc_->AqlProfileApi()) { + metrics_ = MetricsDict::Create(agent_info); + if (metrics_ == NULL) EXC_RAISING(HSA_STATUS_ERROR, "MetricsDict create failed"); Initialize(info, info_count); Finalize(); } @@ -163,7 +164,7 @@ class Context { const char* name = info->name; if (type == ROCPROFILER_TYPE_METRIC) { - const Metric* metric = metrics_.Get(name); + const Metric* metric = metrics_->Get(name); if (metric == NULL) EXC_RAISING(HSA_STATUS_ERROR, "metric '" << name << "' is not found"); auto ret = metrics_map_.insert({name, metric}); if (!ret.second) EXC_RAISING(HSA_STATUS_ERROR, "metric '" << name << "' is registered more then once"); @@ -385,7 +386,7 @@ class Context { // Profile group set std::vector set_; // Metrics dictionary - MetricsDict metrics_; + MetricsDict* metrics_; // Groups map std::map groups_map_; // Info map diff --git a/src/core/metrics.cpp b/src/core/metrics.cpp new file mode 100644 index 0000000000..3c5751d95c --- /dev/null +++ b/src/core/metrics.cpp @@ -0,0 +1,6 @@ +#include "core/metrics.h" + +namespace rocprofiler { +MetricsDict::map_t* MetricsDict::map_ = NULL; +MetricsDict::mutex_t MetricsDict::mutex_; +} diff --git a/src/core/metrics.h b/src/core/metrics.h index 95e3536b67..e4d045f584 100644 --- a/src/core/metrics.h +++ b/src/core/metrics.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -62,6 +63,8 @@ class MetricsDict { public: typedef std::map cache_t; typedef cache_t::const_iterator const_iterator_t; + typedef std::map map_t; + typedef std::mutex mutex_t; class ExprCache : public xml::expr_cache_t { public: @@ -80,14 +83,12 @@ class MetricsDict { const cache_t* const cache_; }; - MetricsDict(const util::AgentInfo* agent_info) : xml_(NULL) { - const char* xml_name = getenv("ROCP_METRICS"); - if (xml_name != NULL) { - xml_ = new xml::Xml(xml_name); - std::cout << "ROCProfiler: importing metrics from '" << xml_name << "':" << std::endl; - ImportMetrics(agent_info, agent_info->gfxip); - ImportMetrics(agent_info, "global"); - } + static MetricsDict* Create(const util::AgentInfo* agent_info) { + std::lock_guard lck(mutex_); + if (map_ == NULL) map_ = new map_t; + auto ret = map_->insert({agent_info->gfxip, NULL}); + if (ret.second) ret.first->second = new MetricsDict(agent_info); + return ret.first->second; } const Metric* Get(const std::string& name) const { @@ -98,6 +99,16 @@ class MetricsDict { } private: + MetricsDict(const util::AgentInfo* agent_info) : xml_(NULL) { + const char* xml_name = getenv("ROCP_METRICS"); + if (xml_name != NULL) { + xml_ = new xml::Xml(xml_name); + std::cout << "ROCProfiler: importing metrics from '" << xml_name << "':" << std::endl; + ImportMetrics(agent_info, agent_info->gfxip); + ImportMetrics(agent_info, "global"); + } + } + void ImportMetrics(const util::AgentInfo* agent_info, const char* scope) { auto scope_list = xml_->GetNodes("top." + std::string(scope) + ".metric"); if (!scope_list.empty()) { @@ -159,9 +170,11 @@ class MetricsDict { } } - // Metrics map xml::Xml* xml_; cache_t cache_; + + static map_t* map_; + static mutex_t mutex_; }; } // namespace rocprofiler