2
0

Evaluation portion for metrics (#123)

* EvaluateAST and validation of RawAST

* Adding MetricDimension class and concepts

* set_dimensions() and improved ValidateRawAST()

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

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

* Addressing 1st round of review comments

* Modified the parser production rules to support the right syntax for REDUCE and SELECT derived metric expressions

* changes to raw_ast.hpp and fmt::format()

* Parser tests updated to support corrected REDUCE and SELECT syntax

* changes to EvaluateAST::set_dimensions() and other dimension related code changes

* Added a test for EvaluateAST::evaluate() to test basic arithmetic on EvaluateAST

* Format source code (via clang-format v11) on sauverma/evaluate-ast (#146)

* source formatting (clang-format v11)

* Add dimension information to counter record

Restructures counter records to have the following design:

rocprofiler_record_id_t which is an int64_t that encodes
both the counter id and dimension information for the
record. The first 16 bits are reserved for the counter id while
the last 48 are split among the dimensions specified in
rocprofiler_dimension_t (currently 8 bits per dimension).
Each of the 8 bits for the dimension stores the dimension
value for that dimension for this record (i.e. a value of 8
on dimension XCC would denote XCC[8] for the counter). The
split among the dimensions will automatically adjust as
dimensions are added or removed.

The record also contains a union of {int64_t hw_counter, double
derived_counter} to specify the value of the record at
rocprofiler_record_id_t. int64_t denotes a physical hardware
counter that has integer types while the double is used for derived
counters (which type this counters values are needs to be queried
separately).

* Integration of new id type + other fixes

---------

Co-authored-by: sauverma93 <sauverma93@users.noreply.github.com>
Co-authored-by: Benjamin Welton <bewelton@amd.com>

* Fixed sissues with reduce() implementation and added a test for reduce()

* Updated parser syntax for reduce() and updated the parser test. Disabled the test for select()

* Build warning fixes

* Modifications to support fetching xcc/etc info from agent

* Initial plumbing working for single counters, cleanup+tests still needed

* Remove string comparison from reduce ops

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

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

* cmake formatting (cmake-format) (#164)

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

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

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

* Merged with master

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

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

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

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

* Test fix

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: bwelton <bwelton@users.noreply.github.com>
Co-authored-by: sauverma93 <sauverma93@users.noreply.github.com>
Co-authored-by: Benjamin Welton <bewelton@amd.com>
Este cometimento está contido em:
Saurabh Verma
2023-11-03 23:10:40 -05:00
cometido por GitHub
ascendente 4f2dc896d3
cometimento 63775f241a
30 ficheiros modificados com 1960 adições e 973 eliminações
+14 -3
Ver ficheiro
@@ -38,13 +38,24 @@ test_callback(rocprofiler_queue_id_t queue_id,
rocprofiler_correlation_id_t corr_id,
const hsa_kernel_dispatch_packet_t*,
void*,
rocprofiler_dispatch_profile_counting_record_t**,
size_t,
rocprofiler_record_counter_t* out_counters,
size_t out_size,
rocprofiler_profile_config_id_t)
{
static int enter_count = 0;
enter_count++;
// Limit output to avoid massive log size
if(enter_count % 100 != 0) return;
std::stringstream ss;
for(size_t i = 0; i < out_size; i++)
{
ss << "(Id: " << out_counters[i].id << " Value [D]: " << out_counters[i].derived_counter
<< ", Value [I]: " << out_counters[i].hw_counter << "),";
}
// Callback containing counter data.
std::clog << "[" << __FUNCTION__ << "] " << queue_id.handle << " | " << agent_id.id.handle
<< " | " << corr_id.internal << "\n";
<< " | " << corr_id.internal << "|" << ss.str() << "\n";
}
int
+38
Ver ficheiro
@@ -34,6 +34,44 @@ ROCPROFILER_EXTERN_C_INIT
* @{
*/
/**
* @brief Query counter id information from record_id
*
* @param [in] id record id from rocprofiler_record_counter_t
* @param [out] counter_id counter id associated with the record
* @return ::rocprofiler_status_t
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_query_record_counter_id(rocprofiler_counter_instance_id_t id,
rocprofiler_counter_id_t* counter_id) ROCPROFILER_NONNULL(2);
/**
* @brief Query dimension position from record_id
*
* @param [in] id record id from rocprofiler_record_counter_t
* @param [in] dim dimension for which positional info is requested
* @param [out] pos value of the dimension in id.
* @return ::rocprofiler_status_t
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_query_record_dimension_position(rocprofiler_counter_instance_id_t id,
rocprofiler_counter_dimension_id_t dim,
size_t* pos) ROCPROFILER_NONNULL(3);
/**
* @brief Return information about the dimension for a specified counter
*
* @param [in] id counter id to query dimension info for.
* @param [in] dim dimension
* @param [out] info info on the dimension (name, instance_size)
* @return ::rocprofiler_status_t
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_query_record_dimension_info(rocprofiler_counter_id_t id,
rocprofiler_counter_dimension_id_t dim,
rocprofiler_record_dimension_info_t* info)
ROCPROFILER_NONNULL(3);
/**
* @brief Query Counter name.
*
+8 -8
Ver ficheiro
@@ -69,14 +69,14 @@ typedef struct
* @param [in] config
*/
typedef void (*rocprofiler_profile_counting_dispatch_callback_t)(
rocprofiler_queue_id_t queue_id,
rocprofiler_agent_t agent_id,
rocprofiler_correlation_id_t correlation_id,
const hsa_kernel_dispatch_packet_t* dispatch_packet,
void* callback_data_args,
rocprofiler_dispatch_profile_counting_record_t** records,
size_t record_count,
rocprofiler_profile_config_id_t config);
rocprofiler_queue_id_t queue_id,
rocprofiler_agent_t agent_id,
rocprofiler_correlation_id_t correlation_id,
const hsa_kernel_dispatch_packet_t* dispatch_packet,
void* callback_data_args,
rocprofiler_record_counter_t* records,
size_t record_count,
rocprofiler_profile_config_id_t config);
/**
* @brief Configure Dispatch Profile Counting Service.
+29 -8
Ver ficheiro
@@ -251,14 +251,23 @@ typedef uint64_t rocprofiler_thread_id_t;
*/
typedef uint32_t rocprofiler_tracing_operation_t;
/**
* @brief Needs non-typedef specification?
*/
typedef uint32_t rocprofiler_counter_instance_id_t;
// forward declaration of struct
typedef struct rocprofiler_pc_sampling_configuration_s rocprofiler_pc_sampling_configuration_t;
/**
* @brief Unique record id encoding both the counter
* and dimensional values (positions) for the record.
*/
typedef uint64_t rocprofiler_counter_instance_id_t;
/**
* @brief A dimension for counter instances. Some example
* dimensions include XCC, SM (Shader), etc. This
* value represents the dimension beind described
* or queried about.
*/
typedef uint64_t rocprofiler_counter_dimension_id_t;
//--------------------------------------------------------------------------------------//
//
// UNIONS
@@ -415,14 +424,26 @@ rocprofiler_record_header_compute_hash(uint32_t category, uint32_t kind)
return value;
}
/**
* @brief Details for the dimension, including its size, for a counter.
*/
typedef struct
{
const char* name;
size_t instance_size;
} rocprofiler_record_dimension_info_t;
/**
* @brief ROCProfiler Profile Counting Counter per instance.
*/
typedef struct
{
rocprofiler_counter_id_t counter_id;
rocprofiler_counter_instance_id_t instance_id;
double counter_value;
rocprofiler_counter_instance_id_t id;
union
{
int64_t hw_counter; //<< physical hardware counter
double derived_counter; //<< derived counter value
};
} rocprofiler_record_counter_t;
/**
+16
Ver ficheiro
@@ -38,6 +38,10 @@ AQLPacketConstruct::AQLPacketConstruct(const hsa::AgentCache& agen
HSA_STATUS_SUCCESS);
LOG_IF(FATAL, !validate_event_result)
<< "Invalid Metric: " << block_index << " " << event_id;
_event_to_metric[std::make_tuple(
static_cast<hsa_ven_amd_aqlprofile_block_name_t>(query_info.id),
block_index,
event_id)] = x;
}
}
// Check that we can collect all of the metrics in a single execution
@@ -152,6 +156,18 @@ AQLPacketConstruct::get_all_events() const
return ret;
}
const counters::Metric*
AQLPacketConstruct::event_to_metric(const hsa_ven_amd_aqlprofile_event_t& event) const
{
if(const auto* ptr = rocprofiler::common::get_val(
_event_to_metric,
std::make_tuple(event.block_name, event.block_index, event.counter_id)))
{
return ptr;
}
return nullptr;
}
void
AQLPacketConstruct::can_collect()
{
+4
Ver ficheiro
@@ -31,6 +31,8 @@ public:
AQLPacketConstruct(const hsa::AgentCache& agent, const std::vector<counters::Metric>& metrics);
std::unique_ptr<hsa::AQLPacket> construct_packet(const AmdExtTable&) const;
const counters::Metric* event_to_metric(const hsa_ven_amd_aqlprofile_event_t& event) const;
private:
struct AQLProfileMetric
{
@@ -44,6 +46,8 @@ private:
const hsa::AgentCache& _agent;
std::vector<AQLProfileMetric> _metrics;
std::vector<hsa_ven_amd_aqlprofile_event_t> _events;
std::map<std::tuple<hsa_ven_amd_aqlprofile_block_name_t, uint32_t, uint32_t>, counters::Metric>
_event_to_metric;
};
} // namespace aql
+45
Ver ficheiro
@@ -3,6 +3,7 @@
#include "lib/common/synchronized.hpp"
#include "lib/rocprofiler/aql/helpers.hpp"
#include "lib/rocprofiler/counters/evaluate_ast.hpp"
#include "lib/rocprofiler/counters/id_decode.hpp"
#include "lib/rocprofiler/counters/metrics.hpp"
#include "lib/rocprofiler/hsa/agent_cache.hpp"
#include "lib/rocprofiler/hsa/queue.hpp"
@@ -110,4 +111,48 @@ rocprofiler_iterate_agent_supported_counters(rocprofiler_agent_t
return cb(ids.data(), ids.size(), user_data);
}
/**
* @brief Query counter id information from record_id
*
* @param [in] id record id from rocprofiler_record_counter_t
* @param [out] counter_id counter id associated with the record
* @return ::rocprofiler_status_t
*/
rocprofiler_status_t ROCPROFILER_API
rocprofiler_query_record_counter_id(rocprofiler_counter_instance_id_t id,
rocprofiler_counter_id_t* counter_id)
{
// Get counter id from record
*counter_id = rocprofiler::counters::rec_to_counter_id(id);
return ROCPROFILER_STATUS_SUCCESS;
}
rocprofiler_status_t ROCPROFILER_API
rocprofiler_query_record_dimension_position(rocprofiler_counter_instance_id_t id,
rocprofiler_counter_dimension_id_t dim,
size_t* pos)
{
*pos = rocprofiler::counters::rec_to_dim_pos(
id, static_cast<rocprofiler::counters::rocprofiler_profile_counter_instance_types>(dim));
return ROCPROFILER_STATUS_SUCCESS;
}
rocprofiler_status_t ROCPROFILER_API
rocprofiler_query_record_dimension_info(rocprofiler_counter_id_t,
rocprofiler_counter_dimension_id_t dim,
rocprofiler_record_dimension_info_t* info)
{
if(const auto* ptr = rocprofiler::common::get_val(
rocprofiler::counters::dimension_map(),
static_cast<rocprofiler::counters::rocprofiler_profile_counter_instance_types>(dim)))
{
info->name = ptr->c_str();
// TODO: Needs info on the instance size per block to fill in.
// counter_id will be used to lookup this information.
info->instance_size = 0;
return ROCPROFILER_STATUS_SUCCESS;
}
return ROCPROFILER_STATUS_ERROR;
}
}
+4 -2
Ver ficheiro
@@ -1,5 +1,7 @@
set(ROCPROFILER_LIB_COUNTERS_SOURCES metrics.cpp evaluate_ast.cpp core.cpp)
set(ROCPROFILER_LIB_COUNTERS_HEADERS metrics.hpp evaluate_ast.hpp core.hpp)
set(ROCPROFILER_LIB_COUNTERS_SOURCES metrics.cpp dimensions.cpp evaluate_ast.cpp core.cpp
id_decode.cpp)
set(ROCPROFILER_LIB_COUNTERS_HEADERS metrics.hpp dimensions.hpp evaluate_ast.hpp core.hpp
id_decode.hpp)
target_sources(rocprofiler-object-library PRIVATE ${ROCPROFILER_LIB_COUNTERS_SOURCES}
${ROCPROFILER_LIB_COUNTERS_HEADERS})
+44 -2
Ver ficheiro
@@ -34,6 +34,38 @@ queue_cb(const std::shared_ptr<rocprofiler::counters::counter_callback_info>& in
// This ensures that HSA exists
if(!info->pkt_generator)
{
// One time setup of profile config
if(info->profile_cfg.reqired_hw_counters.empty())
{
auto& config = info->profile_cfg;
auto agent_name = std::string(config.agent.name);
for(const auto& metric : config.metrics)
{
auto req_counters =
rocprofiler::counters::get_required_hardware_counters(agent_name, metric);
if(!req_counters)
{
throw std::runtime_error(
fmt::format("Could not find counter {}", metric.name()));
}
config.reqired_hw_counters.insert(req_counters->begin(), req_counters->end());
const auto& asts = rocprofiler::counters::get_ast_map();
const auto* agent_map = rocprofiler::common::get_val(asts, agent_name);
if(!agent_map)
throw std::runtime_error(
fmt::format("Coult not build AST for {}", agent_name));
const auto* counter_ast =
rocprofiler::common::get_val(*agent_map, metric.name());
if(!counter_ast)
{
throw std::runtime_error(
fmt::format("Coult not find AST for {}", metric.name()));
}
config.asts.push_back(*counter_ast);
}
}
info->pkt_generator = std::make_unique<rocprofiler::aql::AQLPacketConstruct>(
queue.get_agent(),
std::vector<counters::Metric>{info->profile_cfg.reqired_hw_counters.begin(),
@@ -70,6 +102,7 @@ completed_cb(const std::shared_ptr<rocprofiler::counters::counter_callback_info>
// auto out_buf = pkt->profile.output_buffer.ptr;
// Read data and create user return....
auto decoded_pkt = EvaluateAST::read_pkt(info->pkt_generator.get(), *pkt);
// return AQL packet for reuse.
@@ -82,13 +115,22 @@ completed_cb(const std::shared_ptr<rocprofiler::counters::counter_callback_info>
if(!info->user_cb) return;
std::vector<rocprofiler_record_counter_t> out;
for(auto& ast : info->profile_cfg.asts)
{
auto* ret = ast.evaluate(decoded_pkt);
CHECK(ret);
out.insert(out.end(), ret->begin(), ret->end());
}
// Maybe move to its own thread?
info->user_cb(queue.get_id(),
info->profile_cfg.agent,
rocprofiler_correlation_id_t{},
reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(&kernel),
info->callback_args,
nullptr, // Date pointer does here.
0, // Number of objects
out.data(), // Date pointer does here.
out.size(), // Number of objects
info->profile_cfg.id);
}
+109
Ver ficheiro
@@ -0,0 +1,109 @@
#include "dimensions.hpp"
#include <cstdint>
#include <memory>
#include <unordered_map>
#include <vector>
#include <fmt/core.h>
#include "lib/common/synchronized.hpp"
#include "lib/common/utility.hpp"
#include "lib/rocprofiler/aql/helpers.hpp"
#include "lib/rocprofiler/hsa/queue_controller.hpp"
namespace rocprofiler
{
namespace counters
{
// namespace
// {
// void
// create_block_dimensions(std::string& agent,
// std::string& block_name,
// std::vector<MetricDimension>& dimension_list)
// {
// static std::atomic<uint64_t> id = 0;
// // query hsa/aqlprofile/kfd etc here to get dimension sizes
// // create MetricDimension objects and push_back() in dimension_list
// }
// } // namespace
// BlockDimensionMap&
// getBlockDimensionsMap(std::string& agent)
// {
// static std::unique_ptr<BlockDimensionMap> map = [&]() {
// auto data = std::make_unique<BlockDimensionMap>();
// // TODO: populate this vector with list of all blocks
// std::vector<std::string> block_names;
// for(auto& block : block_names)
// {
// auto& dimensions = data->emplace(block,
// std::vector<MetricDimension>()).first->second; create_block_dimensions(agent, block,
// dimensions);
// }
// return data;
// }();
// return *map;
// }
// const AgentBlockDimensionsMap&
// getAgentBlockDimensionsMap()
// {
// static std::unique_ptr<AgentBlockDimensionsMap> map = [&]() {
// auto data = std::make_unique<AgentBlockDimensionsMap>();
// // TODO: fill this up with agent iteration or through xml
// std::vector<std::string> agent_names;
// // insert the BlockDimensionMap for each agent
// for(auto& agent : agent_names)
// {
// auto& val = getBlockDimensionsMap(agent);
// data->emplace(agent, val);
// }
// return data;
// }();
// return *map;
// }
std::vector<MetricDimension>
getBlockDimensions(const std::string& agent, const Metric& metric)
{
if(!metric.special().empty())
{
// Special non-hardware counters without dimension data
return std::vector<MetricDimension>{
{dimension_map().at(ROCPROFILER_DIMENSION_NONE), 1, ROCPROFILER_DIMENSION_NONE}};
}
for(const auto& [_, maybe_agent] : hsa::get_queue_controller().get_supported_agents())
{
if(maybe_agent.name() == agent)
{
return std::vector<MetricDimension>{
{dimension_map().at(ROCPROFILER_DIMENSION_SHADER_ENGINE),
maybe_agent.get_rocp_agent().num_shader_banks,
ROCPROFILER_DIMENSION_SHADER_ENGINE},
{dimension_map().at(ROCPROFILER_DIMENSION_XCC),
maybe_agent.get_rocp_agent().num_xcc,
ROCPROFILER_DIMENSION_XCC},
{dimension_map().at(ROCPROFILER_DIMENSION_CU),
maybe_agent.get_rocp_agent().cu_count,
ROCPROFILER_DIMENSION_CU},
{dimension_map().at(ROCPROFILER_DIMENSION_AGENT),
maybe_agent.get_rocp_agent().id.handle,
ROCPROFILER_DIMENSION_AGENT}};
// auto query_info = aql::get_query_info(maybe_agent.get_agent(), metric);
// return std::vector<MetricDimension>{
// {metric.block(), query_info.instance_count, ROCPROFILER_DIMENSION_NONE}};
}
}
return {};
}
} // namespace counters
} // namespace rocprofiler
+81
Ver ficheiro
@@ -0,0 +1,81 @@
#pragma once
#include <atomic>
#include <cstdint>
#include <iostream>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "lib/rocprofiler/counters/id_decode.hpp"
#include "lib/rocprofiler/counters/metrics.hpp"
namespace rocprofiler
{
namespace counters
{
class MetricDimension
{
public:
MetricDimension(std::string name,
uint64_t dim_size,
rocprofiler_profile_counter_instance_types type)
: name_(std::move(name))
, size_(dim_size)
, type_(type){};
const std::string& name() const { return name_; }
uint64_t size() const { return size_; }
rocprofiler_profile_counter_instance_types type() const { return type_; }
bool operator==(const MetricDimension& dim) const
{
return std::tie(name_, size_, type_) == std::tie(dim.name_, dim.size_, dim.type_);
}
private:
std::string name_;
uint64_t size_;
rocprofiler_profile_counter_instance_types type_;
};
/*
{
AgentBlockDimensionsMap = {
"gfx906":{},
"gfx908":{
"TCC": [dim_1, dim_2 ... dim_n]
"SQ": [dim_1, dim_2 ... dim_n]
"TCP": [dim_1, dim_2 ... dim_n]
}
}
}
*/
// // map block_name -> MetricDimension
// using BlockDimensionMap = std::unordered_map<std::string, std::vector<MetricDimension>>;
// // map agent_name -> BlockDimensionMap
// using AgentBlockDimensionsMap = std::unordered_map<std::string, BlockDimensionMap&>;
// // map dimension_id -> MetricDimension
// using DimensionIdMap = std::unordered_map<uint64_t, MetricDimension>;
// // get the complete AgentBlockDimensionsMap
// const AgentBlockDimensionsMap&
// getAgentBlockDimensionsMap();
// // get specific dimensions for an agent, block_name
// const std::vector<MetricDimension>&
// getBlockDimension(const std::string& agent,
// std::string block_name,
// rocprofiler_profile_counter_instance_types dim);
// get all dimensions for an agent, block_name
std::vector<MetricDimension>
getBlockDimensions(const std::string& agent, const counters::Metric&);
// // get a specific dimension by id
// const MetricDimension&
// getDimensionById(uint64_t id);
} // namespace counters
} // namespace rocprofiler
+415 -7
Ver ficheiro
@@ -1,15 +1,92 @@
#include "lib/rocprofiler/counters/evaluate_ast.hpp"
#include <fmt/core.h>
#include <exception>
#include <optional>
#include <numeric>
#include <stdexcept>
#include "lib/common/synchronized.hpp"
#include "lib/common/utility.hpp"
#include "lib/rocprofiler/counters/dimensions.hpp"
#include "lib/rocprofiler/counters/parser/reader.hpp"
namespace rocprofiler
{
namespace counters
{
namespace
{
ReduceOperation
get_reduce_op_type_from_string(const std::string& op)
{
static const std::unordered_map<std::string, ReduceOperation> reduce_op_string_to_type = {
{"min", REDUCE_MIN}, {"max", REDUCE_MAX}, {"sum", REDUCE_SUM}, {"avr", REDUCE_AVG}};
ReduceOperation type = REDUCE_NONE;
const auto* reduce_op_type = rocprofiler::common::get_val(reduce_op_string_to_type, op);
if(reduce_op_type) type = *reduce_op_type;
return type;
}
std::vector<rocprofiler_record_counter_t>*
perform_reduction(ReduceOperation reduce_op, std::vector<rocprofiler_record_counter_t>* input_array)
{
rocprofiler_record_counter_t result{.id = 0, .derived_counter = 0};
if(input_array->empty()) return input_array;
switch(reduce_op)
{
case REDUCE_NONE: break;
case REDUCE_MIN:
{
result =
*std::min_element(input_array->begin(), input_array->end(), [](auto& a, auto& b) {
return a.derived_counter < b.derived_counter;
});
break;
}
case REDUCE_MAX:
{
result =
*std::max_element(input_array->begin(), input_array->end(), [](auto& a, auto& b) {
return a.derived_counter > b.derived_counter;
});
break;
}
case REDUCE_SUM:
{
result = std::accumulate(
input_array->begin(),
input_array->end(),
rocprofiler_record_counter_t{.id = 0, .derived_counter = 0},
[](auto& a, auto& b) {
return rocprofiler_record_counter_t{
.id = a.id, .derived_counter = a.derived_counter + b.derived_counter};
});
break;
}
case REDUCE_AVG:
{
result = std::accumulate(
input_array->begin(),
input_array->end(),
rocprofiler_record_counter_t{.id = 0, .derived_counter = 0},
[](auto& a, auto& b) {
return rocprofiler_record_counter_t{
.id = a.id, .derived_counter = a.derived_counter + b.derived_counter};
});
result.derived_counter /= input_array->size();
break;
}
}
input_array->clear();
input_array->push_back(result);
set_dim_in_rec(input_array->begin()->id, ROCPROFILER_DIMENSION_NONE, 0);
return input_array;
}
} // namespace
const std::unordered_map<std::string, EvaluateASTMap>&
get_ast_map()
{
@@ -42,20 +119,35 @@ get_ast_map()
}
try
{
eval_map.emplace(metric.name(), EvaluateAST(by_name, *ast));
} catch(std::out_of_range& e)
auto& evaluate_ast_node =
eval_map.emplace(metric.name(), EvaluateAST(by_name, *ast, gfx))
.first->second;
evaluate_ast_node.validate_raw_ast(
by_name); // TODO: refactor and consolidate internal post-construction
// logic as a Finish() method
} catch(std::exception& e)
{
LOG(ERROR) << e.what();
throw std::runtime_error(
fmt::format("AST was not generated for {}:{}, Counter will be unavailable. "
"Likely cause is a base counter not being defined used in a "
"derrived counter.",
gfx,
metric.name()));
fmt::format("AST was not generated for {}:{}", gfx, metric.name()));
}
yy_delete_buffer(buf);
delete ast;
}
// Set dimensions after all ASTs loaded for arch.
for(auto& [name, ast] : eval_map)
{
try
{
ast.set_dimensions();
} catch(std::exception& e)
{
LOG(ERROR) << "Could not set dimensions for " << name << " failed with "
<< e.what();
}
}
}
return data;
}();
return ast_map;
@@ -75,5 +167,321 @@ get_required_hardware_counters(const std::string& agent, const Metric& metric)
return required_counters;
}
EvaluateAST::EvaluateAST(const std::unordered_map<std::string, Metric>& metrics,
const RawAST& ast,
std::string agent)
: _type(ast.type)
, _reduce_op(get_reduce_op_type_from_string(ast.reduce_op))
, _agent(std::move(agent))
, _reduce_dimension_set(ast.reduce_dimension_set)
{
if(_type == NodeType::REFERENCE_NODE)
{
try
{
_metric = metrics.at(std::get<std::string>(ast.value));
} catch(std::exception& e)
{
throw std::runtime_error(
fmt::format("Unable to lookup metric {}", std::get<std::string>(ast.value)));
}
}
if(_type == NodeType::NUMBER_NODE)
{
_raw_value = std::get<int64_t>(ast.value);
_static_value.push_back({.id = 0, .hw_counter = std::get<int64_t>(ast.value)});
}
for(const auto& nextAst : ast.counter_set)
{
_children.emplace_back(metrics, *nextAst, _agent);
}
}
DimensionTypes
EvaluateAST::set_dimensions()
{
if(_dimension_types != DIMENSION_LAST)
{
return _dimension_types;
}
auto get_dim_types = [&](auto& metric) {
int dim_types = 0;
for(const auto& dim : getBlockDimensions(_agent, metric))
{
dim_types |= (dim.type() != ROCPROFILER_DIMENSION_NONE) ? (0x1 << dim.type()) : 0;
}
return static_cast<DimensionTypes>(dim_types);
};
switch(_type)
{
case NONE:
case RANGE_NODE:
case NUMBER_NODE: break;
case ADDITION_NODE:
case SUBTRACTION_NODE:
case MULTIPLY_NODE:
case DIVIDE_NODE:
{
if(_children[0].set_dimensions() != _children[1].set_dimensions() &&
_children[0].type() != NUMBER_NODE && _children[1].type() != NUMBER_NODE)
throw std::runtime_error(fmt::format("Dimension mis-mismatch: {} and {}",
_children[0].metric(),
_children[1].metric()));
_dimension_types = (_children[0].type() != NUMBER_NODE) ? _children[0].set_dimensions()
: _children[1].set_dimensions();
}
break;
case REFERENCE_NODE:
{
_dimension_types = get_dim_types(_metric);
}
break;
case REDUCE_NODE:
{
// There is only one child node in case of REDUCE_NODE and that
// child node denotes the expression on which the reduce is applied.
// The resulting dimension of REDUCE_NODE will be the child's dimension
// minus the dimensions specified in the reduce_dimension_set.
int original_dim = static_cast<int>(_children[0].set_dimensions());
int turn_off_dims = 0;
for(auto dim : _reduce_dimension_set)
{
turn_off_dims |= (dim != ROCPROFILER_DIMENSION_NONE) ? (0x1 << dim) : 1;
}
int final_dims = _reduce_dimension_set.empty() ? ROCPROFILER_DIMENSION_NONE
: (original_dim & ~turn_off_dims);
_dimension_types = static_cast<DimensionTypes>(final_dims);
}
break;
case SELECT_NODE:
{
// TODO: future scope
}
break;
}
return _dimension_types;
}
void
EvaluateAST::get_required_counters(const std::unordered_map<std::string, EvaluateAST>& asts,
std::set<Metric>& counters) const
{
if(!_metric.empty() && children().empty() && _type != NodeType::NUMBER_NODE)
{
// Base counter
if(_metric.expression().empty())
{
counters.insert(_metric);
return;
}
// Derrived Counter
const auto* expr_ptr = rocprofiler::common::get_val(asts, _metric.name());
if(!expr_ptr) throw std::runtime_error("could not find derived counter");
expr_ptr->get_required_counters(asts, counters);
// TODO: Add guards against infinite recursion
return;
}
for(const auto& child : children())
{
child.get_required_counters(asts, counters);
}
}
bool
EvaluateAST::validate_raw_ast(const std::unordered_map<std::string, Metric>& metrics)
{
bool ret = true;
try
{
switch(_type)
{
case NONE:
case RANGE_NODE:
case NUMBER_NODE: break;
case ADDITION_NODE:
case SUBTRACTION_NODE:
case MULTIPLY_NODE:
case DIVIDE_NODE:
{
// For arithmetic operations '+' '-' '*' '/' check if
// dimensions of both operands are matching. (handled in set_dimensions())
for(auto& child : _children)
{
child.validate_raw_ast(metrics);
}
}
break;
case REFERENCE_NODE:
{
// handled in constructor
}
break;
case REDUCE_NODE:
{
// Future TODO
// Check #1 : Should be applied on a base metric. Derived metric support will be
// added later. Check #2 : Operation should be a supported operation. Check #3 :
// Dimensions specified should be valid for this metric and GPU
// validate the members of RawAST, not the members of this class
}
break;
case SELECT_NODE:
{
// Future TODO
// Check #1 : Should be applied on a base metric. Derived metric support will be
// added later. Check #2 : Operation should be a supported operation. Check #3 :
// Dimensions specified should be valid for this metric and GPU. Check #4 :
// Dimensionindex values should be within limits for this metric and GPU.
}
break;
}
} catch(std::exception& e)
{
throw;
}
// Future TODO:
// check if there are cycles in the graph
return ret;
}
std::unordered_map<uint64_t, std::vector<rocprofiler_record_counter_t>>
EvaluateAST::read_pkt(const aql::AQLPacketConstruct* pkt_gen, hsa::AQLPacket& pkt)
{
struct it_data
{
std::unordered_map<uint64_t, std::vector<rocprofiler_record_counter_t>>* data;
const aql::AQLPacketConstruct* pkt_gen;
};
std::unordered_map<uint64_t, std::vector<rocprofiler_record_counter_t>> ret;
it_data aql_data{.data = &ret, .pkt_gen = pkt_gen};
hsa_status_t status = hsa_ven_amd_aqlprofile_iterate_data(
&pkt.profile,
[](hsa_ven_amd_aqlprofile_info_type_t info_type,
hsa_ven_amd_aqlprofile_info_data_t* info_data,
void* data) {
CHECK(data);
auto& it = *static_cast<it_data*>(data);
if(info_type != HSA_VEN_AMD_AQLPROFILE_INFO_PMC_DATA) return HSA_STATUS_SUCCESS;
const auto* metric = it.pkt_gen->event_to_metric(info_data->pmc_data.event);
if(!metric) return HSA_STATUS_SUCCESS;
auto& vec = it.data->emplace(metric->id(), std::vector<rocprofiler_record_counter_t>{})
.first->second;
auto& next_rec = vec.emplace_back();
set_counter_in_rec(next_rec.id, {.handle = metric->id()});
// Actual dimension info needs to be used here in the future
set_dim_in_rec(next_rec.id, ROCPROFILER_DIMENSION_NONE, vec.size() - 1);
// Note: in the near future we need to use hw_counter here instead
next_rec.derived_counter = info_data->pmc_data.result;
return HSA_STATUS_SUCCESS;
},
&aql_data);
CHECK(status == HSA_STATUS_SUCCESS);
return ret;
}
// convert to buffer at some point
std::vector<rocprofiler_record_counter_t>*
EvaluateAST::evaluate(
std::unordered_map<uint64_t, std::vector<rocprofiler_record_counter_t>>& results_map)
{
auto perform_op = [&](auto&& op) {
auto* r1 = _children[0].evaluate(results_map);
auto* r2 = _children[1].evaluate(results_map);
if(r1->size() < r2->size()) swap(r1, r2);
CHECK(!r1->empty() && !r2->empty());
if(r2->size() == 1)
{
// Special operation on either a number node
// or special node. This is typically a multiple/divide
// or some other type of constant op.
for(auto& val : *r1)
{
val = op(val, *r2->begin());
}
}
else if(r2->size() == r1->size())
{
// Normal combination
std::transform(r1->begin(), r1->end(), r2->begin(), r1->begin(), op);
}
else
{
throw std::runtime_error(
fmt::format("Mismatched Sizes {}, {}", r1->size(), r2->size()));
}
return r1;
};
switch(_type)
{
case NONE:
case RANGE_NODE: break;
case NUMBER_NODE: return &_static_value;
case ADDITION_NODE:
return perform_op([](auto& a, auto& b) {
return rocprofiler_record_counter_t{
.id = a.id, .derived_counter = a.derived_counter + b.derived_counter};
});
case SUBTRACTION_NODE:
return perform_op([](auto& a, auto& b) {
return rocprofiler_record_counter_t{
.id = a.id, .derived_counter = a.derived_counter - b.derived_counter};
});
case MULTIPLY_NODE:
return perform_op([](auto& a, auto& b) {
return rocprofiler_record_counter_t{
.id = a.id, .derived_counter = a.derived_counter * b.derived_counter};
});
case DIVIDE_NODE:
return perform_op([](auto& a, auto& b) {
return rocprofiler_record_counter_t{
.id = a.id,
.derived_counter =
(b.derived_counter == 0 ? 0 : a.derived_counter / b.derived_counter)};
});
case REFERENCE_NODE:
{
auto* result = rocprofiler::common::get_val(results_map, _metric.id());
if(!result)
throw std::runtime_error(
fmt::format("Unable to lookup results for metric {}", _metric.name()));
return result;
}
break;
case REDUCE_NODE:
{
auto* result = rocprofiler::common::get_val(results_map, _children[0]._metric.id());
if(!result)
throw std::runtime_error(fmt::format("Unable to lookup results for metric {}",
_children[0]._metric.name()));
if(_reduce_op == REDUCE_NONE)
throw std::runtime_error(fmt::format("Invalid Second argument to reduce(): {}",
static_cast<int>(_reduce_op)));
return perform_reduction(_reduce_op, result);
}
// Currently unsupported
case SELECT_NODE: break;
}
return nullptr;
}
} // namespace counters
} // namespace rocprofiler
+77 -46
Ver ficheiro
@@ -1,10 +1,13 @@
#pragma once
#include <exception>
#include <iostream>
#include <set>
#include <unordered_map>
#include "lib/common/utility.hpp"
#include "lib/rocprofiler/aql/packet_construct.hpp"
#include "lib/rocprofiler/counters/dimensions.hpp"
#include "lib/rocprofiler/counters/metrics.hpp"
#include "lib/rocprofiler/counters/parser/raw_ast.hpp"
@@ -12,66 +15,69 @@ namespace rocprofiler
{
namespace counters
{
struct metric_result
{
uint64_t metric_id;
std::vector<int> sample_values;
};
enum DimensionTypes
{
DIMENSION_NONE = 0,
DIMENSION_XCC = 1 << 0,
DIMENSION_SHADER_ENGINE = 1 << 1,
DIMENSION_AGENT = 1 << 2,
DIMENSION_PMC_CHANNEL = 1 << 3,
DIMENSION_CU = 1 << 4,
DIMENSION_LAST = 1 << 5,
};
enum ReduceOperation
{
REDUCE_NONE,
REDUCE_MIN,
REDUCE_MAX,
REDUCE_SUM,
REDUCE_AVG,
};
class EvaluateAST
{
public:
EvaluateAST(const std::unordered_map<std::string, Metric>& metrics, const RawAST& ast)
: _type(ast.type)
, _op(ast.operation)
{
if(_type == NodeType::REFERENCE_NODE)
{
_metric = metrics.at(std::get<std::string>(ast.value));
// LOG(ERROR) << fmt::format("CHILD METRIC {}", _metric);
}
EvaluateAST(const std::unordered_map<std::string, Metric>& metrics,
const RawAST& ast,
std::string agent);
if(_type == NodeType::NUMBER_NODE)
{
_raw_value = std::get<int64_t>(ast.value);
}
std::vector<rocprofiler_record_counter_t>* evaluate(
std::unordered_map<uint64_t, std::vector<rocprofiler_record_counter_t>>& results_map);
for(const auto& nextAst : ast.counter_set)
{
_children.emplace_back(metrics, *nextAst);
}
}
DimensionTypes set_dimensions();
bool validate_raw_ast(const std::unordered_map<std::string, Metric>& metrics);
void get_required_counters(const std::unordered_map<std::string, EvaluateAST>& asts,
std::set<Metric>& counters) const
{
if(!_metric.empty() && children().empty() && _type != NodeType::NUMBER_NODE)
{
// Base counter
if(_metric.expression().empty())
{
counters.insert(_metric);
return;
}
std::set<Metric>& counters) const;
// Derrived Counter
const auto* expr_ptr = rocprofiler::common::get_val(asts, _metric.name());
if(!expr_ptr) throw std::runtime_error("could not find derived counter");
expr_ptr->get_required_counters(asts, counters);
return;
}
for(const auto& child : children())
{
child.get_required_counters(asts, counters);
}
}
static std::unordered_map<uint64_t, std::vector<rocprofiler_record_counter_t>> read_pkt(
const aql::AQLPacketConstruct* pkt_gen,
hsa::AQLPacket& pkt);
NodeType type() const { return _type; }
NodeType op() const { return _op; }
ReduceOperation reduce_op() const { return _reduce_op; }
const std::vector<EvaluateAST>& children() const { return _children; }
const Metric& metric() const { return _metric; }
DimensionTypes dimension_types() const { return _dimension_types; }
private:
NodeType _type{NONE};
NodeType _op{NONE};
Metric _metric;
double _raw_value{0};
std::vector<EvaluateAST> _children;
NodeType _type{NONE};
ReduceOperation _reduce_op{REDUCE_NONE};
Metric _metric;
double _raw_value{0};
std::vector<EvaluateAST> _children;
std::string _agent;
DimensionTypes _dimension_types{DIMENSION_LAST};
std::vector<rocprofiler_record_counter_t> _static_value;
std::unordered_set<rocprofiler_profile_counter_instance_types> _reduce_dimension_set;
};
using EvaluateASTMap = std::unordered_map<std::string, EvaluateAST>;
@@ -91,3 +97,28 @@ std::optional<std::set<Metric>>
get_required_hardware_counters(const std::string& agent, const Metric& metric);
} // namespace counters
} // namespace rocprofiler
namespace fmt
{
template <>
struct formatter<rocprofiler_record_counter_t>
{
template <typename ParseContext>
constexpr auto parse(ParseContext& ctx)
{
return ctx.begin();
}
template <typename Ctx>
auto format(rocprofiler_record_counter_t const& data, Ctx& ctx) const
{
return fmt::format_to(ctx.out(),
"(CounterId: {}, Dimension: {:x}, Value [D]: {}, Value [I]: {})",
rocprofiler::counters::rec_to_counter_id(data.id).handle,
rocprofiler::counters::rec_to_dim_pos(
data.id, rocprofiler::counters::ROCPROFILER_DIMENSION_NONE),
data.derived_counter,
data.hw_counter);
}
};
} // namespace fmt
+27
Ver ficheiro
@@ -0,0 +1,27 @@
#include "lib/rocprofiler/counters/id_decode.hpp"
#include <string>
#include <unordered_map>
#include "lib/common/utility.hpp"
namespace rocprofiler
{
namespace counters
{
const std::unordered_map<rocprofiler_profile_counter_instance_types, std::string>&
dimension_map()
{
static std::unordered_map<rocprofiler_profile_counter_instance_types, std::string> map = {
{ROCPROFILER_DIMENSION_NONE, "DIMENSION_NONE"},
{ROCPROFILER_DIMENSION_XCC, "DIMENSION_XCC"},
{ROCPROFILER_DIMENSION_SHADER_ENGINE, "DIMENSION_SHADER_ENGINE"},
{ROCPROFILER_DIMENSION_AGENT, "DIMENSION_AGENT"},
{ROCPROFILER_DIMENSION_PMC_CHANNEL, "DIMENSION_PMC_CHANNEL"},
{ROCPROFILER_DIMENSION_CU, "DIMENSION_CU"},
};
return map;
}
} // namespace counters
} // namespace rocprofiler
+104
Ver ficheiro
@@ -0,0 +1,104 @@
#pragma once
#include <unordered_map>
#include <rocprofiler/fwd.h>
#include <glog/logging.h>
namespace rocprofiler
{
namespace counters
{
constexpr uint64_t COUNTER_BIT_LENGTH = 16;
constexpr uint64_t DIM_BIT_LENGTH = 48;
constexpr uint64_t MAX_64 = std::numeric_limits<uint64_t>::max();
enum rocprofiler_profile_counter_instance_types
{
ROCPROFILER_DIMENSION_NONE = 0, ///< No dimension data, returns/sets 48 bit value as is
ROCPROFILER_DIMENSION_XCC, ///< XCC dimension of result
ROCPROFILER_DIMENSION_SHADER_ENGINE, ///< SE dimension of result
ROCPROFILER_DIMENSION_AGENT, ///< Agent dimension
ROCPROFILER_DIMENSION_PMC_CHANNEL, ///< PMC Channel dimension of result
ROCPROFILER_DIMENSION_CU, ///< Number of compute units
ROCPROFILER_DIMENSION_LAST
};
const std::unordered_map<rocprofiler_profile_counter_instance_types, std::string>&
dimension_map();
inline rocprofiler_counter_id_t
rec_to_counter_id(rocprofiler_counter_instance_id_t id);
inline void
set_dim_in_rec(rocprofiler_counter_instance_id_t& id,
rocprofiler_profile_counter_instance_types dim,
size_t value);
inline void
set_counter_in_rec(rocprofiler_counter_instance_id_t& id, rocprofiler_counter_id_t value);
inline size_t
rec_to_dim_pos(rocprofiler_counter_instance_id_t id,
rocprofiler_profile_counter_instance_types dim);
} // namespace counters
} // namespace rocprofiler
inline rocprofiler_counter_id_t
rocprofiler::counters::rec_to_counter_id(rocprofiler_counter_instance_id_t id)
{
return {.handle = id >> DIM_BIT_LENGTH};
}
inline void
rocprofiler::counters::set_dim_in_rec(rocprofiler_counter_instance_id_t& id,
rocprofiler_profile_counter_instance_types dim,
size_t value)
{
size_t bit_length = DIM_BIT_LENGTH / ROCPROFILER_DIMENSION_LAST;
int64_t mask = (MAX_64 >> (64 - bit_length)) << ((dim - 1) * bit_length);
if(dim == ROCPROFILER_DIMENSION_NONE)
{
// Set all 48 bits of dimension
id = (id & ~(MAX_64 >> COUNTER_BIT_LENGTH)) | value;
bit_length = DIM_BIT_LENGTH;
}
else
{
// Reset bits to 0 for dimension. Does so by getting the bit length as F's then
// shifiting that into the position of dim. Not's that value and then and's it
// with id.
id = (id & ~(mask));
// Set the value for the dimenstion
id = id | (value << ((dim - 1) * bit_length));
}
CHECK(value <= (MAX_64 >> (64 - bit_length))) << "Dimension value exceeds max allowed";
}
inline void
rocprofiler::counters::set_counter_in_rec(rocprofiler_counter_instance_id_t& id,
rocprofiler_counter_id_t value)
{
// Maximum counter value given the current setup.
CHECK(value.handle <= 0xffff) << "Counter id exceeds max allowed";
// Reset bits to 0 for counter id
id = id & ~((MAX_64 >> (64 - DIM_BIT_LENGTH)) << (DIM_BIT_LENGTH));
// Set the value for the dimenstion
id = id | (value.handle << (DIM_BIT_LENGTH));
}
inline size_t
rocprofiler::counters::rec_to_dim_pos(rocprofiler_counter_instance_id_t id,
rocprofiler_profile_counter_instance_types dim)
{
if(dim == ROCPROFILER_DIMENSION_NONE)
{
// read all 48 bits of dimension
return id & (MAX_64 >> COUNTER_BIT_LENGTH);
}
size_t bit_length = DIM_BIT_LENGTH / ROCPROFILER_DIMENSION_LAST;
id = id & ((MAX_64 >> (64 - bit_length)) << ((dim - 1) * bit_length));
return id >> ((dim - 1) * bit_length);
}
+5 -1
Ver ficheiro
@@ -28,10 +28,12 @@ THE SOFTWARE.
#include "lib/common/utility.hpp"
#include "lib/common/xml.hpp"
#include "dimensions.hpp"
#include "glog/logging.h"
#include <dlfcn.h> // for dladdr
#include <atomic>
#include <cstdint>
#include <cstdlib>
#include <filesystem>
#include <optional>
@@ -42,6 +44,7 @@ namespace counters
{
namespace
{
// Future TODO: inheritance? does it work for derived_counters.xml?
MetricMap
loadXml(const std::string& filename)
{
@@ -72,7 +75,8 @@ loadXml(const std::string& filename)
.first->second;
for(const auto& node : nodes)
{
metricVec.emplace_back(node->opts["name"],
metricVec.emplace_back(gfx_name,
node->opts["name"],
node->opts["block"],
node->opts["event"],
node->opts["descr"],
+3 -1
Ver ficheiro
@@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include <iostream>
#include <string>
#include <unordered_map>
@@ -19,7 +20,8 @@ class Metric
{
public:
Metric() = default;
Metric(std::string name,
Metric(const std::string&, // Get rid of this...
std::string name,
std::string block,
std::string event,
std::string dsc,
A apresentação das diferenças no ficheiro foi suprimida por ser demasiado grande Carregar diff
+39 -32
Ver ficheiro
@@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.5.1. */
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -31,8 +31,9 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Undocumented macros, especially those whose name start with YY_,
are private implementation details. Do not rely on them. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YY_ROCPROFILER_SOURCE_LIB_ROCPROFILER_COUNTERS_PARSER_PARSER_H_INCLUDED
#define YY_YY_ROCPROFILER_SOURCE_LIB_ROCPROFILER_COUNTERS_PARSER_PARSER_H_INCLUDED
@@ -50,35 +51,40 @@ extern int yydebug;
using namespace rocprofiler::counters;
#define YYDEBUG 1
#line 54 "parser.h"
#line 55 "parser.h"
/* Token type. */
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
ADD = 258,
SUB = 259,
MUL = 260,
DIV = 261,
ABS = 262,
EQUALS = 263,
OP = 264,
CP = 265,
O_SQ = 266,
C_SQ = 267,
COLON = 268,
EOL = 269,
UMINUS = 270,
CM = 271,
NUMBER = 272,
RANGE = 273,
NAME = 274,
REDUCE = 275,
SELECT = 276,
LOWER_THAN_ELSE = 277,
ELSE = 278
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
ADD = 258, /* ADD */
SUB = 259, /* SUB */
MUL = 260, /* MUL */
DIV = 261, /* DIV */
ABS = 262, /* ABS */
EQUALS = 263, /* EQUALS */
OP = 264, /* OP */
CP = 265, /* CP */
O_SQ = 266, /* O_SQ */
C_SQ = 267, /* C_SQ */
COLON = 268, /* COLON */
EOL = 269, /* EOL */
UMINUS = 270, /* UMINUS */
CM = 271, /* CM */
NUMBER = 272, /* NUMBER */
RANGE = 273, /* RANGE */
NAME = 274, /* NAME */
REDUCE = 275, /* REDUCE */
SELECT = 276, /* SELECT */
LOWER_THAN_ELSE = 277, /* LOWER_THAN_ELSE */
ELSE = 278 /* ELSE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Value type. */
@@ -87,11 +93,12 @@ union YYSTYPE
{
# line 34 "parser.y"
RawAST* a; /* For ast node */
int64_t d;
char* s;
RawAST* a; /* For ast node */
LinkedList* ll; /* For linked list node */
int64_t d;
char* s;
# line 95 "parser.h"
# line 102 "parser.h"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
+28 -28
Ver ficheiro
@@ -33,6 +33,7 @@ void yyerror(rocprofiler::counters::RawAST**, const char *s) { LOG(ERROR) << s;
/*declare data types*/
%union {
RawAST* a; /* For ast node */
LinkedList* ll; /* For linked list node */
int64_t d;
char* s;
}
@@ -43,6 +44,7 @@ void yyerror(rocprofiler::counters::RawAST**, const char *s) { LOG(ERROR) << s;
%type <a> exp /* set data type for expressions */
%type <s> NAME
%type <d> NUMBER
%type <ll> reduce_dim_args select_dim_args
%nonassoc LOWER_THAN_ELSE
%nonassoc ELSE
@@ -54,14 +56,6 @@ void yyerror(rocprofiler::counters::RawAST**, const char *s) { LOG(ERROR) << s;
top:
exp { *result = $1;};
// line: /* nothing */
// | line exp EOL {
// // TODO
// //printf("= %g\n", eval($2)); //evaluate and print the AST
// //printf("> ");
// }
// | line EOL { printf("> "); } /* blank line or a comment */
// ;
exp: NUMBER { $$ = new RawAST(NUMBER_NODE, $1); }
| exp ADD exp { $$ = new RawAST(ADDITION_NODE, {$1, $3}); }
@@ -69,35 +63,41 @@ exp: NUMBER { $$ = new RawAST(NUMBER_NODE, $1); }
| exp MUL exp { $$ = new RawAST(MULTIPLY_NODE, {$1, $3}); }
| exp DIV exp { $$ = new RawAST(DIVIDE_NODE, {$1, $3}); }
| OP exp CP { $$ = $2; }
| O_SQ exp COLON exp C_SQ { $$ = new RawAST(RANGE_NODE, {$2, $4}); }
| NAME { $$ = new RawAST(REFERENCE_NODE, $1);
free($1);
}
| NAME EQUALS exp { $$ = new RawAST(REFERENCE_SET, $1, $3);
free($1);
}
| NAME EQUALS exp CM exp { $$ = new RawAST(REFERENCE_SET, $1, $3, $5);
free($1);
}
| REDUCE OP exp CM NAME CP { $$ = new RawAST(REDUCE_NODE, $3, $5);
| REDUCE OP exp CM NAME CP {
$$ = new RawAST(REDUCE_NODE, $3, $5, NULL);
free($5);
}
| REDUCE OP exp CM NAME CM exp CP { $$ = new RawAST(REDUCE_NODE, $3, $5, $7);
| REDUCE OP exp CM NAME CM O_SQ reduce_dim_args C_SQ CP {
$$ = new RawAST(REDUCE_NODE, $3, $5, $8);
free($5);
}
| SELECT OP exp CM NAME CP { $$ = new RawAST(SELECT_NODE, $3, $5);
free($5);
| SELECT OP exp CM O_SQ select_dim_args C_SQ CP {
$$ = new RawAST(SELECT_NODE, $3, $6);
}
| SELECT OP exp CM NAME CM exp CP { $$ = new RawAST(SELECT_NODE, $3, $5, $7);
free($5);
}
// | NAME O_SQ POS_INTEGER C_SQ { $$ = create_index_access_node($1, $3); }
;
%%
// void yyerror(char const *s)
// {
// fprintf(stderr, "check error saurabh: %s\n", s);
// }
reduce_dim_args: NAME { $$ = new LinkedList($1, NULL);
free($1);
}
| NAME CM reduce_dim_args { $$ = new LinkedList($1, $3);
free($1);
}
;
select_dim_args: NAME EQUALS NUMBER { $$ = new LinkedList($1, $3, NULL);
free($1);
}
| NAME EQUALS NUMBER CM select_dim_args { $$ = new LinkedList($1, $3, $5);
free($1);
}
;
%%
+125 -51
Ver ficheiro
@@ -3,6 +3,8 @@
#include <map>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>
@@ -11,6 +13,9 @@
#include <fmt/ranges.h>
#include <glog/logging.h>
#include "lib/common/utility.hpp"
#include "lib/rocprofiler/counters/id_decode.hpp"
namespace rocprofiler
{
namespace counters
@@ -25,16 +30,31 @@ enum NodeType
RANGE_NODE,
REDUCE_NODE,
REFERENCE_NODE,
REFERENCE_SET,
SELECT_NODE,
SUBTRACTION_NODE,
};
struct LinkedList
{
std::string name;
int data{-1};
LinkedList* next{nullptr};
LinkedList(const char* v, LinkedList* next_node)
: name(std::string{CHECK_NOTNULL(v)})
, next(next_node)
{}
LinkedList(const char* v, int d, LinkedList* next_node)
: name(std::string{CHECK_NOTNULL(v)})
, data(d)
, next(next_node)
{}
};
struct RawAST
{
// Node type
NodeType type{NONE}; // Operation to perform on the counter set
NodeType operation{NONE};
NodeType type{NONE}; // Operation to perform on the counter set
std::string reduce_op;
// Stores either the name or digit dependening on whether this
// is a name or number
@@ -44,10 +64,12 @@ struct RawAST
// Operation is applied to all counters in this set.
std::vector<RawAST*> counter_set;
// Reference set to remove dimensions (such as shader)
// from the result. This is a future looking change and
// will be unsupported in 6.0.
std::vector<RawAST*> reference_set;
// Dimension set to remove dimensions (such as shader engine)
// from the result.
std::unordered_set<rocprofiler_profile_counter_instance_types> reduce_dimension_set;
// Dimension set to select certain dimensions from the result
std::unordered_map<rocprofiler_profile_counter_instance_types, int> select_dimension_set;
// Range restriction on this node
RawAST* range{nullptr};
@@ -61,7 +83,6 @@ struct RawAST
}
};
deleteVec(reference_set);
deleteVec(counter_set);
delete range;
}
@@ -77,47 +98,86 @@ struct RawAST
, value(v)
{}
// Reduce/Select operation constructor. Counter is the counter AST
// to use for the reduce/select op, op is how to reduce (i.e. SUM,AVG,etc),
// refs is the reference set AST. This reference set is copied to flatten
// the AST.
RawAST(NodeType t, RawAST* counter, const char* op, RawAST* refs = nullptr)
static const auto& get_dim_map()
{
static const auto dim_map = []() {
std::map<std::string, rocprofiler_profile_counter_instance_types> out;
const auto& dims = dimension_map();
for(const auto& [id, name] : dims)
{
out.emplace(name, id);
}
return out;
}();
return dim_map;
}
// Reduce operation constructor. Counter is the counter AST
// to use for the reduce op, op is how to reduce (i.e. SUM,AVG,etc),
// dimensions contains the set of dimensions which we want to keep
// in the result. Dimensions not specified are all reduced according to op
RawAST(NodeType t, RawAST* counter, const char* op, LinkedList* dimensions)
: type(t)
, value(std::string{CHECK_NOTNULL(op)})
, reduce_op(CHECK_NOTNULL(op))
, counter_set({counter})
{
copy_reference_set(refs);
if(dimensions)
{
while(dimensions)
{
const rocprofiler_profile_counter_instance_types* dim =
rocprofiler::common::get_val(get_dim_map(), std::string{dimensions->name});
if(!dim)
{
throw std::runtime_error(
fmt::format("Unknown Dimension - {}", dimensions->name));
}
reduce_dimension_set.insert(*dim);
LinkedList* current = dimensions;
dimensions = dimensions->next;
delete current;
}
}
}
// Select operation constructor. Counter is the counter AST
// to use for the reduce op, refs is the reference set AST.
// dimensions contains the mapping for selecting dimensions
// (XCC=1,SE=2,...)
RawAST(NodeType t, RawAST* counter, LinkedList* dimensions)
: type(t)
, counter_set({counter})
{
if(dimensions)
{
LinkedList* ptr = dimensions;
while(ptr)
{
const rocprofiler_profile_counter_instance_types* dim =
rocprofiler::common::get_val(get_dim_map(), dimensions->name);
if(!dim)
{
throw std::runtime_error(
fmt::format("Unknown Dimension - {}", dimensions->name));
}
select_dimension_set.insert({*dim, ptr->data});
LinkedList* current = ptr;
ptr = ptr->next;
delete current;
}
}
else
{
LOG(ERROR) << "select_dimension_set creation failed.";
}
}
RawAST(NodeType t, std::vector<RawAST*> c)
: type(t)
, counter_set(std::move(c))
{}
// Following two calls are for future reference set settings
// for select/reduce ops.
// Referene set constructor, refs is a pointer to an existing
// reference set when multiple references are given (i.e.
// shader=X,anotherRef=Y,....).
RawAST(NodeType t, const char* v, RawAST* r, RawAST* refs = nullptr)
: type(t)
, value(std::string{CHECK_NOTNULL(v)})
, range(r)
{
LOG(ERROR) << "BUilding bad ast";
copy_reference_set(refs);
}
// Flattens reference set tree into this node.
void copy_reference_set(RawAST* ast)
{
if(!ast) return;
reference_set.push_back(ast);
reference_set.insert(
reference_set.end(), ast->reference_set.begin(), ast->reference_set.end());
ast->reference_set.clear();
}
};
} // namespace counters
} // namespace rocprofiler
@@ -146,15 +206,14 @@ struct formatter<rocprofiler::counters::RawAST>
{rocprofiler::counters::RANGE_NODE, "RANGE_NODE"},
{rocprofiler::counters::REDUCE_NODE, "REDUCE_NODE"},
{rocprofiler::counters::REFERENCE_NODE, "REFERENCE_NODE"},
{rocprofiler::counters::REFERENCE_SET, "REFERENCE_SET"},
{rocprofiler::counters::SELECT_NODE, "SELECT_NODE"},
{rocprofiler::counters::SUBTRACTION_NODE, "SUBTRACTION_NODE"},
};
auto out = fmt::format_to(ctx.out(),
"{{\"Type\":\"{}\", \"Operation\":\"{}\",",
"{{\"Type\":\"{}\", \"REDUCE_OP\":\"{}\",",
NodeTypeToString.at(ast.type),
NodeTypeToString.at(ast.operation));
ast.reduce_op);
if(const auto* string_val = std::get_if<std::string>(&ast.value))
{
@@ -170,19 +229,34 @@ struct formatter<rocprofiler::counters::RawAST>
out = fmt::format_to(out, " \"Range\":{},", *ast.range);
}
out = fmt::format_to(out, "\"ReferenceSet\":[");
for(const auto& ref : ast.reference_set)
{
out = fmt::format_to(
out, "{}{}", *CHECK_NOTNULL(ref), ref == ast.reference_set.back() ? "" : ",");
}
out = fmt::format_to(out, "], \"CounterSet\":[");
out = fmt::format_to(out, " \"Counter_Set\":[");
for(const auto& ref : ast.counter_set)
{
out = fmt::format_to(
out, "{}{}", *CHECK_NOTNULL(ref), ref == ast.counter_set.back() ? "" : ",");
}
out = fmt::format_to(out, "], \"Reduce_Dimension_Set\":[");
size_t ReduceSetIndex = 0;
for(const auto& ref : ast.reduce_dimension_set)
{
out = fmt::format_to(out,
"\"{}\"{}",
static_cast<int>(ref),
++ReduceSetIndex == ast.reduce_dimension_set.size() ? "" : ",");
}
out = fmt::format_to(out, "], \"Select_Dimension_Set\":[");
size_t SelectSetIndex = 0;
for(const auto& [type, val] : ast.select_dimension_set)
{
out = fmt::format_to(out,
"\"{},{}\"{}",
static_cast<int>(type),
val,
++SelectSetIndex == ast.select_dimension_set.size() ? "" : ",");
}
return fmt::format_to(out, "]}}");
}
};
+129 -101
Ver ficheiro
@@ -1,5 +1,6 @@
#include <map>
#include <string>
#include <tuple>
#include <gtest/gtest.h>
@@ -9,26 +10,38 @@
TEST(parser, base_ops)
{
std::map<std::string, std::string> expressionToExpected = {
{"AB + BA",
"{\"Type\":\"ADDITION_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"BA\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"},
{"CD - ZX",
"{\"Type\":\"SUBTRACTION_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"CD\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"ZX\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"},
{"NM / DB",
"{\"Type\":\"DIVIDE_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"NM\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"DB\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"},
{"AB * BA",
"{\"Type\":\"MULTIPLY_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"BA\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"}};
"{\"Type\":\"MULTIPLY_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"BA\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"},
{"AB + BA",
"{\"Type\":\"ADDITION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"BA\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"},
{"CD - ZX",
"{\"Type\":\"SUBTRACTION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"CD\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"ZX\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"},
{"NM / DB",
"{\"Type\":\"DIVIDE_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"NM\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"DB\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"}};
for(auto [op, expected] : expressionToExpected)
{
@@ -46,37 +59,53 @@ TEST(parser, order_of_ops)
{
std::map<std::string, std::string> expressionToExpected = {
{"(AB + BA) / CD",
"{\"Type\":\"DIVIDE_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"ADDITION_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"BA\",\"ReferenceSet\":[], "
"\"CounterSet\":[]}]},{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"CD\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"},
{"AD / (CD - ZX)",
"{\"Type\":\"DIVIDE_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AD\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"SUBTRACTION_NODE\", "
"\"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"CD\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"ZX\",\"ReferenceSet\":[], \"CounterSet\":[]}]}]}"},
{"MN * (NM / DB)",
"{\"Type\":\"MULTIPLY_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"MN\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"DIVIDE_NODE\", "
"\"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"NM\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"DB\",\"ReferenceSet\":[], \"CounterSet\":[]}]}]}"},
"{\"Type\":\"DIVIDE_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"ADDITION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"BA\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"CD\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"},
{"(AB / BA) - BN",
"{\"Type\":\"SUBTRACTION_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"DIVIDE_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"BA\",\"ReferenceSet\":[], "
"\"CounterSet\":[]}]},{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"BN\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"}};
"{\"Type\":\"SUBTRACTION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"DIVIDE_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"BA\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"BN\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"},
{"AD / (CD - ZX)",
"{\"Type\":\"DIVIDE_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AD\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"SUBTRACTION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"CD\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"ZX\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"},
{"MN * (NM / DB)",
"{\"Type\":\"MULTIPLY_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"MN\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"DIVIDE_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"NM\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"DB\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}"}};
for(auto [op, expected] : expressionToExpected)
{
@@ -92,32 +121,34 @@ TEST(parser, order_of_ops)
TEST(parser, reduction)
{
std::map<std::string, std::string> expressionToExpected = {
{"reduce(AB, SUM)",
"{\"Type\":\"REDUCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"},
{"reduce(AB+CD, SUM)",
"{\"Type\":\"REDUCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"ADDITION_NODE\", "
"\"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"CD\",\"ReferenceSet\":[], \"CounterSet\":[]}]}]}"},
{"reduce(AB,DIV)+reduce(DC,SUM)",
"{\"Type\":\"ADDITION_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REDUCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"DIV\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"AB\",\"ReferenceSet\":[], "
"\"CounterSet\":[]}]},{\"Type\":\"REDUCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"DC\",\"ReferenceSet\":[], \"CounterSet\":[]}]}]}"},
{"reduce(AB, SUM, shader)",
"{\"Type\":\"REDUCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"shader\",\"ReferenceSet\":[], \"CounterSet\":[]}], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"}};
std::vector<std::tuple<std::string, std::string>> expressionToExpected = {
{"reduce(AB, SUM, [DIMENSION_XCC,DIMENSION_SHADER_ENGINE])",
"{\"Type\":\"REDUCE_NODE\", \"REDUCE_OP\":\"SUM\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[\"2\",\"1\"], \"Select_Dimension_Set\":[]}"},
{"reduce(AB+CD, SUM, [DIMENSION_XCC,DIMENSION_SHADER_ENGINE])",
"{\"Type\":\"REDUCE_NODE\", \"REDUCE_OP\":\"SUM\", "
"\"Counter_Set\":[{\"Type\":\"ADDITION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", "
"\"Value\":\"CD\", \"Counter_Set\":[], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[], "
"\"Select_Dimension_Set\":[]}], \"Reduce_Dimension_Set\":[\"2\",\"1\"], "
"\"Select_Dimension_Set\":[]}"},
{"reduce(AB,DIV, [DIMENSION_XCC,DIMENSION_SHADER_ENGINE])+reduce(DC,SUM, "
"[DIMENSION_XCC,DIMENSION_SHADER_ENGINE])",
"{\"Type\":\"ADDITION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REDUCE_NODE\", \"REDUCE_OP\":\"DIV\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[\"2\",\"1\"], "
"\"Select_Dimension_Set\":[]},{\"Type\":\"REDUCE_NODE\", \"REDUCE_OP\":\"SUM\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"DC\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[\"2\",\"1\"], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}"}};
for(auto [op, expected] : expressionToExpected)
{
@@ -131,34 +162,31 @@ TEST(parser, reduction)
}
}
TEST(parser, selection)
TEST(parser, DISABLED_selection)
{
std::map<std::string, std::string> expressionToExpected = {
{"select(AB, SUM)",
"{\"Type\":\"SELECT_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"},
{"select(AB+CD, SUM)",
"{\"Type\":\"SELECT_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"ADDITION_NODE\", "
"\"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]},{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"CD\",\"ReferenceSet\":[], \"CounterSet\":[]}]}]}"},
{"select(AB,DIV)+select(DC,SUM)",
"{\"Type\":\"ADDITION_NODE\", \"Operation\":\"NONE\",\"ReferenceSet\":[], "
"\"CounterSet\":[{\"Type\":\"SELECT_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"DIV\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"AB\",\"ReferenceSet\":[], "
"\"CounterSet\":[]}]},{\"Type\":\"SELECT_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[], \"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"DC\",\"ReferenceSet\":[], \"CounterSet\":[]}]}]}"},
{"select(AB, SUM, shader)",
"{\"Type\":\"SELECT_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"SUM\",\"ReferenceSet\":[{\"Type\":\"REFERENCE_NODE\", "
"\"Operation\":\"NONE\", \"Value\":\"shader\",\"ReferenceSet\":[], \"CounterSet\":[]}], "
"\"CounterSet\":[{\"Type\":\"REFERENCE_NODE\", \"Operation\":\"NONE\", "
"\"Value\":\"AB\",\"ReferenceSet\":[], \"CounterSet\":[]}]}"}};
{"select(AB, [SE=1,XCC=0])+select(DC,[SE=2])",
"{\"Type\":\"ADDITION_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"SELECT_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[\"(\"XCC\", 0)\",\"(\"SE\", "
"1)\"]},{\"Type\":\"SELECT_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"DC\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[\"(\"SE\", 2)\"]}], "
"\"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}"},
{"select(AB, [SE=2,XCC=1,WGP=3])",
"{\"Type\":\"SELECT_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[\"(\"WGP\", 3)\",\"(\"XCC\", "
"1)\",\"(\"SE\", 2)\"]}"},
{"select(AB, [XCC=0])",
"{\"Type\":\"SELECT_NODE\", \"REDUCE_OP\":\"\", "
"\"Counter_Set\":[{\"Type\":\"REFERENCE_NODE\", \"REDUCE_OP\":\"\", \"Value\":\"AB\", "
"\"Counter_Set\":[], \"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[]}], "
"\"Reduce_Dimension_Set\":[], \"Select_Dimension_Set\":[\"(\"XCC\", 0)\"]}"}};
for(auto [op, expected] : expressionToExpected)
{
+2 -1
Ver ficheiro
@@ -2,7 +2,8 @@ rocprofiler_deactivate_clang_tidy()
include(GoogleTest)
set(ROCPROFILER_LIB_COUNTER_TEST_SOURCES metrics_test.cpp evaluate_ast_test.cpp)
set(ROCPROFILER_LIB_COUNTER_TEST_SOURCES metrics_test.cpp evaluate_ast_test.cpp
dimension.cpp)
add_executable(counter-test)
+82
Ver ficheiro
@@ -0,0 +1,82 @@
#include <gtest/gtest.h>
#include "lib/common/utility.hpp"
#include "lib/rocprofiler/counters/id_decode.hpp"
TEST(dimension, set_get)
{
using namespace rocprofiler::counters;
int64_t max_counter_val = (std::numeric_limits<uint64_t>::max() >>
(64 - (DIM_BIT_LENGTH / ROCPROFILER_DIMENSION_LAST)));
rocprofiler_counter_instance_id_t test_id = 0;
rocprofiler_counter_id_t test_counter{.handle = 123};
set_counter_in_rec(test_id, test_counter);
// 0x007B000000000000 = decimal counter id 123 << DIM_BIT_LENGTH
EXPECT_EQ(test_id, 0x007B000000000000);
test_counter.handle = 321;
set_counter_in_rec(test_id, test_counter);
// 0x0141000000000000 = decimal counter id 321 << DIM_BIT_LENGTH
EXPECT_EQ(test_id, 0x0141000000000000);
EXPECT_EQ(rec_to_counter_id(test_id).handle, 321);
// Test multiples of i, setting/getting those values across all
// dimensions
for(size_t multi_factor = 1; multi_factor < 7; multi_factor++)
{
for(size_t i = 1; i < static_cast<size_t>(ROCPROFILER_DIMENSION_LAST); i++)
{
auto dim = static_cast<rocprofiler_profile_counter_instance_types>(i);
set_dim_in_rec(test_id, dim, i);
EXPECT_EQ(rec_to_dim_pos(test_id, dim), i);
set_dim_in_rec(test_id, dim, i * multi_factor);
for(size_t j = 1; j < static_cast<size_t>(ROCPROFILER_DIMENSION_LAST); j++)
{
if(i == j) continue;
set_dim_in_rec(test_id,
static_cast<rocprofiler_profile_counter_instance_types>(j),
max_counter_val);
EXPECT_EQ(rec_to_dim_pos(
test_id, static_cast<rocprofiler_profile_counter_instance_types>(j)),
max_counter_val);
EXPECT_EQ(rec_to_dim_pos(test_id, dim), i * multi_factor);
}
for(size_t j = static_cast<size_t>(ROCPROFILER_DIMENSION_LAST - 1); j > 0; j--)
{
if(i == j) continue;
set_dim_in_rec(test_id,
static_cast<rocprofiler_profile_counter_instance_types>(j),
max_counter_val);
EXPECT_EQ(rec_to_dim_pos(test_id, (rocprofiler_profile_counter_instance_types) j),
max_counter_val);
EXPECT_EQ(rec_to_dim_pos(test_id, dim), i * multi_factor);
}
// Check that name exists
EXPECT_TRUE(rocprofiler::common::get_val(
rocprofiler::counters::dimension_map(),
static_cast<rocprofiler_profile_counter_instance_types>(i)));
}
}
for(size_t i = static_cast<size_t>(ROCPROFILER_DIMENSION_LAST - 1); i > 0; i--)
{
auto dim = static_cast<rocprofiler_profile_counter_instance_types>(i);
set_dim_in_rec(test_id, dim, i * 5);
EXPECT_EQ(rec_to_dim_pos(test_id, dim), i * 5);
set_dim_in_rec(test_id, dim, i * 3);
EXPECT_EQ(rec_to_dim_pos(test_id, dim), i * 3);
}
test_counter.handle = 123;
set_counter_in_rec(test_id, test_counter);
EXPECT_EQ(rec_to_counter_id(test_id).handle, 123);
// Test that all bits can be set/fetched for dims, 0xFAFBFCFDFEFF is a random
// collection of 48 bits.
set_dim_in_rec(test_id, ROCPROFILER_DIMENSION_NONE, 0xFAFBFCFDFEFF);
EXPECT_EQ(rec_to_dim_pos(test_id, ROCPROFILER_DIMENSION_NONE), 0xFAFBFCFDFEFF);
EXPECT_EQ(rec_to_counter_id(test_id).handle, 123);
}
+138 -65
Ver ficheiro
@@ -1,17 +1,32 @@
#include <cstdint>
#include <tuple>
#include <fmt/core.h>
#include <gtest/gtest.h>
#include "lib/rocprofiler/counters/evaluate_ast.hpp"
#include "evaluate_ast_test.hpp"
#include "lib/rocprofiler/counters/parser/reader.hpp"
namespace
{
ReduceOperation
get_reduce_op_type_from_string(const std::string& op)
{
static const std::unordered_map<std::string, ReduceOperation> reduce_op_string_to_type = {
{"min", REDUCE_MIN}, {"max", REDUCE_MAX}, {"sum", REDUCE_SUM}, {"avr", REDUCE_AVG}};
ReduceOperation type = REDUCE_NONE;
const auto* reduce_op_type = rocprofiler::common::get_val(reduce_op_string_to_type, op);
if(reduce_op_type) type = *reduce_op_type;
return type;
}
bool
isIdentical(const EvaluateAST& eval_ast, const RawAST& raw_ast)
{
if(raw_ast.counter_set.size() != eval_ast.children().size() ||
raw_ast.type != eval_ast.type() || raw_ast.operation != eval_ast.op())
raw_ast.type != eval_ast.type() ||
get_reduce_op_type_from_string(raw_ast.reduce_op) != eval_ast.reduce_op())
{
return false;
}
@@ -30,15 +45,15 @@ isIdentical(const EvaluateAST& eval_ast, const RawAST& raw_ast)
TEST(evaluate_ast, basic_copy)
{
std::unordered_map<std::string, Metric> metrics = {
{"SQ_WAVES", Metric("a", "a", "a", "a", "a", "", 0)},
{"TCC_HIT", Metric("b", "b", "b", "b", "b", "", 1)}};
{"SQ_WAVES", Metric("gfx9", "a", "a", "a", "a", "a", "", 0)},
{"TCC_HIT", Metric("gfx9", "b", "b", "b", "b", "b", "", 1)}};
RawAST* ast = nullptr;
auto* buf = yy_scan_string("SQ_WAVES + TCC_HIT");
yyparse(&ast);
ASSERT_TRUE(ast);
auto eval_ast = EvaluateAST(metrics, *ast);
auto eval_ast = EvaluateAST(metrics, *ast, "gfx9");
EXPECT_TRUE(isIdentical(eval_ast, *ast));
yy_delete_buffer(buf);
@@ -48,9 +63,10 @@ TEST(evaluate_ast, basic_copy)
TEST(evaluate_ast, counter_expansion)
{
std::unordered_map<std::string, Metric> metrics = {
{"SQ_WAVES", Metric("SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("TCC_HIT", "b", "b", "b", "", "", 1)},
{"TEST_DERRIVED", Metric("TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+TCC_HIT", "", 2)}};
{"SQ_WAVES", Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1)},
{"TEST_DERRIVED",
Metric("gfx9", "TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+TCC_HIT", "", 2)}};
std::unordered_map<std::string, EvaluateAST> asts;
for(auto [val, metric] : metrics)
@@ -60,7 +76,7 @@ TEST(evaluate_ast, counter_expansion)
: metric.expression().c_str());
yyparse(&ast);
ASSERT_TRUE(ast);
asts.emplace(val, std::move(EvaluateAST(metrics, *ast)));
asts.emplace(val, std::move(EvaluateAST(metrics, *ast, "gfx9")));
yy_delete_buffer(buf);
delete ast;
}
@@ -68,8 +84,8 @@ TEST(evaluate_ast, counter_expansion)
std::set<Metric> required_counters;
asts.at("TEST_DERRIVED").get_required_counters(asts, required_counters);
EXPECT_EQ(required_counters.size(), 2);
auto expected = std::set<Metric>{{Metric("TCC_HIT", "b", "b", "b", "", "", 1),
Metric("SQ_WAVES", "a", "a", "a", "", "", 0)}};
auto expected = std::set<Metric>{{Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1),
Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)}};
for(auto& counter_found : required_counters)
{
@@ -80,11 +96,12 @@ TEST(evaluate_ast, counter_expansion)
TEST(evaluate_ast, counter_expansion_multi_derived)
{
std::unordered_map<std::string, Metric> metrics = {
{"SQ_WAVES", Metric("SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("TCC_HIT", "b", "b", "b", "", "", 1)},
{"TEST_DERRIVED", Metric("TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+TCC_HIT", "", 2)},
{"SQ_WAVES", Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1)},
{"TEST_DERRIVED",
Metric("gfx9", "TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+TCC_HIT", "", 2)},
{"TEST_DERRIVED3",
Metric("TEST_DERRIVED3", "C", "C", "C", "TEST_DERRIVED+SQ_WAVES+TCC_HIT", "", 3)}};
Metric("gfx9", "TEST_DERRIVED3", "C", "C", "C", "TEST_DERRIVED+SQ_WAVES+TCC_HIT", "", 3)}};
std::unordered_map<std::string, EvaluateAST> asts;
for(auto [val, metric] : metrics)
@@ -94,7 +111,7 @@ TEST(evaluate_ast, counter_expansion_multi_derived)
: metric.expression().c_str());
yyparse(&ast);
ASSERT_TRUE(ast);
asts.emplace(val, std::move(EvaluateAST(metrics, *ast)));
asts.emplace(val, std::move(EvaluateAST(metrics, *ast, "gfx9")));
yy_delete_buffer(buf);
delete ast;
}
@@ -102,8 +119,8 @@ TEST(evaluate_ast, counter_expansion_multi_derived)
std::set<Metric> required_counters;
asts.at("TEST_DERRIVED3").get_required_counters(asts, required_counters);
EXPECT_EQ(required_counters.size(), 2);
auto expected = std::set<Metric>{{Metric("TCC_HIT", "b", "b", "b", "", "", 1),
Metric("SQ_WAVES", "a", "a", "a", "", "", 0)}};
auto expected = std::set<Metric>{{Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1),
Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)}};
for(auto& counter_found : required_counters)
{
@@ -114,12 +131,12 @@ TEST(evaluate_ast, counter_expansion_multi_derived)
TEST(evaluate_ast, counter_expansion_order)
{
std::unordered_map<std::string, Metric> metrics = {
{"SQ_WAVES", Metric("SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("TCC_HIT", "b", "b", "b", "", "", 1)},
{"VLL", Metric("VLL", "b", "b", "b", "", "", 4)},
{"TEST_DERRIVED", Metric("TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+VLL", "", 2)},
{"SQ_WAVES", Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1)},
{"VLL", Metric("gfx9", "VLL", "b", "b", "b", "", "", 4)},
{"TEST_DERRIVED", Metric("gfx9", "TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+VLL", "", 2)},
{"TEST_DERRIVED3",
Metric("TEST_DERRIVED3", "C", "C", "C", "TEST_DERRIVED+SQ_WAVES+TCC_HIT", "", 3)}};
Metric("gfx9", "TEST_DERRIVED3", "C", "C", "C", "TEST_DERRIVED+SQ_WAVES+TCC_HIT", "", 3)}};
std::unordered_map<std::string, EvaluateAST> asts;
for(auto [val, metric] : metrics)
@@ -129,7 +146,7 @@ TEST(evaluate_ast, counter_expansion_order)
: metric.expression().c_str());
yyparse(&ast);
ASSERT_TRUE(ast);
asts.emplace(val, std::move(EvaluateAST(metrics, *ast)));
asts.emplace(val, std::move(EvaluateAST(metrics, *ast, "gfx9")));
yy_delete_buffer(buf);
delete ast;
}
@@ -137,9 +154,9 @@ TEST(evaluate_ast, counter_expansion_order)
std::set<Metric> required_counters;
asts.at("TEST_DERRIVED3").get_required_counters(asts, required_counters);
EXPECT_EQ(required_counters.size(), 3);
auto expected = std::set<Metric>{{Metric("VLL", "b", "b", "b", "", "", 4),
Metric("TCC_HIT", "b", "b", "b", "", "", 1),
Metric("SQ_WAVES", "a", "a", "a", "", "", 0)}};
auto expected = std::set<Metric>{{Metric("gfx9", "VLL", "b", "b", "b", "", "", 4),
Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1),
Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)}};
for(auto& counter_found : required_counters)
{
@@ -147,44 +164,100 @@ TEST(evaluate_ast, counter_expansion_order)
}
}
TEST(evaluate_ast, counter_expansion_function)
{
std::unordered_map<std::string, Metric> metrics = {
{"SQ_WAVES", Metric("SQ_WAVES", "a", "a", "a", "", "", 0)},
{"TCC_HIT", Metric("TCC_HIT", "b", "b", "b", "", "", 1)},
{"VLL", Metric("VLL", "b", "b", "b", "", "", 4)},
{"TEST_DERRIVED", Metric("TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+VLL", "", 2)},
{"TEST_DERRIVED3",
Metric("TEST_DERRIVED3",
"C",
"C",
"C",
"reduce(TEST_DERRIVED,max)+SQ_WAVES+TCC_HIT",
"",
3)}};
// TEST(evaluate_ast, counter_expansion_function)
// {
// std::unordered_map<std::string, Metric> metrics = {
// {"SQ_WAVES", Metric("gfx9", "SQ_WAVES", "a", "a", "a", "", "", 0)},
// {"TCC_HIT", Metric("gfx9", "TCC_HIT", "b", "b", "b", "", "", 1)},
// {"VLL", Metric("gfx9", "VLL", "b", "b", "b", "", "", 4)},
// {"TEST_DERRIVED", Metric("gfx9", "TEST_DERRIVED", "C", "C", "C", "SQ_WAVES+VLL", "",
// 2)}};
std::unordered_map<std::string, EvaluateAST> asts;
for(auto [val, metric] : metrics)
{
RawAST* ast = nullptr;
auto buf = yy_scan_string(metric.expression().empty() ? metric.name().c_str()
: metric.expression().c_str());
yyparse(&ast);
ASSERT_TRUE(ast);
asts.emplace(val, std::move(EvaluateAST(metrics, *ast)));
yy_delete_buffer(buf);
delete ast;
}
// std::unordered_map<std::string, EvaluateAST> asts;
// for(auto [val, metric] : metrics)
// {
// RawAST* ast = nullptr;
// auto buf = yy_scan_string(metric.expression().empty() ? metric.name().c_str()
// : metric.expression().c_str());
// yyparse(&ast);
// ASSERT_TRUE(ast) << metric.expression() << " " << metric.name();
// asts.emplace(val, std::move(EvaluateAST(metrics, *ast, "gfx9")));
// yy_delete_buffer(buf);
// delete ast;
// }
// }
std::set<Metric> required_counters;
asts.at("TEST_DERRIVED3").get_required_counters(asts, required_counters);
EXPECT_EQ(required_counters.size(), 3);
auto expected = std::set<Metric>{{Metric("VLL", "b", "b", "b", "", "", 4),
Metric("TCC_HIT", "b", "b", "b", "", "", 1),
Metric("SQ_WAVES", "a", "a", "a", "", "", 0)}};
// TEST(evaluate_ast, evaluate_simple_math)
// {
// std::unordered_map<std::string, Metric> metrics;
// std::unordered_map<uint64_t, metric_result> results_map;
// std::unordered_map<uint64_t, std::vector<double>> expected_values;
for(auto& counter_found : required_counters)
{
EXPECT_NE(expected.find(counter_found), expected.end());
}
}
// uint64_t id = 0;
// for(auto& data : test_data_evaluate_simple_math)
// {
// metrics.emplace(
// data.name, Metric("gfx9", data.name, "Block", "0", "", data.expr, "", id));
// metric_result res = {id, data.sample_values};
// results_map.emplace(id, res);
// expected_values.emplace(id, data.expected_values);
// ++id;
// }
// std::unordered_map<std::string, EvaluateAST> asts;
// for(auto [val, metric] : metrics)
// {
// RawAST* ast = nullptr;
// auto buf = yy_scan_string(metric.expression().empty() ? metric.name().c_str()
// : metric.expression().c_str());
// yyparse(&ast);
// ASSERT_TRUE(ast);
// asts.emplace(val, std::move(EvaluateAST(metrics, *ast, "gfx9")));
// yy_delete_buffer(buf);
// delete ast;
// }
// for(auto [metric_name, ast] : asts)
// {
// double value = ast.evaluate(results_map);
// uint64_t metric_id = metrics.at(metric_name).id();
// EXPECT_EQ(value, expected_values.at(metric_id)[0]);
// }
// }
// TEST(evaluate_ast, evaluate_evaluate_simple_reduce)
// {
// std::unordered_map<std::string, Metric> metrics;
// std::unordered_map<uint64_t, metric_result> results_map;
// std::unordered_map<uint64_t, std::vector<double>> expected_values;
// uint64_t id = 0;
// for(auto& data : test_data_evaluate_simple_reduce)
// {
// metrics.emplace(
// data.name, Metric("gfx9", data.name, "Block", "0", "", data.expr, "", id));
// metric_result res = {id, data.sample_values};
// results_map.emplace(id, res);
// expected_values.emplace(id, data.expected_values);
// ++id;
// }
// std::unordered_map<std::string, EvaluateAST> asts;
// for(auto [val, metric] : metrics)
// {
// RawAST* ast = nullptr;
// auto buf = yy_scan_string(metric.expression().empty() ? metric.name().c_str()
// : metric.expression().c_str());
// yyparse(&ast);
// ASSERT_TRUE(ast);
// asts.emplace(val, EvaluateAST(metrics, *ast, "gfx9"));
// yy_delete_buffer(buf);
// delete ast;
// }
// for(auto [metric_name, ast]: asts){
// double value = ast.evaluate(results_map);
// uint64_t metric_id = metrics.at(metric_name).id();
// EXPECT_EQ(value, expected_values.at(metric_id)[0]);
// }
// }
@@ -0,0 +1,44 @@
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
#include "lib/rocprofiler/counters/evaluate_ast.hpp"
struct test_data
{
std::string name;
std::string expr;
std::vector<int> sample_values;
std::vector<double> expected_values;
};
static const std::vector<test_data> test_data_evaluate_simple_math = {
{"SQ_WAVES", "", {10, 20, 30}, {60}},
{"TCC_HIT", "", {1, 2, 3, 4, 5}, {15}},
{"SQ_INSTS_VALU", "", {2, 4, 6, 8}, {20}},
/* Add/Subtract/Multiply/Divide */
{"Metric_1", "SQ_WAVES+TCC_HIT", {}, {75}},
{"Metric_2", "SQ_WAVES-TCC_HIT", {}, {45}},
{"Metric_3", "SQ_WAVES*TCC_HIT", {}, {900}},
{"Metric_4", "SQ_WAVES/TCC_HIT", {}, {4}},
/* Order of Ops */
{"Metric_5", "(SQ_WAVES+TCC_HIT)/SQ_INSTS_VALU", {}, {3.75}},
{"Metric_6", "(SQ_WAVES/TCC_HIT)-SQ_INSTS_VALU", {}, {-16}},
{"Metric_7", "SQ_WAVES/(TCC_HIT-SQ_INSTS_VALU)", {}, {-12}},
{"Metric_8", "SQ_WAVES*(TCC_HIT/SQ_INSTS_VALU)", {}, {45}}};
static const std::vector<test_data> test_data_evaluate_simple_reduce = {
{"SQ_WAVES", "", {10, 20, 30}, {60}},
{"TCC_HIT", "", {1, 2, 3}, {6}},
/* Simple reduce operations */
{"Metric_1", "reduce(SQ_WAVES, sum)", {}, {60}},
{"Metric_2", "reduce(SQ_WAVES, sum, [DIMENSION_XCC])", {}, {60}},
{"Metric_3", "reduce(SQ_WAVES, min, [DIMENSION_XCC])", {}, {10}},
{"Metric_4", "reduce(SQ_WAVES, max, [DIMENSION_XCC])", {}, {30}},
{"Metric_5", "reduce(SQ_WAVES, avr, [DIMENSION_XCC])", {}, {20}},
{"Metric_6", "reduce(SQ_WAVES, sum) + reduce(SQ_WAVES, avr)", {}, {80}},
{"Metric_7", "reduce(SQ_WAVES, max) - reduce(TCC_HIT, min)", {}, {29}}};
+7 -1
Ver ficheiro
@@ -1,5 +1,6 @@
#include "metrics_test.h"
#include <glog/logging.h>
#include <gtest/gtest.h>
#include "lib/rocprofiler/counters/metrics.hpp"
@@ -17,7 +18,8 @@ loadTestData(const std::unordered_map<std::string, std::vector<std::vector<std::
auto& metric_vec = ret.emplace(gfx, std::vector<counters::Metric>{}).first->second;
for(const auto& data_vec : dataMap)
{
metric_vec.emplace_back(data_vec.at(0),
metric_vec.emplace_back("gfx9",
data_vec.at(0),
data_vec.at(1),
data_vec.at(2),
data_vec.at(4),
@@ -34,6 +36,7 @@ TEST(metrics, base_load)
{
auto rocp_data = counters::getBaseHardwareMetrics();
auto test_data = loadTestData(basic_gfx908);
ASSERT_EQ(rocp_data.count("gfx908"), 1);
ASSERT_EQ(test_data.count("gfx908"), 1);
auto rocp_data_v = rocp_data.at("gfx908");
@@ -41,7 +44,10 @@ TEST(metrics, base_load)
EXPECT_EQ(rocp_data_v.size(), test_data_v.size());
auto find = [&rocp_data_v](const auto& v) -> std::optional<counters::Metric> {
for(const auto& ditr : rocp_data_v)
{
LOG(ERROR) << fmt::format("{}", ditr);
if(ditr.name() == v.name()) return ditr;
}
return std::nullopt;
};
auto equal = [](const auto& lhs, const auto& rhs) {
+21 -21
Ver ficheiro
@@ -1,9 +1,9 @@
<gfx8 base="gfx8">
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
@@ -40,9 +40,9 @@
<gfx9>
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
@@ -82,9 +82,9 @@
# EA1
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="TCC_EA1_WRREQ" block=TCC event=256 descr="Number of transactions (either 32-byte or 64-byte) going over the TC_EA_wrreq interface. Atomics may travel over the same interface and are generally classified as write requests. This does not include probe commands."></metric>
<metric name="TCC_EA1_WRREQ_64B" block=TCC event=257 descr="Number of 64-byte transactions going (64-byte write or CMPSWAP) over the TC_EA_wrreq interface."></metric>
<metric name="TCC_EA1_WRREQ_STALL" block=TCC event=260 descr="Number of cycles a write request was stalled."></metric>
@@ -120,9 +120,9 @@
<gfx90a>
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="SQ_WAIT_INST_LDS" block=SQ event=91 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block=TCP event=6 descr="TCP stalls TA data interface. Now Windowed."></metric>
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
@@ -388,9 +388,9 @@
<gfx940>
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="SQ_WAIT_INST_LDS" block=SQ event=96 descr="Number of wave-cycles spent waiting for LDS instruction issue. In units of 4 cycles. (per-simd, nondeterministic)"></metric>
<metric name="TCP_TCP_TA_DATA_STALL_CYCLES" block=TCP event=6 descr="TCP stalls TA data interface. Now Windowed."></metric>
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
@@ -661,9 +661,9 @@
<gfx10>
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
<metric name="GRBM_CP_BUSY" block=GRBM event=3 descr="Any of the Command Processor (CPG/CPC/CPF) blocks are busy."></metric>
@@ -726,9 +726,9 @@
<gfx11>
<metric name="MAX_WAVE_SIZE" descr="Max wave size constant" special="yes"></metric>
<metric name="KERNEL_DURATION" descr="The duration of the kernel dispatch" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM" special="yes"></metric>
<metric name="SIMD_NUM" descr="SIMD Number" special="yes"></metric>
<metric name="CU_NUM" descr="CU_NUM" special="yes"></metric>
<metric name="SE_NUM" descr="SE_NUM"></metric>
<metric name="SIMD_NUM" descr="SIMD Number"></metric>
<metric name="CU_NUM" descr="CU_NUM"></metric>
<metric name="GRBM_COUNT" block=GRBM event=0 descr="Tie High - Count Number of Clocks"></metric>
<metric name="GRBM_GUI_ACTIVE" block=GRBM event=2 descr="The GUI is Active"></metric>
<metric name="GL2C_HIT" block=GL2C event=42 descr="Number of cache hits"></metric>
+3 -3
Ver ficheiro
@@ -249,21 +249,21 @@
<metric name="MfmaFlopsF64" expr=SQ_INSTS_VALU_MFMA_MOPS_F64*512 descr="Unit: IOP"></metric>
<metric name="ScaPipeIssueUtil" expr=100*SQ_ACTIVE_INST_SCA/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
<metric name="ValuPipeIssueUtil" expr=100*SQ_ACTIVE_INST_VALU/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
<metric name="VmemPipeIssueUtil" expr=100*4*(SQ_ACTIVE_INST_VMEM+SQ_ACTIVE_INST_FLAT)/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
<metric name="VmemPipeIssueUtil" expr=400*(SQ_ACTIVE_INST_VMEM+SQ_ACTIVE_INST_FLAT)/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
<metric name="MfmaUtil" expr=100*SQ_VALU_MFMA_BUSY_CYCLES/(GRBM_GUI_ACTIVE*CU_NUM*4) descr="Unit: percent"></metric>
<metric name="AvgNumActiveThreads" expr=SQ_THREAD_CYCLES_VALU/SQ_ACTIVE_INST_VALU descr="Unit: percent"></metric>
<metric name="VmemLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_INSTS_VMEM descr="Unit: cycles"></metric>
<metric name="SmemLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_INSTS_SMEM_NORM descr="Unit: cycles"></metric>
## Local Data Share (LDS) Metrics
<metric name="LdsUtil" expr=100*SQ_LDS_IDX_ACTIVE/(GRBM_GUI_ACTIVE*CU_NUM) descr="Unit: percent"></metric>
<metric name="LdsPipeIssueUtil" expr=100*4*SQ_ACTIVE_INST_LDS/(GRBM_GUI_ACTIVE*CU_NUM*2) descr="Unit: percent"></metric>
<metric name="LdsPipeIssueUtil" expr=400*SQ_ACTIVE_INST_LDS/(GRBM_GUI_ACTIVE*CU_NUM*2) descr="Unit: percent"></metric>
<metric name="LdsLatency" expr=SQ_ACCUM_PREV_HIRES/SQ_INSTS_LDS descr="Unit: cycles"></metric>
<metric name="LdsBankConflict" expr=SQ_LDS_BANK_CONFLICT/(SQ_LDS_IDX_ACTIVE-SQ_LDS_BANK_CONFLICT) descr="Unit: conflicts/access"></metric>
## L1I and sL1D Cache Metrics
<metric name="L1iCacheHitRate" expr=100*SQC_ICACHE_HITS/SQC_ICACHE_REQ descr="Unit: percent"></metric>
<metric name="sL1dCacheHitRate" expr=100*SQC_DCACHE_HITS/SQC_DCACHE_REQ descr="Unit: percent"></metric>
## vL1D Cache Metrics
<metric name="vL1dBufCoalesceRate" expr=100*64*TA_TOTAL_WAVEFRONTS_sum/(TCP_TOTAL_ACCESSES_sum*4) descr="Unit: percent"></metric>
<metric name="vL1dBufCoalesceRate" expr=6400*TA_TOTAL_WAVEFRONTS_sum/(TCP_TOTAL_ACCESSES_sum*4) descr="Unit: percent"></metric>
<metric name="vL1dCacheUtil" expr=100*TCP_GATE_EN2_sum/TCP_GATE_EN1_sum descr="Unit: percent"></metric>
<metric name="vL1dCacheTcbHitRate" expr=100*TCP_UTCL1_TRANSLATION_HIT_sum/TCP_UTCL1_REQUEST_sum descr="Unit: percent"></metric>
<metric name="vL1dCacheWaveLatency" expr=TCP_TCP_LATENCY_sum/TCP_TA_TCP_STATE_READ_sum descr="Unit: cycles"></metric>
-13
Ver ficheiro
@@ -34,19 +34,6 @@ rocprofiler_create_profile_config(rocprofiler_agent_t agent,
const auto* metric_ptr = rocprofiler::common::get_val(id_map, counter_id.handle);
if(!metric_ptr) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
config.metrics.push_back(*metric_ptr);
auto agent_name = std::string(agent.name);
auto req_counters =
rocprofiler::counters::get_required_hardware_counters(agent_name, *metric_ptr);
if(!req_counters) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
config.reqired_hw_counters.insert(req_counters->begin(), req_counters->end());
const auto& asts = rocprofiler::counters::get_ast_map();
const auto* agent_map = rocprofiler::common::get_val(asts, agent_name);
if(!agent_map) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
const auto* counter_ast = rocprofiler::common::get_val(*agent_map, metric_ptr->name());
if(!counter_ast) return ROCPROFILER_STATUS_ERROR_COUNTER_NOT_FOUND;
config.asts.push_back(*counter_ast);
}
config.agent = agent;