[RSERP-1802] Add trace decoder to API (#398)

* Add trace decoder to API.

* Cleanup and activity

* Rename

* Minor fix

* Replace tt/TT with thread_trace/THREAD_TRACE

- public API types are not abbreviated

* Fix aliases

* Build system updates

- activate clang-tidy for all subfolders in lib
- fix addition of sources for att-tool

* Fix clang-tidy issues with lib/att-tool/counters.{hpp,cpp}

* Delete counters.cpp

* Formatting

---------

Co-authored-by: Giovanni Baraldi <gbaraldi@amd.com>
Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
このコミットが含まれているのは:
Baraldi, Giovanni
2025-05-17 21:08:33 +02:00
committed by GitHub
コミット 65786f619d
56個のファイルの変更、1175行の追加、1419行の削除
+28 -102
ファイルの表示
@@ -26,10 +26,10 @@
#endif
#include "profile_interface.hpp"
#include "att_decoder.h"
#include "dl.hpp"
#include "perfcounter.hpp"
#include <rocprofiler-sdk/experimental/thread-trace/trace_decoder.h>
#include <cxxabi.h>
#include <cstring>
#include <fstream>
@@ -38,66 +38,49 @@ namespace rocprofiler
{
namespace att_wrapper
{
struct trace_data_t
{
int64_t id{0};
uint8_t* data{nullptr};
uint64_t size{0};
ToolData* tool{nullptr};
};
rocprofiler_att_decoder_status_t
get_trace_data(rocprofiler_att_decoder_record_type_t trace_id,
int /* shader_id */,
void* trace_events,
size_t trace_size,
void* userdata)
void
get_trace_data(rocprofiler_thread_trace_decoder_record_type_t trace_id,
void* trace_events,
size_t trace_size,
void* userdata)
{
C_API_BEGIN
CHECK_NOTNULL(userdata);
trace_data_t& trace_data = *reinterpret_cast<trace_data_t*>(userdata);
CHECK_NOTNULL(trace_data.tool);
ToolData& tool = *trace_data.tool;
ToolData& tool = *static_cast<ToolData*>(userdata);
if(trace_id == ROCPROFILER_ATT_DECODER_TYPE_INFO)
if(trace_id == ROCPROFILER_THREAD_TRACE_DECODER_RECORD_INFO)
{
auto* infos = (rocprofiler_att_decoder_info_t*) trace_events;
auto* infos = (rocprofiler_thread_trace_decoder_info_t*) trace_events;
for(size_t i = 0; i < trace_size; i++)
ROCP_WARNING << tool.dl->att_info_fn(infos[i]);
ROCP_WARNING << rocprofiler_thread_trace_decoder_info_string(tool.decoder, infos[i]);
}
else if(trace_id == ROCPROFILER_ATT_DECODER_TYPE_GFXIP)
else if(trace_id == ROCPROFILER_THREAD_TRACE_DECODER_RECORD_GFXIP)
{
tool.config.filemgr->gfxip = reinterpret_cast<size_t>(trace_events);
}
else if(trace_id == ROCPROFILER_ATT_DECODER_TYPE_OCCUPANCY)
else if(trace_id == ROCPROFILER_THREAD_TRACE_DECODER_RECORD_OCCUPANCY)
{
for(size_t i = 0; i < trace_size; i++)
tool.config.occupancy.push_back(
reinterpret_cast<const att_occupancy_info_v2_t*>(trace_events)[i]);
tool.config.occupancy.push_back(reinterpret_cast<const occupancy_t*>(trace_events)[i]);
}
else if(trace_id == ROCPROFILER_ATT_DECODER_TYPE_PERFEVENT)
else if(trace_id == ROCPROFILER_THREAD_TRACE_DECODER_RECORD_PERFEVENT)
{
PerfcounterFile(tool.config, reinterpret_cast<att_perfevent_t*>(trace_events), trace_size);
PerfcounterFile(tool.config, reinterpret_cast<perfevent_t*>(trace_events), trace_size);
}
if(trace_id != ROCPROFILER_ATT_DECODER_TYPE_WAVE) return ROCPROFILER_ATT_DECODER_STATUS_SUCCESS;
if(trace_id != ROCPROFILER_THREAD_TRACE_DECODER_RECORD_WAVE) return;
bool bInvalid = false;
for(size_t wave_n = 0; wave_n < trace_size; wave_n++)
{
auto& wave = reinterpret_cast<att_wave_data_t*>(trace_events)[wave_n];
auto& wave = reinterpret_cast<wave_t*>(trace_events)[wave_n];
int64_t prev_inst_time = wave.begin_time;
WaveFile(tool.config, wave);
for(size_t j = 0; j < wave.instructions_size; j++)
{
auto& inst = wave.instructions_array[j];
if(inst.pc.marker_id == 0 && inst.pc.addr == 0)
continue;
else if(inst.category >= att_wave_inst_category_t::ATT_INST_LAST)
continue;
if(inst.pc.marker_id == 0 && inst.pc.addr == 0) continue;
try
{
@@ -112,81 +95,24 @@ get_trace_data(rocprofiler_att_decoder_record_type_t trace_id,
}
prev_inst_time = std::max(prev_inst_time, inst.time + inst.duration);
}
WaveFile(tool.config, wave);
}
if(bInvalid) ROCP_WARNING << "Could not fetch some instructions!";
return ROCPROFILER_ATT_DECODER_STATUS_SUCCESS;
C_API_END
return ROCPROFILER_ATT_DECODER_STATUS_ERROR;
}
uint64_t
copy_trace_data(int* seid, uint8_t** buffer, uint64_t* buffer_size, void* userdata)
{
trace_data_t& data = *reinterpret_cast<trace_data_t*>(userdata);
*seid = data.id;
*buffer_size = data.size;
*buffer = data.data;
data.size = 0;
return *buffer_size;
}
rocprofiler_att_decoder_status_t
isa_callback(char* isa_instruction,
uint64_t* isa_memory_size,
uint64_t* isa_size,
pcinfo_t pc,
void* userdata)
{
C_API_BEGIN
CHECK_NOTNULL(userdata);
trace_data_t& trace_data = *reinterpret_cast<trace_data_t*>(userdata);
CHECK_NOTNULL(trace_data.tool);
ToolData& tool = *trace_data.tool;
std::shared_ptr<Instruction> instruction{nullptr};
try
{
CodeLine& line = tool.get(pc);
instruction = line.code_line;
} catch(std::exception& e)
{
ROCP_WARNING << pc.marker_id << ":" << pc.addr << ' ' << e.what();
return ROCPROFILER_ATT_DECODER_STATUS_ERROR;
}
if(!instruction.get()) return ROCPROFILER_ATT_DECODER_STATUS_ERROR_INVALID_ARGUMENT;
{
size_t tmp_isa_size = *isa_size;
*isa_size = instruction->inst.size();
if(*isa_size > tmp_isa_size) return ROCPROFILER_ATT_DECODER_STATUS_ERROR_OUT_OF_RESOURCES;
}
memcpy(isa_instruction, instruction->inst.data(), *isa_size);
*isa_memory_size = instruction->size;
C_API_END
return ROCPROFILER_ATT_DECODER_STATUS_SUCCESS;
}
ToolData::ToolData(const std::vector<char>& _data, WaveConfig& _config, std::shared_ptr<DL> _dl)
ToolData::ToolData(std::vector<char>& _data,
WaveConfig& _config,
rocprofiler_thread_trace_decoder_handle_t _decoder)
: cfile(_config.code)
, config(_config)
, dl(std::move(_dl))
, decoder(_decoder)
{
trace_data_t data{.id = config.shader_engine,
.data = (uint8_t*) _data.data(),
.size = _data.size(),
.tool = this};
auto status = dl->att_parse_data_fn(copy_trace_data, get_trace_data, isa_callback, &data);
if(status != ROCPROFILER_ATT_DECODER_STATUS_SUCCESS)
ROCP_ERROR << "Callback failed with status " << dl->att_status_fn(status);
auto status =
rocprofiler_trace_decode(decoder, get_trace_data, _data.data(), _data.size(), this);
ROCP_ERROR_IF(status != ROCPROFILER_STATUS_SUCCESS) << ": " << status;
}
ToolData::~ToolData() = default;