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.
This commit is contained in:
committed by
GitHub
parent
1addfed9f6
commit
bc9f86ec62
@@ -39,8 +39,6 @@
|
||||
using this_type = hsa_api_meta<table_idx, operation_idx>; \
|
||||
using function_type = hsa_api_func<decltype(::HSA_FUNC)*>::function_type; \
|
||||
\
|
||||
static auto& get_table() { return hsa_table_lookup<table_idx>{}(); } \
|
||||
\
|
||||
template <typename TableT> \
|
||||
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<table_idx>::type, HSA_FUNC_PTR); \
|
||||
} \
|
||||
\
|
||||
static auto& get_table() { return hsa_table_lookup<table_idx>{}(); } \
|
||||
static auto& get_table(tracing_table) \
|
||||
{ \
|
||||
return hsa_table_lookup<table_idx>{}(tracing_table{}); \
|
||||
} \
|
||||
\
|
||||
template <typename TableT> \
|
||||
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 <typename DataT> \
|
||||
static auto& get_api_data_args(DataT& _data) \
|
||||
@@ -165,7 +164,10 @@
|
||||
return offsetof(hsa_table_lookup<table_idx>::type, HSA_FUNC_PTR); \
|
||||
} \
|
||||
\
|
||||
static auto& get_table() { return hsa_table_lookup<table_idx>{}(); } \
|
||||
static auto& get_table(tracing_table) \
|
||||
{ \
|
||||
return hsa_table_lookup<table_idx>{}(tracing_table{}); \
|
||||
} \
|
||||
\
|
||||
template <typename TableT> \
|
||||
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 <typename DataT> \
|
||||
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<TABLE_ID> \
|
||||
{ \
|
||||
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 <> \
|
||||
|
||||
@@ -108,53 +108,82 @@ DEFINE_TABLE_VERSION(img_ext, IMAGE_API)
|
||||
#undef DEFINE_TABLE_VERSION
|
||||
#undef DEFINE_TABLE_VERSION_IMPL
|
||||
|
||||
template <typename Tp>
|
||||
// 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_t, TYPE>(hsa_##ALIAS##_table_version);
|
||||
|
||||
template <typename Tp, typename TableT>
|
||||
Tp*&
|
||||
get_table_impl(hsa_table_version_t _version)
|
||||
{
|
||||
static_assert(common::static_object<Tp>::is_trivial_standard_layout(),
|
||||
static_assert(common::static_object<Tp, TableT>::is_trivial_standard_layout(),
|
||||
"This HSA API table is not a trivial, standard layout type as it should be");
|
||||
|
||||
auto*& val = common::static_object<Tp>::construct();
|
||||
auto*& val = common::static_object<Tp, TableT>::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_t>(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 <size_t TableIdx, typename Tp, size_t OpIdx>
|
||||
template <size_t TableIdx, typename LookupT = internal_table, typename Tp, size_t OpIdx>
|
||||
void
|
||||
copy_table(Tp* _orig, uint64_t _tbl_instance, std::integral_constant<size_t, OpIdx>)
|
||||
{
|
||||
@@ -567,7 +596,7 @@ copy_table(Tp* _orig, uint64_t _tbl_instance, std::integral_constant<size_t, OpI
|
||||
// 3. get the sub-table containing the function pointer in saved table
|
||||
// 4. get reference to function pointer in sub-table in saved table
|
||||
// 5. save the original function in the saved table
|
||||
auto& _copy_table = _info.get_table(hsa_table_lookup<TableIdx>{}());
|
||||
auto& _copy_table = _info.get_table(hsa_table_lookup<TableIdx>{}(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 <size_t TableIdx, typename Tp, size_t OpIdx, size_t... OpIdxTail>
|
||||
template <size_t TableIdx,
|
||||
typename LookupT = internal_table,
|
||||
typename Tp,
|
||||
size_t OpIdx,
|
||||
size_t... OpIdxTail>
|
||||
void
|
||||
copy_table(Tp* _orig, uint64_t _tbl_instance, std::index_sequence<OpIdx, OpIdxTail...>)
|
||||
{
|
||||
copy_table<TableIdx>(_orig, _tbl_instance, std::integral_constant<size_t, OpIdx>{});
|
||||
copy_table<TableIdx, LookupT>(_orig, _tbl_instance, std::integral_constant<size_t, OpIdx>{});
|
||||
if constexpr(sizeof...(OpIdxTail) > 0)
|
||||
copy_table<TableIdx>(_orig, _tbl_instance, std::index_sequence<OpIdxTail...>{});
|
||||
copy_table<TableIdx, LookupT>(_orig, _tbl_instance, std::index_sequence<OpIdxTail...>{});
|
||||
}
|
||||
|
||||
template <size_t TableIdx, typename Tp, size_t OpIdx, size_t... OpIdxTail>
|
||||
@@ -702,17 +735,20 @@ copy_table(TableT* _orig, uint64_t _tbl_instance)
|
||||
{
|
||||
constexpr auto TableIdx = hsa_table_id_lookup<TableT>::value;
|
||||
if(_orig)
|
||||
copy_table<TableIdx>(
|
||||
copy_table<TableIdx, internal_table>(
|
||||
_orig, _tbl_instance, std::make_index_sequence<hsa_domain_info<TableIdx>::last>{});
|
||||
}
|
||||
|
||||
template <typename TableT>
|
||||
void
|
||||
update_table(TableT* _orig)
|
||||
update_table(TableT* _orig, uint64_t _tbl_instance)
|
||||
{
|
||||
constexpr auto TableIdx = hsa_table_id_lookup<TableT>::value;
|
||||
if(_orig)
|
||||
{
|
||||
copy_table<TableIdx, tracing_table>(
|
||||
_orig, _tbl_instance, std::make_index_sequence<hsa_domain_info<TableIdx>::last>{});
|
||||
|
||||
auto _contexts = context::get_registered_contexts();
|
||||
update_table<TableIdx>(
|
||||
_contexts, _orig, std::make_index_sequence<hsa_domain_info<TableIdx>::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>(TABLE_TYPE * _tbl, uint64_t _instv); \
|
||||
template void update_table<TABLE_TYPE>(TABLE_TYPE * _tbl); \
|
||||
template const char* name_by_id<TABLE_IDX>(uint32_t); \
|
||||
template uint32_t id_by_name<TABLE_IDX>(const char*); \
|
||||
template std::vector<uint32_t> get_ids<TABLE_IDX>(); \
|
||||
template std::vector<const char*> get_names<TABLE_IDX>(); \
|
||||
template void iterate_args<TABLE_IDX>( \
|
||||
#define INSTANTIATE_HSA_TABLE_FUNC(TABLE_TYPE, TABLE_IDX) \
|
||||
template void copy_table<TABLE_TYPE>(TABLE_TYPE * _tbl, uint64_t _instv); \
|
||||
template void update_table<TABLE_TYPE>(TABLE_TYPE * _tbl, uint64_t _instv); \
|
||||
template const char* name_by_id<TABLE_IDX>(uint32_t); \
|
||||
template uint32_t id_by_name<TABLE_IDX>(const char*); \
|
||||
template std::vector<uint32_t> get_ids<TABLE_IDX>(); \
|
||||
template std::vector<const char*> get_names<TABLE_IDX>(); \
|
||||
template void iterate_args<TABLE_IDX>( \
|
||||
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)
|
||||
|
||||
@@ -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 <size_t Idx>
|
||||
struct hsa_table_lookup;
|
||||
|
||||
@@ -130,6 +148,6 @@ copy_table(TableT* _orig, uint64_t _tbl_instance);
|
||||
|
||||
template <typename TableT>
|
||||
void
|
||||
update_table(TableT* _orig);
|
||||
update_table(TableT* _orig, uint64_t _tbl_instance);
|
||||
} // namespace hsa
|
||||
} // namespace rocprofiler
|
||||
|
||||
@@ -718,25 +718,24 @@ rocprofiler_set_api_table(const char* name,
|
||||
|
||||
auto* hsa_api_table = static_cast<HsaApiTable*>(*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(
|
||||
|
||||
Reference in New Issue
Block a user