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]
这个提交包含在:
@@ -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*
|
||||
|
||||
在新工单中引用
屏蔽一个用户