Add check to ensure metrics are valid on GPU Arch (#384)

* Add check to ensure metrics are valid on GPU Arch

Ensure requested metrics are valid on the GPU arch. If not valid,
error is returned during profile config init.

* source formatting (clang-format v11) (#385)

Co-authored-by: bwelton <bwelton@users.noreply.github.com>

* Update metrics.cpp

* source formatting (clang-format v11) (#386)

Co-authored-by: bwelton <bwelton@users.noreply.github.com>

* Update metrics.cpp

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: bwelton <bwelton@users.noreply.github.com>

[ROCm/rocprofiler-sdk commit: 0952308c4a]
这个提交包含在:
Benjamin Welton
2024-01-16 19:47:45 -08:00
提交者 GitHub
父节点 099db3bab7
当前提交 871048b7b9
修改 6 个文件,包含 91 行新增1 行删除
@@ -78,6 +78,7 @@ typedef enum // NOLINT(performance-enum-size)
///< with current version of rocprofiler
ROCPROFILER_STATUS_ERROR_INVALID_ARGUMENT, ///< Function invoked with one or more invalid
///< arguments
ROCPROFILER_STATUS_ERROR_METRIC_NOT_VALID_FOR_AGENT, ///< Invalid metric supplied to agent.
ROCPROFILER_STATUS_LAST,
} rocprofiler_status_t;
@@ -231,6 +231,30 @@ getMetricsForAgent(const std::string& agent)
return empty;
}
bool
checkValidMetric(const std::string& agent, const Metric& metric)
{
static auto*& agent_to_id =
common::static_object<std::unordered_map<std::string, std::unordered_set<uint64_t>>>::
construct([]() -> std::unordered_map<std::string, std::unordered_set<uint64_t>> {
std::unordered_map<std::string, std::unordered_set<uint64_t>> ret;
const auto& map = *CHECK_NOTNULL(getMetricMap());
for(const auto& [agent_name, metrics] : map)
{
auto& id_set =
ret.emplace(agent_name, std::unordered_set<uint64_t>{}).first->second;
for(const auto& m : metrics)
{
id_set.insert(m.id());
}
}
return ret;
}());
const auto* agent_map = common::get_val(*agent_to_id, agent);
return agent_map != nullptr && agent_map->count(metric.id()) > 0;
}
bool
operator<(Metric const& lhs, Metric const& rhs)
{
@@ -115,6 +115,12 @@ getMetricsForAgent(const std::string&);
*/
const MetricIdMap*
getMetricIdMap();
/**
* Checks if a metric is valid for a given agent
**/
bool
checkValidMetric(const std::string& agent, const Metric& metric);
} // namespace counters
} // namespace rocprofiler
@@ -25,6 +25,8 @@
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <algorithm>
#include "lib/rocprofiler-sdk/agent.hpp"
#include "lib/rocprofiler-sdk/counters/metrics.hpp"
@@ -121,3 +123,55 @@ TEST(metrics, derived_load)
EXPECT_TRUE(equal(itr, *val)) << fmt::format("\n\t{} \n\t\t!= \n\t{}", itr, *val);
}
}
TEST(metrics, check_agent_valid)
{
const auto& rocp_data = *counters::getMetricMap();
auto common_metrics = [&]() -> std::set<uint64_t> {
std::set<uint64_t> ret;
for(const auto& [gfx, counters] : rocp_data)
{
std::set<uint64_t> counter_ids;
for(const auto& metric : counters)
{
counter_ids.insert(metric.id());
}
if(ret.empty())
{
ret = counter_ids;
}
else
{
std::set<uint64_t> out_intersection;
std::set_intersection(ret.begin(),
ret.end(),
counter_ids.begin(),
counter_ids.end(),
std::inserter(out_intersection, out_intersection.begin()));
}
if(ret.empty()) return ret;
}
return ret;
}();
for(const auto& [gfx, counters] : rocp_data)
{
for(const auto& metric : counters)
{
ASSERT_EQ(counters::checkValidMetric(gfx, metric), true)
<< gfx << " " << fmt::format("{}", metric);
}
for(const auto& [other_gfx, other_counters] : rocp_data)
{
if(other_gfx == gfx) continue;
for(const auto& metric : other_counters)
{
if(common_metrics.count(metric.id())) continue;
EXPECT_EQ(counters::checkValidMetric(gfx, metric), false);
}
}
}
}
@@ -51,13 +51,16 @@ rocprofiler_create_profile_config(rocprofiler_agent_t agent,
std::make_shared<rocprofiler::counters::profile_config>();
const auto& id_map = *CHECK_NOTNULL(rocprofiler::counters::getMetricIdMap());
for(size_t i = 0; i < counters_count; i++)
{
auto& counter_id = counters_list[i];
const auto* metric_ptr = rocprofiler::common::get_val(id_map, counter_id.handle);
if(!metric_ptr) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
if(!rocprofiler::counters::checkValidMetric(std::string(agent.name), *metric_ptr))
{
return ROCPROFILER_STATUS_ERROR_METRIC_NOT_VALID_FOR_AGENT;
}
config->metrics.push_back(*metric_ptr);
}
@@ -71,6 +71,8 @@ ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_INCOMPATIBLE_ABI,
"with this version of rocprofiler")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_INVALID_ARGUMENT,
"Function invoked with one or more invalid arguments")
ROCPROFILER_STATUS_STRING(ROCPROFILER_STATUS_ERROR_METRIC_NOT_VALID_FOR_AGENT,
"Metric is not valid for the agent")
template <size_t Idx, size_t... Tail>
const char*