From b52034fed8fb890792088e027dd75ea35666bd9b Mon Sep 17 00:00:00 2001 From: "Bill(Shuzhou) Liu" Date: Thu, 31 Aug 2023 09:08:46 -0500 Subject: [PATCH] Add API for the memory type Get the memory type from libdrm and add a new API. Change-Id: I89327bca2ef860f2e3f4f6ca20def2331eba66c0 --- example/amd_smi_drm_example.cc | 2 +- example/amd_smi_nodrm_example.cc | 2 +- include/amd_smi/amdsmi.h | 59 ++++++++++++++++- py-interface/amdsmi_interface.py | 2 +- py-interface/amdsmi_wrapper.py | 14 ++-- src/amd_smi/amd_smi.cc | 66 ++++++++++++++++++- tests/amd_smi_test/functional/id_info_read.cc | 13 ++++ 7 files changed, 145 insertions(+), 13 deletions(-) diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index 3696c4a1df..6083324519 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -619,7 +619,7 @@ int main() { << "\n\n"; // Get frame buffer - amdsmi_vram_info_t vram_usage = {}; + amdsmi_vram_usage_t vram_usage = {}; ret = amdsmi_get_gpu_vram_usage(processor_handles[j], &vram_usage); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_gpu_vram_usage:\n"); diff --git a/example/amd_smi_nodrm_example.cc b/example/amd_smi_nodrm_example.cc index 0e159f1658..afa66edfd7 100644 --- a/example/amd_smi_nodrm_example.cc +++ b/example/amd_smi_nodrm_example.cc @@ -308,7 +308,7 @@ int main() { << "\n\n"; // Get frame buffer - amdsmi_vram_info_t vram_usage = {}; + amdsmi_vram_usage_t vram_usage = {}; ret = amdsmi_get_gpu_vram_usage(processor_handles[j], &vram_usage); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_gpu_vram_usage:\n"); diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index c1ae90cdae..0b6723f8f8 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -322,6 +322,40 @@ typedef enum { FW_ID__MAX } amdsmi_fw_block_t; + +typedef enum { + VRAM_TYPE_UNKNOWN = 0, + VRAM_TYPE_GDDR1 = 1, + VRAM_TYPE_DDR2 = 2, + VRAM_TYPE_GDDR3 = 3, + VRAM_TYPE_GDDR4 = 4, + VRAM_TYPE_GDDR5 = 5, + VRAM_TYPE_HBM = 6, + VRAM_TYPE_DDR3 = 7, + VRAM_TYPE_DDR4 = 8, + VRAM_TYPE_GDDR6 = 9, + VRAM_TYPE__MAX = VRAM_TYPE_GDDR6 +} amdsmi_vram_type_t; + +typedef enum { + AMDSMI_VRAM_VENDOR__PLACEHOLDER0, + AMDSMI_VRAM_VENDOR__SAMSUNG, + AMDSMI_VRAM_VENDOR__INFINEON, + AMDSMI_VRAM_VENDOR__ELPIDA, + AMDSMI_VRAM_VENDOR__ETRON, + AMDSMI_VRAM_VENDOR__NANYA, + AMDSMI_VRAM_VENDOR__HYNIX, + AMDSMI_VRAM_VENDOR__MOSEL, + AMDSMI_VRAM_VENDOR__WINBOND, + AMDSMI_VRAM_VENDOR__ESMT, + AMDSMI_VRAM_VENDOR__PLACEHOLDER1, + AMDSMI_VRAM_VENDOR__PLACEHOLDER2, + AMDSMI_VRAM_VENDOR__PLACEHOLDER3, + AMDSMI_VRAM_VENDOR__PLACEHOLDER4, + AMDSMI_VRAM_VENDOR__PLACEHOLDER5, + AMDSMI_VRAM_VENDOR__MICRON, +} amdsmi_vram_vendor_type_t; + /** * @brief This structure represents a range (e.g., frequencies or voltages). */ @@ -343,7 +377,7 @@ typedef struct { uint32_t vram_total; uint32_t vram_used; uint32_t reserved[2]; -} amdsmi_vram_info_t; +} amdsmi_vram_usage_t; typedef struct { amdsmi_range_t supported_freq_range; @@ -399,6 +433,13 @@ typedef struct { uint32_t reserved[19]; } amdsmi_asic_info_t; +typedef struct{ + amdsmi_vram_type_t vram_type; + amdsmi_vram_vendor_type_t vram_vendor; + uint64_t vram_size_mb; +} amdsmi_vram_info_t; + + typedef struct { char driver_version[AMDSMI_MAX_STRING_LENGTH]; char driver_date[AMDSMI_MAX_STRING_LENGTH]; @@ -3425,6 +3466,19 @@ amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_handle, amdsmi_driv amdsmi_status_t amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_info_t *info); +/** + * @brief Returns vram info + * + * @param[in] processor_handle PF of a processor for which to query + * + * @param[out] info Reference to vram info structure + * Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_gpu_vram_info( + amdsmi_processor_handle processor_handle, amdsmi_vram_info_t *info); + /** * @brief Returns the board part number and board information for the requested device * @@ -3566,7 +3620,8 @@ amdsmi_get_clock_info(amdsmi_processor_handle processor_handle, amdsmi_clk_type_ * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_gpu_vram_usage(amdsmi_processor_handle processor_handle, amdsmi_vram_info_t *info); +amdsmi_get_gpu_vram_usage(amdsmi_processor_handle processor_handle, amdsmi_vram_usage_t *info); + /** @} End gpumon */ diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index bc83181d2a..c0e10a3404 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -995,7 +995,7 @@ def amdsmi_get_gpu_vram_usage( processor_handle, amdsmi_wrapper.amdsmi_processor_handle ) - vram_info = amdsmi_wrapper.amdsmi_vram_info_t() + vram_info = amdsmi_wrapper.amdsmi_vram_usage_t() _check_res( amdsmi_wrapper.amdsmi_get_gpu_vram_usage( processor_handle, ctypes.byref(vram_info)) diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index eeded45f6b..d2f9eefa92 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -578,17 +578,17 @@ struct_amdsmi_xgmi_info_t._fields_ = [ ] amdsmi_xgmi_info_t = struct_amdsmi_xgmi_info_t -class struct_amdsmi_vram_info_t(Structure): +class struct_amdsmi_vram_usage_t(Structure): pass -struct_amdsmi_vram_info_t._pack_ = 1 # source:False -struct_amdsmi_vram_info_t._fields_ = [ +struct_amdsmi_vram_usage_t._pack_ = 1 # source:False +struct_amdsmi_vram_usage_t._fields_ = [ ('vram_total', ctypes.c_uint32), ('vram_used', ctypes.c_uint32), ('reserved', ctypes.c_uint32 * 2), ] -amdsmi_vram_info_t = struct_amdsmi_vram_info_t +amdsmi_vram_usage_t = struct_amdsmi_vram_usage_t class struct_amdsmi_frequency_range_t(Structure): pass @@ -1637,7 +1637,7 @@ amdsmi_get_clock_info.restype = amdsmi_status_t amdsmi_get_clock_info.argtypes = [amdsmi_processor_handle, amdsmi_clk_type_t, ctypes.POINTER(struct_amdsmi_clk_info_t)] amdsmi_get_gpu_vram_usage = _libraries['libamd_smi.so'].amdsmi_get_gpu_vram_usage amdsmi_get_gpu_vram_usage.restype = amdsmi_status_t -amdsmi_get_gpu_vram_usage.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_vram_info_t)] +amdsmi_get_gpu_vram_usage.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_vram_usage_t)] amdsmi_get_gpu_process_list = _libraries['libamd_smi.so'].amdsmi_get_gpu_process_list amdsmi_get_gpu_process_list.restype = amdsmi_status_t amdsmi_get_gpu_process_list.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)] @@ -1868,7 +1868,7 @@ __all__ = \ 'amdsmi_topo_get_numa_node_number', 'amdsmi_utilization_counter_t', 'amdsmi_vbios_info_t', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', - 'amdsmi_voltage_type_t', 'amdsmi_vram_info_t', + 'amdsmi_voltage_type_t', 'amdsmi_vram_usage_t', 'amdsmi_xgmi_info_t', 'amdsmi_xgmi_status_t', 'processor_type_t', 'size_t', 'struct_amd_metrics_table_header_t', 'struct_amdsmi_asic_info_t', 'struct_amdsmi_board_info_t', @@ -1888,7 +1888,7 @@ __all__ = \ 'struct_amdsmi_range_t', 'struct_amdsmi_retired_page_record_t', 'struct_amdsmi_utilization_counter_t', 'struct_amdsmi_vbios_info_t', 'struct_amdsmi_version_t', - 'struct_amdsmi_vram_info_t', 'struct_amdsmi_xgmi_info_t', + 'struct_amdsmi_vram_usage_t', 'struct_amdsmi_xgmi_info_t', 'struct_engine_usage_', 'struct_fields_', 'struct_fw_info_list_', 'struct_memory_usage_', 'uint32_t', 'uint64_t', 'union_amdsmi_bdf_t'] diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index b48fc5c60f..6a70a880a5 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -503,7 +503,7 @@ amdsmi_status_t amdsmi_get_temp_metric(amdsmi_processor_handle processor_handle } amdsmi_status_t amdsmi_get_gpu_vram_usage(amdsmi_processor_handle processor_handle, - amdsmi_vram_info_t *vram_info) { + amdsmi_vram_usage_t *vram_info) { AMDSMI_CHECK_INIT(); @@ -716,6 +716,70 @@ amdsmi_status_t amdsmi_get_gpu_vram_vendor(amdsmi_processor_handle processor_han return rsmi_wrapper(rsmi_dev_vram_vendor_get, processor_handle, brand, len); } +amdsmi_status_t amdsmi_get_gpu_vram_info( + amdsmi_processor_handle processor_handle, amdsmi_vram_info_t *info) { + AMDSMI_CHECK_INIT(); + + if (info == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; + amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, + &gpu_device); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + // init the info structure with default value + info->vram_type = VRAM_TYPE_UNKNOWN; + info->vram_size_mb = 0; + info->vram_vendor = AMDSMI_VRAM_VENDOR__PLACEHOLDER0; + + // Only can read vram type from libdrm + if (gpu_device->check_if_drm_is_supported()) { + struct drm_amdgpu_info_device dev_info = {}; + r = gpu_device->amdgpu_query_info( + AMDGPU_INFO_DEV_INFO, + sizeof(struct drm_amdgpu_info_device), &dev_info); + if (r == AMDSMI_STATUS_SUCCESS) { + info->vram_type = static_cast( + dev_info.vram_type); + } + } + + // map the vendor name to enum + char brand[256]; + r = rsmi_wrapper(rsmi_dev_vram_vendor_get, processor_handle, brand, 255); + if (r == AMDSMI_STATUS_SUCCESS) { + if (strcasecmp(brand, "SAMSUNG") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__SAMSUNG; + if (strcasecmp(brand, "INFINEON") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__INFINEON; + if (strcasecmp(brand, "ELPIDA") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__ELPIDA; + if (strcasecmp(brand, "ETRON") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__ETRON; + if (strcasecmp(brand, "NANYA") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__NANYA; + if (strcasecmp(brand, "HYNIX") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__HYNIX; + if (strcasecmp(brand, "MOSEL") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__MOSEL; + if (strcasecmp(brand, "WINBOND") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__WINBOND; + if (strcasecmp(brand, "ESMT") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__ESMT; + if (strcasecmp(brand, "MICRON") == 0) + info->vram_vendor = AMDSMI_VRAM_VENDOR__MICRON; + } + uint64_t total = 0; + r = rsmi_wrapper(rsmi_dev_memory_total_get, processor_handle, + RSMI_MEM_TYPE_VRAM, &total); + info->vram_size_mb = total; + + return AMDSMI_STATUS_SUCCESS; +} + amdsmi_status_t amdsmi_init_gpu_event_notification(amdsmi_processor_handle processor_handle) { return rsmi_wrapper(rsmi_event_notification_init, processor_handle); diff --git a/tests/amd_smi_test/functional/id_info_read.cc b/tests/amd_smi_test/functional/id_info_read.cc index c22f127ac0..35345ffd18 100755 --- a/tests/amd_smi_test/functional/id_info_read.cc +++ b/tests/amd_smi_test/functional/id_info_read.cc @@ -145,6 +145,19 @@ void TestIdInfoRead::Run(void) { } } + + amdsmi_vram_info_t vram_info; + err = amdsmi_get_gpu_vram_info(processor_handles_[i], &vram_info); + CHK_ERR_ASRT(err) + IF_VERB(STANDARD) { + std::cout << "\t**Device Vram type id: " + << 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_mb << std::endl; + } + err = amdsmi_get_gpu_vendor_name(processor_handles_[i], buffer, kBufferLen); if (err == AMDSMI_STATUS_NOT_SUPPORTED) { std::cout << "\t**Device Vendor name string not found on this system." <<