Files
systems-assistant[bot] b60c0ceddd [rocprofv3] Unconditionally collect stream and kernel rename data in rocprofv3 for rocpd (#171)
* Remove config checks for stream and kernel rename data collection

* Updated csv generation to check if kernel rename is on before calling get_kernel_name

* Update metadata to use kernel_rename bool argument

* Formatting + unconditionally store kernel name in rocpd

* Readded kernel rename parameter after rebase

* Fixed rebase conflicts

* Updated comment in line with github comments

* Added check in rocpd csv.cpp to output kernel name if region name is empty

* Add test for kernel rename

---------

Co-authored-by: Ian Trowbridge <Ian.Trowbridge@amd.com>
2025-09-10 16:03:15 -05:00

874 строки
28 KiB
C++

// MIT License
//
// Copyright (c) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "metadata.hpp"
#include "agent_info.hpp"
#include "host_symbol_info.hpp"
#include "kernel_symbol_info.hpp"
#include "node_info.hpp"
#include "lib/att-tool/att_lib_wrapper.hpp"
#include "lib/common/environment.hpp"
#include "lib/common/filesystem.hpp"
#include "lib/common/logging.hpp"
#include "lib/common/string_entry.hpp"
#include "lib/common/utility.hpp"
#include "lib/output/agent_info.hpp"
#include "lib/output/host_symbol_info.hpp"
#include "lib/output/kernel_symbol_info.hpp"
#include "lib/output/node_info.hpp"
#include <rocprofiler-sdk/fwd.h>
#include <rocprofiler-sdk/rocprofiler.h>
#include <rocprofiler-sdk/cxx/details/tokenize.hpp>
#include <fmt/core.h>
#include <fmt/format.h>
#include <dlfcn.h>
#include <unistd.h>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
namespace rocprofiler
{
namespace tool
{
namespace
{
namespace fs = ::rocprofiler::common::filesystem;
rocprofiler_status_t
query_pc_sampling_configuration(const rocprofiler_pc_sampling_configuration_t* configs,
long unsigned int num_config,
void* user_data)
{
auto* avail_configs =
static_cast<std::vector<rocprofiler_pc_sampling_configuration_t>*>(user_data);
for(size_t i = 0; i < num_config; i++)
{
avail_configs->emplace_back(configs[i]);
}
return ROCPROFILER_STATUS_SUCCESS;
}
/**
* @brief Processes and stores the supported counters for a given agent.
*
* This function iterates over all counters supported by the given agent.
* If a filter set is provided, only counters present in the filter set are processed.
* Otherwise, all counters are collected.
*
* @param agent_id The ID of the agent whose counters are being processed.
* @param filter_set Optional set of counter names to filter which counters to load. If null,
* all supported counters will be loaded.
* @param output_map A reference to the map where the processed counter information will be stored.
*
* @return ROCPROFILER_STATUS_SUCCESS on success, or an appropriate error status on failure.
*/
rocprofiler_status_t
process_agent_counters(rocprofiler_agent_id_t agent_id,
std::set<std::string>* filter_set,
agent_counter_info_map_t& output_map)
{
struct callback_data_t
{
std::set<std::string>* counters_set = nullptr;
agent_counter_info_map_t* agent_counter_info = nullptr;
};
auto cb_data = callback_data_t{filter_set, &output_map};
return rocprofiler_iterate_agent_supported_counters(
agent_id,
[](rocprofiler_agent_id_t id,
rocprofiler_counter_id_t* counters,
size_t num_counters,
void* user_data) {
auto* data = static_cast<callback_data_t*>(user_data);
auto* counters_set_data = data->counters_set;
auto* agent_counter_info_data = data->agent_counter_info;
agent_counter_info_data->emplace(id, counter_info_vec_t{});
for(size_t i = 0; i < num_counters; ++i)
{
auto _info = rocprofiler_counter_info_v1_t{};
auto _dim_ids = std::vector<rocprofiler_counter_dimension_id_t>{};
auto _dim_info = std::vector<rocprofiler_counter_record_dimension_info_t>{};
ROCPROFILER_CHECK(rocprofiler_query_counter_info(
counters[i], ROCPROFILER_COUNTER_INFO_VERSION_1, &_info));
if(counters_set_data != nullptr && counters_set_data->count(_info.name) == 0)
continue;
for(uint64_t j = 0; j < _info.dimensions_count; ++j)
{
if(_info.dimensions[j] == nullptr)
{
ROCP_WARNING << fmt::format(
"nullptr dimension encountered for counter '{}' at index {}",
_info.name,
j);
continue;
}
_dim_ids.emplace_back(_info.dimensions[j]->id);
_dim_info.emplace_back(*_info.dimensions[j]);
}
agent_counter_info_data->at(id).emplace_back(
id, _info, std::move(_dim_ids), std::move(_dim_info));
}
return ROCPROFILER_STATUS_SUCCESS;
},
&cb_data);
}
} // namespace
kernel_symbol_info::kernel_symbol_info()
: base_type{0, 0, 0, "", 0, 0, 0, 0, 0, 0, 0, 0, 0, {.handle = 0}}
{}
constexpr auto null_address_v = rocprofiler_address_t{.handle = 0};
constexpr auto null_dim3_v = rocprofiler_dim3_t{.x = 0, .y = 0, .z = 0};
host_function_info::host_function_info()
: base_type{0,
0,
0,
0,
null_address_v,
null_address_v,
"",
0,
null_dim3_v,
null_dim3_v,
null_dim3_v,
null_dim3_v,
0}
{}
metadata::metadata(inprocess)
: buffer_names{sdk::get_buffer_tracing_names()}
, callback_names{sdk::get_callback_tracing_names()}
, node_data{read_node_info()}
, command_line{common::read_command_line(getpid())}
{
ROCPROFILER_CHECK(rocprofiler_query_available_agents(
ROCPROFILER_AGENT_INFO_VERSION_0,
[](rocprofiler_agent_version_t, const void** _agents, size_t _num_agents, void* _data) {
auto* _agents_v = static_cast<agent_info_vec_t*>(_data);
_agents_v->reserve(_num_agents);
for(size_t i = 0; i < _num_agents; ++i)
{
auto* agent = static_cast<const rocprofiler_agent_v0_t*>(_agents[i]);
_agents_v->emplace_back(*agent);
}
return ROCPROFILER_STATUS_SUCCESS;
},
sizeof(rocprofiler_agent_v0_t),
&agents));
{
auto _gpu_agents = std::vector<agent_info*>{};
_gpu_agents.reserve(agents.size());
for(auto& itr : agents)
{
if(itr.type == ROCPROFILER_AGENT_TYPE_GPU)
{
_gpu_agents.emplace_back(&itr);
auto pc_configs = std::vector<rocprofiler_pc_sampling_configuration_t>{};
rocprofiler_query_pc_sampling_agent_configurations(
itr.id, query_pc_sampling_configuration, &pc_configs);
agent_pc_sample_config_info.emplace(itr.id, pc_configs);
}
}
// make sure they are sorted by node id
std::sort(_gpu_agents.begin(), _gpu_agents.end(), [](const auto& lhs, const auto& rhs) {
return CHECK_NOTNULL(lhs)->node_id < CHECK_NOTNULL(rhs)->node_id;
});
int64_t _dev_id = 0;
for(auto& itr : _gpu_agents)
itr->gpu_index = _dev_id++;
}
for(auto itr : agents)
agents_map.emplace(itr.id, itr);
// Add kernel ID of zero
kernel_symbol_info info{};
info.kernel_id = 0;
info.formatted_kernel_name = "0";
info.demangled_kernel_name = "0";
info.truncated_kernel_name = "0";
add_kernel_symbol(std::move(info));
}
/**
* @brief Initializes the metadata by loading all counters supported on GPU agents.
*
* This method is used by the `rocprofv3-avail` tool to enumerate all available counters
* for each GPU agent in the system.
*
* For each non-CPU agent, this function calls `process_agent_counters` with a null filter,
* ensuring that all counters supported by that agent are queried and stored in metadata.
*/
void metadata::init(inprocess)
{
if(inprocess_init) return;
inprocess_init = true;
for(const auto& agent : agents)
{
if(agent.type == ROCPROFILER_AGENT_TYPE_CPU) continue;
auto status = process_agent_counters(agent.id, nullptr, agent_counter_info);
ROCP_WARNING_IF(status != ROCPROFILER_STATUS_SUCCESS) << fmt::format(
"rocprofiler_iterate_agent_supported_counters failed for agent {} ({}) :: {}",
agent.node_id,
agent.name,
rocprofiler_get_status_string(status));
}
}
/**
* @brief Initializes the metadata by loading only selected counters for GPU agents.
*
* This method is used by the `rocprofv3` tool when profiling with a list
* of performance counters which are profiled by user.
*
* This filtering reduces runtime overhead and significantly shrinks the size of
* generated JSON metadata in profiling output.
*/
void
metadata::init(inprocess_with_counters&& data)
{
if(inprocess_init) return;
inprocess_init = true;
// No counters to process, exit early. Kernel trace doesn't have to iterate counters.
if(data.counters.empty()) return;
auto gpu_index_to_counters_map = std::map<int, std::set<std::string>>{};
for(const auto& agent : agents)
{
gpu_index_to_counters_map[agent.gpu_index] = {};
}
// Used to parse counters like "SQ_WAVES:device=0".
constexpr auto device_qualifier = std::string_view{":device="};
for(const auto& pmc_counter : data.counters)
{
auto name_v = pmc_counter;
if(auto pos = pmc_counter.find(device_qualifier); pos != std::string::npos)
{
name_v = pmc_counter.substr(0, pos);
auto device_id_s = pmc_counter.substr(pos + device_qualifier.length());
ROCP_FATAL_IF(device_id_s.empty() ||
device_id_s.find_first_not_of("0123456789") != std::string::npos)
<< fmt::format("Invalid device qualifier format (expected ':device=N') in '{}'",
pmc_counter);
auto device_id_l = std::stol(device_id_s);
if(gpu_index_to_counters_map.find(device_id_l) == gpu_index_to_counters_map.end())
{
ROCP_WARNING << fmt::format("Device ID not found for PMC counter '{}'",
pmc_counter);
continue;
}
// Add the counter to the corresponding device.
gpu_index_to_counters_map[device_id_l].emplace(name_v);
}
else
{
// No device qualifier — add to all devices.
for(auto& [_, counters] : gpu_index_to_counters_map)
counters.emplace(name_v);
}
}
// Process selected counters for each GPU agent.
for(const auto& agent : agents)
{
if(agent.type == ROCPROFILER_AGENT_TYPE_CPU) continue;
auto* filter = &gpu_index_to_counters_map[agent.gpu_index];
auto status = process_agent_counters(agent.id, filter, agent_counter_info);
ROCP_WARNING_IF(status != ROCPROFILER_STATUS_SUCCESS) << fmt::format(
"rocprofiler_iterate_agent_supported_counters failed for agent {} ({}) :: {}",
agent.node_id,
agent.name,
rocprofiler_get_status_string(status));
}
}
const agent_info*
metadata::get_agent(rocprofiler_agent_id_t _val) const
{
for(const auto& itr : agents)
{
if(itr.id == _val) return &itr;
}
return nullptr;
}
const code_object_info*
metadata::get_code_object(uint64_t code_obj_id) const
{
return code_objects.rlock([code_obj_id](const auto& _data) -> const code_object_info* {
return &_data.at(code_obj_id);
});
}
code_object_load_info_vec_t
metadata::get_code_object_load_info() const
{
auto _data = code_object_load.rlock([](const auto& _data_v) {
auto _info = std::vector<rocprofiler::att_wrapper::CodeobjLoadInfo>{};
_info.reserve(_data_v.size());
for(const auto& itr : _data_v)
_info.emplace_back(itr);
return _info;
});
uint64_t _sz = 0;
for(const auto& itr : _data)
_sz = std::max(_sz, itr.id);
ROCP_WARNING_IF((_sz + 1) - _data.size() > 1000) << fmt::format(
"Spares index detected for code object load info: {} < {}", _data.size(), _sz);
auto _code_obj_data = std::vector<rocprofiler::att_wrapper::CodeobjLoadInfo>{};
_code_obj_data.resize(_sz + 1, rocprofiler::att_wrapper::CodeobjLoadInfo{});
// index by the code object id
for(auto& itr : _data)
_code_obj_data.at(itr.id) = itr;
return _code_obj_data;
}
std::vector<std::string>
metadata::get_att_filenames() const
{
auto data = std::vector<std::string>{};
for(const auto& filenames : att_filenames)
{
for(const auto& file : filenames.second.second)
{
data.emplace_back(fs::path{file}.filename());
}
}
return data;
}
const kernel_symbol_info*
metadata::get_kernel_symbol(uint64_t kernel_id) const
{
return kernel_symbols.rlock([kernel_id](const auto& _data) -> const kernel_symbol_info* {
return &_data.at(kernel_id);
});
}
const host_function_info*
metadata::get_host_function(uint64_t host_function_id) const
{
return host_functions.rlock([host_function_id](const auto& _data) -> const host_function_info* {
return &_data.at(host_function_id);
});
}
const tool_counter_info*
metadata::get_counter_info(uint64_t instance_id) const
{
auto _counter_id = rocprofiler_counter_id_t{.handle = 0};
ROCPROFILER_CHECK(rocprofiler_query_record_counter_id(instance_id, &_counter_id));
return get_counter_info(_counter_id);
}
const tool_counter_info*
metadata::get_counter_info(rocprofiler_counter_id_t id) const
{
for(const auto& itr : agent_counter_info)
{
for(const auto& aitr : itr.second)
{
if(aitr.id == id) return &aitr;
}
}
return nullptr;
}
const counter_dimension_info_vec_t*
metadata::get_counter_dimension_info(uint64_t instance_id) const
{
return &CHECK_NOTNULL(get_counter_info(instance_id))->dimensions;
}
code_object_data_vec_t
metadata::get_code_objects() const
{
auto _data = code_objects.rlock([](const auto& _data_v) {
auto _info = std::vector<code_object_info>{};
_info.reserve(_data_v.size());
for(const auto& itr : _data_v)
_info.emplace_back(itr.second);
return _info;
});
uint64_t _sz = 0;
for(const auto& itr : _data)
_sz = std::max(_sz, itr.code_object_id);
auto _code_obj_data = std::vector<code_object_info>{};
_code_obj_data.resize(_sz + 1, code_object_info{});
// index by the code object id
for(auto& itr : _data)
_code_obj_data.at(itr.code_object_id) = itr;
return _code_obj_data;
}
kernel_symbol_data_vec_t
metadata::get_kernel_symbols() const
{
auto _data = kernel_symbols.rlock([](const auto& _data_v) {
auto _info = std::vector<kernel_symbol_info>{};
_info.reserve(_data_v.size());
for(const auto& itr : _data_v)
_info.emplace_back(itr.second);
return _info;
});
uint64_t kernel_data_size = 0;
for(const auto& itr : _data)
kernel_data_size = std::max(kernel_data_size, itr.kernel_id);
auto _symbol_data = std::vector<kernel_symbol_info>{};
_symbol_data.resize(kernel_data_size + 1, kernel_symbol_info{});
// index by the kernel id
for(auto& itr : _data)
_symbol_data.at(itr.kernel_id) = std::move(itr);
return _symbol_data;
}
host_function_data_vec_t
metadata::get_host_symbols() const
{
return host_functions.rlock([](const auto& _data_v) {
auto _info = std::vector<host_function_info>{};
_info.resize(_data_v.size() + 1, host_function_info{});
for(const auto& itr : _data_v)
_info.at(itr.first) = itr.second;
return _info;
});
}
metadata::agent_info_ptr_vec_t
metadata::get_gpu_agents() const
{
auto _data = metadata::agent_info_ptr_vec_t{};
for(const auto& itr : agents)
{
if(itr.type == ROCPROFILER_AGENT_TYPE_GPU) _data.emplace_back(&itr);
}
return _data;
}
pc_sample_config_vec_t
metadata::get_pc_sample_config_info(rocprofiler_agent_id_t _val) const
{
auto _ret = pc_sample_config_vec_t{};
if(agent_pc_sample_config_info.find(_val) == agent_pc_sample_config_info.end()) return _ret;
auto pc_sample_config = agent_pc_sample_config_info.at(_val);
for(const auto& itr : pc_sample_config)
{
_ret.emplace_back(itr);
}
return _ret;
}
counter_info_vec_t
metadata::get_counter_info() const
{
auto _ret = std::vector<tool_counter_info>{};
for(const auto& itr : agent_counter_info)
{
for(const auto& iitr : itr.second)
_ret.emplace_back(iitr);
}
return _ret;
}
counter_dimension_vec_t
metadata::get_counter_dimension_info() const
{
auto _ret = counter_dimension_vec_t{};
for(const auto& itr : agent_counter_info)
{
for(const auto& iitr : itr.second)
for(const auto& ditr : iitr.dimensions)
_ret.emplace_back(ditr);
}
auto _sorter = [](const rocprofiler_counter_record_dimension_info_t& lhs,
const rocprofiler_counter_record_dimension_info_t& rhs) {
return std::tie(lhs.id, lhs.instance_size) < std::tie(rhs.id, rhs.instance_size);
};
auto _equiv = [](const rocprofiler_counter_record_dimension_info_t& lhs,
const rocprofiler_counter_record_dimension_info_t& rhs) {
return std::tie(lhs.id, lhs.instance_size) == std::tie(rhs.id, rhs.instance_size);
};
std::sort(_ret.begin(), _ret.end(), _sorter);
_ret.erase(std::unique(_ret.begin(), _ret.end(), _equiv), _ret.end());
return _ret;
}
metadata::string_index_map_t
metadata::get_string_entries() const
{
return string_entries.rlock([](const auto& _inp) {
auto _sorted = std::vector<std::string_view>{};
_sorted.reserve(_inp.size());
for(const auto& itr : _inp)
_sorted.emplace_back(std::string_view{*itr.second});
std::sort(_sorted.begin(), _sorted.end());
auto _ret = string_index_map_t{};
size_t _idx = 1;
for(const auto& itr : _sorted)
_ret.emplace(itr, _idx++);
return _ret;
});
}
bool
metadata::add_marker_message(uint64_t corr_id, std::string&& msg)
{
return marker_messages.wlock(
[](auto& _data, uint64_t _cid_v, std::string&& _msg) -> bool {
return _data.emplace(_cid_v, std::move(_msg)).second;
},
corr_id,
std::move(msg));
}
bool
metadata::add_code_object(code_object_info obj)
{
return code_objects.wlock(
[](code_object_data_map_t& _data_v, code_object_info _obj_v) -> bool {
return _data_v.emplace(_obj_v.code_object_id, _obj_v).second;
},
obj);
}
bool
metadata::add_kernel_symbol(kernel_symbol_info&& sym)
{
return kernel_symbols.wlock(
[](kernel_symbol_data_map_t& _data_v, kernel_symbol_info&& _sym_v) -> bool {
return _data_v.emplace(_sym_v.kernel_id, std::move(_sym_v)).second;
},
std::move(sym));
}
bool
metadata::add_host_function(host_function_info&& func)
{
return host_functions.wlock(
[](host_function_info_map_t& _data_v, host_function_info&& _func_v) -> bool {
return _data_v.emplace(_func_v.host_function_id, std::move(_func_v)).second;
},
std::move(func));
}
bool
metadata::add_string_entry(size_t key, std::string_view str)
{
return string_entries.ulock(
[](const auto& _data, size_t _key, std::string_view) { return (_data.count(_key) > 0); },
[](auto& _data, size_t _key, std::string_view _str) {
_data.emplace(_key, new std::string{_str});
return true;
},
key,
str);
}
bool
metadata::add_external_correlation_id(uint64_t val)
{
return external_corr_ids.wlock(
[](auto& _data, uint64_t _val) { return _data.emplace(_val).second; }, val);
}
bool
metadata::add_runtime_initialization(rocprofiler_runtime_initialization_operation_t runtime_op)
{
return runtime_initialization_set.wlock(
[](auto& _data, rocprofiler_runtime_initialization_operation_t _runtime_op) {
return _data.emplace(_runtime_op).second;
},
runtime_op);
}
uint64_t
metadata::add_kernel_rename_val(std::string_view rename_string, uint64_t internal_corr_id)
{
return kernel_rename_map.wlock(
[](auto& _data, std::string_view _str, uint64_t _val) {
return _data.emplace(_str, _val).first->second;
},
rename_string,
internal_corr_id);
}
bool
metadata::is_runtime_initialized(rocprofiler_runtime_initialization_operation_t runtime_op) const
{
return runtime_initialization_set.rlock(
[](const auto& _data, rocprofiler_runtime_initialization_operation_t _runtime_op) {
return _data.count(_runtime_op) > 0;
},
runtime_op);
}
void
metadata::set_process_id(pid_t _pid, pid_t _ppid, const std::vector<std::string>& _command_line)
{
process_id = _pid;
parent_process_id = _ppid;
if(!_command_line.empty())
command_line = _command_line;
else if(_pid == getpid())
command_line = common::read_command_line(_pid);
if(auto _start_ns = common::get_process_start_time_ns(_pid); _start_ns > 0)
process_start_ns = _start_ns;
}
std::string_view
metadata::get_marker_message(uint64_t corr_id) const
{
return marker_messages.rlock(
[](const auto& _data, uint64_t _corr_id_v) -> std::string_view {
return (_data.count(_corr_id_v) > 0) ? _data.at(_corr_id_v) : std::string_view{};
},
corr_id);
}
std::string_view
metadata::get_kernel_name(uint64_t kernel_id, bool rename_kernel, uint64_t rename_id) const
{
if(rename_kernel)
{
auto string_entry = kernel_rename_map.rlock(
[](auto& _data, uint64_t _val) {
for(const auto& itr : _data)
if(itr.second == _val) return itr.first;
return std::string_view{};
},
rename_id);
if(!string_entry.empty())
{
if(const auto* _name = common::get_string_entry(string_entry))
return std::string_view{*_name};
}
}
const auto* _kernel_data = get_kernel_symbol(kernel_id);
return CHECK_NOTNULL(_kernel_data)->formatted_kernel_name;
}
std::string_view
metadata::get_kind_name(rocprofiler_callback_tracing_kind_t kind) const
{
return callback_names.at(kind);
}
std::string_view
metadata::get_kind_name(rocprofiler_buffer_tracing_kind_t kind) const
{
return buffer_names.at(kind);
}
std::string_view
metadata::get_operation_name(rocprofiler_callback_tracing_kind_t kind,
rocprofiler_tracing_operation_t op) const
{
return callback_names.at(kind, op);
}
std::string_view
metadata::get_operation_name(rocprofiler_buffer_tracing_kind_t kind,
rocprofiler_tracing_operation_t op) const
{
return buffer_names.at(kind, op);
}
agent_index
metadata::get_agent_index(rocprofiler_agent_id_t id, agent_indexing index) const
{
const auto* _agent = get_agent(id);
ROCP_FATAL_IF(!_agent) << "Information of the agent with handle: " << id.handle
<< " is not present";
// stringify agent type
auto get_type = [_agent]() -> std::string_view {
switch(_agent->type)
{
case ROCPROFILER_AGENT_TYPE_CPU: return "CPU";
case ROCPROFILER_AGENT_TYPE_GPU: return "GPU";
case ROCPROFILER_AGENT_TYPE_NONE:
case ROCPROFILER_AGENT_TYPE_LAST: break;
}
return "UNK";
};
return create_agent_index(
index,
_agent->node_id, // absolute index
static_cast<uint32_t>(_agent->logical_node_id), // relative index
static_cast<uint32_t>(_agent->logical_node_type_id), // type-relative index
get_type());
}
const std::string*
metadata::get_string_entry(size_t key) const
{
const auto* ret = string_entries.rlock(
[](const auto& _data, size_t _key) -> const std::string* {
if(_data.count(_key) > 0) return _data.at(_key).get();
return nullptr;
},
key);
if(!ret) ret = common::get_string_entry(key);
return ret;
}
int64_t
metadata::get_instruction_index(rocprofiler_pc_t record)
{
inst_t ins;
ins.code_object_id = record.code_object_id;
ins.code_object_offset = record.code_object_offset;
auto itr = indexes.find(ins);
if(itr != indexes.end()) return itr->second;
auto idx = instruction_decoder.size();
auto pc_instruction = decode_instruction(record);
instruction_decoder.emplace_back(pc_instruction->inst);
instruction_comment.emplace_back(pc_instruction->comment);
indexes.emplace(ins, idx);
return idx;
}
void
metadata::add_decoder(rocprofiler_code_object_info_t* obj_data)
{
if(obj_data->storage_type == ROCPROFILER_CODE_OBJECT_STORAGE_TYPE_FILE)
{
decoder.wlock(
[](auto& _decoder, rocprofiler_code_object_info_t* obj_data_v) {
_decoder.addDecoder(obj_data_v->uri,
obj_data_v->code_object_id,
obj_data_v->load_delta,
obj_data_v->load_size);
},
obj_data);
}
else
{
decoder.wlock(
[](auto& _decoder, rocprofiler_code_object_info_t* obj_data_v) {
_decoder.addDecoder(
// NOLINTBEGIN(performance-no-int-to-ptr)
reinterpret_cast<const void*>(obj_data_v->memory_base),
// NOLINTEND(performance-no-int-to-ptr)
obj_data_v->memory_size,
obj_data_v->code_object_id,
obj_data_v->load_delta,
obj_data_v->load_size);
},
obj_data);
}
}
std::unique_ptr<instruction_t>
metadata::decode_instruction(rocprofiler_pc_t pc)
{
return decoder.wlock(
[](auto& _decoder, uint64_t id, uint64_t addr) { return _decoder.get(id, addr); },
pc.code_object_id,
pc.code_object_offset);
}
agent_index
create_agent_index(const rocprofiler::tool::agent_indexing index,
uint32_t agent_abs_index,
uint32_t agent_log_index,
uint32_t agent_type_index,
const std::string_view agent_type)
{
switch(index)
{
case rocprofiler::tool::agent_indexing::node: // absolute
{
return agent_index{"Agent", agent_abs_index, agent_type};
}
case rocprofiler::tool::agent_indexing::logical_node: // relative (default)
{
return agent_index{"Agent", agent_log_index, agent_type};
}
case rocprofiler::tool::agent_indexing::logical_node_type: // type-relative
{
return agent_index{agent_type, agent_type_index, agent_type};
}
}
ROCP_CI_LOG(WARNING) << fmt::format(
"Unsupported agent indexing {} for agent-{}", static_cast<int>(index), agent_abs_index);
return agent_index{};
}
} // namespace tool
} // namespace rocprofiler