From bc9f86ec625022eff260c4862ec952b9d2621349 Mon Sep 17 00:00:00 2001 From: "Jonathan R. Madsen" Date: Tue, 26 Mar 2024 17:11:34 -0500 Subject: [PATCH] Update HSA copy table (#687) - two copies of HSA table: internal and tracing - internal is used to invoke HSA function without any possibility of triggering tracing, etc. --- source/lib/rocprofiler-sdk/hsa/defines.hpp | 24 +++--- source/lib/rocprofiler-sdk/hsa/hsa.cpp | 86 +++++++++++++++------ source/lib/rocprofiler-sdk/hsa/hsa.hpp | 20 ++++- source/lib/rocprofiler-sdk/registration.cpp | 23 +++--- 4 files changed, 106 insertions(+), 47 deletions(-) diff --git a/source/lib/rocprofiler-sdk/hsa/defines.hpp b/source/lib/rocprofiler-sdk/hsa/defines.hpp index 8ea93360e3..815fbf8a2f 100644 --- a/source/lib/rocprofiler-sdk/hsa/defines.hpp +++ b/source/lib/rocprofiler-sdk/hsa/defines.hpp @@ -39,8 +39,6 @@ using this_type = hsa_api_meta; \ using function_type = hsa_api_func::function_type; \ \ - static auto& get_table() { return hsa_table_lookup{}(); } \ - \ template \ static auto& get_table(TableT& _v) \ { \ @@ -60,8 +58,6 @@ return _table.HSA_FUNC_PTR; \ } \ } \ - \ - static auto& get_table_func() { return get_table_func(get_table()); } \ }; \ } \ } @@ -90,7 +86,10 @@ return offsetof(hsa_table_lookup::type, HSA_FUNC_PTR); \ } \ \ - static auto& get_table() { return hsa_table_lookup{}(); } \ + static auto& get_table(tracing_table) \ + { \ + return hsa_table_lookup{}(tracing_table{}); \ + } \ \ template \ static auto& get_table(TableT& _v) \ @@ -112,7 +111,7 @@ } \ } \ \ - static auto& get_table_func() { return get_table_func(get_table()); } \ + static auto& get_table_func() { return get_table_func(get_table(tracing_table{})); } \ \ template \ static auto& get_api_data_args(DataT& _data) \ @@ -165,7 +164,10 @@ return offsetof(hsa_table_lookup::type, HSA_FUNC_PTR); \ } \ \ - static auto& get_table() { return hsa_table_lookup{}(); } \ + static auto& get_table(tracing_table) \ + { \ + return hsa_table_lookup{}(tracing_table{}); \ + } \ \ template \ static auto& get_table(TableT& _v) \ @@ -187,7 +189,7 @@ } \ } \ \ - static auto& get_table_func() { return get_table_func(get_table()); } \ + static auto& get_table_func() { return get_table_func(get_table(tracing_table{})); } \ \ template \ static auto& get_api_data_args(DataT& _data) \ @@ -224,13 +226,17 @@ { \ namespace hsa \ { \ + struct tracing_table; \ + struct internal_table; \ + \ template <> \ struct hsa_table_lookup \ { \ using type = TYPE; \ auto& operator()(type& _v) const { return _v; } \ auto& operator()(type* _v) const { return *_v; } \ - auto& operator()() const { return (*this)(get_##NAME##_table()); } \ + auto& operator()(tracing_table) const { return (*this)(get_tracing_##NAME##_table()); } \ + auto& operator()(internal_table) const { return (*this)(get_##NAME##_table()); } \ }; \ \ template <> \ diff --git a/source/lib/rocprofiler-sdk/hsa/hsa.cpp b/source/lib/rocprofiler-sdk/hsa/hsa.cpp index 1cc3e05c4e..1b822dbe80 100644 --- a/source/lib/rocprofiler-sdk/hsa/hsa.cpp +++ b/source/lib/rocprofiler-sdk/hsa/hsa.cpp @@ -108,53 +108,82 @@ DEFINE_TABLE_VERSION(img_ext, IMAGE_API) #undef DEFINE_TABLE_VERSION #undef DEFINE_TABLE_VERSION_IMPL -template +// helper to ensure that table type is paired with the correct table version +#define GET_TABLE_IMPL(ALIAS, TYPE) \ + get_table_impl(hsa_##ALIAS##_table_version); + +template Tp*& get_table_impl(hsa_table_version_t _version) { - static_assert(common::static_object::is_trivial_standard_layout(), + static_assert(common::static_object::is_trivial_standard_layout(), "This HSA API table is not a trivial, standard layout type as it should be"); - auto*& val = common::static_object::construct(); + auto*& val = common::static_object::construct(); val->version = _version; return val; } } // namespace +hsa_core_table_t* +get_tracing_core_table() +{ + static auto*& val = GET_TABLE_IMPL(core, tracing_table); + return val; +} + +hsa_amd_ext_table_t* +get_tracing_amd_ext_table() +{ + static auto*& val = GET_TABLE_IMPL(amd_ext, tracing_table); + return val; +} + +hsa_fini_ext_table_t* +get_tracing_fini_ext_table() +{ + static auto*& val = GET_TABLE_IMPL(fini_ext, tracing_table); + return val; +} + +hsa_img_ext_table_t* +get_tracing_img_ext_table() +{ + static auto*& val = GET_TABLE_IMPL(img_ext, tracing_table); + return val; +} + hsa_table_version_t get_table_version() { return hsa_api_table_version; } -// helper to ensure that table type is paired with the correct table version -#define GET_TABLE_IMPL(ALIAS) get_table_impl(hsa_##ALIAS##_table_version); - hsa_core_table_t* get_core_table() { - static auto*& val = GET_TABLE_IMPL(core); + static auto*& val = GET_TABLE_IMPL(core, internal_table); return val; } hsa_amd_ext_table_t* get_amd_ext_table() { - static auto*& val = GET_TABLE_IMPL(amd_ext); + static auto*& val = GET_TABLE_IMPL(amd_ext, internal_table); return val; } hsa_fini_ext_table_t* get_fini_ext_table() { - static auto*& val = GET_TABLE_IMPL(fini_ext); + static auto*& val = GET_TABLE_IMPL(fini_ext, internal_table); return val; } hsa_img_ext_table_t* get_img_ext_table() { - static auto*& val = GET_TABLE_IMPL(img_ext); + static auto*& val = GET_TABLE_IMPL(img_ext, internal_table); return val; } @@ -547,7 +576,7 @@ should_wrap_functor(const context::context_array_t& _contexts, return false; } -template +template void copy_table(Tp* _orig, uint64_t _tbl_instance, std::integral_constant) { @@ -567,7 +596,7 @@ copy_table(Tp* _orig, uint64_t _tbl_instance, std::integral_constant{}()); + auto& _copy_table = _info.get_table(hsa_table_lookup{}(LookupT{})); auto& _copy_func = _info.get_table_func(_copy_table); LOG_IF(FATAL, _copy_func && _tbl_instance == 0) @@ -621,13 +650,17 @@ update_table(const context::context_array_t& _contexts, } } -template +template void copy_table(Tp* _orig, uint64_t _tbl_instance, std::index_sequence) { - copy_table(_orig, _tbl_instance, std::integral_constant{}); + copy_table(_orig, _tbl_instance, std::integral_constant{}); if constexpr(sizeof...(OpIdxTail) > 0) - copy_table(_orig, _tbl_instance, std::index_sequence{}); + copy_table(_orig, _tbl_instance, std::index_sequence{}); } template @@ -702,17 +735,20 @@ copy_table(TableT* _orig, uint64_t _tbl_instance) { constexpr auto TableIdx = hsa_table_id_lookup::value; if(_orig) - copy_table( + copy_table( _orig, _tbl_instance, std::make_index_sequence::last>{}); } template void -update_table(TableT* _orig) +update_table(TableT* _orig, uint64_t _tbl_instance) { constexpr auto TableIdx = hsa_table_id_lookup::value; if(_orig) { + copy_table( + _orig, _tbl_instance, std::make_index_sequence::last>{}); + auto _contexts = context::get_registered_contexts(); update_table( _contexts, _orig, std::make_index_sequence::last>{}); @@ -722,14 +758,14 @@ update_table(TableT* _orig) using iterate_args_data_t = rocprofiler_callback_tracing_hsa_api_data_t; using iterate_args_cb_t = rocprofiler_callback_tracing_operation_args_cb_t; -#define INSTANTIATE_HSA_TABLE_FUNC(TABLE_TYPE, TABLE_IDX) \ - template void copy_table(TABLE_TYPE * _tbl, uint64_t _instv); \ - template void update_table(TABLE_TYPE * _tbl); \ - template const char* name_by_id(uint32_t); \ - template uint32_t id_by_name(const char*); \ - template std::vector get_ids(); \ - template std::vector get_names(); \ - template void iterate_args( \ +#define INSTANTIATE_HSA_TABLE_FUNC(TABLE_TYPE, TABLE_IDX) \ + template void copy_table(TABLE_TYPE * _tbl, uint64_t _instv); \ + template void update_table(TABLE_TYPE * _tbl, uint64_t _instv); \ + template const char* name_by_id(uint32_t); \ + template uint32_t id_by_name(const char*); \ + template std::vector get_ids(); \ + template std::vector get_names(); \ + template void iterate_args( \ uint32_t, const iterate_args_data_t&, iterate_args_cb_t, int32_t, void*); INSTANTIATE_HSA_TABLE_FUNC(hsa_core_table_t, ROCPROFILER_HSA_TABLE_ID_Core) diff --git a/source/lib/rocprofiler-sdk/hsa/hsa.hpp b/source/lib/rocprofiler-sdk/hsa/hsa.hpp index 79aefa9a15..491ecafd9d 100644 --- a/source/lib/rocprofiler-sdk/hsa/hsa.hpp +++ b/source/lib/rocprofiler-sdk/hsa/hsa.hpp @@ -32,6 +32,12 @@ namespace rocprofiler { namespace hsa { +struct tracing_table +{}; + +struct internal_table +{}; + using hsa_api_table_t = ::HsaApiTable; using hsa_table_version_t = ::ApiTableVersion; using hsa_core_table_t = ::CoreApiTable; @@ -57,6 +63,18 @@ get_fini_ext_table(); hsa_img_ext_table_t* get_img_ext_table(); +hsa_core_table_t* +get_tracing_core_table(); + +hsa_amd_ext_table_t* +get_tracing_amd_ext_table(); + +hsa_fini_ext_table_t* +get_tracing_fini_ext_table(); + +hsa_img_ext_table_t* +get_tracing_img_ext_table(); + template struct hsa_table_lookup; @@ -130,6 +148,6 @@ copy_table(TableT* _orig, uint64_t _tbl_instance); template void -update_table(TableT* _orig); +update_table(TableT* _orig, uint64_t _tbl_instance); } // namespace hsa } // namespace rocprofiler diff --git a/source/lib/rocprofiler-sdk/registration.cpp b/source/lib/rocprofiler-sdk/registration.cpp index b53f2ab795..8be91c119e 100644 --- a/source/lib/rocprofiler-sdk/registration.cpp +++ b/source/lib/rocprofiler-sdk/registration.cpp @@ -718,25 +718,24 @@ rocprofiler_set_api_table(const char* name, auto* hsa_api_table = static_cast(*tables); + // store a reference of the HsaApiTable implementations for invoking these functions + // without going through tracing wrappers + rocprofiler::hsa::copy_table(hsa_api_table->core_, lib_instance); + rocprofiler::hsa::copy_table(hsa_api_table->amd_ext_, lib_instance); + rocprofiler::hsa::copy_table(hsa_api_table->image_ext_, lib_instance); + rocprofiler::hsa::copy_table(hsa_api_table->finalizer_ext_, lib_instance); + // need to construct agent mappings before initializing the queue controller rocprofiler::agent::construct_agent_cache(hsa_api_table); rocprofiler::hsa::queue_controller_init(hsa_api_table); rocprofiler::hsa::code_object_init(hsa_api_table); rocprofiler::hsa::async_copy_init(hsa_api_table, lib_instance); - // any internal modifications to the HsaApiTable need to be done before we make the - // copy or else those modifications will be lost when HSA API tracing is enabled - // because the HSA API tracing invokes the function pointers from the copy below - rocprofiler::hsa::copy_table(hsa_api_table->core_, lib_instance); - rocprofiler::hsa::copy_table(hsa_api_table->amd_ext_, lib_instance); - rocprofiler::hsa::copy_table(hsa_api_table->image_ext_, lib_instance); - rocprofiler::hsa::copy_table(hsa_api_table->finalizer_ext_, lib_instance); - // install rocprofiler API wrappers - rocprofiler::hsa::update_table(hsa_api_table->core_); - rocprofiler::hsa::update_table(hsa_api_table->amd_ext_); - rocprofiler::hsa::update_table(hsa_api_table->image_ext_); - rocprofiler::hsa::update_table(hsa_api_table->finalizer_ext_); + rocprofiler::hsa::update_table(hsa_api_table->core_, lib_instance); + rocprofiler::hsa::update_table(hsa_api_table->amd_ext_, lib_instance); + rocprofiler::hsa::update_table(hsa_api_table->image_ext_, lib_instance); + rocprofiler::hsa::update_table(hsa_api_table->finalizer_ext_, lib_instance); // allow tools to install API wrappers rocprofiler::intercept_table::notify_intercept_table_registration(