diff --git a/runtime/hsa-runtime/core/inc/amd_gpu_agent.h b/runtime/hsa-runtime/core/inc/amd_gpu_agent.h index c1da3ac69a..36c3fbd6bc 100644 --- a/runtime/hsa-runtime/core/inc/amd_gpu_agent.h +++ b/runtime/hsa-runtime/core/inc/amd_gpu_agent.h @@ -187,6 +187,11 @@ class GpuAgentInt : public core::Agent { // Only valid when async scratch reclaim is supported // @retval HSA_STATUS_SUCCESS if successful virtual hsa_status_t SetAsyncScratchThresholds(size_t use_once_limit) = 0; + + // @brief Iterate through supported PC Sampling configurations + // @retval HSA_STATUS_SUCCESS if successful + virtual hsa_status_t PcSamplingIterateConfig(hsa_ven_amd_pcs_iterate_configuration_callback_t cb, + void* cb_data) = 0; }; class GpuAgent : public GpuAgentInt { @@ -467,6 +472,9 @@ class GpuAgent : public GpuAgentInt { // @brief Override from core::Agent. hsa_status_t EnableDmaProfiling(bool enable) override; + hsa_status_t PcSamplingIterateConfig(hsa_ven_amd_pcs_iterate_configuration_callback_t cb, + void* cb_data); + // @brief Node properties. const HsaNodeProperties properties_; diff --git a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp index 87c7190944..bef9dd58d7 100644 --- a/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp +++ b/runtime/hsa-runtime/core/runtime/amd_gpu_agent.cpp @@ -65,6 +65,7 @@ #include "core/util/os.h" #include "inc/hsa_ext_image.h" #include "inc/hsa_ven_amd_aqlprofile.h" +#include "inc/hsa_ven_amd_pc_sampling.h" #include "core/inc/amd_trap_handler_v1.h" #include "core/inc/amd_blit_shaders.h" @@ -2301,5 +2302,66 @@ core::Agent* GpuAgent::GetNearestCpuAgent() const { return nearCpu; } +hsa_status_t ConvertHsaKmtPcSamplingInfoToHsa(HsaPcSamplingInfo* hsaKmtPcSampling, + hsa_ven_amd_pcs_configuration_t* hsaPcSampling) { + assert(hsaKmtPcSampling && "Invalid hsaKmtPcSampling"); + assert(hsaPcSampling && "Invalid hsaPcSampling"); + + switch (hsaKmtPcSampling->method) { + case HSA_PC_SAMPLING_METHOD_KIND_HOSTTRAP_V1: + hsaPcSampling->method = HSA_VEN_AMD_PCS_METHOD_HOSTTRAP_V1; + break; + case HSA_PC_SAMPLING_METHOD_KIND_STOCHASTIC_V1: + hsaPcSampling->method = HSA_VEN_AMD_PCS_METHOD_STOCHASTIC_V1; + break; + default: + // Sampling method not supported do not return this method to the user + return HSA_STATUS_ERROR; + } + switch (hsaKmtPcSampling->units) { + case HSA_PC_SAMPLING_UNIT_INTERVAL_MICROSECONDS: + hsaPcSampling->units = HSA_VEN_AMD_PCS_INTERVAL_UNITS_MICRO_SECONDS; + break; + case HSA_PC_SAMPLING_UNIT_INTERVAL_CYCLES: + hsaPcSampling->units = HSA_VEN_AMD_PCS_INTERVAL_UNITS_CLOCK_CYCLES; + break; + case HSA_PC_SAMPLING_UNIT_INTERVAL_INSTRUCTIONS: + hsaPcSampling->units = HSA_VEN_AMD_PCS_INTERVAL_UNITS_INSTRUCTIONS; + break; + default: + // Sampling unit not supported do not return this method to the user + return HSA_STATUS_ERROR; + } + + hsaPcSampling->min_interval = hsaKmtPcSampling->value_min; + hsaPcSampling->max_interval = hsaKmtPcSampling->value_max; + hsaPcSampling->flags = hsaKmtPcSampling->flags; + return HSA_STATUS_SUCCESS; +} + +hsa_status_t GpuAgent::PcSamplingIterateConfig(hsa_ven_amd_pcs_iterate_configuration_callback_t cb, + void* cb_data) { + uint32_t size = 0; + + // First query to get size of list needed + HSAKMT_STATUS ret = hsaKmtPcSamplingQueryCapabilities(node_id(), NULL, 0, &size); + if (ret != HSAKMT_STATUS_SUCCESS || size == 0) return HSA_STATUS_ERROR; + + std::vector sampleInfoList(size); + ret = hsaKmtPcSamplingQueryCapabilities(node_id(), sampleInfoList.data(), sampleInfoList.size(), + &size); + + if (ret != HSAKMT_STATUS_SUCCESS) return HSA_STATUS_ERROR; + + for (uint32_t i = 0; i < size; i++) { + hsa_ven_amd_pcs_configuration_t hsaPcSampling; + if (ConvertHsaKmtPcSamplingInfoToHsa(&sampleInfoList[i], &hsaPcSampling) == HSA_STATUS_SUCCESS + && cb(&hsaPcSampling, cb_data) == HSA_STATUS_INFO_BREAK) + return HSA_STATUS_SUCCESS; + } + return HSA_STATUS_SUCCESS; +} + + } // namespace amd } // namespace rocr diff --git a/runtime/hsa-runtime/hsacore.so.def b/runtime/hsa-runtime/hsacore.so.def index 4d9c92186f..953df6e4cc 100644 --- a/runtime/hsa-runtime/hsacore.so.def +++ b/runtime/hsa-runtime/hsacore.so.def @@ -252,6 +252,7 @@ global: hsa_tools_scratch_event_free_end; hsa_tools_scratch_event_async_reclaim_start; hsa_tools_scratch_event_async_reclaim_end; + hsa_ven_amd_pcs_iterate_configuration; local: *; diff --git a/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp b/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp index ac4b693d08..33bd0f6c50 100644 --- a/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp +++ b/runtime/hsa-runtime/pcs/hsa_ven_amd_pc_sampling.cpp @@ -79,6 +79,22 @@ template static __forceinline bool IsValid(T* ptr) { namespace pcs { +hsa_status_t hsa_ven_amd_pcs_iterate_configuration( + hsa_agent_t hsa_agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback, + void* callback_data) { + TRY; + IS_OPEN(); + + core::Agent* agent = core::Agent::Convert(hsa_agent); + if (agent == NULL || !agent->IsValid() || agent->device_type() != core::Agent::kAmdGpuDevice) + return HSA_STATUS_ERROR_INVALID_AGENT; + + return PcsRuntime::instance()->PcSamplingIterateConfig(agent, configuration_callback, + callback_data); + CATCH; +} + + 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; 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 index d57f38e90b..23d1acddf7 100644 --- 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 @@ -55,6 +55,10 @@ namespace rocr { namespace pcs { +hsa_status_t hsa_ven_amd_pcs_iterate_configuration( + hsa_agent_t agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback, + void* callback_data); + // Update Api table with func pointers that implement functionality void LoadPcSampling(core::PcSamplingExtTableInternal* pcs_api); diff --git a/runtime/hsa-runtime/pcs/pcs_runtime.cpp b/runtime/hsa-runtime/pcs/pcs_runtime.cpp index e742aebc13..0d2c49aeb7 100644 --- a/runtime/hsa-runtime/pcs/pcs_runtime.cpp +++ b/runtime/hsa-runtime/pcs/pcs_runtime.cpp @@ -94,6 +94,13 @@ void PcsRuntime::DestroySingleton() { } void ReleasePcSamplingRsrcs() { PcsRuntime::DestroySingleton(); } +hsa_status_t PcsRuntime::PcSamplingIterateConfig( + core::Agent* agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback, + void* callback_data) { + AMD::GpuAgentInt* gpu_agent = static_cast(agent); + return gpu_agent->PcSamplingIterateConfig(configuration_callback, callback_data); +} + } // namespace pcs } // namespace rocr diff --git a/runtime/hsa-runtime/pcs/pcs_runtime.h b/runtime/hsa-runtime/pcs/pcs_runtime.h index 20c045ae2a..59af11b4a6 100644 --- a/runtime/hsa-runtime/pcs/pcs_runtime.h +++ b/runtime/hsa-runtime/pcs/pcs_runtime.h @@ -68,6 +68,10 @@ class PcsRuntime { /// @brief Destroy singleton object. static void DestroySingleton(); + hsa_status_t PcSamplingIterateConfig( + core::Agent* agent, hsa_ven_amd_pcs_iterate_configuration_callback_t configuration_callback, + void* callback_data); + private: /// @brief Initialize singleton object, must be called once. static PcsRuntime* CreateSingleton();