Adding att v3 support (#84)

* Adding att v3 support

* misc fix

* bug fix

* Python linting workflow and rules

* fix regex

* Adding temporary args

* fix temporary args

* fix format

* remove att_perfcounters from test input

* Review comments (#163)

Co-authored-by: Giovanni Baraldi <gbaraldi@amd.com>

* Revert "Review comments (#163)"

This reverts commit 9ef0f8e5a4489d5581255e1b70ced2aef5c1c1d0.

* Address review comments 2

* review changes

* review comments

* review

* cmake alias

* review

* review

* review

* review

* Enabling percounter in v3 script

* review

* formatting

* formatting

---------

Co-authored-by: Jonathan R. Madsen <jonathanrmadsen@gmail.com>
Co-authored-by: Baraldi, Giovanni <Giovanni.Baraldi@amd.com>
Co-authored-by: Giovanni Baraldi <gbaraldi@amd.com>

[ROCm/rocprofiler-sdk commit: d4a51e4102]
This commit is contained in:
Nagaraj, Sriraksha
2025-02-04 04:05:38 -06:00
committed by GitHub
parent 6c773a7616
commit 4282aa31d9
32 changed files with 2068 additions and 43 deletions
@@ -25,6 +25,7 @@
#include "statistics.hpp"
#include "timestamps.hpp"
#include "lib/common/filesystem.hpp"
#include "lib/common/string_entry.hpp"
#include "lib/common/utility.hpp"
@@ -37,6 +38,7 @@ namespace rocprofiler
{
namespace tool
{
namespace fs = common::filesystem;
json_output::json_output(const output_config& cfg,
std::string_view filename,
JSONOutputArchive::Options _opts)
@@ -115,11 +117,18 @@ write_json(json_output& json_ar,
json_ar(cereal::make_nvp("counters", tool_metadata.get_counter_info()));
{
auto callback_name_info = tool_metadata.callback_names;
auto buffer_name_info = tool_metadata.buffer_names;
auto counter_dims = tool_metadata.get_counter_dimension_info();
auto marker_msg_data = tool_metadata.marker_messages.get();
auto callback_name_info = tool_metadata.callback_names;
auto buffer_name_info = tool_metadata.buffer_names;
auto counter_dims = tool_metadata.get_counter_dimension_info();
auto marker_msg_data = tool_metadata.marker_messages.get();
auto code_object_load_info = tool_metadata.get_code_object_load_info();
auto att_filenames = tool_metadata.get_att_filenames();
auto code_object_snapshot_filenames = std::vector<std::string>{};
code_object_snapshot_filenames.reserve(code_object_load_info.size());
for(auto info : code_object_load_info)
{
code_object_snapshot_filenames.emplace_back(fs::path(info.name).filename());
}
json_ar.setNextName("strings");
json_ar.startNode();
json_ar(cereal::make_nvp("callback_records", callback_name_info));
@@ -131,7 +140,8 @@ write_json(json_output& json_ar,
json_ar(
cereal::make_nvp("pc_sample_instructions", tool_metadata.get_pc_sample_instructions()));
json_ar(cereal::make_nvp("pc_sample_comments", tool_metadata.get_pc_sample_comments()));
json_ar(cereal::make_nvp("att_filenames", att_filenames));
json_ar(cereal::make_nvp("code_object_snapshot_filenames", code_object_snapshot_filenames));
{
auto _extern_corr_id_strings = std::map<size_t, std::string>{};
if(cfg.kernel_rename)
@@ -22,12 +22,15 @@
#include "metadata.hpp"
#include "lib/common/filesystem.hpp"
#include "lib/common/string_entry.hpp"
#include "lib/output/agent_info.hpp"
#include "lib/output/host_symbol_info.hpp"
#include "lib/output/kernel_symbol_info.hpp"
#include "lib/rocprofiler-sdk-att/att_lib_wrapper.hpp"
#include <rocprofiler-sdk/fwd.h>
#include <rocprofiler-sdk/cxx/details/tokenize.hpp>
#include <memory>
#include <vector>
@@ -36,6 +39,7 @@ namespace rocprofiler
{
namespace tool
{
namespace fs = common::filesystem;
namespace
{
rocprofiler_status_t
@@ -218,6 +222,34 @@ metadata::get_code_object(uint64_t code_obj_id) const
});
}
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;
});
return _data;
}
std::vector<std::string>
metadata::get_att_filenames() const
{
auto data = std::vector<std::string>{};
for(auto filenames : att_filenames)
{
for(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
{
@@ -32,6 +32,7 @@
#include "lib/common/demangle.hpp"
#include "lib/common/logging.hpp"
#include "lib/common/synchronized.hpp"
#include "lib/rocprofiler-sdk-att/att_lib_wrapper.hpp"
#include <rocprofiler-sdk/agent.h>
#include <rocprofiler-sdk/buffer_tracing.h>
@@ -74,8 +75,11 @@ using marker_message_ordered_map_t = std::map<uint64_t, std::string>;
using string_entry_map_t = std::unordered_map<size_t, std::unique_ptr<std::string>>;
using counter_dimension_vec_t = std::vector<rocprofiler_record_dimension_info_t>;
using external_corr_id_set_t = std::unordered_set<uint64_t>;
using code_obj_decoder_t = rocprofiler::sdk::codeobj::disassembly::CodeobjAddressTranslate;
using instruction_t = rocprofiler::sdk::codeobj::disassembly::Instruction;
using code_obj_decoder_t = rocprofiler::sdk::codeobj::disassembly::CodeobjAddressTranslate;
using instruction_t = rocprofiler::sdk::codeobj::disassembly::Instruction;
using att_agent_filenames_t = std::pair<rocprofiler_agent_id_t, std::vector<std::string>>;
using att_filenames_map_t = std::unordered_map<rocprofiler_dispatch_id_t, att_agent_filenames_t>;
using code_object_load_info_vec_t = std::vector<rocprofiler::att_wrapper::CodeobjLoadInfo>;
template <typename Tp>
using synced_map = common::Synchronized<Tp, true>;
@@ -94,14 +98,16 @@ struct metadata
agent_counter_info_map_t agent_counter_info = {};
agent_pc_sample_config_info_map_t agent_pc_sample_config_info = {};
sdk::buffer_name_info buffer_names = {};
sdk::callback_name_info callback_names = {};
synced_map<code_object_data_map_t> code_objects = {};
synced_map<kernel_symbol_data_map_t> kernel_symbols = {};
synced_map<marker_message_map_t> marker_messages = {};
synced_map<string_entry_map_t> string_entries = {};
synced_map<external_corr_id_set_t> external_corr_ids = {};
synced_map<host_function_info_map_t> host_functions = {};
sdk::buffer_name_info buffer_names = {};
sdk::callback_name_info callback_names = {};
synced_map<code_object_data_map_t> code_objects = {};
synced_map<kernel_symbol_data_map_t> kernel_symbols = {};
synced_map<marker_message_map_t> marker_messages = {};
synced_map<string_entry_map_t> string_entries = {};
synced_map<external_corr_id_set_t> external_corr_ids = {};
synced_map<host_function_info_map_t> host_functions = {};
synced_map<code_object_load_info_vec_t> code_object_load = {};
att_filenames_map_t att_filenames = {};
metadata() = default;
metadata(inprocess);
@@ -122,6 +128,7 @@ struct metadata
const tool_counter_info* get_counter_info(rocprofiler_counter_id_t id) const;
const counter_dimension_info_vec_t* get_counter_dimension_info(uint64_t instance_id) const;
std::vector<std::string> get_att_filenames() const;
code_object_data_vec_t get_code_objects() const;
kernel_symbol_data_vec_t get_kernel_symbols() const;
host_function_data_vec_t get_host_symbols() const;
@@ -135,6 +142,7 @@ struct metadata
std::string_view get_comment(int64_t index) const { return instruction_comment.at(index); }
int64_t get_instruction_index(rocprofiler_pc_t record);
void add_decoder(rocprofiler_code_object_info_t* obj_data_v);
code_object_load_info_vec_t get_code_object_load_info() const;
template <typename Tp>
Tp get_marker_messages(Tp&&);
@@ -29,6 +29,7 @@ find_package(
lib/cmake/amd_comgr)
add_library(rocprofiler-sdk-att-parser STATIC)
add_library(rocprofiler-sdk::rocprofiler-sdk-att-parser ALIAS rocprofiler-sdk-att-parser)
target_sources(rocprofiler-sdk-att-parser PRIVATE ${ATT_TOOL_SOURCE_FILES})
target_link_libraries(
@@ -86,8 +86,8 @@ get_shader_id(const std::string& name)
auto run_pos = name.rfind('_');
if(run_pos == std::string::npos) throw std::runtime_error("Invalid name");
std::string_view stripped = name.substr(0, run_pos);
auto se_number_pos = stripped.rfind('_');
std::string stripped = name.substr(0, run_pos);
auto se_number_pos = stripped.rfind('_');
if(se_number_pos == std::string::npos || se_number_pos + 1 >= stripped.size())
throw std::runtime_error("Invalid name");
@@ -97,15 +97,11 @@ get_shader_id(const std::string& name)
std::vector<tool_att_capability_t>
query_att_decode_capability()
{
std::vector<tool_att_capability_t> ret;
auto ret = std::vector<tool_att_capability_t>{};
for(auto& [cap, libname] : get_lib_names())
{
if(auto handle = dlopen(libname, RTLD_NOW | RTLD_LOCAL))
{
dlclose(handle);
ret.push_back(cap);
}
if(DL(libname).handle != 0) ret.push_back(cap);
}
return ret;
@@ -20,12 +20,19 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "dl.hpp"
#include "lib/rocprofiler-sdk-att/dl.hpp"
#include "lib/common/environment.hpp"
#include "lib/common/filesystem.hpp"
#include "lib/common/logging.hpp"
#include <rocprofiler-sdk/cxx/details/tokenize.hpp>
#include <dlfcn.h>
#include <atomic>
#include <cassert>
#include <cstdlib>
#include <mutex>
#include <set>
#include <stdexcept>
#include <string>
@@ -33,9 +40,26 @@ namespace rocprofiler
{
namespace att_wrapper
{
DL::DL(const char* dlname)
namespace fs = ::rocprofiler::common::filesystem;
fs::path
get_search_path(std::string path_name)
{
handle = dlopen(dlname, RTLD_NOW | RTLD_LOCAL);
if(fs::exists(path_name)) return fs::path(path_name);
return "";
}
DL::DL(const char* libname)
{
auto paths = rocprofiler::common::get_env("ROCPROF_ATT_LIBRARY_PATH", "");
if(paths.empty()) return;
auto path_set = rocprofiler::sdk::parse::tokenize(paths, ":");
for(auto&& name : path_set)
{
handle = dlopen((get_search_path(name) / libname).string().c_str(), RTLD_LAZY | RTLD_LOCAL);
if(handle) break;
}
if(!handle) return;
att_parse_data_fn =
@@ -35,7 +35,7 @@ class DL
using StatusFn = decltype(rocprofiler_att_decoder_get_status_string);
public:
DL(const char* dlname);
DL(const char* libname);
~DL();
ParseFn* att_parse_data_fn = nullptr;
@@ -6,14 +6,15 @@ project(rocprofiler-att-parser-tests LANGUAGES CXX)
add_executable(att-parser-tool-v3)
target_link_libraries(
att-parser-tool-v3
PRIVATE rocprofiler-sdk-att-parser rocprofiler-sdk::rocprofiler-sdk-json
PRIVATE rocprofiler-sdk::rocprofiler-sdk-att-parser
rocprofiler-sdk::rocprofiler-sdk-json
rocprofiler-sdk::rocprofiler-sdk-common-library)
target_sources(att-parser-tool-v3 PRIVATE standalone_tool_main.cpp)
add_executable(att-decoder-test)
target_link_libraries(
att-decoder-test
PRIVATE rocprofiler-sdk-att-parser
PRIVATE rocprofiler-sdk::rocprofiler-sdk-att-parser
rocprofiler-sdk::rocprofiler-sdk-json
rocprofiler-sdk::rocprofiler-sdk-common-library
rocprofiler-sdk::rocprofiler-sdk-glog
@@ -22,6 +23,7 @@ target_link_libraries(
GTest::gtest_main)
target_sources(att-decoder-test PRIVATE att_decoder_test.cpp)
set(env-att-lib "ROCPROF_ATT_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/../lib")
add_library(att_decoder_testing SHARED)
target_sources(att_decoder_testing PRIVATE dummy_decoder.cpp)
@@ -31,6 +33,7 @@ if(NOT ROCPROFILER_MEMCHECK)
SOURCES att_decoder_test.cpp
TEST_LIST att-decoder-test_TESTS
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(${att-decoder-test_TESTS} PROPERTIES TIMEOUT 10 LABELS
"unittests")
set_tests_properties(
${att-decoder-test_TESTS} PROPERTIES ENVIRONMENT "${env-att-lib}" TIMEOUT 10
LABELS "unittests")
endif()
@@ -6,7 +6,7 @@ project(rocprofiler-att-parser-waitcnt-tests LANGUAGES CXX)
add_executable(att-decoder-waitcnt-test)
target_link_libraries(
att-decoder-waitcnt-test
PRIVATE rocprofiler-sdk-att-parser
PRIVATE rocprofiler-sdk::rocprofiler-sdk-att-parser
rocprofiler-sdk::rocprofiler-sdk-json
rocprofiler-sdk::rocprofiler-sdk-common-library
rocprofiler-sdk::rocprofiler-sdk-glog
@@ -23,7 +23,8 @@ target_link_libraries(
rocprofiler-sdk::rocprofiler-sdk-perfetto
rocprofiler-sdk::rocprofiler-sdk-otf2
rocprofiler-sdk::rocprofiler-sdk-dw
rocprofiler-sdk::rocprofiler-sdk-amd-comgr)
rocprofiler-sdk::rocprofiler-sdk-amd-comgr
rocprofiler-sdk::rocprofiler-sdk-att-parser)
set_target_properties(
rocprofiler-sdk-tool
@@ -144,6 +144,68 @@ get_kernel_filter_range(const std::string& kernel_filter)
return range_set;
}
std::vector<att_perfcounter>
parse_att_counters(std::string line)
{
auto counters = std::vector<att_perfcounter>{};
if(line.empty()) return counters;
// strip the comment
if(auto pos = line.find('#'); pos != std::string::npos) line = line.substr(0, pos);
// trim line for any white spaces after comment strip
trim(line);
// check to see if comment stripping + trim resulted in empty line
if(line.empty()) return counters;
handle_special_chars(line);
auto extract_counter_name_and_simd_mask = [](std::string& input) {
std::string counter_name = "";
auto ret = att_perfcounter{};
size_t pos = input.find(':');
if(pos != std::string::npos)
{
ret.counter_name = input.substr(0, pos);
ret.simd_mask = std::stoi(input.substr(pos + 1), nullptr, 16);
}
else
counter_name = input;
return ret;
};
// regex to check if string is of the form "counter_name:simd_mask"
std::regex pattern(R"([a-zA-Z0-9_]+(:0x[0-9a-fA-F]+)?)");
std::set<std::string> unique_counters;
auto input_ss = std::stringstream{line};
while(true)
{
auto counter = std::string{};
input_ss >> counter;
if(counter.empty()) break;
// check if the counter string matches the pattern
if(!std::regex_match(counter, pattern))
{
ROCP_FATAL << "Invalid counter format for ATT: " << counter
<< ". Expected format : Counter_name:optional_simd_mask(hexadecimal)";
}
// Consider only those counters where combination of counter name and simd mask is unique
if(unique_counters.insert(counter).second == false) continue;
auto res = extract_counter_name_and_simd_mask(counter);
counters.emplace_back(res);
}
return counters;
}
std::set<std::string>
parse_counters(std::string line)
{
@@ -193,6 +255,8 @@ config::config()
, kernel_filter_range{get_kernel_filter_range(
get_env("ROCPROF_KERNEL_FILTER_RANGE", std::string{}))}
, counters{parse_counters(get_env("ROCPROF_COUNTERS", std::string{}))}
, att_param_perfcounters{
parse_att_counters(get_env("ROCPROF_ATT_PARAM_PERFCOUNTERS", std::string{}))}
{
if(kernel_filter_include.empty()) kernel_filter_include = std::string{".*"};
@@ -29,6 +29,7 @@
#include "lib/common/units.hpp"
#include "lib/output/format_path.hpp"
#include "lib/output/output_config.hpp"
#include "lib/rocprofiler-sdk-att/att_lib_wrapper.hpp"
#include <rocprofiler-sdk/cxx/serialization.hpp>
@@ -63,6 +64,12 @@ get_config();
std::string
format_name(std::string_view _name, const config& = get_config<>());
struct att_perfcounter
{
std::string counter_name = {};
uint32_t simd_mask = 0xf;
};
struct config : output_config
{
using base_type = output_config;
@@ -101,13 +108,20 @@ struct config : output_config
bool list_metrics = get_env("ROCPROF_LIST_METRICS", false);
bool list_metrics_output_file = get_env("ROCPROF_OUTPUT_LIST_METRICS_FILE", false);
bool pc_sampling_host_trap = false;
bool advanced_thread_trace = get_env("ROCPROF_ADVANCED_THREAD_TRACE", false);
size_t pc_sampling_interval = get_env("ROCPROF_PC_SAMPLING_INTERVAL", 1);
bool att_serialize_all = get_env("ROCPROF_ATT_PARAM_SERIALIZE_ALL", false);
rocprofiler_pc_sampling_method_t pc_sampling_method_value = ROCPROFILER_PC_SAMPLING_METHOD_NONE;
rocprofiler_pc_sampling_unit_t pc_sampling_unit_value = ROCPROFILER_PC_SAMPLING_UNIT_NONE;
std::string stats_summary_unit = get_env("ROCPROF_STATS_SUMMARY_UNITS", "nsec");
int mpi_size = get_mpi_size();
int mpi_rank = get_mpi_rank();
uint64_t att_param_shader_engine_mask =
get_env<uint64_t>("ROCPROF_ATT_PARAM_SHADER_ENGINE_MASK", 0x1);
uint64_t att_param_buffer_size = get_env<uint64_t>("ROCPROF_ATT_PARAM_BUFFER_SIZE", 0x6000000);
uint64_t att_param_simd_select = get_env<uint64_t>("ROCPROF_ATT_PARAM_SIMD_SELECT", 0xF);
uint64_t att_param_target_cu = get_env<uint64_t>("ROCPROF_ATT_PARAM_TARGET_CU", 1);
std::string kernel_filter_include = get_env("ROCPROF_KERNEL_FILTER_INCLUDE_REGEX", ".*");
std::string kernel_filter_exclude = get_env("ROCPROF_KERNEL_FILTER_EXCLUDE_REGEX", "");
@@ -115,8 +129,10 @@ struct config : output_config
std::string pc_sampling_unit = get_env("ROCPROF_PC_SAMPLING_UNIT", "none");
std::string extra_counters_contents = get_env("ROCPROF_EXTRA_COUNTERS_CONTENTS", "");
std::unordered_set<uint32_t> kernel_filter_range = {};
std::set<std::string> counters = {};
std::unordered_set<uint32_t> kernel_filter_range = {};
std::set<std::string> counters = {};
std::string att_capability = get_env("ROCPROF_ATT_CAPABILITY", "");
std::vector<att_perfcounter> att_param_perfcounters = {};
std::queue<CollectionPeriod> collection_periods = {};
@@ -45,8 +45,11 @@
#include "lib/output/statistics.hpp"
#include "lib/output/tmp_file.hpp"
#include "lib/output/tmp_file_buffer.hpp"
#include "lib/rocprofiler-sdk-att/att_lib_wrapper.hpp"
#include <rocprofiler-sdk/agent.h>
#include <rocprofiler-sdk/amd_detail/thread_trace_core.h>
#include <rocprofiler-sdk/amd_detail/thread_trace_dispatch.h>
#include <rocprofiler-sdk/buffer_tracing.h>
#include <rocprofiler-sdk/callback_tracing.h>
#include <rocprofiler-sdk/experimental/counters.h>
@@ -193,9 +196,10 @@ using kernel_iteration_t = std::unordered_map<rocprofiler_kernel_id_t, uint32
using kernel_rename_map_t = std::unordered_map<uint64_t, uint64_t>;
using kernel_rename_stack_t = std::stack<uint64_t>;
auto* tool_metadata = as_pointer<tool::metadata>(tool::metadata::inprocess{});
auto target_kernels = common::Synchronized<targeted_kernels_map_t>{};
auto kernel_iteration = common::Synchronized<kernel_iteration_t, true>{};
auto* tool_metadata = as_pointer<tool::metadata>(tool::metadata::inprocess{});
auto target_kernels = common::Synchronized<targeted_kernels_map_t>{};
auto kernel_iteration = common::Synchronized<kernel_iteration_t, true>{};
std::mutex att_shader_data;
thread_local auto thread_dispatch_rename = as_pointer<kernel_rename_stack_t>();
thread_local auto thread_dispatch_rename_dtor = common::scope_destructor{[]() {
@@ -238,7 +242,14 @@ is_targeted_kernel(uint64_t _kern_id)
// If the iteration range is not given then all iterations of the kernel is profiled
if(_range.empty())
return true;
{
if(!tool::get_config().advanced_thread_trace)
return true;
else
{
if(itr == 1) return true;
}
}
else if(_range.find(itr) != _range.end())
return true;
return false;
@@ -607,6 +618,75 @@ code_object_tracing_callback(rocprofiler_callback_tracing_record_t record,
{
CHECK_NOTNULL(tool_metadata)->add_decoder(obj_data);
}
if(obj_data->storage_type == ROCPROFILER_CODE_OBJECT_STORAGE_TYPE_MEMORY &&
tool::get_config().advanced_thread_trace)
{
const char* gpu_name = tool_metadata->agents_map.at(obj_data->rocp_agent).name;
auto filename = fmt::format("{}_code_object_id_{}",
std::string(gpu_name),
std::to_string(obj_data->code_object_id));
auto output_stream = get_output_stream(tool::get_config(), filename, ".out");
std::string output_filename =
get_output_filename(tool::get_config(), filename, ".out");
// NOLINTNEXTLINE(performance-no-int-to-ptr)
output_stream.stream->write(reinterpret_cast<char*>(obj_data->memory_base),
obj_data->memory_size);
tool_metadata->code_object_load.wlock(
[](auto& data_vec,
std::string file_name,
tool::rocprofiler_code_object_info_t* obj_data_v) {
data_vec.push_back({file_name,
obj_data_v->code_object_id,
obj_data_v->load_base,
obj_data_v->load_size});
},
output_filename,
obj_data);
}
else if(obj_data->storage_type == ROCPROFILER_CODE_OBJECT_STORAGE_TYPE_FILE &&
tool::get_config().advanced_thread_trace)
{
const char* gpu_name = tool_metadata->agents_map.at(obj_data->rocp_agent).name;
auto filename = fmt::format("{}_code_object_id_{}",
std::string(gpu_name),
std::to_string(obj_data->code_object_id));
auto output_stream = get_output_stream(tool::get_config(), filename, ".out");
std::string output_filename =
get_output_filename(tool::get_config(), filename, ".out");
uint8_t* binary = nullptr;
size_t buffer_size = 0;
std::ifstream code_object_file(obj_data->uri, std::ios::binary | std::ios::ate);
if(code_object_file.good())
{
buffer_size = code_object_file.tellg();
code_object_file.seekg(0, std::ios::beg);
binary = new(std::nothrow) uint8_t[buffer_size];
if(binary &&
!code_object_file.read(reinterpret_cast<char*>(binary), buffer_size))
{
delete[] binary;
binary = nullptr;
}
}
// NOLINTBEGIN(performance-no-int-to-ptr)
output_stream.stream->write(reinterpret_cast<char*>(obj_data->memory_base),
obj_data->memory_size);
// NOLINTEND(performance-no-int-to-ptr)
tool_metadata->code_object_load.wlock(
[](auto& data_vec,
std::string file_name,
tool::rocprofiler_code_object_info_t* obj_data_v) {
data_vec.push_back({file_name,
obj_data_v->code_object_id,
obj_data_v->load_base,
obj_data_v->load_size});
},
output_filename,
obj_data);
}
}
else if(record.phase == ROCPROFILER_CALLBACK_PHASE_UNLOAD)
{
@@ -879,6 +959,38 @@ get_instruction_index(rocprofiler_pc_t pc)
} // namespace
std::vector<rocprofiler_att_parameter_t>
get_att_perfcounter_params(std::vector<rocprofiler::tool::att_perfcounter>& att_perf_counters)
{
std::vector<rocprofiler_att_parameter_t> _data;
if(att_perf_counters.empty()) return _data;
static const auto gpu_agents = get_gpu_agents();
static const auto gpu_agents_counter_info = get_agent_counter_info();
for(const auto& [agent_, tool_counter_info_] : gpu_agents_counter_info)
{
for(const auto& counter_info_ : tool_counter_info_)
{
if(std::string_view(counter_info_.block) != "SQ") continue;
for(const auto& att_perf_counter : att_perf_counters)
{
if(std::string_view(counter_info_.name) == att_perf_counter.counter_name)
{
auto param = rocprofiler_att_parameter_t{};
param.type = ROCPROFILER_ATT_PARAMETER_PERFCOUNTER,
param.counter_id = counter_info_.id,
param.simd_mask = att_perf_counter.simd_mask;
_data.emplace_back(param);
}
}
}
}
return _data;
}
void
rocprofiler_pc_sampling_callback(rocprofiler_context_id_t /* context_id*/,
rocprofiler_buffer_id_t /* buffer_id*/,
@@ -920,6 +1032,55 @@ rocprofiler_pc_sampling_callback(rocprofiler_context_id_t /* context_id*/,
}
}
void
att_shader_data_callback(rocprofiler_agent_id_t agent,
int64_t se_id,
void* se_data,
size_t data_size,
rocprofiler_user_data_t userdata)
{
std::lock_guard<std::mutex> lock(att_shader_data);
std::stringstream filename;
filename << fmt::format("{}_shader_engine_{}_{}", agent.handle, se_id, userdata.value);
auto dispatch_id = static_cast<rocprofiler_dispatch_id_t>(userdata.value);
auto output_stream = get_output_stream(tool::get_config(), filename.str(), ".att");
std::string output_filename = get_output_filename(tool::get_config(), filename.str(), ".att");
output_stream.stream->write(reinterpret_cast<char*>(se_data), data_size);
tool_metadata->att_filenames[dispatch_id].first = agent;
tool_metadata->att_filenames[dispatch_id].second.emplace_back(output_filename);
}
rocprofiler_att_control_flags_t
att_dispatch_callback(rocprofiler_agent_id_t /* agent_id */,
rocprofiler_queue_id_t /* queue_id */,
rocprofiler_correlation_id_t /* correlation_id */,
rocprofiler_kernel_id_t kernel_id,
rocprofiler_dispatch_id_t dispatch_id,
void* /*userdata_config*/,
rocprofiler_user_data_t* userdata_shader)
{
userdata_shader->value = dispatch_id;
kernel_iteration.wlock(
[](auto& _kernel_iter, rocprofiler_kernel_id_t _kernel_id) {
auto itr = _kernel_iter.find(_kernel_id);
if(itr == _kernel_iter.end())
_kernel_iter.emplace(_kernel_id, 1);
else
{
itr->second++;
}
},
kernel_id);
if(is_targeted_kernel(kernel_id))
{
return ROCPROFILER_ATT_CONTROL_START_AND_STOP;
}
return ROCPROFILER_ATT_CONTROL_NONE;
}
void
dispatch_callback(rocprofiler_dispatch_counting_service_data_t dispatch_data,
rocprofiler_profile_config_id_t* config,
@@ -1214,6 +1375,37 @@ tool_init(rocprofiler_client_finalize_t fini_func, void* tool_data)
}
}
if(tool::get_config().advanced_thread_trace)
{
auto parameters = std::vector<rocprofiler_att_parameter_t>{};
uint64_t target_cu = tool::get_config().att_param_target_cu;
uint64_t simd_select = tool::get_config().att_param_simd_select;
uint64_t buffer_sz = tool::get_config().att_param_buffer_size;
uint64_t shader_mask = tool::get_config().att_param_shader_engine_mask;
auto& att_perf = tool::get_config().att_param_perfcounters;
bool att_serialize_all = tool::get_config().att_serialize_all;
auto att_perf_params = get_att_perfcounter_params(att_perf);
parameters.insert(parameters.end(), att_perf_params.begin(), att_perf_params.end());
// TODO: att params could be different for different devices. How to support?
// Input file schema might also need to change to support multiple ATT params
parameters.push_back({ROCPROFILER_ATT_PARAMETER_TARGET_CU, {target_cu}});
parameters.push_back({ROCPROFILER_ATT_PARAMETER_SIMD_SELECT, {simd_select}});
parameters.push_back({ROCPROFILER_ATT_PARAMETER_BUFFER_SIZE, {buffer_sz}});
parameters.push_back({ROCPROFILER_ATT_PARAMETER_SHADER_ENGINE_MASK, {shader_mask}});
parameters.push_back({ROCPROFILER_ATT_PARAMETER_SERIALIZE_ALL, {att_serialize_all}});
ROCPROFILER_CALL(
rocprofiler_configure_dispatch_thread_trace_service(get_client_ctx(),
parameters.data(),
parameters.size(),
att_dispatch_callback,
att_shader_data_callback,
tool_data),
"thread trace service configure");
}
if(tool::get_config().hip_runtime_api_trace || tool::get_config().hip_compiler_api_trace)
{
ROCPROFILER_CALL(rocprofiler_create_buffer(get_client_ctx(),
@@ -1504,6 +1696,40 @@ tool_fini(void* /*tool_data*/)
tool::generate_csv(tool::get_config(), *tool_metadata, contributions);
}
if(tool::get_config().advanced_thread_trace)
{
std::unordered_map<std::string_view, rocprofiler::att_wrapper::tool_att_capability_t>
tool_att_capability_map = {
{"testing", rocprofiler::att_wrapper::ATT_CAPABILITIES_TESTING},
{"summary", rocprofiler::att_wrapper::ATT_CAPABILITIES_SUMMARY},
{"trace", rocprofiler::att_wrapper::ATT_CAPABILITIES_TRACE},
{"debug", rocprofiler::att_wrapper::ATT_CAPABILITIES_DEBUG}};
ROCP_FATAL_IF(tool::get_config().att_capability.empty())
<< "Provide the decoder parser method as input";
auto att_capability_value = tool_att_capability_map.at(tool::get_config().att_capability);
auto decoder = rocprofiler::att_wrapper::ATTDecoder(att_capability_value);
ROCP_FATAL_IF(!decoder.valid()) << "Decoder library not found at ROCPORF_ATT_LIBRARY_PATH";
auto codeobj = tool_metadata->get_code_object_load_info();
auto output_path = tool::format_path(tool::get_config().output_path);
for(auto& [dispatch_id, att_filename_data] : tool_metadata->att_filenames)
{
std::string formats = "json,csv";
// if(tool::get_config().json_output) formats += "json,";
// if(tool::get_config().csv_output) formats += "csv,";
std::stringstream ui_name;
ui_name << fmt::format("ui_output_agent_{}_dispatch_{}",
std::to_string(att_filename_data.first.handle),
dispatch_id);
auto out_path = fmt::format("{}/{}", output_path, ui_name.str());
std::string in_path = ".";
decoder.parse(in_path, out_path, att_filename_data.second, codeobj, formats);
}
}
if(tool::get_config().json_output)
{
auto json_ar = tool::open_json(tool::get_config());