From 0bc244e10a12b59df6e633ca77444177e25858f4 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Sat, 23 Sep 2023 15:26:52 +0000 Subject: [PATCH] PC Sampling: Create PC Sampling interfaces Create new interface group for PC Sampling Change-Id: I59b4cfe9f8d1ae313dc28be1d2ed49f750d8212b --- runtime/hsa-runtime/CMakeLists.txt | 10 ++ runtime/hsa-runtime/core/inc/amd_gpu_agent.h | 1 + .../hsa-runtime/core/inc/hsa_api_trace_int.h | 2 + .../hsa-runtime/core/inc/hsa_ext_interface.h | 16 ++- .../core/runtime/amd_gpu_agent.cpp | 4 + runtime/hsa-runtime/core/runtime/hsa.cpp | 21 +++- .../core/runtime/hsa_api_trace.cpp | 19 ++++ .../core/runtime/hsa_ext_interface.cpp | 87 ++++++++++++++++ runtime/hsa-runtime/core/runtime/runtime.cpp | 5 + runtime/hsa-runtime/core/util/flag.h | 6 ++ runtime/hsa-runtime/inc/hsa.h | 6 +- runtime/hsa-runtime/inc/hsa_api_trace.h | 26 +++++ .../hsa-runtime/inc/hsa_api_trace_version.h | 30 +++--- .../hsa-runtime/inc/hsa_ven_amd_pc_sampling.h | 6 ++ .../pcs/hsa_ven_amd_pc_sampling.cpp | 92 +++++++++++++++++ .../pcs/inc/hsa_ven_amd_pc_sampling_impl.h | 67 +++++++++++++ runtime/hsa-runtime/pcs/pcs_runtime.cpp | 99 +++++++++++++++++++ runtime/hsa-runtime/pcs/pcs_runtime.h | 84 ++++++++++++++++ 18 files changed, 564 insertions(+), 17 deletions(-) create mode 100644 runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp create mode 100644 runtime/hsa-runtime/pcs/inc/hsa_ven_amd_pc_sampling_impl.h create mode 100644 runtime/hsa-runtime/pcs/pcs_runtime.cpp create mode 100644 runtime/hsa-runtime/pcs/pcs_runtime.h diff --git a/runtime/hsa-runtime/CMakeLists.txt b/runtime/hsa-runtime/CMakeLists.txt index 321d6e98a4..9e8c108842 100644 --- a/runtime/hsa-runtime/CMakeLists.txt +++ b/runtime/hsa-runtime/CMakeLists.txt @@ -208,6 +208,16 @@ add_dependencies( ${CORE_RUNTIME_TARGET} amd_trap_handler_v2 ) add_subdirectory( ${CMAKE_CURRENT_SOURCE_DIR}/core/runtime/blit_shaders ) add_dependencies( ${CORE_RUNTIME_TARGET} amd_blit_shaders_v2) +option(PC_SAMPLING_SUPPORT "Enable PC Sampling Support" ON) + +if (${PC_SAMPLING_SUPPORT}) + target_compile_definitions(${CORE_RUNTIME_TARGET} PRIVATE HSA_PC_SAMPLING_SUPPORT) + + set( PCS_SRCS pcs/hsa_ven_amd_pc_sampling.cpp pcs/pcs_runtime.cpp ) + + target_sources( ${CORE_RUNTIME_TARGET} PRIVATE ${PCS_SRCS} ) +endif() + if ( NOT DEFINED IMAGE_SUPPORT AND CMAKE_SYSTEM_PROCESSOR MATCHES "i?86|x86_64|amd64|AMD64|loongarch64" ) set ( IMAGE_SUPPORT ON ) endif() diff --git a/runtime/hsa-runtime/core/inc/amd_gpu_agent.h b/runtime/hsa-runtime/core/inc/amd_gpu_agent.h index bf3e4635fb..c1da3ac69a 100644 --- a/runtime/hsa-runtime/core/inc/amd_gpu_agent.h +++ b/runtime/hsa-runtime/core/inc/amd_gpu_agent.h @@ -59,6 +59,7 @@ #include "core/util/small_heap.h" #include "core/util/locks.h" #include "core/util/lazy_ptr.h" +#include "pcs/pcs_runtime.h" namespace rocr { namespace AMD { diff --git a/runtime/hsa-runtime/core/inc/hsa_api_trace_int.h b/runtime/hsa-runtime/core/inc/hsa_api_trace_int.h index f270efb72f..e61e8a5dbd 100644 --- a/runtime/hsa-runtime/core/inc/hsa_api_trace_int.h +++ b/runtime/hsa-runtime/core/inc/hsa_api_trace_int.h @@ -53,6 +53,7 @@ namespace core { static const uint32_t HSA_EXT_FINALIZER_API_TABLE_ID = 0; static const uint32_t HSA_EXT_IMAGE_API_TABLE_ID = 1; static const uint32_t HSA_EXT_AQLPROFILE_API_TABLE_ID = 2; + static const uint32_t HSA_EXT_PC_SAMPLING_API_TABLE_ID = 3; ::HsaApiTable hsa_api; ::CoreApiTable core_api; @@ -60,6 +61,7 @@ namespace core { ::FinalizerExtTable finalizer_api; ::ImageExtTable image_api; ::ToolsApiTable tools_api; + ::PcSamplingExtTable pcs_api; HsaApiTable(); void Init(); diff --git a/runtime/hsa-runtime/core/inc/hsa_ext_interface.h b/runtime/hsa-runtime/core/inc/hsa_ext_interface.h index 20a51759f9..c6b275b1e3 100644 --- a/runtime/hsa-runtime/core/inc/hsa_ext_interface.h +++ b/runtime/hsa-runtime/core/inc/hsa_ext_interface.h @@ -57,12 +57,17 @@ struct ImageExtTableInternal : public ImageExtTable { decltype(::hsa_amd_image_get_info_max_dim)* hsa_amd_image_get_info_max_dim_fn; }; +struct PcSamplingExtTableInternal : public PcSamplingExtTable {}; + class ExtensionEntryPoints { public: // Table of function pointers for Hsa Extension Image ImageExtTableInternal image_api; + // Table of function pointers for Hsa vendor PC Sampling + PcSamplingExtTableInternal pcs_api; + // Table of function pointers for Hsa Extension Finalizer FinalizerExtTable finalizer_api; @@ -77,6 +82,12 @@ class ExtensionEntryPoints { // Reset Api tables to point to null implementations void UnloadImage(); + // Update PC Sampling Api table with handles to implementation + void LoadPcSampling(); + + // Reset PC Sampling tables to point to null implementations + void UnloadPcSampling(); + private: typedef void (*Load_t)(const ::HsaApiTable* table); typedef void (*Unload_t)(); @@ -89,6 +100,9 @@ class ExtensionEntryPoints { // Initialize table for HSA Image Extension Api's void InitImageExtTable(); + // Initialize table for HSA PC Sampling Extension Api's + void InitPcSamplingExtTable(); + // Initialize Amd Ext table for Api related to Images void InitAmdExtTable(); @@ -96,7 +110,7 @@ class ExtensionEntryPoints { void UpdateAmdExtTable(decltype(::hsa_amd_image_create)* func_ptr); DISALLOW_COPY_AND_ASSIGN(ExtensionEntryPoints); -}; +}; } // namespace core } // namespace rocr diff --git a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp index 1c179f06ec..87c7190944 100644 --- a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +++ b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp @@ -1309,6 +1309,10 @@ hsa_status_t GpuAgent::GetInfo(hsa_agent_info_t attribute, void* value) const { setFlag(HSA_EXTENSION_IMAGES); } + if (core::hsa_internal_api_table_.pcs_api.hsa_ven_amd_pcs_iterate_configuration_fn != NULL) { + setFlag(HSA_EXTENSION_AMD_PC_SAMPLING); + } + if (os::LibHandle lib = os::LoadLib(kAqlProfileLib)) { os::CloseLib(lib); setFlag(HSA_EXTENSION_AMD_AQLPROFILE); diff --git a/runtime/hsa-runtime/core/runtime/hsa.cpp b/runtime/hsa-runtime/core/runtime/hsa.cpp index 6c161cd0a1..8ad8ff2648 100644 --- a/runtime/hsa-runtime/core/runtime/hsa.cpp +++ b/runtime/hsa-runtime/core/runtime/hsa.cpp @@ -343,7 +343,8 @@ static size_t get_extension_table_length(uint16_t extension, uint16_t major, uin {"hsa_ven_amd_loader_1_01_pfn_t", sizeof(hsa_ven_amd_loader_1_01_pfn_t)}, {"hsa_ven_amd_loader_1_02_pfn_t", sizeof(hsa_ven_amd_loader_1_02_pfn_t)}, {"hsa_ven_amd_loader_1_03_pfn_t", sizeof(hsa_ven_amd_loader_1_03_pfn_t)}, - {"hsa_ven_amd_aqlprofile_1_00_pfn_t", sizeof(hsa_ven_amd_aqlprofile_1_00_pfn_t)}}; + {"hsa_ven_amd_aqlprofile_1_00_pfn_t", sizeof(hsa_ven_amd_aqlprofile_1_00_pfn_t)}, + {"hsa_ven_amd_pc_sampling_1_00_pfn_t", sizeof(hsa_ven_amd_pc_sampling_1_00_pfn_t)}}; static const size_t num_tables = sizeof(sizes) / sizeof(sizes_t); if (minor > 99) return 0; @@ -372,6 +373,9 @@ static size_t get_extension_table_length(uint16_t extension, uint16_t major, uin case HSA_EXTENSION_AMD_AQLPROFILE: name = "hsa_ven_amd_aqlprofile_"; break; + case HSA_EXTENSION_AMD_PC_SAMPLING: + name = "hsa_ven_amd_pc_sampling_"; + break; default: return 0; } @@ -429,6 +433,21 @@ hsa_status_t hsa_system_get_major_extension_table(uint16_t extension, uint16_t v return HSA_STATUS_SUCCESS; } + if (extension == HSA_EXTENSION_AMD_PC_SAMPLING) { + if (version_major != core::Runtime::runtime_singleton_->extensions_.pcs_api.version.major_id) { + return HSA_STATUS_ERROR; + } + hsa_ven_amd_pc_sampling_1_00_pfn_t ext_table; + ext_table.hsa_ven_amd_pcs_create = hsa_ven_amd_pcs_create; + ext_table.hsa_ven_amd_pcs_create_from_id = hsa_ven_amd_pcs_create_from_id; + ext_table.hsa_ven_amd_pcs_destroy = hsa_ven_amd_pcs_destroy; + ext_table.hsa_ven_amd_pcs_start = hsa_ven_amd_pcs_start; + ext_table.hsa_ven_amd_pcs_stop = hsa_ven_amd_pcs_stop; + ext_table.hsa_ven_amd_pcs_flush = hsa_ven_amd_pcs_flush; + + memcpy(table, &ext_table, Min(sizeof(ext_table), table_length)); + } + if (extension == HSA_EXTENSION_FINALIZER) { if (version_major != core::Runtime::runtime_singleton_->extensions_.finalizer_api.version.major_id) { diff --git a/runtime/hsa-runtime/core/runtime/hsa_api_trace.cpp b/runtime/hsa-runtime/core/runtime/hsa_api_trace.cpp index 0c3ba59a7b..bd753936e5 100644 --- a/runtime/hsa-runtime/core/runtime/hsa_api_trace.cpp +++ b/runtime/hsa-runtime/core/runtime/hsa_api_trace.cpp @@ -84,6 +84,7 @@ void HsaApiTable::Init() { constexpr size_t expected_image_ext_table_size = 120; constexpr size_t expected_finalizer_ext_table_size = 64; constexpr size_t expected_tools_table_size = 64; + constexpr size_t expected_pc_sampling_ext_table_size = 72; static_assert(sizeof(CoreApiTable) == expected_core_api_table_size, "HSA core API table size changed, bump HSA_CORE_API_TABLE_STEP_VERSION and set " @@ -101,6 +102,9 @@ void HsaApiTable::Init() { static_assert(sizeof(ToolsApiTable) == expected_tools_table_size, "HSA tools table size changed, bump HSA_TOOLS_API_TABLE_STEP_VERSION " "and set expected_tools_table_size to the new size of the struct"); + static_assert(sizeof(PcSamplingExtTable) == expected_pc_sampling_ext_table_size, + "HSA finalizer ext table size changed, bump HSA_PC_SAMPLING_API_TABLE_STEP_VERSION " + "and set expected_pc_sampling_ext_table_size to the new size of the struct"); // Initialize Version of Api Table hsa_api.version.major_id = HSA_API_TABLE_MAJOR_VERSION; @@ -120,6 +124,7 @@ void HsaApiTable::Init() { // of Hsa Runtime initialization, including their major ids hsa_api.finalizer_ext_ = NULL; hsa_api.image_ext_ = NULL; + hsa_api.pc_sampling_ext_ = NULL; UpdateTools(); hsa_api.tools_ = &tools_api; @@ -146,6 +151,13 @@ void HsaApiTable::CloneExts(void* ext_table, uint32_t table_id) { hsa_api.image_ext_ = &image_api; return; } + + // Update HSA Extension PC Sampling Api table + if (table_id == HSA_EXT_PC_SAMPLING_API_TABLE_ID) { + pcs_api = *reinterpret_cast(ext_table); + hsa_api.pc_sampling_ext_ = &pcs_api; + return; + } } void HsaApiTable::LinkExts(void* ext_table, uint32_t table_id) { @@ -165,6 +177,13 @@ void HsaApiTable::LinkExts(void* ext_table, uint32_t table_id) { hsa_api.image_ext_ = reinterpret_cast(ext_table); return; } + + // Update HSA Extension PC Sampling Api table + if (table_id == HSA_EXT_PC_SAMPLING_API_TABLE_ID) { + pcs_api = *reinterpret_cast(ext_table); + hsa_api.pc_sampling_ext_ = &pcs_api; + return; + } } // Update Api table for Hsa Core Runtime diff --git a/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp b/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp index 2931b2b54f..d872e485b6 100644 --- a/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp +++ b/runtime/hsa-runtime/core/runtime/hsa_ext_interface.cpp @@ -41,6 +41,7 @@ //////////////////////////////////////////////////////////////////////////////// #include "image/inc/hsa_ext_image_impl.h" +#include "pcs/inc/hsa_ven_amd_pc_sampling_impl.h" #include "core/inc/hsa_ext_interface.h" #include "core/inc/runtime.h" @@ -56,6 +57,7 @@ namespace core { ExtensionEntryPoints::ExtensionEntryPoints() { InitFinalizerExtTable(); InitImageExtTable(); + InitPcSamplingExtTable(); InitAmdExtTable(); } @@ -99,6 +101,22 @@ void ExtensionEntryPoints::InitImageExtTable() { image_api.hsa_ext_image_create_with_layout_fn = hsa_ext_null; } +// Initialize PC Sampling function table to be NULLs +void ExtensionEntryPoints::InitPcSamplingExtTable() { + // Initialize Version of Api Table + pcs_api.version.major_id = 0x00; + pcs_api.version.minor_id = 0x00; + pcs_api.version.step_id = 0x00; + + pcs_api.hsa_ven_amd_pcs_iterate_configuration_fn = hsa_ext_null; + pcs_api.hsa_ven_amd_pcs_create_fn = hsa_ext_null; + pcs_api.hsa_ven_amd_pcs_create_from_id_fn = hsa_ext_null; + pcs_api.hsa_ven_amd_pcs_destroy_fn = hsa_ext_null; + pcs_api.hsa_ven_amd_pcs_start_fn = hsa_ext_null; + pcs_api.hsa_ven_amd_pcs_stop_fn = hsa_ext_null; + pcs_api.hsa_ven_amd_pcs_flush_fn = hsa_ext_null; +} + // Initialize Amd Ext table for Api related to Images void ExtensionEntryPoints::InitAmdExtTable() { hsa_api_table_.amd_ext_api.hsa_amd_image_create_fn = hsa_ext_null; @@ -131,6 +149,9 @@ void ExtensionEntryPoints::UnloadImage() { void ExtensionEntryPoints::Unload() { // Reset Image apis to hsa_ext_null function UnloadImage(); +#ifdef HSA_PC_SAMPLING_SUPPORT + rocr::pcs::ReleasePcSamplingRsrcs(); +#endif for (auto lib : libs_) { void* ptr = os::GetExportAddress(lib, "Unload"); @@ -148,6 +169,7 @@ void ExtensionEntryPoints::Unload() { libs_.clear(); InitFinalizerExtTable(); + InitPcSamplingExtTable(); InitImageExtTable(); InitAmdExtTable(); core::hsa_internal_api_table_.Reset(); @@ -180,6 +202,23 @@ bool ExtensionEntryPoints::LoadImage() { return true; } +void ExtensionEntryPoints::LoadPcSampling() { +#ifdef HSA_PC_SAMPLING_SUPPORT + if (core::Runtime::runtime_singleton_->flag().disable_pc_sampling()) return; + + // Bind to Image implementation api's + rocr::pcs::LoadPcSampling(&pcs_api); + + // Initialize Version of Api Table + pcs_api.version.major_id = HSA_PC_SAMPLING_API_TABLE_MAJOR_VERSION; + pcs_api.version.minor_id = sizeof(PcSamplingExtTable); + pcs_api.version.step_id = HSA_PC_SAMPLING_API_TABLE_STEP_VERSION; + + // Update private copy of Api table with handle for Image extensions + hsa_internal_api_table_.CloneExts(&pcs_api, core::HsaApiTable::HSA_EXT_PC_SAMPLING_API_TABLE_ID); +#endif +} + bool ExtensionEntryPoints::LoadFinalizer(std::string library_name) { os::LibHandle lib = os::LoadLib(library_name); if (lib == NULL) { @@ -429,6 +468,54 @@ hsa_status_t hsa_ext_image_create_with_layout( image); } +hsa_status_t HSA_API hsa_ven_amd_pcs_iterate_configuration( + hsa_agent_t agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback, + void* callback_data) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api + .hsa_ven_amd_pcs_iterate_configuration_fn(agent, configuration_callback, callback_data); +} + +hsa_status_t HSA_API hsa_ven_amd_pcs_create( + hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method, hsa_ven_amd_pcs_units_t units, + size_t interval, size_t latency, size_t buffer_size, + hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data, + hsa_ven_amd_pcs_t* pc_sampling) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_create_fn( + agent, method, units, interval, latency, buffer_size, data_ready_callback, + client_callback_data, pc_sampling); +} + +hsa_status_t HSA_API hsa_ven_amd_pcs_create_from_id( + uint32_t pcs_id, hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method, + hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency, size_t buffer_size, + hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data, + hsa_ven_amd_pcs_t* pc_sampling) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api + .hsa_ven_amd_pcs_create_from_id_fn(pcs_id, agent, method, units, interval, latency, + buffer_size, data_ready_callback, client_callback_data, + pc_sampling); +} + +hsa_status_t HSA_API hsa_ven_amd_pcs_destroy(hsa_ven_amd_pcs_t pc_sampling) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_destroy_fn( + pc_sampling); +} + +hsa_status_t HSA_API hsa_ven_amd_pcs_start(hsa_ven_amd_pcs_t pc_sampling) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_start_fn( + pc_sampling); +} + +hsa_status_t HSA_API hsa_ven_amd_pcs_stop(hsa_ven_amd_pcs_t pc_sampling) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_stop_fn( + pc_sampling); +} + +hsa_status_t HSA_API hsa_ven_amd_pcs_flush(hsa_ven_amd_pcs_t pc_sampling) { + return rocr::core::Runtime::runtime_singleton_->extensions_.pcs_api.hsa_ven_amd_pcs_flush_fn( + pc_sampling); +} + //---------------------------------------------------------------------------// // Stubs for internal extension functions //---------------------------------------------------------------------------// diff --git a/runtime/hsa-runtime/core/runtime/runtime.cpp b/runtime/hsa-runtime/core/runtime/runtime.cpp index ec37c154a8..62e9362d68 100644 --- a/runtime/hsa-runtime/core/runtime/runtime.cpp +++ b/runtime/hsa-runtime/core/runtime/runtime.cpp @@ -1998,6 +1998,11 @@ void Runtime::LoadExtensions() { extensions_.LoadImage(); hsa_api_table_.LinkExts(&extensions_.image_api, core::HsaApiTable::HSA_EXT_IMAGE_API_TABLE_ID); + + // Update Hsa Api Table with handle of PCS extension Apis + extensions_.LoadPcSampling(); + hsa_api_table_.LinkExts(&extensions_.pcs_api, + core::HsaApiTable::HSA_EXT_PC_SAMPLING_API_TABLE_ID); } void Runtime::UnloadExtensions() { extensions_.Unload(); } diff --git a/runtime/hsa-runtime/core/util/flag.h b/runtime/hsa-runtime/core/util/flag.h index ff09283994..84b7f72dd1 100644 --- a/runtime/hsa-runtime/core/util/flag.h +++ b/runtime/hsa-runtime/core/util/flag.h @@ -184,6 +184,9 @@ class Flag { var = os::GetEnvVar("HSA_DISABLE_IMAGE"); disable_image_ = (var == "1") ? true : false; + var = os::GetEnvVar("HSA_DISABLE_PC_SAMPLING"); + disable_pc_sampling_ = (var == "1") ? true : false; + var = os::GetEnvVar("HSA_LOADER_ENABLE_MMAP_URI"); loader_enable_mmap_uri_ = (var == "1") ? true : false; @@ -297,6 +300,8 @@ class Flag { bool disable_image() const { return disable_image_; } + bool disable_pc_sampling() const { return disable_pc_sampling_; } + bool loader_enable_mmap_uri() const { return loader_enable_mmap_uri_; } size_t force_sdma_size() const { return force_sdma_size_; } @@ -353,6 +358,7 @@ class Flag { bool no_scratch_reclaim_; bool no_scratch_thread_limit_; bool disable_image_; + bool disable_pc_sampling_; bool loader_enable_mmap_uri_; bool check_sramecc_validity_; bool debug_; diff --git a/runtime/hsa-runtime/inc/hsa.h b/runtime/hsa-runtime/inc/hsa.h index 148c693be7..1ad714c44c 100644 --- a/runtime/hsa-runtime/inc/hsa.h +++ b/runtime/hsa-runtime/inc/hsa.h @@ -598,10 +598,14 @@ typedef enum { * AqlProfile extension. */ HSA_EXTENSION_AMD_AQLPROFILE = 0x202, + /** + * PC Sampling extension. + */ + HSA_EXTENSION_AMD_PC_SAMPLING = 0x203, /** * Last AMD extension. */ - HSA_AMD_LAST_EXTENSION = 0x202 + HSA_AMD_LAST_EXTENSION = 0x203 } hsa_extension_t; /** diff --git a/runtime/hsa-runtime/inc/hsa_api_trace.h b/runtime/hsa-runtime/inc/hsa_api_trace.h index 2e18b2399c..799f716550 100644 --- a/runtime/hsa-runtime/inc/hsa_api_trace.h +++ b/runtime/hsa-runtime/inc/hsa_api_trace.h @@ -50,11 +50,13 @@ #include "hsa_ext_amd.h" #include "hsa_ext_finalize.h" #include "hsa_amd_tool.h" +#include "hsa_ven_amd_pc_sampling.h" #else #include "inc/hsa_ext_image.h" #include "inc/hsa_ext_amd.h" #include "inc/hsa_ext_finalize.h" #include "inc/hsa_amd_tool.h" +#include "inc/hsa_ven_amd_pc_sampling.h" #endif #include @@ -176,6 +178,19 @@ struct ImageExtTable { decltype(hsa_ext_image_create_with_layout)* hsa_ext_image_create_with_layout_fn; }; +// Table to export HSA PC Sampling Extension Apis +struct PcSamplingExtTable { + ApiTableVersion version; + decltype(hsa_ven_amd_pcs_iterate_configuration)* hsa_ven_amd_pcs_iterate_configuration_fn; + decltype(hsa_ven_amd_pcs_create)* hsa_ven_amd_pcs_create_fn; + decltype(hsa_ven_amd_pcs_create_from_id)* hsa_ven_amd_pcs_create_from_id_fn; + decltype(hsa_ven_amd_pcs_destroy)* hsa_ven_amd_pcs_destroy_fn; + decltype(hsa_ven_amd_pcs_start)* hsa_ven_amd_pcs_start_fn; + decltype(hsa_ven_amd_pcs_stop)* hsa_ven_amd_pcs_stop_fn; + decltype(hsa_ven_amd_pcs_flush)* hsa_ven_amd_pcs_flush_fn; +}; + + // Table to export AMD Extension Apis struct AmdExtTable { ApiTableVersion version; @@ -449,6 +464,9 @@ struct HsaApiTable { // Table of function pointers for tools to use ToolsApiTable* tools_; + + // Table of function pointers to AMD PC Sampling Extension + PcSamplingExtTable* pc_sampling_ext_; }; // Structure containing instances of different api tables @@ -459,6 +477,7 @@ struct HsaApiTableContainer { FinalizerExtTable finalizer_ext; ImageExtTable image_ext; ToolsApiTable tools; + PcSamplingExtTable pc_sampling_ext; // Default initialization of a container instance HsaApiTableContainer() { @@ -490,6 +509,11 @@ struct HsaApiTableContainer { tools.version.minor_id = sizeof(ToolsApiTable); tools.version.step_id = HSA_TOOLS_API_TABLE_STEP_VERSION; root.tools_ = &tools; + + pc_sampling_ext.version.major_id = HSA_PC_SAMPLING_API_TABLE_MAJOR_VERSION; + pc_sampling_ext.version.minor_id = sizeof(PcSamplingExtTable); + pc_sampling_ext.version.step_id = HSA_PC_SAMPLING_API_TABLE_STEP_VERSION; + root.pc_sampling_ext_ = &pc_sampling_ext; } }; @@ -547,5 +571,7 @@ static void inline copyTables(const HsaApiTable* src, HsaApiTable* dest) { copyElement(&dest->image_ext_->version, &src->image_ext_->version); if ((offsetof(HsaApiTable, tools_) < dest->version.minor_id)) copyElement(&dest->tools_->version, &src->tools_->version); + if ((offsetof(HsaApiTable, pc_sampling_ext_) < dest->version.minor_id)) + copyElement(&dest->pc_sampling_ext_->version, &src->pc_sampling_ext_->version); } #endif diff --git a/runtime/hsa-runtime/inc/hsa_api_trace_version.h b/runtime/hsa-runtime/inc/hsa_api_trace_version.h index 52c340a33e..1d14d585ff 100644 --- a/runtime/hsa-runtime/inc/hsa_api_trace_version.h +++ b/runtime/hsa-runtime/inc/hsa_api_trace_version.h @@ -46,21 +46,23 @@ // CODE IN THIS FILE **MUST** BE C-COMPATIBLE // Major Ids of the Api tables exported by Hsa Core Runtime -#define HSA_API_TABLE_MAJOR_VERSION 0x03 -#define HSA_CORE_API_TABLE_MAJOR_VERSION 0x02 -#define HSA_AMD_EXT_API_TABLE_MAJOR_VERSION 0x02 -#define HSA_FINALIZER_API_TABLE_MAJOR_VERSION 0x02 -#define HSA_IMAGE_API_TABLE_MAJOR_VERSION 0x02 -#define HSA_AQLPROFILE_API_TABLE_MAJOR_VERSION 0x01 -#define HSA_TOOLS_API_TABLE_MAJOR_VERSION 0x01 +#define HSA_API_TABLE_MAJOR_VERSION 0x03 +#define HSA_CORE_API_TABLE_MAJOR_VERSION 0x02 +#define HSA_AMD_EXT_API_TABLE_MAJOR_VERSION 0x02 +#define HSA_FINALIZER_API_TABLE_MAJOR_VERSION 0x02 +#define HSA_IMAGE_API_TABLE_MAJOR_VERSION 0x02 +#define HSA_AQLPROFILE_API_TABLE_MAJOR_VERSION 0x01 +#define HSA_TOOLS_API_TABLE_MAJOR_VERSION 0x01 +#define HSA_PC_SAMPLING_API_TABLE_MAJOR_VERSION 0x01 // Step Ids of the Api tables exported by Hsa Core Runtime -#define HSA_API_TABLE_STEP_VERSION 0x00 -#define HSA_CORE_API_TABLE_STEP_VERSION 0x00 -#define HSA_AMD_EXT_API_TABLE_STEP_VERSION 0x01 -#define HSA_FINALIZER_API_TABLE_STEP_VERSION 0x00 -#define HSA_IMAGE_API_TABLE_STEP_VERSION 0x00 -#define HSA_AQLPROFILE_API_TABLE_STEP_VERSION 0x00 -#define HSA_TOOLS_API_TABLE_STEP_VERSION 0x00 +#define HSA_API_TABLE_STEP_VERSION 0x01 +#define HSA_CORE_API_TABLE_STEP_VERSION 0x00 +#define HSA_AMD_EXT_API_TABLE_STEP_VERSION 0x01 +#define HSA_FINALIZER_API_TABLE_STEP_VERSION 0x00 +#define HSA_IMAGE_API_TABLE_STEP_VERSION 0x00 +#define HSA_AQLPROFILE_API_TABLE_STEP_VERSION 0x00 +#define HSA_TOOLS_API_TABLE_STEP_VERSION 0x00 +#define HSA_PC_SAMPLING_API_TABLE_STEP_VERSION 0x00 #endif // HSA_RUNTIME_INC_HSA_API_TRACE_VERSION_H diff --git a/runtime/hsa-runtime/inc/hsa_ven_amd_pc_sampling.h b/runtime/hsa-runtime/inc/hsa_ven_amd_pc_sampling.h index 991a306966..019f0ea5c9 100644 --- a/runtime/hsa-runtime/inc/hsa_ven_amd_pc_sampling.h +++ b/runtime/hsa-runtime/inc/hsa_ven_amd_pc_sampling.h @@ -393,6 +393,12 @@ typedef struct hsa_ven_amd_pc_sampling_1_00_pfn_t { void* client_callback_data, hsa_ven_amd_pcs_t* pc_sampling); + hsa_status_t (*hsa_ven_amd_pcs_create_from_id)( + uint32_t pcs_id, hsa_agent_t agent, hsa_ven_amd_pcs_method_kind_t method, + hsa_ven_amd_pcs_units_t units, size_t interval, size_t latency, size_t buffer_size, + hsa_ven_amd_pcs_data_ready_callback_t data_ready_callback, void* client_callback_data, + hsa_ven_amd_pcs_t* pc_sampling); + hsa_status_t (*hsa_ven_amd_pcs_destroy)(hsa_ven_amd_pcs_t pc_sampling); hsa_status_t (*hsa_ven_amd_pcs_start)(hsa_ven_amd_pcs_t pc_sampling); diff --git a/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp b/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp new file mode 100644 index 0000000000..ac4b693d08 --- /dev/null +++ b/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp @@ -0,0 +1,92 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// The University of Illinois/NCSA +// Open Source License (NCSA) +// +// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved. +// +// Developed by: +// +// AMD Research and AMD HSA Software Development +// +// Advanced Micro Devices, Inc. +// +// www.amd.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal with the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimers. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimers in +// the documentation and/or other materials provided with the distribution. +// - Neither the names of Advanced Micro Devices, Inc, +// nor the names of its contributors may be used to endorse or promote +// products derived from this Software without specific prior written +// permission. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS WITH THE SOFTWARE. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "pcs_runtime.h" +#include "core/inc/agent.h" +#include "core/inc/amd_gpu_agent.h" +#include "core/inc/exceptions.h" + +namespace rocr { +namespace AMD { +hsa_status_t handleException(); + +template static __forceinline T handleExceptionT() { + handleException(); + abort(); + return T(); +} +} // namespace AMD + +#define IS_OPEN() \ + do { \ + if (!core::Runtime::runtime_singleton_->IsOpen()) return HSA_STATUS_ERROR_NOT_INITIALIZED; \ + } while (false) + +template static __forceinline bool IsValid(T* ptr) { + return (ptr == NULL) ? NULL : ptr->IsValid(); +} + +#define TRY try { +#define CATCH \ + } \ + catch (...) { \ + return AMD::handleException(); \ + } +#define CATCHRET(RETURN_TYPE) \ + } \ + catch (...) { \ + return AMD::handleExceptionT(); \ + } + +namespace pcs { + +void LoadPcSampling(core::PcSamplingExtTableInternal* pcs_api) { + pcs_api->hsa_ven_amd_pcs_iterate_configuration_fn = hsa_ven_amd_pcs_iterate_configuration; + pcs_api->hsa_ven_amd_pcs_create_fn = hsa_ven_amd_pcs_create; + pcs_api->hsa_ven_amd_pcs_destroy_fn = hsa_ven_amd_pcs_destroy; + pcs_api->hsa_ven_amd_pcs_start_fn = hsa_ven_amd_pcs_start; + pcs_api->hsa_ven_amd_pcs_stop_fn = hsa_ven_amd_pcs_stop; + pcs_api->hsa_ven_amd_pcs_flush_fn = hsa_ven_amd_pcs_flush; +} + +} // namespace pcs +} // namespace rocr diff --git a/runtime/hsa-runtime/pcs/inc/hsa_ven_amd_pc_sampling_impl.h b/runtime/hsa-runtime/pcs/inc/hsa_ven_amd_pc_sampling_impl.h new file mode 100644 index 0000000000..d57f38e90b --- /dev/null +++ b/runtime/hsa-runtime/pcs/inc/hsa_ven_amd_pc_sampling_impl.h @@ -0,0 +1,67 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// The University of Illinois/NCSA +// Open Source License (NCSA) +// +// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved. +// +// Developed by: +// +// AMD Research and AMD HSA Software Development +// +// Advanced Micro Devices, Inc. +// +// www.amd.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal with the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimers. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimers in +// the documentation and/or other materials provided with the distribution. +// - Neither the names of Advanced Micro Devices, Inc, +// nor the names of its contributors may be used to endorse or promote +// products derived from this Software without specific prior written +// permission. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS WITH THE SOFTWARE. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef HSA_VEN_AMD_PC_SAMPLING_IMPL_H +#define HSA_VEN_AMD_PC_SAMPLING_IMPL_H + +#include "inc/hsa.h" +#include "inc/hsa_ext_amd.h" +#include "inc/hsa_ven_amd_pc_sampling.h" +#include "core/inc/hsa_ext_interface.h" + +//---------------------------------------------------------------------------// +// APIs that implement PC Sampling functionality +//---------------------------------------------------------------------------// + +namespace rocr { +namespace pcs { + +// Update Api table with func pointers that implement functionality +void LoadPcSampling(core::PcSamplingExtTableInternal* pcs_api); + +// Release resources acquired by Image implementation +void ReleasePcSamplingRsrcs(); + +} // namespace pcs +} // namespace rocr + +#endif // HSA_VEN_AMD_PC_SAMPLING_IMPL_H diff --git a/runtime/hsa-runtime/pcs/pcs_runtime.cpp b/runtime/hsa-runtime/pcs/pcs_runtime.cpp new file mode 100644 index 0000000000..e742aebc13 --- /dev/null +++ b/runtime/hsa-runtime/pcs/pcs_runtime.cpp @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// The University of Illinois/NCSA +// Open Source License (NCSA) +// +// Copyright (c) 2023, Advanced Micro Devices, Inc. All rights reserved. +// +// Developed by: +// +// AMD Research and AMD HSA Software Development +// +// Advanced Micro Devices, Inc. +// +// www.amd.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal with the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimers. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimers in +// the documentation and/or other materials provided with the distribution. +// - Neither the names of Advanced Micro Devices, Inc, +// nor the names of its contributors may be used to endorse or promote +// products derived from this Software without specific prior written +// permission. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS WITH THE SOFTWARE. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "pcs_runtime.h" + +#include +#include + +#include "core/inc/runtime.h" + +#include "core/inc/amd_gpu_agent.h" + +namespace rocr { +namespace pcs { + +std::atomic PcsRuntime::instance_(NULL); +std::mutex PcsRuntime::instance_mutex_; + +PcsRuntime* PcsRuntime::instance() { + PcsRuntime* instance = instance_.load(std::memory_order_acquire); + if (instance == NULL) { + // Protect the initialization from multi threaded access. + std::lock_guard lock(instance_mutex_); + + // Make sure we are not initializing it twice. + instance = instance_.load(std::memory_order_relaxed); + if (instance != NULL) { + return instance; + } + + instance = CreateSingleton(); + if (instance == NULL) { + return NULL; + } + } + + return instance; +} + +PcsRuntime* PcsRuntime::CreateSingleton() { + PcsRuntime* instance = new PcsRuntime(); + + instance_.store(instance, std::memory_order_release); + return instance; +} + +void PcsRuntime::DestroySingleton() { + PcsRuntime* instance = instance_.load(std::memory_order_acquire); + if (instance == NULL) { + return; + } + + instance_.store(NULL, std::memory_order_release); + delete instance; +} + +void ReleasePcSamplingRsrcs() { PcsRuntime::DestroySingleton(); } + +} // namespace pcs +} // namespace rocr diff --git a/runtime/hsa-runtime/pcs/pcs_runtime.h b/runtime/hsa-runtime/pcs/pcs_runtime.h new file mode 100644 index 0000000000..20c045ae2a --- /dev/null +++ b/runtime/hsa-runtime/pcs/pcs_runtime.h @@ -0,0 +1,84 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// The University of Illinois/NCSA +// Open Source License (NCSA) +// +// Copyright (c) 2014-2020, Advanced Micro Devices, Inc. All rights reserved. +// +// Developed by: +// +// AMD Research and AMD HSA Software Development +// +// Advanced Micro Devices, Inc. +// +// www.amd.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal with the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimers. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimers in +// the documentation and/or other materials provided with the distribution. +// - Neither the names of Advanced Micro Devices, Inc, +// nor the names of its contributors may be used to endorse or promote +// products derived from this Software without specific prior written +// permission. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS WITH THE SOFTWARE. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef HSA_RUNTIME_PCS_RUNTIME_H +#define HSA_RUNTIME_PCS_RUNTIME_H + +#include +#include +#include + +#include "hsakmt/hsakmt.h" + +#include "hsa_ven_amd_pc_sampling.h" +#include "core/inc/agent.h" +#include "core/inc/exceptions.h" + + +namespace rocr { +namespace pcs { + +class PcsRuntime { + public: + PcsRuntime() {} + ~PcsRuntime() {} + + /// @brief Getter for the PcsRuntime singleton object. + static PcsRuntime* instance(); + + /// @brief Destroy singleton object. + static void DestroySingleton(); + + private: + /// @brief Initialize singleton object, must be called once. + static PcsRuntime* CreateSingleton(); + + /// Pointer to singleton object. + static std::atomic instance_; + static std::mutex instance_mutex_; + + DISALLOW_COPY_AND_ASSIGN(PcsRuntime); +}; + +} // namespace pcs +} // namespace rocr +#endif // HSA_RUNTIME_PCS_RUNTIME_H