From af3670d7581c9dd8b8f89361a8f7a046e718684e Mon Sep 17 00:00:00 2001 From: "Oliveira, Daniel" Date: Fri, 2 Aug 2024 21:40:28 -0500 Subject: [PATCH 1/3] SWDEV-463372: amdsmi_get_utilization_count() adds decoder_activity GPU Metrics info `gpu_metrics.vcn_activity` is exposed through amdsmi_get_utilization_count(). Code changes related to the following: * API * CLI * Unit tests Change-Id: I831b2a81bdc0e090a6698dcb689d10f91ed87dd9 Signed-off-by: Oliveira, Daniel --- include/amd_smi/amdsmi.h | 20 +++-- py-interface/amdsmi_interface.py | 6 +- py-interface/amdsmi_wrapper.py | 56 +++++++----- rocm_smi/include/rocm_smi/rocm_smi.h | 18 +++- rocm_smi/src/rocm_smi.cc | 58 +++++++++++-- .../functional/metrics_counter_read.cc | 86 +++++++++++++++++-- 6 files changed, 196 insertions(+), 48 deletions(-) diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 1fd022bd2c..75afb7289c 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -1093,10 +1093,15 @@ typedef enum { */ typedef enum { AMDSMI_UTILIZATION_COUNTER_FIRST = 0, - //!< GFX Activity + //!< Corse grain activity counters AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = AMDSMI_UTILIZATION_COUNTER_FIRST, AMDSMI_COARSE_GRAIN_MEM_ACTIVITY, //!< Memory Activity - AMDSMI_UTILIZATION_COUNTER_LAST = AMDSMI_COARSE_GRAIN_MEM_ACTIVITY + AMDSMI_COARSE_DECODER_ACTIVITY, //!< Decoder Activity + //!< Fine grain activity counters + AMDSMI_FINE_GRAIN_GFX_ACTIVITY = 100, + AMDSMI_FINE_GRAIN_MEM_ACTIVITY = 101, + AMDSMI_FINE_DECODER_ACTIVITY = 102, + AMDSMI_UTILIZATION_COUNTER_LAST = AMDSMI_FINE_DECODER_ACTIVITY } amdsmi_utilization_counter_type_t; /** @@ -1111,11 +1116,16 @@ typedef enum { /** * @brief The utilization counter data */ +//! The max number of values per counter type +#define AMDSMI_MAX_UTILIZATION_VALUES 4 typedef struct { - amdsmi_utilization_counter_type_t type; //!< Utilization counter type - uint64_t value; //!< Utilization counter value + amdsmi_utilization_counter_type_t type; //!< Utilization counter type + uint64_t value; //!< Coarse grain activity counter value (average) + uint64_t fine_value[AMDSMI_MAX_UTILIZATION_VALUES]; //!< Utilization counter value + uint16_t fine_value_count; } amdsmi_utilization_counter_t; + /** * @brief Reserved Memory Page Record */ @@ -3162,7 +3172,7 @@ amdsmi_status_t amdsmi_set_gpu_clk_range(amdsmi_processor_handle processor_handl * * @platform{gpu_bm_linux} @platform{guest_1vf} * - * @details Given a processor handle @p processor_handle, a clock type @p clk_type, + * @details Given a processor handle @p processor_handle, a clock type @p clk_type, * a value @p clk_value needs to be set, and the @p level indicates min or max * clock you want to set, this function the clock limit. * diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index db00f18226..a7360b66fd 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -386,6 +386,10 @@ class AmdSmiIoLinkType(IntEnum): class AmdSmiUtilizationCounterType(IntEnum): COARSE_GRAIN_GFX_ACTIVITY = amdsmi_wrapper.AMDSMI_COARSE_GRAIN_GFX_ACTIVITY COARSE_GRAIN_MEM_ACTIVITY = amdsmi_wrapper.AMDSMI_COARSE_GRAIN_MEM_ACTIVITY + COARSE_DECODER_ACTIVITY = amdsmi_wrapper.AMDSMI_COARSE_DECODER_ACTIVITY + FINE_GRAIN_GFX_ACTIVITY = amdsmi_wrapper.AMDSMI_FINE_GRAIN_GFX_ACTIVITY + FINE_GRAIN_MEM_ACTIVITY = amdsmi_wrapper.AMDSMI_FINE_GRAIN_MEM_ACTIVITY + FINE_DECODER_ACTIVITY = amdsmi_wrapper.AMDSMI_FINE_DECODER_ACTIVITY UTILIZATION_COUNTER_FIRST = amdsmi_wrapper.AMDSMI_UTILIZATION_COUNTER_FIRST UTILIZATION_COUNTER_LAST = amdsmi_wrapper.AMDSMI_UTILIZATION_COUNTER_LAST @@ -3395,7 +3399,7 @@ def amdsmi_get_utilization_count( if counter_type == "AMDSMI_UTILIZATION_COUNTER_FIRST": counter_type = "AMDSMI_COARSE_GRAIN_GPU_ACTIVITY" if counter_type == "AMDSMI_UTILIZATION_COUNTER_LAST": - counter_type = "AMDSMI_COARSE_GRAIN_MEM_ACTIVITY" + counter_type = "AMDSMI_FINE_DECODER_ACTIVITY" result.append( {"type": counter_type, "value": util_counter_list[index].value}) diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index c7650bb4aa..77138d266a 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -1452,12 +1452,20 @@ amdsmi_utilization_counter_type_t__enumvalues = { 0: 'AMDSMI_UTILIZATION_COUNTER_FIRST', 0: 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', 1: 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', - 1: 'AMDSMI_UTILIZATION_COUNTER_LAST', + 2: 'AMDSMI_COARSE_DECODER_ACTIVITY', + 100: 'AMDSMI_FINE_GRAIN_GFX_ACTIVITY', + 101: 'AMDSMI_FINE_GRAIN_MEM_ACTIVITY', + 102: 'AMDSMI_FINE_DECODER_ACTIVITY', + 102: 'AMDSMI_UTILIZATION_COUNTER_LAST', } AMDSMI_UTILIZATION_COUNTER_FIRST = 0 AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = 0 AMDSMI_COARSE_GRAIN_MEM_ACTIVITY = 1 -AMDSMI_UTILIZATION_COUNTER_LAST = 1 +AMDSMI_COARSE_DECODER_ACTIVITY = 2 +AMDSMI_FINE_GRAIN_GFX_ACTIVITY = 100 +AMDSMI_FINE_GRAIN_MEM_ACTIVITY = 101 +AMDSMI_FINE_DECODER_ACTIVITY = 102 +AMDSMI_UTILIZATION_COUNTER_LAST = 102 amdsmi_utilization_counter_type_t = ctypes.c_uint32 # enum # values for enumeration 'amdsmi_power_type_t' @@ -1478,6 +1486,9 @@ struct_amdsmi_utilization_counter_t._fields_ = [ ('type', amdsmi_utilization_counter_type_t), ('PADDING_0', ctypes.c_ubyte * 4), ('value', ctypes.c_uint64), + ('fine_value', ctypes.c_uint64 * 4), + ('fine_value_count', ctypes.c_uint16), + ('PADDING_1', ctypes.c_ubyte * 6), ] amdsmi_utilization_counter_t = struct_amdsmi_utilization_counter_t @@ -2411,6 +2422,7 @@ __all__ = \ 'AMDSMI_CLK_TYPE_SYS', 'AMDSMI_CLK_TYPE_VCLK0', 'AMDSMI_CLK_TYPE_VCLK1', 'AMDSMI_CLK_TYPE__MAX', 'AMDSMI_CNTR_CMD_START', 'AMDSMI_CNTR_CMD_STOP', + 'AMDSMI_COARSE_DECODER_ACTIVITY', 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', 'AMDSMI_COMPUTE_PARTITION_CPX', 'AMDSMI_COMPUTE_PARTITION_DPX', @@ -2443,25 +2455,27 @@ __all__ = \ 'AMDSMI_EVT_NOTIF_GPU_PRE_RESET', 'AMDSMI_EVT_NOTIF_LAST', 'AMDSMI_EVT_NOTIF_NONE', 'AMDSMI_EVT_NOTIF_RING_HANG', 'AMDSMI_EVT_NOTIF_THERMAL_THROTTLE', 'AMDSMI_EVT_NOTIF_VMFAULT', - 'AMDSMI_FREQ_IND_INVALID', 'AMDSMI_FREQ_IND_MAX', - 'AMDSMI_FREQ_IND_MIN', 'AMDSMI_FW_ID_ASD', 'AMDSMI_FW_ID_CP_CE', - 'AMDSMI_FW_ID_CP_ME', 'AMDSMI_FW_ID_CP_MEC1', - 'AMDSMI_FW_ID_CP_MEC2', 'AMDSMI_FW_ID_CP_MEC_JT1', - 'AMDSMI_FW_ID_CP_MEC_JT2', 'AMDSMI_FW_ID_CP_MES', - 'AMDSMI_FW_ID_CP_PFP', 'AMDSMI_FW_ID_CP_PM4', 'AMDSMI_FW_ID_DFC', - 'AMDSMI_FW_ID_DMCU', 'AMDSMI_FW_ID_DMCU_ERAM', - 'AMDSMI_FW_ID_DMCU_ISR', 'AMDSMI_FW_ID_DRV_CAP', - 'AMDSMI_FW_ID_FIRST', 'AMDSMI_FW_ID_IMU_DRAM', - 'AMDSMI_FW_ID_IMU_IRAM', 'AMDSMI_FW_ID_ISP', 'AMDSMI_FW_ID_MC', - 'AMDSMI_FW_ID_MES_KIQ', 'AMDSMI_FW_ID_MES_STACK', - 'AMDSMI_FW_ID_MES_THREAD1', 'AMDSMI_FW_ID_MES_THREAD1_STACK', - 'AMDSMI_FW_ID_MMSCH', 'AMDSMI_FW_ID_PM', 'AMDSMI_FW_ID_PPTABLE', - 'AMDSMI_FW_ID_PSP_BL', 'AMDSMI_FW_ID_PSP_DBG', - 'AMDSMI_FW_ID_PSP_INTF', 'AMDSMI_FW_ID_PSP_KEYDB', - 'AMDSMI_FW_ID_PSP_SOC', 'AMDSMI_FW_ID_PSP_SOSDRV', - 'AMDSMI_FW_ID_PSP_SPL', 'AMDSMI_FW_ID_PSP_SYSDRV', - 'AMDSMI_FW_ID_PSP_TOC', 'AMDSMI_FW_ID_REG_ACCESS_WHITELIST', - 'AMDSMI_FW_ID_RLC', 'AMDSMI_FW_ID_RLCV_LX7', 'AMDSMI_FW_ID_RLC_P', + 'AMDSMI_FINE_DECODER_ACTIVITY', 'AMDSMI_FINE_GRAIN_GFX_ACTIVITY', + 'AMDSMI_FINE_GRAIN_MEM_ACTIVITY', 'AMDSMI_FREQ_IND_INVALID', + 'AMDSMI_FREQ_IND_MAX', 'AMDSMI_FREQ_IND_MIN', 'AMDSMI_FW_ID_ASD', + 'AMDSMI_FW_ID_CP_CE', 'AMDSMI_FW_ID_CP_ME', + 'AMDSMI_FW_ID_CP_MEC1', 'AMDSMI_FW_ID_CP_MEC2', + 'AMDSMI_FW_ID_CP_MEC_JT1', 'AMDSMI_FW_ID_CP_MEC_JT2', + 'AMDSMI_FW_ID_CP_MES', 'AMDSMI_FW_ID_CP_PFP', + 'AMDSMI_FW_ID_CP_PM4', 'AMDSMI_FW_ID_DFC', 'AMDSMI_FW_ID_DMCU', + 'AMDSMI_FW_ID_DMCU_ERAM', 'AMDSMI_FW_ID_DMCU_ISR', + 'AMDSMI_FW_ID_DRV_CAP', 'AMDSMI_FW_ID_FIRST', + 'AMDSMI_FW_ID_IMU_DRAM', 'AMDSMI_FW_ID_IMU_IRAM', + 'AMDSMI_FW_ID_ISP', 'AMDSMI_FW_ID_MC', 'AMDSMI_FW_ID_MES_KIQ', + 'AMDSMI_FW_ID_MES_STACK', 'AMDSMI_FW_ID_MES_THREAD1', + 'AMDSMI_FW_ID_MES_THREAD1_STACK', 'AMDSMI_FW_ID_MMSCH', + 'AMDSMI_FW_ID_PM', 'AMDSMI_FW_ID_PPTABLE', 'AMDSMI_FW_ID_PSP_BL', + 'AMDSMI_FW_ID_PSP_DBG', 'AMDSMI_FW_ID_PSP_INTF', + 'AMDSMI_FW_ID_PSP_KEYDB', 'AMDSMI_FW_ID_PSP_SOC', + 'AMDSMI_FW_ID_PSP_SOSDRV', 'AMDSMI_FW_ID_PSP_SPL', + 'AMDSMI_FW_ID_PSP_SYSDRV', 'AMDSMI_FW_ID_PSP_TOC', + 'AMDSMI_FW_ID_REG_ACCESS_WHITELIST', 'AMDSMI_FW_ID_RLC', + 'AMDSMI_FW_ID_RLCV_LX7', 'AMDSMI_FW_ID_RLC_P', 'AMDSMI_FW_ID_RLC_RESTORE_LIST_CNTL', 'AMDSMI_FW_ID_RLC_RESTORE_LIST_GPM_MEM', 'AMDSMI_FW_ID_RLC_RESTORE_LIST_SRM_MEM', diff --git a/rocm_smi/include/rocm_smi/rocm_smi.h b/rocm_smi/include/rocm_smi/rocm_smi.h index e53527b1ce..a9dcaa18ce 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/rocm_smi/include/rocm_smi/rocm_smi.h @@ -765,10 +765,15 @@ typedef enum _RSMI_IO_LINK_TYPE { */ typedef enum { RSMI_UTILIZATION_COUNTER_FIRST = 0, - //!< GFX Activity + //!< Corse grain activity counters RSMI_COARSE_GRAIN_GFX_ACTIVITY = RSMI_UTILIZATION_COUNTER_FIRST, RSMI_COARSE_GRAIN_MEM_ACTIVITY, //!< Memory Activity - RSMI_UTILIZATION_COUNTER_LAST = RSMI_COARSE_GRAIN_MEM_ACTIVITY + RSMI_COARSE_DECODER_ACTIVITY, //!< Decoder Activity + //!< Fine grain activity counters + RSMI_FINE_GRAIN_GFX_ACTIVITY = 100, + RSMI_FINE_GRAIN_MEM_ACTIVITY = 101, + RSMI_FINE_DECODER_ACTIVITY = 102, + RSMI_UTILIZATION_COUNTER_LAST = RSMI_FINE_DECODER_ACTIVITY } RSMI_UTILIZATION_COUNTER_TYPE; /** @@ -783,11 +788,16 @@ typedef enum { /** * @brief The utilization counter data */ +//! The max number of values per counter type +#define RSMI_MAX_UTILIZATION_VALUES 4 typedef struct { - RSMI_UTILIZATION_COUNTER_TYPE type; //!< Utilization counter type - uint64_t value; //!< Utilization counter value + RSMI_UTILIZATION_COUNTER_TYPE type; //!< Utilization counter type + uint64_t value; //!< Coarse grain activity counter value (average) + uint64_t fine_value[RSMI_MAX_UTILIZATION_VALUES]; //!< Utilization counter value (individual values) + uint16_t fine_value_count; } rsmi_utilization_counter_t; + /** * @brief Reserved Memory Page Record */ diff --git a/rocm_smi/src/rocm_smi.cc b/rocm_smi/src/rocm_smi.cc index c38d97480a..1526e5832c 100755 --- a/rocm_smi/src/rocm_smi.cc +++ b/rocm_smi/src/rocm_smi.cc @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -2087,7 +2088,7 @@ rsmi_status_t rsmi_dev_process_isolation_get(uint32_t dv_ind, } /* - for 4 partition: enforce isolation is enabled on partition 2 and + for 4 partition: enforce isolation is enabled on partition 2 and disabled on partitions 0, 1, 3. $ cat /sys/class/drm/cardX/device/enforce_isolation 0 0 1 0 @@ -4209,6 +4210,7 @@ rsmi_utilization_count_get(uint32_t dv_ind, rsmi_status_t ret; rsmi_gpu_metrics_t gpu_metrics; uint32_t val_ui32; + uint16_t val_counter(0); ret = rsmi_dev_gpu_metrics_info_get(dv_ind, &gpu_metrics); if (ret != RSMI_STATUS_SUCCESS) { @@ -4217,21 +4219,61 @@ rsmi_utilization_count_get(uint32_t dv_ind, for (uint32_t index = 0 ; index < count; index++) { switch (utilization_counters[index].type) { + case RSMI_COARSE_GRAIN_GFX_ACTIVITY: - val_ui32 = gpu_metrics.gfx_activity_acc; + case RSMI_FINE_GRAIN_GFX_ACTIVITY: + val_counter = 1; + utilization_counters[index].value = gpu_metrics.gfx_activity_acc; + utilization_counters[index].fine_value[0] = + (gpu_metrics.gfx_activity_acc != std::numeric_limits::max()) + ? gpu_metrics.gfx_activity_acc : std::numeric_limits::max(); + utilization_counters[index].fine_value_count = + (gpu_metrics.gfx_activity_acc == std::numeric_limits::max()) + ? 0 : val_counter; break; + case RSMI_COARSE_GRAIN_MEM_ACTIVITY: - val_ui32 = gpu_metrics.mem_activity_acc; + case RSMI_FINE_GRAIN_MEM_ACTIVITY: + val_counter = 1; + utilization_counters[index].value = gpu_metrics.mem_activity_acc; + utilization_counters[index].fine_value[0] = + (gpu_metrics.mem_activity_acc != std::numeric_limits::max()) + ? gpu_metrics.mem_activity_acc : std::numeric_limits::max(); + utilization_counters[index].fine_value_count = + (gpu_metrics.mem_activity_acc == std::numeric_limits::max()) + ? 0 : val_counter; break; + + case RSMI_COARSE_DECODER_ACTIVITY: + case RSMI_FINE_DECODER_ACTIVITY: + { + auto value_count = uint16_t(0); + auto value_accum = uint64_t(0); + for (const auto& elem : gpu_metrics.vcn_activity) { + if (elem != std::numeric_limits::max()) { + ++value_count; + value_accum += elem; + } + + if (utilization_counters[index].type == RSMI_UTILIZATION_COUNTER_TYPE::RSMI_FINE_DECODER_ACTIVITY) { + utilization_counters[index].fine_value[value_count] = elem; + } + } + + utilization_counters[index].value = 0; + utilization_counters[index].fine_value_count = value_count; + if (utilization_counters[index].type == RSMI_UTILIZATION_COUNTER_TYPE::RSMI_COARSE_DECODER_ACTIVITY) { + if (value_count > 0) { + utilization_counters[index].value = (value_accum / value_count); + } + } + } + break; + default: return RSMI_STATUS_INVALID_ARGS; } - if (val_ui32 == UINT32_MAX) { - return RSMI_STATUS_NOT_SUPPORTED; - } - utilization_counters[index].value = val_ui32; } - *timestamp = gpu_metrics.system_clock_counter; return ret; diff --git a/tests/amd_smi_test/functional/metrics_counter_read.cc b/tests/amd_smi_test/functional/metrics_counter_read.cc index 28225637d5..868f046dfb 100644 --- a/tests/amd_smi_test/functional/metrics_counter_read.cc +++ b/tests/amd_smi_test/functional/metrics_counter_read.cc @@ -49,6 +49,7 @@ #include #include #include +#include #include #include "amd_smi/amdsmi.h" @@ -132,28 +133,95 @@ void TestMetricsCounterRead::Run(void) { ASSERT_EQ(err, AMDSMI_STATUS_INVAL); // Coarse Grain counters - amdsmi_utilization_counter_t utilization_counters[2]; + constexpr uint32_t kUTILIZATION_COUNTERS(3); + amdsmi_utilization_counter_t utilization_counters[kUTILIZATION_COUNTERS]; utilization_counters[0].type = AMDSMI_COARSE_GRAIN_GFX_ACTIVITY; utilization_counters[1].type = AMDSMI_COARSE_GRAIN_MEM_ACTIVITY; + utilization_counters[2].type = AMDSMI_COARSE_DECODER_ACTIVITY; + err = amdsmi_get_utilization_count(processor_handles_[i], utilization_counters, - 2, ×tamp); + kUTILIZATION_COUNTERS, ×tamp); if (err != AMDSMI_STATUS_SUCCESS) { if (err == AMDSMI_STATUS_NOT_SUPPORTED) { IF_VERB(STANDARD) { std::cout << "\t**" << - "Not supported on this machine" << std::endl; + "amdsmi_get_utilization_count(): Not supported on this machine" << std::endl; return; } } } else { CHK_ERR_ASRT(err); IF_VERB(STANDARD) { - std::cout << std::dec << "gfx_activity=" - << utilization_counters[0].value << '\n'; - std::cout << std::dec << "mem_activity=" - << utilization_counters[1].value << '\n'; - std::cout << std::dec << "timestamp=" - << timestamp << '\n'; + std::cout << "\n\namdsmi_get_utilization_count() : COARSE GRAIN ACTIVITIES" << "\n"; + for (auto idx = uint32_t(0); idx < kUTILIZATION_COUNTERS; ++idx) { + switch (utilization_counters[idx].type) { + case AMDSMI_COARSE_GRAIN_GFX_ACTIVITY: + std::cout << "-> gfx_activity: [" << utilization_counters[idx].fine_value_count << "]" << "\n"; + break; + + case AMDSMI_COARSE_GRAIN_MEM_ACTIVITY: + std::cout << "-> mem_activity: [" << utilization_counters[idx].fine_value_count << "]" << "\n";; + break; + + case AMDSMI_COARSE_DECODER_ACTIVITY: + std::cout << "-> decoder_activity: [" << utilization_counters[idx].fine_value_count << "]" << "\n"; + break; + + default: + break; + } + + for (auto val_idx = uint16_t(0); val_idx < utilization_counters[idx].fine_value_count; ++val_idx) { + std::cout << "\t" << std::dec << utilization_counters[idx].value << "\n"; + } + } + + std::cout << std::dec << "timestamp=" << timestamp << '\n'; + } + } + + // Fine Grain counters + utilization_counters[0].type = AMDSMI_FINE_GRAIN_GFX_ACTIVITY; + utilization_counters[1].type = AMDSMI_FINE_GRAIN_MEM_ACTIVITY; + utilization_counters[2].type = AMDSMI_FINE_DECODER_ACTIVITY; + err = amdsmi_get_utilization_count(processor_handles_[i], utilization_counters, + kUTILIZATION_COUNTERS, ×tamp); + if (err != AMDSMI_STATUS_SUCCESS) { + if (err == AMDSMI_STATUS_NOT_SUPPORTED) { + IF_VERB(STANDARD) { + std::cout << "\t**" << + "amdsmi_get_utilization_count(): Not supported on this machine" << std::endl; + return; + } + } + } else { + CHK_ERR_ASRT(err); + IF_VERB(STANDARD) { + std::cout << "\n\namdsmi_get_utilization_count() : FINE GRAIN ACTIVITIES" << "\n"; + for (auto idx = uint32_t(0); idx < kUTILIZATION_COUNTERS; ++idx) { + switch (utilization_counters[idx].type) { + case AMDSMI_FINE_GRAIN_GFX_ACTIVITY: + std::cout << "-> gfx_activity: [" << utilization_counters[idx].fine_value_count << "]" << "\n"; + break; + + case AMDSMI_FINE_GRAIN_MEM_ACTIVITY: + std::cout << "-> mem_activity: [" << utilization_counters[idx].fine_value_count << "]" << "\n";; + break; + + case AMDSMI_FINE_DECODER_ACTIVITY: + std::cout << "-> decoder_activity: [" << utilization_counters[idx].fine_value_count << "]" << "\n"; + break; + + default: + break; + } + + for (auto val_idx = uint16_t(0); val_idx < utilization_counters[idx].fine_value_count; ++val_idx) { + std::cout << "\t" << std::dec << utilization_counters[idx].fine_value[val_idx] << "\n"; + } + } + + std::cout << std::dec << "timestamp=" << timestamp << '\n'; } } From 893f13ab988c7907365f7f1f165c3d4e99b56f96 Mon Sep 17 00:00:00 2001 From: "Oliveira, Daniel" Date: Mon, 5 Aug 2024 17:15:42 -0500 Subject: [PATCH 2/3] SWDEV-463399: amdsmi_get_gpu_vram_info() adds bit-width Driver info `amdgpu_gpu_info.vram_bit_width` is exposed through amdsmi_get_gpu_vram_info(). Code changes related to the following: * API * CLI * Unit tests * Examples Change-Id: I8abd8db7a603078b2b1c008b2685cecf35caf3d2 Signed-off-by: Oliveira, Daniel --- amdsmi_cli/amdsmi_commands.py | 6 +++++- example/amd_smi_drm_example.cc | 14 ++++++++++++++ include/amd_smi/amdsmi.h | 3 ++- py-interface/amdsmi_interface.py | 1 + py-interface/amdsmi_wrapper.py | 4 +++- src/amd_smi/amd_smi.cc | 3 +++ tests/amd_smi_test/functional/id_info_read.cc | 10 ++++++++-- 7 files changed, 36 insertions(+), 5 deletions(-) diff --git a/amdsmi_cli/amdsmi_commands.py b/amdsmi_cli/amdsmi_commands.py index 80dbeac7f1..63e4298f9b 100644 --- a/amdsmi_cli/amdsmi_commands.py +++ b/amdsmi_cli/amdsmi_commands.py @@ -693,7 +693,8 @@ class AMDSMICommands(): if args.vram: vram_info_dict = {"type" : "N/A", "vendor" : "N/A", - "size" : "N/A"} + "size" : "N/A", + "bit_width" : "N/A"} try: vram_info = amdsmi_interface.amdsmi_get_gpu_vram_info(args.gpu) @@ -729,6 +730,9 @@ class AMDSMICommands(): vram_info_dict['size'] = {"value" : vram_info['vram_size'], "unit" : vram_size_unit} + # Populate bit width + vram_info_dict['bit_width'] = vram_info['vram_bit_width'] + except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get vram info for gpu %s | %s", gpu_id, e.get_error_info()) diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index 94179c47bc..9f3de13957 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -303,6 +303,20 @@ int main() { printf("\tRevisionID: 0x%x\n", asic_info.rev_id); printf("\tAsic serial: 0x%s\n\n", asic_info.asic_serial); + // Get VRAM info + amdsmi_vram_info_t vram_info = {}; + ret = amdsmi_get_gpu_vram_info(processor_handles[j], &vram_info); + if (ret != amdsmi_status_t::AMDSMI_STATUS_NOT_SUPPORTED) { + CHK_AMDSMI_RET(ret) + printf(" Output of amdsmi_get_gpu_vram_info:\n"); + printf("\tVRAM Size: 0x%lx (%ld) \n", vram_info.vram_size, vram_info.vram_size); + printf("\tBIT Width: 0x%x (%d) \n\n", vram_info.vram_bit_width, vram_info.vram_bit_width); + } + else { + printf("\t**amdsmi_get_gpu_vram_info() not supported on this system.\n"); + } + + // Get VBIOS info amdsmi_vbios_info_t vbios_info = {}; ret = amdsmi_get_gpu_vbios_info(processor_handles[j], &vbios_info); diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 75afb7289c..f49636e675 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -616,7 +616,8 @@ typedef struct { amdsmi_vram_type_t vram_type; amdsmi_vram_vendor_type_t vram_vendor; uint64_t vram_size; - uint64_t reserved[6]; + uint32_t vram_bit_width; + uint64_t reserved[5]; } amdsmi_vram_info_t; diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index a7360b66fd..7ddb94d2ee 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -1770,6 +1770,7 @@ def amdsmi_get_gpu_vram_info( "vram_type": vram_info.vram_type, "vram_vendor": vram_info.vram_vendor, "vram_size": vram_info.vram_size, + "vram_bit_width": vram_info.vram_bit_width } diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index 77138d266a..1c7a4377d4 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -953,7 +953,9 @@ struct_amdsmi_vram_info_t._fields_ = [ ('vram_type', amdsmi_vram_type_t), ('vram_vendor', amdsmi_vram_vendor_type_t), ('vram_size', ctypes.c_uint64), - ('reserved', ctypes.c_uint64 * 6), + ('vram_bit_width', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ('reserved', ctypes.c_uint64 * 5), ] amdsmi_vram_info_t = struct_amdsmi_vram_info_t diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 8e0905b5b2..9f4d3aa74a 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "amd_smi/amdsmi.h" #include "amd_smi/impl/fdinfo.h" @@ -799,6 +800,7 @@ amdsmi_status_t amdsmi_get_gpu_vram_info( info->vram_type = AMDSMI_VRAM_TYPE_UNKNOWN; info->vram_size = 0; info->vram_vendor = AMDSMI_VRAM_VENDOR__PLACEHOLDER0; + info->vram_bit_width = std::numeric_limitsvram_bit_width)>::max(); // Only can read vram type from libdrm if (gpu_device->check_if_drm_is_supported()) { @@ -808,6 +810,7 @@ amdsmi_status_t amdsmi_get_gpu_vram_info( sizeof(struct drm_amdgpu_info_device), &dev_info); if (r == AMDSMI_STATUS_SUCCESS) { info->vram_type = amd::smi::vram_type_value(dev_info.vram_type); + info->vram_bit_width = dev_info.vram_bit_width; } } diff --git a/tests/amd_smi_test/functional/id_info_read.cc b/tests/amd_smi_test/functional/id_info_read.cc index d6e208fbdd..322da175c3 100755 --- a/tests/amd_smi_test/functional/id_info_read.cc +++ b/tests/amd_smi_test/functional/id_info_read.cc @@ -154,8 +154,14 @@ void TestIdInfoRead::Run(void) { << vram_info.vram_type << std::endl; std::cout << "\t**Device Vram vendor id: " << vram_info.vram_vendor << std::endl; - std::cout << "\t**Device Vram size: " - << vram_info.vram_size << std::endl; + std::cout << "\t**Device Vram size: 0x" + << std::hex << vram_info.vram_size + << " (" << std::dec << vram_info.vram_size << ")" + << std::endl; + std::cout << "\t**Device Bit Width: 0x" + << std::hex << vram_info.vram_bit_width + << " (" << std::dec << vram_info.vram_bit_width << ")" + << std::endl; } err = amdsmi_get_gpu_vendor_name(processor_handles_[i], buffer, kBufferLen); From b05849dad0f2de1761ff78049aac81b15df7c2c9 Mon Sep 17 00:00:00 2001 From: "Oliveira, Daniel" Date: Mon, 5 Aug 2024 20:49:53 -0500 Subject: [PATCH 3/3] SWDEV-463401: amdsmi_get_gpu_asic_info() adds num_of_compute_units number of compute units `amdgpu_gpu_info.num_of_compute_units` is exposed through amdsmi_get_gpu_asic_info(). Code changes related to the following: * API * CLI * Unit tests * Examples Change-Id: Ibeb612d079ed87437a0e56124b8504098fc2dcfd Signed-off-by: Oliveira, Daniel --- example/amd_smi_drm_example.cc | 3 ++- example/amd_smi_nodrm_example.cc | 3 ++- include/amd_smi/amdsmi.h | 3 ++- py-interface/amdsmi_interface.py | 7 +++++- py-interface/amdsmi_wrapper.py | 3 ++- rocm_smi/include/rocm_smi/rocm_smi_kfd.h | 4 ++++ rocm_smi/include/rocm_smi/rocm_smi_utils.h | 4 ++-- rocm_smi/src/rocm_smi_kfd.cc | 27 ++++++++++++++++++++++ rocm_smi/src/rocm_smi_utils.cc | 20 ++++++++++++++++ src/amd_smi/amd_smi.cc | 9 ++++++++ src/amd_smi/amd_smi_utils.cc | 1 + 11 files changed, 77 insertions(+), 7 deletions(-) diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index 9f3de13957..e8ef3d80d9 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -301,7 +301,8 @@ int main() { printf("\tDeviceID: 0x%lx\n", asic_info.device_id); printf("\tVendorID: 0x%x\n", asic_info.vendor_id); printf("\tRevisionID: 0x%x\n", asic_info.rev_id); - printf("\tAsic serial: 0x%s\n\n", asic_info.asic_serial); + printf("\tAsic serial: 0x%s\n", asic_info.asic_serial); + printf("\tNum of Computes: %d\n\n", asic_info.num_of_compute_units); // Get VRAM info amdsmi_vram_info_t vram_info = {}; diff --git a/example/amd_smi_nodrm_example.cc b/example/amd_smi_nodrm_example.cc index 37f5b9645b..19e8cf5947 100644 --- a/example/amd_smi_nodrm_example.cc +++ b/example/amd_smi_nodrm_example.cc @@ -151,7 +151,8 @@ int main() { printf("\tVendorID: 0x%x\n", asic_info.vendor_id); printf("\tRevisionID: 0x%x\n", asic_info.rev_id); printf("\tAsic serial: 0x%s\n", asic_info.asic_serial); - printf("\tOAM id: 0x%x\n\n", asic_info.oam_id); + printf("\tOAM id: 0x%x\n", asic_info.oam_id); + printf("\tNum of Computes: %d\n\n", asic_info.num_of_compute_units); // Get VBIOS info amdsmi_vbios_info_t vbios_info = {}; diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index f49636e675..8be2c18b36 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -588,7 +588,8 @@ typedef struct { uint32_t rev_id; char asic_serial[AMDSMI_NORMAL_STRING_LENGTH]; uint32_t oam_id; //< 0xFFFF if not supported - uint32_t reserved[18]; + uint32_t num_of_compute_units; //< 0xFFFFFFFF if not supported + uint32_t reserved[17]; } amdsmi_asic_info_t; typedef enum { diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 7ddb94d2ee..664b7d2b3e 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -1643,7 +1643,8 @@ def amdsmi_get_gpu_asic_info( "device_id": asic_info_struct.device_id, "rev_id": _padHexValue(hex(asic_info_struct.rev_id), 2), "asic_serial": asic_info_struct.asic_serial.decode("utf-8"), - "oam_id": asic_info_struct.oam_id + "oam_id": asic_info_struct.oam_id, + "num_compute_units": asic_info_struct.num_of_compute_units } string_values = ["market_name", "vendor_name"] @@ -1670,6 +1671,10 @@ def amdsmi_get_gpu_asic_info( if asic_info["oam_id"] == 0xFFFF: # uint 16 max asic_info["oam_id"] = "N/A" + # Check for max value as a sign for not applicable + if asic_info["num_compute_units"] == 0xFFFFFFFF: # uint 32 max + asic_info["num_compute_units"] = "N/A" + # Remove commas from vendor name for clean output asic_info["vendor_name"] = asic_info["vendor_name"].replace(',', '') diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index 1c7a4377d4..57fc962a0a 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -901,7 +901,8 @@ struct_amdsmi_asic_info_t._fields_ = [ ('rev_id', ctypes.c_uint32), ('asic_serial', ctypes.c_char * 32), ('oam_id', ctypes.c_uint32), - ('reserved', ctypes.c_uint32 * 18), + ('num_of_compute_units', ctypes.c_uint32), + ('reserved', ctypes.c_uint32 * 17), ] amdsmi_asic_info_t = struct_amdsmi_asic_info_t diff --git a/rocm_smi/include/rocm_smi/rocm_smi_kfd.h b/rocm_smi/include/rocm_smi/rocm_smi_kfd.h index 1173f48109..81a76400ce 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_kfd.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_kfd.h @@ -90,6 +90,10 @@ class KFDNode { // Get gfx target version from kfd int get_gfx_target_version(uint64_t* gfx_target_version); + // Get simd_per_cu from kfd + int32_t get_simd_per_cu(uint64_t* simd_per_cu) const; + int32_t get_simd_count(uint64_t* simd_count) const; + private: uint32_t node_indx_; uint32_t amdgpu_dev_index_; diff --git a/rocm_smi/include/rocm_smi/rocm_smi_utils.h b/rocm_smi/include/rocm_smi/rocm_smi_utils.h index eb53dfbba3..36261d89e6 100755 --- a/rocm_smi/include/rocm_smi/rocm_smi_utils.h +++ b/rocm_smi/include/rocm_smi/rocm_smi_utils.h @@ -126,8 +126,8 @@ std::string print_rsmi_od_volt_freq_data_t(rsmi_od_volt_freq_data_t *odv); std::string print_rsmi_od_volt_freq_regions(uint32_t num_regions, rsmi_freq_volt_region_t *regions); bool is_sudo_user(); -rsmi_status_t rsmi_get_gfx_target_version(uint32_t dv_ind, - std::string *gfx_version); +rsmi_status_t rsmi_get_gfx_target_version(uint32_t dv_ind, std::string *gfx_version); +rsmi_status_t rsmi_dev_number_of_computes_get(uint32_t dv_ind, uint32_t* num_computes); std::string leftTrim(const std::string &s); std::string rightTrim(const std::string &s); diff --git a/rocm_smi/src/rocm_smi_kfd.cc b/rocm_smi/src/rocm_smi_kfd.cc index 13d2c27be0..b319a1fcd4 100755 --- a/rocm_smi/src/rocm_smi_kfd.cc +++ b/rocm_smi/src/rocm_smi_kfd.cc @@ -1077,5 +1077,32 @@ int KFDNode::get_gfx_target_version(uint64_t *gfx_target_version) { return ret; } +int32_t KFDNode::get_simd_per_cu(uint64_t* simd_per_cu) const +{ + const std::string properties_path("/sys/class/kfd/kfd/topology/nodes/" + + std::to_string(this->node_indx_) + + "/properties"); + + auto tmp_simd_per_cu = uint64_t(0); + auto ret = read_node_properties(this->node_indx_, "simd_per_cu", + &tmp_simd_per_cu); + *simd_per_cu = tmp_simd_per_cu; + return ret; +} + +int32_t KFDNode::get_simd_count(uint64_t* simd_count) const +{ + const std::string properties_path("/sys/class/kfd/kfd/topology/nodes/" + + std::to_string(this->node_indx_) + + "/properties"); + + auto tmp_simd_count = uint64_t(0); + auto ret = read_node_properties(this->node_indx_, "simd_count", + &tmp_simd_count); + *simd_count = tmp_simd_count; + return ret; +} + + } // namespace smi } // namespace amd diff --git a/rocm_smi/src/rocm_smi_utils.cc b/rocm_smi/src/rocm_smi_utils.cc index 122584f9bd..32f0209654 100755 --- a/rocm_smi/src/rocm_smi_utils.cc +++ b/rocm_smi/src/rocm_smi_utils.cc @@ -65,6 +65,7 @@ #include #include "rocm_smi/rocm_smi.h" +#include "rocm_smi/rocm_smi_kfd.h" #include "rocm_smi/rocm_smi_utils.h" #include "rocm_smi/rocm_smi_exception.h" #include "rocm_smi/rocm_smi_main.h" @@ -1198,6 +1199,25 @@ rsmi_status_t rsmi_get_gfx_target_version(uint32_t dv_ind, } } +rsmi_status_t rsmi_dev_number_of_computes_get(uint32_t dv_ind, uint32_t* num_computes) +{ + GET_DEV_AND_KFDNODE_FROM_INDX + + auto tmp_simd_per_cu = uint64_t(0); + auto tmp_simd_count = uint64_t(0); + auto ret_simd_per_cu = kfd_node->get_simd_per_cu(&tmp_simd_per_cu); + auto ret_simd_count = kfd_node->get_simd_count(&tmp_simd_count); + + if (((ret_simd_per_cu != 0) || (ret_simd_count != 0)) || + ((tmp_simd_per_cu == 0) || (tmp_simd_count == 0))) { + return rsmi_status_t::RSMI_STATUS_NOT_SUPPORTED; + } + + *num_computes = (tmp_simd_count / tmp_simd_per_cu); + return rsmi_status_t::RSMI_STATUS_SUCCESS; +} + + std::queue getAllDeviceGfxVers() { uint32_t num_monitor_devs = 0; rsmi_status_t ret; diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 9f4d3aa74a..be0adfd876 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -757,6 +757,15 @@ amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_i &(tmp_oam_id)); info->oam_id = tmp_oam_id; + // default to 0xffffffff as not supported + info->num_of_compute_units = std::numeric_limits::max(); + auto tmp_num_of_compute_units = uint32_t(0); + status = rsmi_wrapper(amd::smi::rsmi_dev_number_of_computes_get, processor_handle, + &tmp_num_of_compute_units); + if (status == amdsmi_status_t::AMDSMI_STATUS_SUCCESS) { + info->num_of_compute_units = tmp_num_of_compute_units; + } + return AMDSMI_STATUS_SUCCESS; } diff --git a/src/amd_smi/amd_smi_utils.cc b/src/amd_smi/amd_smi_utils.cc index fa8a6e1e4e..7c64fb4ba4 100644 --- a/src/amd_smi/amd_smi_utils.cc +++ b/src/amd_smi/amd_smi_utils.cc @@ -615,3 +615,4 @@ amdsmi_status_t smi_amdgpu_is_gpu_power_management_enabled(amd::smi::AMDSmiGPUDe *enabled = false; return AMDSMI_STATUS_SUCCESS; } +