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:
committed by
GitHub
parent
6c773a7616
commit
4282aa31d9
@@ -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()
|
||||
|
||||
+1
-1
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user