From bc4d2bc3839f4b5253f97dee4b6f7664622f3bc4 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 15 Feb 2024 16:49:10 -0600 Subject: [PATCH 01/15] Cleanup & rev_id fix Signed-off-by: Maisam Arif Change-Id: I497037939b3f13b4f835762f2cdd42261e7f26f4 Signed-off-by: Maisam Arif [ROCm/amdsmi commit: 482930eee3bba00d7f5bc6424a48755d692dfdf5] --- projects/amdsmi/amdsmi_cli/README.md | 8 ++++---- projects/amdsmi/py-interface/amdsmi_interface.py | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index 966baae543..470d8de6eb 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -620,7 +620,7 @@ ASIC: SUBVENDOR_ID: 0 DEVICE_ID: 0x74a0 REV_ID: 0x0 - ASIC_SERIAL: 0x71660a3c71d5f817 + ASIC_SERIAL: 0x71660A3C71D5F817 OAM_ID: 0 BUS: BDF: 0000:01:00.0 @@ -731,7 +731,7 @@ ASIC: SUBVENDOR_ID: 0 DEVICE_ID: 0x74a0 REV_ID: 0x0 - ASIC_SERIAL: 0xb4b2fa0be8628b1a + ASIC_SERIAL: 0xB4B2FA0BE8628B1A OAM_ID: 1 BUS: BDF: 0001:01:00.0 @@ -842,7 +842,7 @@ ASIC: SUBVENDOR_ID: 0 DEVICE_ID: 0x74a0 REV_ID: 0x0 - ASIC_SERIAL: 0xa9073066a98ba4a6 + ASIC_SERIAL: 0xA9073066A98BA4A6 OAM_ID: 2 BUS: BDF: 0002:01:00.0 @@ -953,7 +953,7 @@ ASIC: SUBVENDOR_ID: 0 DEVICE_ID: 0x74a0 REV_ID: 0x0 - ASIC_SERIAL: 0x53a0a1ff3830f499 + ASIC_SERIAL: 0x53A0A1FF3830F499 OAM_ID: 3 BUS: BDF: 0003:01:00.0 diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 5def0d6a31..8dd3f11936 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -1574,7 +1574,7 @@ def amdsmi_get_gpu_asic_info( "vendor_name": asic_info_struct.vendor_name.decode("utf-8"), "subvendor_id": asic_info_struct.subvendor_id, "device_id": asic_info_struct.device_id, - "rev_id": asic_info_struct.rev_id, + "rev_id": hex(asic_info_struct.rev_id), "asic_serial": asic_info_struct.asic_serial.decode("utf-8"), "oam_id": asic_info_struct.oam_id } @@ -1584,16 +1584,18 @@ def amdsmi_get_gpu_asic_info( if not asic_info[value]: asic_info[value] = "N/A" - hex_values = ["vendor_id", "subvendor_id", "device_id", "rev_id"] + hex_values = ["vendor_id", "subvendor_id", "device_id"] for value in hex_values: if asic_info[value]: asic_info[value] = hex(asic_info[value]) else: asic_info[value] = "N/A" - # Ensure hex output for asic_serial + # Convert asic serial (hex string) to hex output format if asic_info["asic_serial"]: - asic_info["asic_serial"] = str.format("0x{:016X}", int(asic_info["asic_serial"], base=16)) + asic_serial_string = asic_info["asic_serial"] + asic_serial_hex = int(asic_serial_string, base=16) + asic_info["asic_serial"] = str.format("0x{:016X}", asic_serial_hex) else: asic_info["asic_serial"] = "N/A" From c3bfdbe8063694a89eaca707ab808da4b789f75b Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 20 Feb 2024 04:56:52 -0600 Subject: [PATCH 02/15] Aligned cache property enum with Host Signed-off-by: Maisam Arif Change-Id: Ie64a33f55c9a9a7cc8c806419509897351f37c70 [ROCm/amdsmi commit: 703fdb0ed24d7fb4cee16882541a96b062cf0597] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 20 ++++++--- projects/amdsmi/include/amd_smi/amdsmi.h | 14 +++--- projects/amdsmi/py-interface/README.md | 12 ++--- .../amdsmi/py-interface/amdsmi_interface.py | 17 +++---- .../amdsmi/py-interface/amdsmi_wrapper.py | 44 +++++++++---------- projects/amdsmi/src/amd_smi/amd_smi.cc | 8 ++-- 6 files changed, 59 insertions(+), 56 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 7462d2c53e..dfc108ae25 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -550,11 +550,17 @@ class AMDSMICommands(): static_dict['vram'] = vram_info if args.cache: try: - cach_info_list = amdsmi_interface.amdsmi_get_gpu_cache_info(args.gpu) - logging.debug(f"cache_info dictionary = {cach_info_list}") + cache_info_list = amdsmi_interface.amdsmi_get_gpu_cache_info(args.gpu)['cache'] + logging.debug(f"cache_info dictionary = {cache_info_list}") + + for index, cache_info in enumerate(cache_info_list): + new_cache_info = {"cache" : index} + new_cache_info.update(cache_info) + cache_info_list[index] = new_cache_info + if self.logger.is_human_readable_format(): cache_info_dict_format = {} - for cache_dict in cach_info_list: + for cache_dict in cache_info_list: cache_index = "cache_" + str(cache_dict["cache"]) cache_info_dict_format[cache_index] = cache_dict @@ -567,15 +573,15 @@ class AMDSMICommands(): # take cache_properties out of list -> display as string, removing brackets cache_info_dict_format[cache_index]["cache_properties"] = ", ".join(cache_info_dict_format[cache_index]["cache_properties"]) - cach_info_list = cache_info_dict_format + cache_info_list = cache_info_dict_format - logging.debug(f"After human_readable | cache_info = {cach_info_list}") + logging.debug(f"After human_readable | cache_info = {cache_info_list}") except amdsmi_exception.AmdSmiLibraryException as e: - cach_info_list = "N/A" + cache_info_list = "N/A" logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()) - static_dict['cache_info'] = cach_info_list + static_dict['cache_info'] = cache_info_list if 'ras' in current_platform_args: if args.ras: ras_dict = {"eeprom_version": "N/A", diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index e62974313f..13c11f76b0 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -541,17 +541,17 @@ typedef struct { * @brief cache properties */ typedef enum { - AMDSMI_CACHE_PROPERTIES_ENABLED = 0x00000001, - AMDSMI_CACHE_PROPERTIES_DATA_CACHE = 0x00000002, - AMDSMI_CACHE_PROPERTIES_INST_CACHE = 0x00000004, - AMDSMI_CACHE_PROPERTIES_CPU_CACHE = 0x00000008, - AMDSMI_CACHE_PROPERTIES_SIMD_CACHE = 0x00000010, -} amdsmi_cache_properties_type_t; + AMDSMI_CACHE_PROPERTY_ENABLED = 0x00000001, + AMDSMI_CACHE_PROPERTY_DATA_CACHE = 0x00000002, + AMDSMI_CACHE_PROPERTY_INST_CACHE = 0x00000004, + AMDSMI_CACHE_PROPERTY_CPU_CACHE = 0x00000008, + AMDSMI_CACHE_PROPERTY_SIMD_CACHE = 0x00000010, +} amdsmi_cache_property_type_t; typedef struct { uint32_t num_cache_types; struct cache_ { - uint32_t cache_properties; // amdsmi_cache_properties_type_t which is a bitmask + uint32_t cache_properties; // amdsmi_cache_property_type_t which is a bitmask uint32_t cache_size; /* In KB */ uint32_t cache_level; uint32_t max_num_cu_shared; /* Indicates how many Compute Units share this cache instance */ diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index 96abe99459..b4c79a351d 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -476,8 +476,7 @@ Schema: ```JSON { - cache: {"type" : "number"}, - cache_properties: + cache_properties: { "type" : "array", "items" : {"type" : "string"} @@ -491,7 +490,6 @@ Schema: Field | Description ---|--- -`cache` | cache index from 0-9 `cache_properties` | list of up to 4 cache property type strings. Ex. data ("DATA_CACHE"), instruction ("INST_CACHE"), CPU ("CPU_CACHE"), or SIMD ("SIMD_CACHE"). `cache_size` | size of cache in KB `cache_level` | level of cache @@ -515,13 +513,11 @@ try: for device in devices: cache_info = amdsmi_get_gpu_cache_info(device) for cache_index, cache_values in cache_info.items(): - print(cache_index) + print(cache_values['cache_properties']) print(cache_values['cache_size']) print(cache_values['cache_level']) - print(cache_values['data_cache']) - print(cache_values['instruction_cache']) - print(cache_values['cpu_cache']) - print(cache_values['simd_cache']) + print(cache_values['max_num_cu_shared']) + print(cache_values['num_cache_instance']) except AmdSmiException as e: print(e) ``` diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 8dd3f11936..5f6627eb35 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -1670,7 +1670,6 @@ def amdsmi_get_gpu_cache_info( for cache_index in range(cache_info_struct.num_cache_types): # Put cache_properties at the start of the dictionary for readability cache_dict = { - "cache": cache_index, "cache_properties": [], # This will be a list of strings "cache_size": cache_info_struct.cache[cache_index].cache_size, "cache_level": cache_info_struct.cache[cache_index].cache_level, @@ -1680,17 +1679,17 @@ def amdsmi_get_gpu_cache_info( # Check against cache properties bitmask cache_properties = cache_info_struct.cache[cache_index].cache_properties - data_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTIES_DATA_CACHE - inst_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTIES_INST_CACHE - cpu_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTIES_CPU_CACHE - simd_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTIES_SIMD_CACHE + data_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTY_DATA_CACHE + inst_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTY_INST_CACHE + cpu_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTY_CPU_CACHE + simd_cache = cache_properties & amdsmi_wrapper.AMDSMI_CACHE_PROPERTY_SIMD_CACHE cache_properties_status = [data_cache, inst_cache, cpu_cache, simd_cache] cache_property_list = [] for cache_property in cache_properties_status: if cache_property: - property_name = amdsmi_wrapper.amdsmi_cache_properties_type_t__enumvalues[cache_property] - property_name = property_name.replace("AMDSMI_CACHE_PROPERTIES_", "") + property_name = amdsmi_wrapper.amdsmi_cache_property_type_t__enumvalues[cache_property] + property_name = property_name.replace("AMDSMI_CACHE_PROPERTY_", "") cache_property_list.append(property_name) cache_dict["cache_properties"] = cache_property_list @@ -1699,7 +1698,9 @@ def amdsmi_get_gpu_cache_info( if not cache_info_list: raise AmdSmiLibraryException(amdsmi_wrapper.AMDSMI_STATUS_NO_DATA) - return cache_info_list + return { + "cache": cache_info_list + } def amdsmi_get_gpu_vbios_info( diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 9c21209eb0..a1a6b9b70b 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -813,20 +813,20 @@ struct_amdsmi_vbios_info_t._fields_ = [ amdsmi_vbios_info_t = struct_amdsmi_vbios_info_t -# values for enumeration 'amdsmi_cache_properties_type_t' -amdsmi_cache_properties_type_t__enumvalues = { - 1: 'AMDSMI_CACHE_PROPERTIES_ENABLED', - 2: 'AMDSMI_CACHE_PROPERTIES_DATA_CACHE', - 4: 'AMDSMI_CACHE_PROPERTIES_INST_CACHE', - 8: 'AMDSMI_CACHE_PROPERTIES_CPU_CACHE', - 16: 'AMDSMI_CACHE_PROPERTIES_SIMD_CACHE', +# values for enumeration 'amdsmi_cache_property_type_t' +amdsmi_cache_property_type_t__enumvalues = { + 1: 'AMDSMI_CACHE_PROPERTY_ENABLED', + 2: 'AMDSMI_CACHE_PROPERTY_DATA_CACHE', + 4: 'AMDSMI_CACHE_PROPERTY_INST_CACHE', + 8: 'AMDSMI_CACHE_PROPERTY_CPU_CACHE', + 16: 'AMDSMI_CACHE_PROPERTY_SIMD_CACHE', } -AMDSMI_CACHE_PROPERTIES_ENABLED = 1 -AMDSMI_CACHE_PROPERTIES_DATA_CACHE = 2 -AMDSMI_CACHE_PROPERTIES_INST_CACHE = 4 -AMDSMI_CACHE_PROPERTIES_CPU_CACHE = 8 -AMDSMI_CACHE_PROPERTIES_SIMD_CACHE = 16 -amdsmi_cache_properties_type_t = ctypes.c_uint32 # enum +AMDSMI_CACHE_PROPERTY_ENABLED = 1 +AMDSMI_CACHE_PROPERTY_DATA_CACHE = 2 +AMDSMI_CACHE_PROPERTY_INST_CACHE = 4 +AMDSMI_CACHE_PROPERTY_CPU_CACHE = 8 +AMDSMI_CACHE_PROPERTY_SIMD_CACHE = 16 +amdsmi_cache_property_type_t = ctypes.c_uint32 # enum class struct_amdsmi_gpu_cache_info_t(Structure): pass @@ -2308,14 +2308,14 @@ amdsmi_get_esmi_err_msg.restype = amdsmi_status_t amdsmi_get_esmi_err_msg.argtypes = [amdsmi_status_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))] __all__ = \ ['AGG_BW0', 'AMDSMI_ARG_PTR_NULL', 'AMDSMI_AVERAGE_POWER', - 'AMDSMI_CACHE_PROPERTIES_CPU_CACHE', - 'AMDSMI_CACHE_PROPERTIES_DATA_CACHE', - 'AMDSMI_CACHE_PROPERTIES_ENABLED', - 'AMDSMI_CACHE_PROPERTIES_INST_CACHE', - 'AMDSMI_CACHE_PROPERTIES_SIMD_CACHE', - 'AMDSMI_CARD_FORM_FACTOR_OAM', 'AMDSMI_CARD_FORM_FACTOR_PCIE', - 'AMDSMI_CARD_FORM_FACTOR_UNKNOWN', 'AMDSMI_CNTR_CMD_START', - 'AMDSMI_CNTR_CMD_STOP', 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', + 'AMDSMI_CACHE_PROPERTY_CPU_CACHE', + 'AMDSMI_CACHE_PROPERTY_DATA_CACHE', + 'AMDSMI_CACHE_PROPERTY_ENABLED', + 'AMDSMI_CACHE_PROPERTY_INST_CACHE', + 'AMDSMI_CACHE_PROPERTY_SIMD_CACHE', 'AMDSMI_CARD_FORM_FACTOR_OAM', + 'AMDSMI_CARD_FORM_FACTOR_PCIE', 'AMDSMI_CARD_FORM_FACTOR_UNKNOWN', + 'AMDSMI_CNTR_CMD_START', 'AMDSMI_CNTR_CMD_STOP', + 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', 'AMDSMI_CURRENT_POWER', 'AMDSMI_DEV_PERF_LEVEL_AUTO', 'AMDSMI_DEV_PERF_LEVEL_DETERMINISM', 'AMDSMI_DEV_PERF_LEVEL_FIRST', 'AMDSMI_DEV_PERF_LEVEL_HIGH', @@ -2477,7 +2477,7 @@ __all__ = \ 'VRAM_TYPE_GDDR6', 'VRAM_TYPE_HBM', 'VRAM_TYPE_UNKNOWN', 'VRAM_TYPE__MAX', 'WR_BW0', 'amd_metrics_table_header_t', 'amdsmi_asic_info_t', 'amdsmi_bdf_t', 'amdsmi_bit_field_t', - 'amdsmi_board_info_t', 'amdsmi_cache_properties_type_t', + 'amdsmi_board_info_t', 'amdsmi_cache_property_type_t', 'amdsmi_card_form_factor_t', 'amdsmi_clk_info_t', 'amdsmi_clk_type_t', 'amdsmi_compute_partition_type_t', 'amdsmi_container_types_t', 'amdsmi_counter_command_t', diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index 77b7fbe202..2f68823540 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -448,13 +448,13 @@ amdsmi_status_t amdsmi_get_gpu_cache_info( // convert from sysfs type to CRAT type(HSA Cache Affinity type) info->cache[i].cache_properties = 0; if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_DATA) - info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTIES_DATA_CACHE; + info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTY_DATA_CACHE; if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_INSTRUCTION) - info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTIES_INST_CACHE; + info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTY_INST_CACHE; if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_CPU) - info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTIES_CPU_CACHE; + info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTY_CPU_CACHE; if (rsmi_info.cache[i].flags & HSA_CACHE_TYPE_HSACU) - info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTIES_SIMD_CACHE; + info->cache[i].cache_properties |= AMDSMI_CACHE_PROPERTY_SIMD_CACHE; info->cache[i].cache_size = rsmi_info.cache[i].cache_size_kb; info->cache[i].cache_level = rsmi_info.cache[i].cache_level; From 1e6fd88ac6f02c248f578a719e5fbc4e3c9474ca Mon Sep 17 00:00:00 2001 From: Deepak Mewar Date: Fri, 16 Feb 2024 12:27:51 +0000 Subject: [PATCH 03/15] Fix for multiple hsmp freq sources not reported on some setups Change-Id: I8afe7076bd7790cf408ef104c50ac8d258b7d3fc Signed-off-by: Maisam Arif [ROCm/amdsmi commit: 84608807da4913a4d66b555d2afa580822d2de59] --- projects/amdsmi/include/amd_smi/amdsmi.h | 13 +++++++++++++ .../amdsmi/py-interface/amdsmi_interface.py | 10 ++++++++-- projects/amdsmi/py-interface/amdsmi_wrapper.py | 17 +++++++++-------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 13c11f76b0..0233c3cf24 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -1608,6 +1608,19 @@ typedef struct __attribute__((__packed__)){ uint32_t gfxclk_frequency[8]; } amdsmi_hsmp_metrics_table_t; +/** + * @brief hsmp frequency limit source names + */ +static char* const amdsmi_hsmp_freqlimit_src_names[] = { + "cHTC-Active", + "PROCHOT", + "TDC limit", + "PPT Limit", + "OPN Max", + "Reliability Limit", + "APML Agent", + "HSMP Agent" +}; #endif /*****************************************************************************/ diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 5f6627eb35..6b22359404 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -828,8 +828,9 @@ def amdsmi_get_cpu_socket_current_active_freq_limit( processor_handle, amdsmi_wrapper.amdsmi_processor_handle ) + amdsmi_wrapper.amdsmi_get_cpu_socket_current_active_freq_limit.argtypes = [amdsmi_wrapper.amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint16), ctypes.POINTER(ctypes.c_char_p * len(amdsmi_wrapper.amdsmi_hsmp_freqlimit_src_names))] freq = ctypes.c_uint16() - src_type = ctypes.pointer(ctypes.pointer(ctypes.c_char())) + src_type = (ctypes.c_char_p * len(amdsmi_wrapper.amdsmi_hsmp_freqlimit_src_names))() _check_res( amdsmi_wrapper.amdsmi_get_cpu_socket_current_active_freq_limit( @@ -837,9 +838,14 @@ def amdsmi_get_cpu_socket_current_active_freq_limit( ) ) + freq_src = [] + for names in src_type: + if names is not None: + freq_src.append(names.decode('utf-8')) + return { "freq": f"{freq.value} MHz", - "freq_src": f"{amdsmi_wrapper.string_cast(src_type.contents)}" + "freq_src": f"{freq_src}" } def amdsmi_get_cpu_socket_freq_range( diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index a1a6b9b70b..8b49fd9b2c 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -1846,6 +1846,7 @@ struct_amdsmi_hsmp_metrics_table_t._fields_ = [ ] amdsmi_hsmp_metrics_table_t = struct_amdsmi_hsmp_metrics_table_t +amdsmi_hsmp_freqlimit_src_names = ['cHTC-Active', 'PROCHOT', 'TDC limit', 'PPT Limit', 'OPN Max', 'Reliability Limit', 'APML Agent', 'HSMP Agent'] # Variable ctypes.POINTER(ctypes.c_char) * 8 uint64_t = ctypes.c_uint64 amdsmi_init = _libraries['libamd_smi.so'].amdsmi_init amdsmi_init.restype = amdsmi_status_t @@ -2618,14 +2619,14 @@ __all__ = \ 'amdsmi_voltage_type_t', 'amdsmi_vram_info_t', 'amdsmi_vram_type_t', 'amdsmi_vram_usage_t', 'amdsmi_vram_vendor_type_t', 'amdsmi_xgmi_info_t', - 'amdsmi_xgmi_status_t', 'processor_type_t', 'size_t', - 'struct__links', 'struct_amd_metrics_table_header_t', - 'struct_amdsmi_asic_info_t', 'struct_amdsmi_board_info_t', - 'struct_amdsmi_clk_info_t', 'struct_amdsmi_counter_value_t', - 'struct_amdsmi_ddr_bw_metrics_t', 'struct_amdsmi_dimm_power_t', - 'struct_amdsmi_dimm_thermal_t', 'struct_amdsmi_dpm_level_t', - 'struct_amdsmi_driver_info_t', 'struct_amdsmi_engine_usage_t', - 'struct_amdsmi_error_count_t', + 'amdsmi_xgmi_status_t', 'amdsmi_hsmp_freqlimit_src_names', + 'processor_type_t', 'size_t', 'struct__links', + 'struct_amd_metrics_table_header_t', 'struct_amdsmi_asic_info_t', + 'struct_amdsmi_board_info_t', 'struct_amdsmi_clk_info_t', + 'struct_amdsmi_counter_value_t', 'struct_amdsmi_ddr_bw_metrics_t', + 'struct_amdsmi_dimm_power_t', 'struct_amdsmi_dimm_thermal_t', + 'struct_amdsmi_dpm_level_t', 'struct_amdsmi_driver_info_t', + 'struct_amdsmi_engine_usage_t', 'struct_amdsmi_error_count_t', 'struct_amdsmi_evt_notification_data_t', 'struct_amdsmi_freq_volt_region_t', 'struct_amdsmi_frequencies_t', 'struct_amdsmi_frequency_range_t', 'struct_amdsmi_fw_info_t', From 6536a9d969dd43ff99b50c03a549bb2d5e5c94a7 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Wed, 21 Feb 2024 06:46:02 -0600 Subject: [PATCH 04/15] Unified human readable output tabbing with Host Signed-off-by: Maisam Arif Change-Id: Ie8ebe783e0e2cd445a0b29431c11302a0675a010 [ROCm/amdsmi commit: 180f8937911f750365ac4be310c57ec5322193a7] --- projects/amdsmi/amdsmi_cli/amdsmi_logger.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py index 52286918b8..0b65cc250d 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py @@ -126,6 +126,18 @@ class AMDSMILogger(): # First Capitalize all keys in the json object capitalized_json = self._capitalize_keys(json_object) + + # Increase tabbing for device arguments by pulling them out of the main dictionary and assiging them to an empty string + tabbed_dictionary = {} + for key, value in capitalized_json.items(): + if key not in ["GPU", "CPU", "CORE"]: + tabbed_dictionary[key] = value + + for key, value in tabbed_dictionary.items(): + del capitalized_json[key] + + capitalized_json["AMDSMI_SPACING_REMOVAL"] = tabbed_dictionary + json_string = json.dumps(capitalized_json, indent=4) yaml_data = yaml.safe_load(json_string) yaml_output = yaml.dump(yaml_data, sort_keys=False, allow_unicode=True) From 2c3537e3897216be5c63ca8f65d639187024ea78 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Wed, 21 Feb 2024 03:48:09 -0600 Subject: [PATCH 05/15] Refactor ESMI Initialization and Argument Parsing Signed-off-by: Maisam Arif Change-Id: Iefab3a8110e0d3c525ee0cef1bdef9101550e9de [ROCm/amdsmi commit: f58613561c3c52197e484ad0d6fa02e218c3b68e] --- projects/amdsmi/amdsmi_cli/README.md | 16 +- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 1701 ++++++++++------- projects/amdsmi/amdsmi_cli/amdsmi_helpers.py | 22 +- projects/amdsmi/amdsmi_cli/amdsmi_init.py | 58 +- projects/amdsmi/amdsmi_cli/amdsmi_logger.py | 3 +- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 1089 ++++++----- projects/amdsmi/include/amd_smi/amdsmi.h | 4 +- projects/amdsmi/py-interface/README.md | 9 +- .../amdsmi/py-interface/amdsmi_wrapper.py | 4 +- projects/amdsmi/src/amd_smi/amd_smi_system.cc | 4 +- 10 files changed, 1615 insertions(+), 1295 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index 470d8de6eb..0fa72b8534 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -183,7 +183,7 @@ Static Arguments: -l, --limit All limit metric values (i.e. power and thermal limits) -u, --numa All numa node information -CPU Option: +CPU Arguments: -s, --smu All SMU FW information -i, --interface_ver Displays hsmp interface version @@ -276,7 +276,7 @@ usage: amd-smi metric [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] [--cpu_lclk_dpm_level NBIOID] [--cpu_pwr_svi_telemtry_rails] [--cpu_io_bandwidth IO_BW LINKID_NAME] [--cpu_xgmi_bandwidth XGMI_BW LINKID_NAME] [--cpu_enable_apb] - [--cpu_disable_apb DF_PSTATE] [--set_cpu_pow_limit POW_LIMIT] + [--cpu_disable_apb DF_PSTATE] [--set_cpu_pwr_limit PWR_LIMIT] [--set_cpu_xgmi_link_width MIN_WIDTH MAX_WIDTH] [--set_cpu_lclk_dpm_level NBIOID MIN_DPM MAX_DPM] [--core_boost_limit] [--core_curr_active_freq_core_limit] @@ -285,10 +285,10 @@ usage: amd-smi metric [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] [--cpu_metrics_table] [--core_energy] [--socket_energy] [--set_cpu_pwr_eff_mode MODE] [--cpu_ddr_bandwidth] [--cpu_temp] [--cpu_dimm_temp_range_rate DIMM_ADDR] - [--cpu_dimm_pow_conumption DIMM_ADDR] + [--cpu_dimm_pow_consumption DIMM_ADDR] [--cpu_dimm_thermal_sensor DIMM_ADDR] [--set_cpu_gmi3_link_width MIN_LW MAX_LW] - [--set_cpu_pcie_lnk_rate LINK_RATE] + [--set_cpu_pcie_link_rate LINK_RATE] [--set_cpu_df_pstate_range MAX_PSTATE MIN_PSTATE] If no GPU is specified, returns metric information for all GPUs on the system. @@ -329,7 +329,7 @@ Metric arguments: -x, --xgmi-err XGMI error information since last read -E, --energy Amount of energy consumed -CPU Option: +CPU Arguments: --cpu_power_metrics Cpu power metrics --cpu_prochot Displays prochot status --cpu_freq_metrics Displays currentFclkMemclk frequencies and cclk frequency limit @@ -353,18 +353,18 @@ CPU Option: --cpu_ddr_bandwidth Displays per socket max ddr bw, current utilized bw and current utilized ddr bw in percentage --cpu_temp Displays cpu socket temperature --cpu_dimm_temp_range_rate DIMM_ADDR Displays dimm temperature range and refresh rate - --cpu_dimm_pow_conumption DIMM_ADDR Displays dimm power consumption + --cpu_dimm_pow_consumption DIMM_ADDR Displays dimm power consumption --cpu_dimm_thermal_sensor DIMM_ADDR Displays dimm thermal sensor Set Options: - --set_cpu_pow_limit POW_LIMIT Set power limit for the given socket. Input parameter is power limit value. + --set_cpu_pwr_limit PWR_LIMIT Set power limit for the given socket. Input parameter is power limit value. --set_cpu_xgmi_link_width MIN_WIDTH MAX_WIDTH Set max and Min linkwidth. Input parameters are min and max link width values --set_cpu_lclk_dpm_level NBIOID MIN_DPM MAX_DPM Sets the max and min dpm level on a given NBIO. Inpur parameters are die_index, min dpm, max dpm. --set_soc_boost_limit BOOST_LIMIT Sets the boost limit for the given socket. Input parameter is socket limit value --set_core_boost_limit BOOST_LIMIT Sets the boost limit for the given core. Input parameter is core limit value --set_cpu_pwr_eff_mode MODE Sets the power efficency mode policy. Input parameter is mode. --set_cpu_gmi3_link_width MIN_LW MAX_LW Sets max and min gmi3 link width range - --set_cpu_pcie_lnk_rate LINK_RATE Sets pcie link rate + --set_cpu_pcie_link_rate LINK_RATE Sets pcie link rate --set_cpu_df_pstate_range MAX_PSTATE MIN_PSTATE Sets max and min df-pstates Command Modifiers: diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index dfc108ae25..bb717e498d 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -46,44 +46,55 @@ class AMDSMICommands(): self.device_handles = [] self.cpu_handles = [] self.core_handles = [] - try: - self.device_handles = amdsmi_interface.amdsmi_get_processor_handles() - except amdsmi_exception.AmdSmiLibraryException as e: - if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, - amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): - logging.error('Unable to get devices, driver not initialized (amdgpu not found in modules)') - else: - raise e - - if len(self.device_handles) == 0: - logging.info('Unable to detect any devices, check if driver is initialized (amdgpu not found in modules)') - - # Fetch CPU handles - try: - self.cpu_handles = amdsmi_interface.amdsmi_get_cpusocket_handles() - except amdsmi_exception.AmdSmiLibraryException as e: - if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, - amdsmi_interface.amdsmi_wrapper.AMDSMI_NO_DRV): - - logging.info('Unable to get CPU devices, hsmp driver not loaded') - else: - raise e - - # core handles - try: - self.core_handles = amdsmi_interface.amdsmi_get_cpucore_handles() - except amdsmi_exception.AmdSmiLibraryException as e: - if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, - amdsmi_interface.amdsmi_wrapper.AMDSMI_NO_DRV): - logging.info('Unable to get CORE devices, hsmp driver not loaded') - else: - raise e - - if (len(self.device_handles) == 0 and len(self.cpu_handles) == 0 and len(self.core_handles) == 0): - logging.error('Unable to detect any devices, check if amdgpu and hsmp drivers are initialized') - sys.exit(-1) self.stop = '' + amdsmi_init_flag = self.helpers.get_amdsmi_init_flag() + logging.debug(f"AMDSMI Init Flag: {amdsmi_init_flag}") + exit_flag = False + + if self.helpers.is_amdgpu_initialized(): + try: + self.device_handles = amdsmi_interface.amdsmi_get_processor_handles() + except amdsmi_exception.AmdSmiLibraryException as e: + if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, + amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): + logging.error('Unable to get devices, driver not initialized (amdgpu not found in modules)') + else: + raise e + + if len(self.device_handles) == 0: + # No GPU's found post amdgpu driver initialization + logging.error('Unable to detect any GPU devices, check amdgpu version and module status') + exit_flag = True + + if self.helpers.is_amd_hsmp_initialized(): + try: + self.cpu_handles = amdsmi_interface.amdsmi_get_cpusocket_handles() + except amdsmi_exception.AmdSmiLibraryException as e: + if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, + amdsmi_interface.amdsmi_wrapper.AMDSMI_NO_DRV): + logging.info('Unable to get CPU devices, amd_hsmp driver not loaded') + else: + raise e + + # core handles + try: + self.core_handles = amdsmi_interface.amdsmi_get_cpucore_handles() + except amdsmi_exception.AmdSmiLibraryException as e: + if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, + amdsmi_interface.amdsmi_wrapper.AMDSMI_NO_DRV): + logging.info('Unable to get CORE devices, amd_hsmp driver not loaded') + else: + raise e + + if len(self.cpu_handles) == 0 and len(self.core_handles) == 0: + # No CPU's found post amd_hsmp driver initialization + logging.error('Unable to detect any CPU devices, check amd_hsmp version and module status') + exit_flag = True + + if exit_flag: + sys.exit(-1) + def version(self, args): """Print Version String @@ -164,7 +175,7 @@ class AMDSMICommands(): self.logger.print_output() - def get_static_cpu(self, args, multiple_devices=False, cpu=None): + def static_cpu(self, args, multiple_devices=False, cpu=None, interface_ver=None): """Get Static information for target cpu Args: @@ -176,57 +187,61 @@ class AMDSMICommands(): None: Print output via AMDSMILogger to destination """ - if (cpu): + if cpu: args.cpu = cpu + if interface_ver: + args.interface_ver = interface_ver - #store cpu args that are applicable to the current platform + # Store cpu args that are applicable to the current platform curr_platform_cpu_args = ["smu", "interface_ver"] curr_platform_cpu_values = [args.smu, args.interface_ver] - if (not any(curr_platform_cpu_values)): + # If no cpu options are passed, return all available args + if not any(curr_platform_cpu_values): for arg in curr_platform_cpu_args: setattr(args, arg, True) - if (len(self.cpu_handles)): - handled_multiple_cpus, device_handle = self.helpers.handle_cpus(args, - self.logger, - self.get_static_cpu) - if handled_multiple_cpus: - return # This function is recursive - args.cpu = device_handle - # get cpu id for logging - cpu_id = self.helpers.get_cpu_id_from_device_handle(args.cpu) - logging.debug(f"Static Arg information for CPU {cpu_id} on {self.helpers.os_info()}") + # Handle multiple CPUs + handled_multiple_cpus, device_handle = self.helpers.handle_cpus(args, + self.logger, + self.static_cpu) + if handled_multiple_cpus: + return # This function is recursive + args.cpu = device_handle - static_dict = {} + # Get cpu id for logging + cpu_id = self.helpers.get_cpu_id_from_device_handle(args.cpu) + logging.debug(f"Static Arg information for CPU {cpu_id} on {self.helpers.os_info()}") - if (args.smu): - try: - smu = amdsmi_interface.amdsmi_get_cpu_smu_fw_version(args.cpu) - static_dict["smu"] = {"FW_VERSION" : f"{ smu['smu_fw_major_ver_num']}" - f".{smu['smu_fw_minor_ver_num']}.{smu['smu_fw_debug_ver_num']}"} - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["smu"] = "N/A" - logging.debug("Failed to get SMU FW for cpu %s | %s", cpu_id, e.get_error_info()) + static_dict = {} - if (args.interface_ver): - static_dict["interface_version"] = {} - try: - intf_ver = amdsmi_interface.amdsmi_get_cpu_hsmp_proto_ver(args.cpu) - static_dict["interface_version"]["proto version"] = intf_ver - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["interface_version"]["proto version"] = "N/A" - logging.debug("Failed to get proto version for cpu %s | %s", cpu_id, e.get_error_info()) + if args.smu: + try: + smu = amdsmi_interface.amdsmi_get_cpu_smu_fw_version(args.cpu) + static_dict["smu"] = {"FW_VERSION" : f"{smu['smu_fw_major_ver_num']}." + f"{smu['smu_fw_minor_ver_num']}.{smu['smu_fw_debug_ver_num']}"} + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["smu"] = "N/A" + logging.debug("Failed to get SMU FW for cpu %s | %s", cpu_id, e.get_error_info()) - multiple_devices_csv_override = False - self.logger.store_cpu_output(args.cpu, 'values', static_dict) - if multiple_devices: - self.logger.store_multiple_device_output() - return # Skip printing when there are multiple devices - self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) + if args.interface_ver: + static_dict["interface_version"] = {} + try: + intf_ver = amdsmi_interface.amdsmi_get_cpu_hsmp_proto_ver(args.cpu) + static_dict["interface_version"]["proto version"] = intf_ver + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["interface_version"]["proto version"] = "N/A" + logging.debug("Failed to get proto version for cpu %s | %s", cpu_id, e.get_error_info()) + + multiple_devices_csv_override = False + self.logger.store_cpu_output(args.cpu, 'values', static_dict) + if multiple_devices: + self.logger.store_multiple_device_output() + return # Skip printing when there are multiple devices + self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) - def get_static_gpu(self, args, multiple_devices=False, gpu=None, asic=None, bus=None, vbios=None, + def static_gpu(self, args, multiple_devices=False, gpu=None, asic=None, bus=None, vbios=None, limit=None, driver=None, ras=None, board=None, numa=None, vram=None, cache=None, partition=None, dfc_ucode=None, fb_info=None, num_vf=None): """Get Static information for target gpu @@ -303,11 +318,11 @@ class AMDSMICommands(): current_platform_args += ["dfc_ucode", "fb_info", "num_vf"] current_platform_values += [args.dfc_ucode, args.fb_info, args.num_vf] - if (not any(current_platform_values)): + if not any(current_platform_values): for arg in current_platform_args: setattr(args, arg, True) - handled_multiple_gpus, device_handle = self.helpers.handle_gpus(args, self.logger, self.get_static_gpu) + handled_multiple_gpus, device_handle = self.helpers.handle_gpus(args, self.logger, self.static_gpu) if handled_multiple_gpus: return # This function is recursive args.gpu = device_handle @@ -318,8 +333,8 @@ class AMDSMICommands(): logging.debug(f"Applicable Args: {current_platform_args}") logging.debug(f"Arg Values: {current_platform_values}") + # Populate static dictionary for each enabled argument static_dict = {} - if args.asic: try: asic_info = amdsmi_interface.amdsmi_get_gpu_asic_info(args.gpu) @@ -651,8 +666,8 @@ class AMDSMICommands(): static_dict['numa'] = {'node' : numa_node_number, 'affinity' : numa_affinity} - multiple_devices_csv_override = False # Convert and store output by pid for csv format + multiple_devices_csv_override = False if self.logger.is_csv_format(): # expand if ras blocks are populated if self.helpers.is_linux() and self.helpers.is_baremetal() and args.ras: @@ -715,55 +730,66 @@ class AMDSMICommands(): Returns: None: Print output via AMDSMILogger to destination """ - # Set args.* to passed in arguments - if gpu: - args.gpu = gpu + # Mutually exclusive arguments if cpu: args.cpu = cpu - if interface_ver: - args.interface_ver = interface_ver + if gpu: + args.gpu = gpu - gpus = args.gpu - cpus = args.cpu + # Check if a CPU argument has been set + cpu_args_enabled = False + cpu_attributes = ["smu", "interface_ver"] + for attr in cpu_attributes: + if hasattr(args, attr): + cpu_args_enabled |= bool(getattr(args, attr)) - gpu_options = any([args.gpu, args.asic, args.bus, args.vbios, args.driver, args.vram, args.cache, args.board]) - cpu_options = any([args.smu, args.interface_ver]) + # Check if a GPU argument has been set + gpu_args_enabled = False + gpu_attributes = ["asic", "bus", "vbios", "limit", "driver", "ras", + "board", "numa", "vram", "cache", "partition", + "dfc_ucode", "fb_info", "num_vf"] + for attr in gpu_attributes: + if hasattr(args, attr): + gpu_args_enabled |= bool(getattr(args, attr)) - # Handle No GPU passed - if args.gpu == None: - args.gpu = self.device_handles + # Handle CPU and GPU intialization cases + if self.helpers.is_amd_hsmp_initialized() and self.helpers.is_amdgpu_initialized(): + # Print out all CPU and all GPU static info only if no device was specified. + # If a GPU or CPU argument is provided only print out the specified device. + if args.cpu == None and args.gpu == None: + if not cpu_args_enabled and not gpu_args_enabled: + args.cpu = self.cpu_handles + args.gpu = self.device_handles - # Handle No CPU passed - if args.cpu == None: - args.cpu = self.cpu_handles + # Handle cases where the user has only specified an argument and no specific device + if args.gpu == None and gpu_args_enabled: + args.gpu = self.device_handles + if args.cpu == None and cpu_args_enabled: + args.cpu = self.cpu_handles - if (len(self.cpu_handles) and ((((not gpus) and (not cpus)) or cpus) - and not gpu_options)): - self.get_static_cpu(args, cpu) - else: - logging.info("No CPU devices present") + if args.cpu: + self.static_cpu(args, multiple_devices, cpu, interface_ver) + if args.gpu: + self.logger.output = {} + self.logger.clear_multiple_devices_ouput() + self.static_gpu(args, multiple_devices, gpu, asic, + bus, vbios, limit, driver, ras, + board, numa, vram, cache, partition, + dfc_ucode, fb_info, num_vf) + elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized + if args.cpu == None: + args.cpu = self.cpu_handles - if (cpu_options and (len(self.cpu_handles) == 0)): - logging.error("No CPU devices present") - sys.exit(-1) + self.static_cpu(args, multiple_devices, cpu, interface_ver) + elif self.helpers.is_amdgpu_initialized(): # Only GPU is initialized + if args.gpu == None: + args.gpu = self.device_handles - if (len(self.device_handles) and ((((not gpus) and (not cpus)) or gpus) - and not cpu_options)): self.logger.clear_multiple_devices_ouput() - self.get_static_gpu(args, multiple_devices, gpu, asic, + self.static_gpu(args, multiple_devices, gpu, asic, bus, vbios, limit, driver, ras, board, numa, vram, cache, partition, dfc_ucode, fb_info, num_vf) - else: - logging.info("No GPU devices present") - - if (gpu_options and (len(self.device_handles) == 0)): - logging.error("No GPU devices present") - sys.exit(-1) - - if (len(self.cpu_handles) == 0 and len(self.device_handles) == 0): - logging.error("No CPU and GPU devices present") - sys.exit(-1) def firmware(self, args, multiple_devices=False, gpu=None, fw_list=True): @@ -972,7 +998,7 @@ class AMDSMICommands(): Args: args (Namespace): Namespace containing the parsed CLI args multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. - watching_output (bool, optional): True if watch option has been set. Defaults to False. + watching_output (bool, optional): True if watch argument has been set. Defaults to False. gpu (device_handle, optional): device_handle for target device. Defaults to None. usage (bool, optional): Value override for args.usage. Defaults to None. watch (Positive int, optional): Value override for args.watch. Defaults to None. @@ -1077,7 +1103,7 @@ class AMDSMICommands(): # Handle watch logic, will only enter this block once if args.watch: - self.helpers.handle_watch(args=args, subcommand=self.metric, logger=self.logger) + self.helpers.handle_watch(args=args, subcommand=self.metric_gpu, logger=self.logger) return # Handle multiple GPUs @@ -1125,6 +1151,7 @@ class AMDSMICommands(): logging.debug(f"Metric Arg information for GPU {gpu_id} on {self.helpers.os_info()}") logging.debug(f"Args: {current_platform_args}") logging.debug(f"Values: {current_platform_values}") + # Set the platform applicable args to True if no args are set if not any(current_platform_values): for arg in current_platform_args: @@ -1653,14 +1680,12 @@ class AMDSMICommands(): self.logger.store_watch_output(multiple_device_enabled=False) - def metric_cpu(self, args, multiple_devices=False, cpu=None, power_metrics=None, prochot=None, - freq_metrics=None, c0_res=None, lclk_dpm_level=None,pwr_svi_telemtry_rails=None, - io_bandwidth=None, xgmi_bandwidth=None, enable_apb=None, disable_apb=None, - set_pow_limit=None, set_xgmi_link_width=None, set_lclk_dpm_level=None, - set_soc_boost_limit=None, metrics_ver=None, metrics_table=None, socket_energy=None, - set_pwr_eff_mode=None, ddr_bandwidth=None, cpu_temp=None, dimm_temp_range_rate=None, - dimm_pow_conumption=None, dimm_thermal_sensor=None, set_gmi3_link_width=None, - set_pcie_lnk_rate=None, set_df_pstate_range=None): + def metric_cpu(self, args, multiple_devices=False, cpu=None, cpu_power_metrics=None, cpu_prochot=None, + cpu_freq_metrics=None, cpu_c0_res=None, cpu_lclk_dpm_level=None, + cpu_pwr_svi_telemtry_rails=None, cpu_io_bandwidth=None, cpu_xgmi_bandwidth=None, + cpu_metrics_ver=None, cpu_metrics_table=None, cpu_socket_energy=None, + cpu_ddr_bandwidth=None, cpu_temp=None, cpu_dimm_temp_range_rate=None, + cpu_dimm_pow_consumption=None, cpu_dimm_thermal_sensor=None): """Get Metric information for target cpu Args: @@ -1668,531 +1693,364 @@ class AMDSMICommands(): multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. cpu (cpu_handle, optional): device_handle for target device. Defaults to None. cpu_power_metrics (bool, optional): Value override for args.cpu_power_metrics. Defaults to None - prochot (bool, optional): Value override for args.prochot. Defaults to None. - freq_metrics (bool, optional): Value override for args.freq_metrics. Defaults to None. - c0_res (bool, optional): Value override for args.c0_res. Defaults to None - lclk_dpm_level (list, optional): Value override for args.lclk_dpm_level. Defaults to None - pwr_svi_telemtry_rails (list, optional): value override for args.pwr_svi_telemtry_rails. Defaults to None - io_bandwidth (list, optional): value override for args.io_bandwidth. Defaults to None - xgmi_bandwidth (list, optional): value override for args.xgmi_bandwidth. Defaults to None - enable_apb (bool, optional): Value override for args.enable_apb. Defaults to None - disable_apb (bool, optional): Value override for args.disable_apb. Defaults to None - set_pow_limit (int, optional): Value override for args.cpu_set_pow_limit. Defaults to None - set_xgmi_link_width (list, optional): Value override for args.set_cpu_xgmi_link_width. Defaults to None - set_lclk_dpm_level (list, optional): Value override for args.set_cpu_lclk_dpm_level. Defaults to None - set_soc_boost_limit (list, optional): Value override for args.set_soc_boost_limit. Defaults to None - metrics_ver (bool, optional): Value override for args.cpu_metrics_ver. Defaults to None - metrics_table (bool, optional): Value override for args.cpu_metrics_table. Defaults to None - socket_energy (bool, optional): Value override for args.socket_energy. Defaults to None - set_pwr_eff_mode (list, optional): Value override for args.set_cpu_pwr_eff_mode. Defaults to None - ddr_bandwidth (bool, optional): Value override for args.ddr_bandwidth. Defaults to None + cpu_prochot (bool, optional): Value override for args.cpu_prochot. Defaults to None. + cpu_freq_metrics (bool, optional): Value override for args.cpu_freq_metrics. Defaults to None. + cpu_c0_res (bool, optional): Value override for args.cpu_c0_res. Defaults to None + cpu_lclk_dpm_level (list, optional): Value override for args.cpu_lclk_dpm_level. Defaults to None + cpu_pwr_svi_telemtry_rails (list, optional): value override for args.cpu_pwr_svi_telemtry_rails. Defaults to None + cpu_io_bandwidth (list, optional): value override for args.cpu_io_bandwidth. Defaults to None + cpu_xgmi_bandwidth (list, optional): value override for args.cpu_xgmi_bandwidth. Defaults to None + cpu_metrics_ver (bool, optional): Value override for args.cpu_metrics_ver. Defaults to None + cpu_metrics_table (bool, optional): Value override for args.cpu_metrics_table. Defaults to None + cpu_socket_energy (bool, optional): Value override for args.cpu_socket_energy. Defaults to None + cpu_ddr_bandwidth (bool, optional): Value override for args.cpu_ddr_bandwidth. Defaults to None cpu_temp (bool, optional): Value override for args.cpu_temp. Defaults to None - dimm_temp_range_rate (list, optional): Dimm address.Value override for args.cpu_dimm_temp_range_rate. Defaults to None - dimm_pow_conumption (list, optional): Dimm address. Value override for args.cpu_dimm_pow_conumption. Defaults to None - dimm_thermal_sensor (list, optional): Dimm address. Value override for args.cpu_dimm_thermal_sensor. Defaults to None - set_gmi3_link_width (list, optional): Min and Max link wdiths.Value override for args.set_cpu_gmi3_link_width. Defaults to None - set_pcie_lnk_rate (list, optional): Link rate.Value override for args.set_cpu_pcie_lnk_rate. Defaults to None - set_df_pstate_range (list, optional): Max and Min pstates.Value override for args.set_cpu_df_pstate_range. Defaults to None + cpu_dimm_temp_range_rate (list, optional): Dimm address. Value override for args.cpu_dimm_temp_range_rate. Defaults to None + cpu_dimm_pow_consumption (list, optional): Dimm address. Value override for args.cpu_dimm_pow_consumption. Defaults to None + cpu_dimm_thermal_sensor (list, optional): Dimm address. Value override for args.cpu_dimm_thermal_sensor. Defaults to None + Returns: None: Print output via AMDSMILogger to destination """ - if (cpu): + if cpu: args.cpu = cpu - if (power_metrics): - args.cpu_power_metrics = power_metrics - if (prochot): - args.cpu_prochot = prochot - if (freq_metrics): - args.cpu_freq_metrics = freq_metrics - if (c0_res): - args.cpu_c0_res = c0_res - if (lclk_dpm_level): - args.cpu_lclk_dpm_level = lclk_dpm_level - if (pwr_svi_telemtry_rails): - args.cpu_pwr_svi_telemtry_rails = pwr_svi_telemtry_rails - if (io_bandwidth): - args.cpu_io_bandwidth = io_bandwidth - if (xgmi_bandwidth): - args.cpu_xgmi_bandwidth = xgmi_bandwidth - if (enable_apb): - args.cpu_enable_apb = enable_apb - if (disable_apb): - args.cpu_disable_apb = disable_apb - if (set_pow_limit): - args.set_cpu_pow_limit = set_pow_limit - if (set_xgmi_link_width): - args.set_xgmi_link_width = set_xgmi_link_width - if (set_lclk_dpm_level): - args.set_lclk_dpm_level = set_lclk_dpm_level - if (set_soc_boost_limit): - args.set_soc_boost_limit = set_soc_boost_limit - if (metrics_ver): - args.cpu_metrics_ver = metrics_ver - if (metrics_table): - args.cpu_metrics_table = metrics_table - if (socket_energy): - args.socket_energy = socket_energy - if (set_pwr_eff_mode): - args.set_cpu_pwr_eff_mode = set_pwr_eff_mode - if (ddr_bandwidth): - args.set_cpu_pwr_eff_mode = ddr_bandwidth - if (cpu_temp): + if cpu_power_metrics: + args.cpu_power_metrics = cpu_power_metrics + if cpu_prochot: + args.cpu_prochot = cpu_prochot + if cpu_freq_metrics: + args.cpu_freq_metrics = cpu_freq_metrics + if cpu_c0_res: + args.cpu_c0_res = cpu_c0_res + if cpu_lclk_dpm_level: + args.cpu_lclk_dpm_level = cpu_lclk_dpm_level + if cpu_pwr_svi_telemtry_rails: + args.cpu_pwr_svi_telemtry_rails = cpu_pwr_svi_telemtry_rails + if cpu_io_bandwidth: + args.cpu_io_bandwidth = cpu_io_bandwidth + if cpu_xgmi_bandwidth: + args.cpu_xgmi_bandwidth = cpu_xgmi_bandwidth + if cpu_metrics_ver: + args.cpu_metrics_ver = cpu_metrics_ver + if cpu_metrics_table: + args.cpu_metrics_table = cpu_metrics_table + if cpu_socket_energy: + args.cpu_socket_energy = cpu_socket_energy + if cpu_ddr_bandwidth: + args.cpu_ddr_bandwidth = cpu_ddr_bandwidth + if cpu_temp: args.cpu_temp = cpu_temp - if (dimm_temp_range_rate): - args.cpu_dimm_temp_range_rate = dimm_temp_range_rate - if (dimm_pow_conumption): - args.cpu_dimm_pow_conumption = dimm_pow_conumption - if (dimm_thermal_sensor): - args.cpu_dimm_thermal_sensor = dimm_thermal_sensor - if (set_gmi3_link_width): - args.set_cpu_gmi3_link_width = set_gmi3_link_width - if (set_pcie_lnk_rate): - args.set_cpu_pcie_lnk_rate = set_pcie_lnk_rate - if (set_df_pstate_range): - args.set_cpu_df_pstate_range = set_df_pstate_range - + if cpu_dimm_temp_range_rate: + args.cpu_dimm_temp_range_rate = cpu_dimm_temp_range_rate + if cpu_dimm_pow_consumption: + args.cpu_dimm_pow_consumption = cpu_dimm_pow_consumption + if cpu_dimm_thermal_sensor: + args.cpu_dimm_thermal_sensor = cpu_dimm_thermal_sensor #store cpu args that are applicable to the current platform curr_platform_cpu_args = ["cpu_power_metrics", "cpu_prochot", "cpu_freq_metrics", "cpu_c0_res", "cpu_lclk_dpm_level", "cpu_pwr_svi_telemtry_rails", - "cpu_io_bandwidth", "cpu_xgmi_bandwidth", "cpu_disable_apb", - "set_cpu_pow_limit","set_cpu_xgmi_link_width", "set_cpu_lclk_dpm_level", - "set_soc_boost_limit", "cpu_metrics_ver", "cpu_metrics_table", - "socket_energy", "set_cpu_pwr_eff_mode", "cpu_ddr_bandwidth", - "cpu_temp", "cpu_dimm_temp_range_rate", "cpu_dimm_pow_conumption", - "cpu_dimm_thermal_sensor", "set_cpu_gmi3_link_width", "set_cpu_pcie_lnk_rate", - "set_cpu_df_pstate_range", "cpu_enable_apb"] + "cpu_io_bandwidth", "cpu_xgmi_bandwidth", "cpu_metrics_ver", + "cpu_metrics_table", "cpu_socket_energy", "cpu_ddr_bandwidth", + "cpu_temp", "cpu_dimm_temp_range_rate", "cpu_dimm_pow_consumption", + "cpu_dimm_thermal_sensor"] curr_platform_cpu_values = [args.cpu_power_metrics, args.cpu_prochot, args.cpu_freq_metrics, args.cpu_c0_res, args.cpu_lclk_dpm_level, args.cpu_pwr_svi_telemtry_rails, - args.cpu_io_bandwidth, args.cpu_xgmi_bandwidth, args.cpu_disable_apb, - args.set_cpu_pow_limit, args.set_cpu_xgmi_link_width, args.set_cpu_lclk_dpm_level, - args.set_soc_boost_limit, args.cpu_metrics_ver, args.cpu_metrics_table, - args.socket_energy, args.set_cpu_pwr_eff_mode, args.cpu_ddr_bandwidth, - args.cpu_temp, args.cpu_dimm_temp_range_rate, args.cpu_dimm_pow_conumption, - args.cpu_dimm_thermal_sensor, args.set_cpu_gmi3_link_width, args.set_cpu_pcie_lnk_rate, - args.set_cpu_df_pstate_range, args.cpu_enable_apb] + args.cpu_io_bandwidth, args.cpu_xgmi_bandwidth, args.cpu_metrics_ver, + args.cpu_metrics_table, args.cpu_socket_energy, args.cpu_ddr_bandwidth, + args.cpu_temp, args.cpu_dimm_temp_range_rate, args.cpu_dimm_pow_consumption, + args.cpu_dimm_thermal_sensor] - - # Handle No CPU passed + # Handle No CPU passed (fall back as this should be defined in metric()) if args.cpu == None: args.cpu = self.cpu_handles - if (not any(curr_platform_cpu_values)): + if not any(curr_platform_cpu_values): for arg in curr_platform_cpu_args: - if arg not in("cpu_lclk_dpm_level", "cpu_io_bandwidth", "cpu_xgmi_bandwidth", "cpu_disable_apb", - "set_cpu_pow_limit", "set_cpu_xgmi_link_width", "set_cpu_lclk_dpm_level", - "set_soc_boost_limit", "set_cpu_pwr_eff_mode", "cpu_dimm_temp_range_rate", - "cpu_dimm_temp_range_rate", "cpu_dimm_pow_conumption", "cpu_dimm_thermal_sensor", - "set_cpu_gmi3_link_width", "set_cpu_pcie_lnk_rate", "set_cpu_df_pstate_range", - "cpu_enable_apb"): + if arg not in("cpu_lclk_dpm_level", "cpu_io_bandwidth", "cpu_xgmi_bandwidth", + "cpu_dimm_temp_range_rate", "cpu_dimm_pow_consumption", "cpu_dimm_thermal_sensor"): setattr(args, arg, True) - if (len(self.cpu_handles)): - handled_multiple_cpus, device_handle = self.helpers.handle_cpus(args, - self.logger, - self.metric_cpu) - if handled_multiple_cpus: - return # This function is recursive - args.cpu = device_handle - # get cpu id for logging - cpu_id = self.helpers.get_cpu_id_from_device_handle(args.cpu) - logging.debug(f"Metric Arg information for CPU {cpu_id} on {self.helpers.os_info()}") + handled_multiple_cpus, device_handle = self.helpers.handle_cpus(args, + self.logger, + self.metric_cpu) + if handled_multiple_cpus: + return # This function is recursive + args.cpu = device_handle + # get cpu id for logging + cpu_id = self.helpers.get_cpu_id_from_device_handle(args.cpu) + logging.debug(f"Metric Arg information for CPU {cpu_id} on {self.helpers.os_info()}") - static_dict = {} - if (args.cpu_power_metrics): - static_dict["power_metrics"] = {} - try: - soc_pow = amdsmi_interface.amdsmi_get_cpu_socket_power(args.cpu) - static_dict["power_metrics"]["socket power"] = soc_pow - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["power_metrics"]["socket power"] = "N/A" - logging.debug("Failed to get socket power for cpu %s | %s", cpu_id, e.get_error_info()) + static_dict = {} + if args.cpu_power_metrics: + static_dict["power_metrics"] = {} + try: + soc_pow = amdsmi_interface.amdsmi_get_cpu_socket_power(args.cpu) + static_dict["power_metrics"]["socket power"] = soc_pow + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["power_metrics"]["socket power"] = "N/A" + logging.debug("Failed to get socket power for cpu %s | %s", cpu_id, e.get_error_info()) - try: - soc_pow_limit = amdsmi_interface.amdsmi_get_cpu_socket_power_cap(args.cpu) - static_dict["power_metrics"]["socket power limit"] = soc_pow_limit - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["power_metrics"]["socket power limit"] = "N/A" - logging.debug("Failed to get socket power limit for cpu %s | %s", cpu_id, e.get_error_info()) + try: + soc_pwr_limit = amdsmi_interface.amdsmi_get_cpu_socket_power_cap(args.cpu) + static_dict["power_metrics"]["socket power limit"] = soc_pwr_limit + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["power_metrics"]["socket power limit"] = "N/A" + logging.debug("Failed to get socket power limit for cpu %s | %s", cpu_id, e.get_error_info()) - try: - soc_max_pow_limit = amdsmi_interface.amdsmi_get_cpu_socket_power_cap_max(args.cpu) - static_dict["power_metrics"]["socket max power limit"] = soc_max_pow_limit - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["power_metrics"]["socket max power limit"] = "N/A" - logging.debug("Failed to get max socket power limit for cpu %s | %s", cpu_id, e.get_error_info()) + try: + soc_max_pwr_limit = amdsmi_interface.amdsmi_get_cpu_socket_power_cap_max(args.cpu) + static_dict["power_metrics"]["socket max power limit"] = soc_max_pwr_limit + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["power_metrics"]["socket max power limit"] = "N/A" + logging.debug("Failed to get max socket power limit for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_prochot: + static_dict["prochot"] = {} + try: + proc_status = amdsmi_interface.amdsmi_get_cpu_prochot_status(args.cpu) + static_dict["prochot"]["prochot_status"] = proc_status + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["prochot"]["prochot_status"] = "N/A" + logging.debug("Failed to get prochot status for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_freq_metrics: + static_dict["freq_metrics"] = {} + try: + fclk_mclk = amdsmi_interface.amdsmi_get_cpu_fclk_mclk(args.cpu) + static_dict["freq_metrics"]["fclkmemclk"] = fclk_mclk + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["freq_metrics"]["fclkmemclk"] = "N/A" + logging.debug("Failed to get current fclkmemclk freq for cpu %s | %s", cpu_id, e.get_error_info()) - if (args.cpu_prochot): - static_dict["prochot"] = {} - try: - proc_status = amdsmi_interface.amdsmi_get_cpu_prochot_status(args.cpu) - static_dict["prochot"]["prochot_status"] = proc_status - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["prochot"]["prochot_status"] = "N/A" - logging.debug("Failed to get prochot status for cpu %s | %s", cpu_id, e.get_error_info()) + try: + cclk_freq = amdsmi_interface.amdsmi_get_cpu_cclk_limit(args.cpu) + static_dict["freq_metrics"]["cclkfreqlimit"] = cclk_freq + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["freq_metrics"]["cclkfreqlimit"] = "N/A" + logging.debug("Failed to get current cclk freq for cpu %s | %s", cpu_id, e.get_error_info()) - if (args.cpu_freq_metrics): - static_dict["freq_metrics"] = {} - try: - fclk_mclk = amdsmi_interface.amdsmi_get_cpu_fclk_mclk(args.cpu) - static_dict["freq_metrics"]["fclkmemclk"] = fclk_mclk - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["freq_metrics"]["fclkmemclk"] = "N/A" - logging.debug("Failed to get current fclkmemclk freq for cpu %s | %s", cpu_id, e.get_error_info()) + try: + soc_cur_freq_limit = amdsmi_interface.amdsmi_get_cpu_socket_current_active_freq_limit(args.cpu) + static_dict["freq_metrics"]["soc_current_active_freq_limit"] = soc_cur_freq_limit + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["freq_metrics"]["soc_current_active_freq_limit"] = "N/A" + logging.debug("Failed to get socket current freq limit for cpu %s | %s", cpu_id, e.get_error_info()) - try: - cclk_freq = amdsmi_interface.amdsmi_get_cpu_cclk_limit(args.cpu) - static_dict["freq_metrics"]["cclkfreqlimit"] = cclk_freq - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["freq_metrics"]["cclkfreqlimit"] = "N/A" - logging.debug("Failed to get current cclk freq for cpu %s | %s", cpu_id, e.get_error_info()) + try: + soc_freq_range = amdsmi_interface.amdsmi_get_cpu_socket_freq_range(args.cpu) + static_dict["freq_metrics"]["soc_freq_range"] = soc_freq_range + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["freq_metrics"]["soc_freq_range"] = "N/A" + logging.debug("Failed to get socket freq range for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_c0_res: + static_dict["c0_residency"] = {} + try: + residency = amdsmi_interface.amdsmi_get_cpu_socket_c0_residency(args.cpu) + static_dict["c0_residency"]["residency"] = residency + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["c0_residency"]["residency"] = "N/A" + logging.debug("Failed to get C0 residency for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_lclk_dpm_level: + static_dict["socket_dpm"] = {} + try: + dpm_val = amdsmi_interface.amdsmi_get_cpu_socket_lclk_dpm_level(args.cpu, + args.cpu_lclk_dpm_level[0][0]) + static_dict["socket_dpm"]["dpml_level_range"] = dpm_val + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["socket_dpm"]["dpml_level_range"] = "N/A" + logging.debug("Failed to get socket dpm level range for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_pwr_svi_telemtry_rails: + static_dict["svi_telemetry_all_rails"] = {} + try: + power = amdsmi_interface.amdsmi_get_cpu_pwr_svi_telemetry_all_rails(args.cpu) + static_dict["svi_telemetry_all_rails"]["power"] = power + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["c0_residency"]["residency"] = "N/A" + logging.debug("Failed to get svi telemetry all rails for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_io_bandwidth: + static_dict["io_bandwidth"] = {} + try: + bandwidth = amdsmi_interface.amdsmi_get_cpu_current_io_bandwidth(args.cpu, + int(args.cpu_io_bandwidth[0][0]), + args.cpu_io_bandwidth[0][1]) + static_dict["io_bandwidth"]["band_width"] = bandwidth + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["io_bandwidth"]["band_width"] = "N/A" + logging.debug("Failed to get io bandwidth for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_xgmi_bandwidth: + static_dict["xgmi_bandwidth"] = {} + try: + bandwidth = amdsmi_interface.amdsmi_get_cpu_current_xgmi_bw(args.cpu, + int(args.cpu_xgmi_bandwidth[0][0]), + args.cpu_xgmi_bandwidth[0][1]) + static_dict["xgmi_bandwidth"]["band_width"] = bandwidth + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["xgmi_bandwidth"]["band_width"] = "N/A" + logging.debug("Failed to get xgmi bandwidth for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_metrics_ver: + static_dict["metric_version"] = {} + try: + version = amdsmi_interface.amdsmi_get_hsmp_metrics_table_version(args.cpu) + static_dict["metric_version"]["version"] = version + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["metric_version"]["version"] = "N/A" + logging.debug("Failed to get metrics table version for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_metrics_table: + static_dict["metrics_table"] = {} + try: + cpu_fam = amdsmi_interface.amdsmi_get_cpu_family() + static_dict["metrics_table"]["cpu_family"] = cpu_fam + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["metrics_table"]["cpu_family"] = "N/A" + logging.debug("Failed to get cpu family | %s", e.get_error_info()) + try: + cpu_mod = amdsmi_interface.amdsmi_get_cpu_model() + static_dict["metrics_table"]["cpu_model"] = cpu_mod + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["metrics_table"]["cpu_model"] = "N/A" + logging.debug("Failed to get cpu model | %s", e.get_error_info()) + try: + cpu_metrics_table = amdsmi_interface.amdsmi_get_hsmp_metrics_table(args.cpu) + static_dict["metrics_table"]["response"] = cpu_metrics_table + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["metrics_table"]["response"] = "N/A" + logging.debug("Failed to get metrics table for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_socket_energy: + static_dict["socket_energy"] = {} + try: + energy = amdsmi_interface.amdsmi_get_cpu_socket_energy(args.cpu) + static_dict["socket_energy"]["response"] = energy + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["socket_energy"]["response"] = "N/A" + logging.debug("Failed to get socket energy for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_ddr_bandwidth: + static_dict["ddr_bandwidth"] = {} + try: + resp = amdsmi_interface.amdsmi_get_cpu_ddr_bw(args.cpu) + static_dict["ddr_bandwidth"]["response"] = resp + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["ddr_bandwidth"]["response"] = "N/A" + logging.debug("Failed to get ddr bandwdith for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_temp: + static_dict["cpu_temp"] = {} + try: + resp = amdsmi_interface.amdsmi_get_cpu_socket_temperature(args.cpu) + static_dict["cpu_temp"]["response"] = resp + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["cpu_temp"]["response"] = "N/A" + logging.debug("Failed to get cpu temperature for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_dimm_temp_range_rate: + static_dict["dimm_temp_range_rate"] = {} + try: + resp = amdsmi_interface.amdsmi_get_cpu_dimm_temp_range_and_refresh_rate(args.cpu, args.cpu_dimm_temp_range_rate[0][0]) + static_dict["dimm_temp_range_rate"]["response"] = resp + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["dimm_temp_range_rate"]["response"] = "N/A" + logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_dimm_pow_consumption: + static_dict["dimm_pow_consumption"] = {} + try: + resp = amdsmi_interface.amdsmi_get_cpu_dimm_power_consumption(args.cpu, args.cpu_dimm_pow_consumption[0][0]) + static_dict["dimm_pow_consumption"]["response"] = resp + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["dimm_pow_consumption"]["response"] = "N/A" + logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) + if args.cpu_dimm_thermal_sensor: + static_dict["dimm_thermal_sensor"] = {} + try: + resp = amdsmi_interface.amdsmi_get_cpu_dimm_thermal_sensor(args.cpu, args.cpu_dimm_thermal_sensor[0][0]) + static_dict["dimm_thermal_sensor"]["response"] = resp + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["dimm_thermal_sensor"]["response"] = "N/A" + logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) - try: - soc_cur_freq_limit = amdsmi_interface.amdsmi_get_cpu_socket_current_active_freq_limit(args.cpu) - static_dict["freq_metrics"]["soc_current_active_freq_limit"] = soc_cur_freq_limit - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["freq_metrics"]["soc_current_active_freq_limit"] = "N/A" - logging.debug("Failed to get socket current freq limit for cpu %s | %s", cpu_id, e.get_error_info()) - - try: - soc_freq_range = amdsmi_interface.amdsmi_get_cpu_socket_freq_range(args.cpu) - static_dict["freq_metrics"]["soc_freq_range"] = soc_freq_range - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["freq_metrics"]["soc_freq_range"] = "N/A" - logging.debug("Failed to get socket freq range for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_c0_res): - static_dict["c0_residency"] = {} - try: - residency = amdsmi_interface.amdsmi_get_cpu_socket_c0_residency(args.cpu) - static_dict["c0_residency"]["residency"] = residency - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["c0_residency"]["residency"] = "N/A" - logging.debug("Failed to get C0 residency for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_lclk_dpm_level): - static_dict["socket_dpm"] = {} - try: - dpm_val = amdsmi_interface.amdsmi_get_cpu_socket_lclk_dpm_level(args.cpu, - args.cpu_lclk_dpm_level[0][0]) - static_dict["socket_dpm"]["dpml_level_range"] = dpm_val - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["socket_dpm"]["dpml_level_range"] = "N/A" - logging.debug("Failed to get socket dpm level range for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_pwr_svi_telemtry_rails): - static_dict["svi_telemetry_all_rails"] = {} - try: - power = amdsmi_interface.amdsmi_get_cpu_pwr_svi_telemetry_all_rails(args.cpu) - static_dict["svi_telemetry_all_rails"]["power"] = power - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["c0_residency"]["residency"] = "N/A" - logging.debug("Failed to get svi telemetry all rails for cpu %s | %s", cpu_id, e.get_error_info()) - if (args.cpu_io_bandwidth): - static_dict["io_bandwidth"] = {} - try: - bandwidth = amdsmi_interface.amdsmi_get_cpu_current_io_bandwidth(args.cpu, - int(args.cpu_io_bandwidth[0][0]), - args.cpu_io_bandwidth[0][1]) - static_dict["io_bandwidth"]["band_width"] = bandwidth - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["io_bandwidth"]["band_width"] = "N/A" - logging.debug("Failed to get io bandwidth for cpu %s | %s", cpu_id, e.get_error_info()) - if (args.cpu_xgmi_bandwidth): - static_dict["xgmi_bandwidth"] = {} - try: - bandwidth = amdsmi_interface.amdsmi_get_cpu_current_xgmi_bw(args.cpu, - int(args.cpu_xgmi_bandwidth[0][0]), - args.cpu_xgmi_bandwidth[0][1]) - static_dict["xgmi_bandwidth"]["band_width"] = bandwidth - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["xgmi_bandwidth"]["band_width"] = "N/A" - logging.debug("Failed to get xgmi bandwidth for cpu %s | %s", cpu_id, e.get_error_info()) - if (args.cpu_enable_apb): - static_dict["apbenable"] = {} - try: - amdsmi_interface.amdsmi_cpu_apb_enable(args.cpu) - static_dict["apbenable"]["state"] = "Enabled DF - Pstate performance boost algorithm" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["apbenable"]["state"] = "N/A" - logging.debug("Failed to enable APB for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_disable_apb): - static_dict["apbdisable"] = {} - try: - amdsmi_interface.amdsmi_cpu_apb_disable(args.cpu, args.cpu_disable_apb[0][0]) - static_dict["apbdisable"]["state"] = "Disabled DF - Pstate performance boost algorithm" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["apbdisable"]["state"] = "N/A" - logging.debug("Failed to enable APB for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.set_cpu_pow_limit): - static_dict["set_pow_limit"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_socket_power_cap(args.cpu, args.set_cpu_pow_limit[0][0]) - static_dict["set_pow_limit"]["Response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_pow_limit"]["Response"] = "N/A" - logging.debug("Failed to set power limit for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.set_cpu_xgmi_link_width): - static_dict["set_xgmi_link_width"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_xgmi_width(args.cpu, args.set_cpu_xgmi_link_width[0][0], - args.set_cpu_xgmi_link_width[0][1]) - static_dict["set_xgmi_link_width"]["Response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_xgmi_link_width"]["Response"] = "N/A" - logging.debug("Failed to set xgmi link width for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.set_cpu_lclk_dpm_level): - static_dict["set_lclk_dpm_level"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_socket_lclk_dpm_level(args.cpu, args.set_cpu_lclk_dpm_level[0][0], - args.set_cpu_lclk_dpm_level[0][1], - args.set_cpu_lclk_dpm_level[0][2]) - static_dict["set_lclk_dpm_level"]["Response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_lclk_dpm_level"]["Response"] = "N/A" - logging.debug("Failed to set lclk dpm level for cpu %s | %s", cpu_id, e.get_error_info()) - if (args.set_soc_boost_limit): - static_dict["set_soc_boost_limit"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_socket_boostlimit(args.cpu, args.set_soc_boost_limit[0][0]) - static_dict["set_soc_boost_limit"]["Response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_soc_boost_limit"]["Response"] = "N/A" - logging.debug("Failed to set socket boost limit for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_metrics_ver): - static_dict["metric_version"] = {} - try: - version = amdsmi_interface.amdsmi_get_hsmp_metrics_table_version(args.cpu) - static_dict["metric_version"]["version"] = version - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["metric_version"]["version"] = "N/A" - logging.debug("Failed to get metrics table version for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_metrics_table): - static_dict["metrics_table"] = {} - try: - cpu_fam = amdsmi_interface.amdsmi_get_cpu_family() - static_dict["metrics_table"]["cpu_family"] = cpu_fam - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["metrics_table"]["cpu_family"] = "N/A" - logging.debug("Failed to get cpu family | %s", e.get_error_info()) - try: - cpu_mod = amdsmi_interface.amdsmi_get_cpu_model() - static_dict["metrics_table"]["cpu_model"] = cpu_mod - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["metrics_table"]["cpu_model"] = "N/A" - logging.debug("Failed to get cpu model | %s", e.get_error_info()) - try: - metrics_table = amdsmi_interface.amdsmi_get_hsmp_metrics_table(args.cpu) - static_dict["metrics_table"]["response"] = metrics_table - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["metrics_table"]["response"] = "N/A" - logging.debug("Failed to get metrics table for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.socket_energy): - static_dict["socket_energy"] = {} - try: - energy = amdsmi_interface.amdsmi_get_cpu_socket_energy(args.cpu) - static_dict["socket_energy"]["response"] = energy - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["socket_energy"]["response"] = "N/A" - logging.debug("Failed to get socket energy for cpu %s | %s", cpu_id, e.get_error_info()) - - if(args.set_cpu_pwr_eff_mode): - static_dict["set_pwr_eff_mode"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_pwr_efficiency_mode(args.cpu, args.set_cpu_pwr_eff_mode[0][0]) - static_dict["set_pwr_eff_mode"]["Response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_pwr_eff_mode"]["Response"] = "N/A" - logging.debug("Failed to set power efficiency mode for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_ddr_bandwidth): - static_dict["ddr_bandwidth"] = {} - try: - resp = amdsmi_interface.amdsmi_get_cpu_ddr_bw(args.cpu) - static_dict["ddr_bandwidth"]["response"] = resp - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["ddr_bandwidth"]["response"] = "N/A" - logging.debug("Failed to get ddr bandwdith for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_temp): - static_dict["cpu_temp"] = {} - try: - resp = amdsmi_interface.amdsmi_get_cpu_socket_temperature(args.cpu) - static_dict["cpu_temp"]["response"] = resp - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["cpu_temp"]["response"] = "N/A" - logging.debug("Failed to get cpu temperature for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_dimm_temp_range_rate): - static_dict["dimm_temp_range_rate"] = {} - try: - resp = amdsmi_interface.amdsmi_get_cpu_dimm_temp_range_and_refresh_rate(args.cpu, args.cpu_dimm_temp_range_rate[0][0]) - static_dict["dimm_temp_range_rate"]["response"] = resp - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["dimm_temp_range_rate"]["response"] = "N/A" - logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_dimm_pow_conumption): - static_dict["dimm_pow_conumption"] = {} - try: - resp = amdsmi_interface.amdsmi_get_cpu_dimm_power_consumption(args.cpu, args.cpu_dimm_pow_conumption[0][0]) - static_dict["dimm_pow_conumption"]["response"] = resp - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["dimm_pow_conumption"]["response"] = "N/A" - logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.cpu_dimm_thermal_sensor): - static_dict["dimm_thermal_sensor"] = {} - try: - resp = amdsmi_interface.amdsmi_get_cpu_dimm_thermal_sensor(args.cpu, args.cpu_dimm_thermal_sensor[0][0]) - static_dict["dimm_thermal_sensor"]["response"] = resp - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["dimm_thermal_sensor"]["response"] = "N/A" - logging.debug("Failed to get dimm temperature range and refresh rate for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.set_cpu_gmi3_link_width): - static_dict["set_gmi3_link_width"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_gmi3_link_width_range(args.cpu, args.set_cpu_gmi3_link_width[0][0], - args.set_cpu_gmi3_link_width[0][1]) - static_dict["set_gmi3_link_width"]["response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_gmi3_link_width"]["response"] = "N/A" - logging.debug("Failed to set gmi3 link width for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.set_cpu_pcie_lnk_rate): - static_dict["set_pcie_lnk_rate"] = {} - try: - resp = amdsmi_interface.amdsmi_set_cpu_pcie_link_rate(args.cpu, args.set_cpu_pcie_lnk_rate[0][0]) - static_dict["set_pcie_lnk_rate"]["prev_mode"] = resp - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_pcie_lnk_rate"]["prev_mode"] = "N/A" - logging.debug("Failed to set pcie link rate for cpu %s | %s", cpu_id, e.get_error_info()) - - if (args.set_cpu_df_pstate_range): - static_dict["set_df_pstate_range"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_df_pstate_range(args.cpu, args.set_cpu_df_pstate_range[0][0], - args.set_cpu_df_pstate_range[0][1]) - static_dict["set_df_pstate_range"]["response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_df_pstate_range"]["response"] = "N/A" - logging.debug("Failed to set df pstate range for cpu %s | %s", cpu_id, e.get_error_info()) - - multiple_devices_csv_override = False - self.logger.store_cpu_output(args.cpu, 'values', static_dict) - if multiple_devices: - self.logger.store_multiple_device_output() - return # Skip printing when there are multiple devices - self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) + multiple_devices_csv_override = False + self.logger.store_cpu_output(args.cpu, 'values', static_dict) + if multiple_devices: + self.logger.store_multiple_device_output() + return # Skip printing when there are multiple devices + self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) - def metric_core(self, args, multiple_devices=False, core=None, boost_limit=None, - curr_active_freq_core_limit=None, set_core_boost_limit=None, core_energy=None): + def metric_core(self, args, multiple_devices=False, core=None, core_boost_limit=None, + core_curr_active_freq_core_limit=None, core_energy=None): """Get Static information for target core Args: args (Namespace): Namespace containing the parsed CLI args multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. - core (device_handle, optional): device_handle for target device. Defaults to None. - boost_limit (bool, optional): Value override for args.boostlimit. Defaults to None - curr_active_freq_core_limit (bool, optional): Value override for args.boostlimit. Defaults to None - set_core_boost_limit(list, optional): boost limit value.Value override for args.set_core_boost_limit. Defaults to None + core (device_handle, optional): device_handle for target core. Defaults to None. + core_boost_limit (bool, optional): Value override for args.core_boost_limit. Defaults to None + core_curr_active_freq_core_limit (bool, optional): Value override for args.core_curr_active_freq_core_limit. Defaults to None core_energy (bool, optional): Value override for args.core_energy. Defaults to None Returns: None: Print output via AMDSMILogger to destination """ if core: args.core = core - if boost_limit: - args.core_boost_limit = boost_limit - if curr_active_freq_core_limit: - args.core_curr_active_freq_core_limit = curr_active_freq_core_limit - if set_core_boost_limit: - args.set_core_boost_limit = boost_limit + if core_boost_limit: + args.core_boost_limit = core_boost_limit + if core_curr_active_freq_core_limit: + args.core_curr_active_freq_core_limit = core_curr_active_freq_core_limit if core_energy: args.core_energy = core_energy #store core args that are applicable to the current platform - curr_platform_core_args = ["core_boost_limit", "core_curr_active_freq_core_limit", - "set_core_boost_limit","core_energy"] - curr_platform_core_values = [args.core_boost_limit, args.core_curr_active_freq_core_limit, - args.set_core_boost_limit, args.core_energy] + curr_platform_core_args = ["core_boost_limit", "core_curr_active_freq_core_limit", "core_energy"] + curr_platform_core_values = [args.core_boost_limit, args.core_curr_active_freq_core_limit, args.core_energy] - # Handle No core passed + # Handle No cores passed if args.core == None: args.core = self.core_handles - if (not any(curr_platform_core_values)): + if not any(curr_platform_core_values): for arg in curr_platform_core_args: - if arg not in (["set_core_boost_limit"]): - setattr(args, arg, True) + setattr(args, arg, True) - if (len(self.core_handles)): - handled_multiple_cores, device_handle = self.helpers.handle_cores(args, - self.logger, - self.metric_core) - if handled_multiple_cores: - return # This function is recursive - args.core = device_handle - # get core id for logging - core_id = self.helpers.get_core_id_from_device_handle(args.core) - logging.debug(f"Static Arg information for Core {core_id} on {self.helpers.os_info()}") + handled_multiple_cores, device_handle = self.helpers.handle_cores(args, + self.logger, + self.metric_core) + if handled_multiple_cores: + return # This function is recursive + args.core = device_handle + # get core id for logging + core_id = self.helpers.get_core_id_from_device_handle(args.core) + logging.debug(f"Static Arg information for Core {core_id} on {self.helpers.os_info()}") - static_dict = {} - if (args.core_boost_limit): - static_dict["boost_limit"] ={} + static_dict = {} + if args.core_boost_limit: + static_dict["boost_limit"] ={} - try: - boost_limit = amdsmi_interface.amdsmi_get_cpu_core_boostlimit(args.core) - static_dict["boost_limit"]["value"] = boost_limit - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["boost_limit"]["value"] = "N/A" - logging.debug("Failed to get core boost limit for core %s | %s", core_id, e.get_error_info()) - if (args.core_curr_active_freq_core_limit): - static_dict["curr_active_freq_core_limit"] = {} + try: + core_boost_limit = amdsmi_interface.amdsmi_get_cpu_core_boostlimit(args.core) + static_dict["boost_limit"]["value"] = core_boost_limit + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["boost_limit"]["value"] = "N/A" + logging.debug("Failed to get core boost limit for core %s | %s", core_id, e.get_error_info()) + if args.core_curr_active_freq_core_limit: + static_dict["curr_active_freq_core_limit"] = {} - try: - freq = amdsmi_interface.amdsmi_get_cpu_core_current_freq_limit(args.core) - static_dict["curr_active_freq_core_limit"]["value"] = freq - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["curr_active_freq_core_limit"]["value"] = "N/A" - logging.debug("Failed to get current active frequency core for core %s | %s", core_id, e.get_error_info()) + try: + freq = amdsmi_interface.amdsmi_get_cpu_core_current_freq_limit(args.core) + static_dict["curr_active_freq_core_limit"]["value"] = freq + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["curr_active_freq_core_limit"]["value"] = "N/A" + logging.debug("Failed to get current active frequency core for core %s | %s", core_id, e.get_error_info()) + if args.core_energy: + static_dict["core_energy"] ={} + try: + energy = amdsmi_interface.amdsmi_get_cpu_core_energy(args.core) + static_dict["core_energy"]["value"] = energy + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["core_energy"]["value"] = "N/A" + logging.debug("Failed to get core energy for core %s | %s", core_id, e.get_error_info()) - if (args.set_core_boost_limit): - static_dict["set_core_boost_limit"] = {} - try: - amdsmi_interface.amdsmi_set_cpu_core_boostlimit(args.core, args.set_core_boost_limit[0][0]) - static_dict["set_core_boost_limit"]["Response"] = "Set Operation successful" - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["set_core_boost_limit"]["Response"] = "N/A" - logging.debug("Failed to set core boost limit for cpu %s | %s", core_id, e.get_error_info()) - - - if (args.core_energy): - static_dict["core_energy"] ={} - try: - energy = amdsmi_interface.amdsmi_get_cpu_core_energy(args.core) - static_dict["core_energy"]["value"] = energy - except amdsmi_exception.AmdSmiLibraryException as e: - static_dict["core_energy"]["value"] = "N/A" - logging.debug("Failed to get core energy for core %s | %s", core_id, e.get_error_info()) - - - multiple_devices_csv_override = False - self.logger.store_core_output(args.core, 'values', static_dict) - if multiple_devices: - self.logger.store_multiple_device_output() - return # Skip printing when there are multiple devices - self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) + multiple_devices_csv_override = False + self.logger.store_core_output(args.core, 'values', static_dict) + if multiple_devices: + self.logger.store_multiple_device_output() + return # Skip printing when there are multiple devices + self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) def metric(self, args, multiple_devices=False, watching_output=False, gpu=None, @@ -2200,22 +2058,21 @@ class AMDSMICommands(): clock=None, temperature=None, ecc=None, ecc_block=None, pcie=None, fan=None, voltage_curve=None, overdrive=None, perf_level=None, xgmi_err=None, energy=None, mem_usage=None, schedule=None, - guard=None, guest_data=None, fb_usage=None, xgmi=None,cpu=None, - cpu_power_metrics=None, prochot=None, freq_metrics=None, c0_res=None, - lclk_dpm_level=None,pwr_svi_telemtry_rails=None, io_bandwidth=None, - xgmi_bandwidth=None, enable_apb=None, disable_apb=None,set_pow_limit=None, - set_xgmi_link_width=None, set_lclk_dpm_level=None, set_soc_boost_limit=None, - metrics_ver=None, metrics_table=None, socket_energy=None,set_pwr_eff_mode=None, - ddr_bandwidth=None, cpu_temp=None, dimm_temp_range_rate=None,dimm_pow_conumption=None, - dimm_thermal_sensor=None, set_gmi3_link_width=None, set_pcie_lnk_rate=None, - set_df_pstate_range=None, core=None, boost_limit=None, - curr_active_freq_core_limit=None, set_core_boost_limit=None, core_energy=None): + guard=None, guest_data=None, fb_usage=None, xgmi=None, + cpu=None, cpu_power_metrics=None, cpu_prochot=None, cpu_freq_metrics=None, + cpu_c0_res=None, cpu_lclk_dpm_level=None, cpu_pwr_svi_telemtry_rails=None, + cpu_io_bandwidth=None, cpu_xgmi_bandwidth=None, cpu_metrics_ver=None, + cpu_metrics_table=None, cpu_socket_energy=None, cpu_ddr_bandwidth=None, + cpu_temp=None, cpu_dimm_temp_range_rate=None, cpu_dimm_pow_consumption=None, + cpu_dimm_thermal_sensor=None, + core=None, core_boost_limit=None, core_curr_active_freq_core_limit=None, + core_energy=None): """Get Metric information for target gpu Args: args (Namespace): Namespace containing the parsed CLI args multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. - watching_output (bool, optional): True if watch option has been set. Defaults to False. + watching_output (bool, optional): True if watch argument has been set. Defaults to False. gpu (device_handle, optional): device_handle for target device. Defaults to None. usage (bool, optional): Value override for args.usage. Defaults to None. watch (Positive int, optional): Value override for args.watch. Defaults to None. @@ -2239,38 +2096,29 @@ class AMDSMICommands(): guest_data (bool, optional): Value override for args.guest_data. Defaults to None. fb_usage (bool, optional): Value override for args.fb_usage. Defaults to None. xgmi (bool, optional): Value override for args.xgmi. Defaults to None. - cpu (device_handle, optional): cpu index. Defaults to None - cpu_power_metrics (bool, optional): Value override for args.cpu_power_metrics. Defaults to None - prochot (bool, optional): Value override for args.prochot. Defaults to None. - freq_metrics (bool, optional): Value override for args.freq_metrics. Defaults to None. - c0_res (bool, optional): Value override for args.c0_res. Defaults to None - lclk_dpm_level (list, optional): Value override for args.lclk_dpm_level. Defaults to None - pwr_svi_telemtry_rails (list, optional): value override for args.pwr_svi_telemtry_rails. Defaults to None - io_bandwidth (list, optional): value override for args.io_bandwidth. Defaults to None - xgmi_bandwidth (list, optional): value override for args.xgmi_bandwidth. Defaults to None - enable_apb (bool, optional): Value override for args.enable_apb. Defaults to None - disable_apb (bool, optional): Value override for args.disable_apb. Defaults to None - set_pow_limit (int, optional): Value override for args.cpu_set_pow_limit. Defaults to None - set_xgmi_link_width (list, optional): Value override for args.set_cpu_xgmi_link_width. Defaults to None - set_lclk_dpm_level (list, optional): Value override for args.set_cpu_lclk_dpm_level. Defaults to None - set_soc_boost_limit (list, optional): Value override for args.set_soc_boost_limit. Defaults to None - metrics_ver (bool, optional): Value override for args.cpu_metrics_ver. Defaults to None - metrics_table (bool, optional): Value override for args.cpu_metrics_table. Defaults to None - socket_energy (bool, optional): Value override for args.socket_energy. Defaults to None - set_pwr_eff_mode (list, optional): Value override for args.set_cpu_pwr_eff_mode. Defaults to None - ddr_bandwidth (bool, optional): Value override for args.ddr_bandwidth. Defaults to None - cpu_temp (bool, optional): Value override for args.cpu_temp. Defaults to None - dimm_temp_range_rate (list, optional): Dimm address.Value override for args.cpu_dimm_temp_range_rate. Defaults to None - dimm_pow_conumption (list, optional): Dimm address. Value override for args.cpu_dimm_pow_conumption. Defaults to None - dimm_thermal_sensor (list, optional): Dimm address. Value override for args.cpu_dimm_thermal_sensor. Defaults to None - set_gmi3_link_width (list, optional): Min and Max link wdiths.Value override for args.set_cpu_gmi3_link_width. Defaults to None - set_pcie_lnk_rate (list, optional): Link rate.Value override for args.set_cpu_pcie_lnk_rate. Defaults to None - set_df_pstate_range (list, optional): Max and Min pstates.Value override for args.set_cpu_df_pstate_range. Defaults to None - core (int, optional): core index. Value override for args.core.Defaults to None - boost_limit (bool, optional): Value override for args.boostlimit. Defaults to None - curr_active_freq_core_limit (bool, optional): Value override for args.boostlimit. Defaults to None - set_core_boost_limit(list, optional): boost limit value.Value override for args.set_core_boost_limit. Defaults to None + cpu (cpu_handle, optional): device_handle for target device. Defaults to None. + cpu_power_metrics (bool, optional): Value override for args.cpu_power_metrics. Defaults to None + cpu_prochot (bool, optional): Value override for args.cpu_prochot. Defaults to None. + cpu_freq_metrics (bool, optional): Value override for args.cpu_freq_metrics. Defaults to None. + cpu_c0_res (bool, optional): Value override for args.cpu_c0_res. Defaults to None + cpu_lclk_dpm_level (list, optional): Value override for args.cpu_lclk_dpm_level. Defaults to None + cpu_pwr_svi_telemtry_rails (list, optional): value override for args.cpu_pwr_svi_telemtry_rails. Defaults to None + cpu_io_bandwidth (list, optional): value override for args.cpu_io_bandwidth. Defaults to None + cpu_xgmi_bandwidth (list, optional): value override for args.cpu_xgmi_bandwidth. Defaults to None + cpu_metrics_ver (bool, optional): Value override for args.cpu_metrics_ver. Defaults to None + cpu_metrics_table (bool, optional): Value override for args.cpu_metrics_table. Defaults to None + cpu_socket_energy (bool, optional): Value override for args.cpu_socket_energy. Defaults to None + cpu_ddr_bandwidth (bool, optional): Value override for args.cpu_ddr_bandwidth. Defaults to None + cpu_temp (bool, optional): Value override for args.cpu_temp. Defaults to None + cpu_dimm_temp_range_rate (list, optional): Dimm address. Value override for args.cpu_dimm_temp_range_rate. Defaults to None + cpu_dimm_pow_consumption (list, optional): Dimm address. Value override for args.cpu_dimm_pow_consumption. Defaults to None + cpu_dimm_thermal_sensor (list, optional): Dimm address. Value override for args.cpu_dimm_thermal_sensor. Defaults to None + + core (device_handle, optional): device_handle for target core. Defaults to None. + core_boost_limit (bool, optional): Value override for args.core_boost_limit. Defaults to None + core_curr_active_freq_core_limit (bool, optional): Value override for args.core_curr_active_freq_core_limit. Defaults to None + core_energy (bool, optional): Value override for args.core_energy. Defaults to None Raises: IndexError: Index error if gpu list is empty @@ -2278,119 +2126,123 @@ class AMDSMICommands(): Returns: None: Print output via AMDSMILogger to destination """ - gpus = args.gpu - cpus= args.cpu - cores = args.core + # TODO Move watch logic into here and make it driver agnostic or enable it for CPU arguments - # GPU Options check against each attribute - gpu_options = False - if hasattr(args, 'gpu'): - gpu_options |= bool(args.gpu) - if hasattr(args, 'usage'): - gpu_options |= bool(args.usage) - if hasattr(args, 'watch'): - gpu_options |= bool(args.watch) - if hasattr(args, 'watch_time'): - gpu_options |= bool(args.watch_time) - if hasattr(args, 'iterations'): - gpu_options |= bool(args.iterations) - if hasattr(args, 'power'): - gpu_options |= bool(args.power) - if hasattr(args, 'clock'): - gpu_options |= bool(args.clock) - if hasattr(args, 'temperature'): - gpu_options |= bool(args.temperature) - if hasattr(args, 'ecc'): - gpu_options |= bool(args.ecc) - if hasattr(args, 'ecc_block'): - gpu_options |= bool(args.ecc_block) - if hasattr(args, 'pcie'): - gpu_options |= bool(args.pcie) - if hasattr(args, 'fan'): - gpu_options |= bool(args.fan) - if hasattr(args, 'voltage_curve'): - gpu_options |= bool(args.voltage_curve) - if hasattr(args, 'overdrive'): - gpu_options |= bool(args.overdrive) - if hasattr(args, 'perf_level'): - gpu_options |= bool(args.perf_level) - if hasattr(args, 'xgmi_err'): - gpu_options |= bool(args.xgmi_err) - if hasattr(args, 'energy'): - gpu_options |= bool(args.energy) - if hasattr(args, 'mem_usage'): - gpu_options |= bool(args.mem_usage) - if hasattr(args, 'schedule'): - gpu_options |= bool(args.schedule) - if hasattr(args, 'guard'): - gpu_options |= bool(args.guard) - if hasattr(args, 'guest_data'): - gpu_options |= bool(args.guest_data) - if hasattr(args, 'fb_usage'): - gpu_options |= bool(args.fb_usage) - if hasattr(args, 'xgmi'): - gpu_options |= bool(args.xgmi) + # Mutually exculsive args + if gpu: + args.gpu = gpu + if cpu: + args.cpu = cpu + if core: + args.core = core - cpu_options = any([args.cpu, args.cpu_power_metrics, args.cpu_prochot, - args.cpu_freq_metrics, args.cpu_c0_res, args.cpu_lclk_dpm_level, - args.cpu_pwr_svi_telemtry_rails, args.cpu_io_bandwidth, args.cpu_xgmi_bandwidth, - args.cpu_enable_apb, args.cpu_disable_apb, args.set_cpu_pow_limit, - args.set_cpu_xgmi_link_width, args.set_cpu_lclk_dpm_level, - args.set_soc_boost_limit,args.cpu_metrics_ver, args.cpu_metrics_table, - args.socket_energy, args.set_cpu_pwr_eff_mode,args.cpu_ddr_bandwidth, - args.cpu_temp, args.cpu_dimm_temp_range_rate, args.cpu_dimm_pow_conumption, - args.cpu_dimm_thermal_sensor, args.set_cpu_gmi3_link_width, - args.set_cpu_pcie_lnk_rate, args.set_cpu_df_pstate_range]) + # Check if a GPU argument has been set + gpu_args_enabled = False + gpu_attributes = ["usage", "watch", "watch_time", "iterations", "power", "clock", + "temperature", "ecc", "ecc_block", "pcie", "fan", "voltage_curve", + "overdrive", "perf_level", "xgmi_err", "energy", "mem_usage", "schedule", + "guard", "guest_data", "fb_usage", "xgmi"] + for attr in gpu_attributes: + if hasattr(args, attr): + gpu_args_enabled |= bool(getattr(args, attr)) - core_options = any([args.core_boost_limit, args.core_curr_active_freq_core_limit, - args.set_core_boost_limit, args.core_energy]) + # Check if a CPU argument has been set + cpu_args_enabled = False + cpu_attributes = ["cpu_power_metrics", "cpu_prochot", "cpu_freq_metrics", "cpu_c0_res", + "cpu_lclk_dpm_level", "cpu_pwr_svi_telemtry_rails", "cpu_io_bandwidth", + "cpu_xgmi_bandwidth", "cpu_metrics_ver", "cpu_metrics_table", + "cpu_socket_energy", "cpu_ddr_bandwidth", "cpu_temp", "cpu_dimm_temp_range_rate", + "cpu_dimm_pow_consumption", "cpu_dimm_thermal_sensor"] + for attr in cpu_attributes: + if hasattr(args, attr): + cpu_args_enabled |= bool(getattr(args, attr)) - if gpu_options and len(self.device_handles) == 0: - logging.error("No GPU devices present") - sys.exit(-1) + # Check if a Core argument has been set + core_args_enabled = False + core_attributes = ["core_boost_limit", "core_curr_active_freq_core_limit", "core_energy"] + for attr in core_attributes: + if hasattr(args, attr): + core_args_enabled |= bool(getattr(args, attr)) + logging.debug("gpu_args_enabled: %s, cpu_args_enabled: %s, core_args_enabled: %s", + gpu_args_enabled, cpu_args_enabled, core_args_enabled) + logging.debug("args.gpu: %s, args.cpu: %s, args.core: %s", args.gpu, args.cpu, args.core) - if ((len(self.device_handles) and ((((not gpus) and (not cpus) and (not cores)) or gpus) - and not cpu_options and not core_options))): - self.metric_gpu(args, multiple_devices, watching_output, gpu, - usage, watch, watch_time, iterations, power, - clock, temperature, ecc, ecc_block, pcie, - fan, voltage_curve, overdrive, perf_level, - xgmi_err, energy, mem_usage, schedule, - guard, guest_data, fb_usage, xgmi) + # Handle CPU and GPU driver intialization cases + if self.helpers.is_amd_hsmp_initialized() and self.helpers.is_amdgpu_initialized(): + # If a GPU or CPU argument is provided only print out the specified device. + if args.cpu == None and args.gpu == None and args.core == None: + # If no args are set, print out all CPU, GPU, and Core metrics info + if not gpu_args_enabled and not cpu_args_enabled and not core_args_enabled: + args.cpu = self.cpu_handles + args.gpu = self.device_handles + args.core = self.core_handles + # Handle cases where the user has only specified an argument and no specific device + if args.gpu == None and gpu_args_enabled: + args.gpu = self.device_handles + if args.cpu == None and cpu_args_enabled: + args.cpu = self.cpu_handles + if args.core == None and core_args_enabled: + args.core = self.core_handles - if ((len(self.cpu_handles) and ((((not gpus) and (not cpus) and (not cores)) or cpus) - and not gpu_options and not core_options))): - self.logger.clear_multiple_devices_ouput() - self.metric_cpu(args, multiple_devices, cpu, cpu_power_metrics, prochot, - freq_metrics, c0_res, lclk_dpm_level, pwr_svi_telemtry_rails, - io_bandwidth, xgmi_bandwidth, enable_apb, disable_apb, - set_pow_limit,set_xgmi_link_width, set_lclk_dpm_level, - set_soc_boost_limit, metrics_ver, metrics_table, socket_energy, - set_pwr_eff_mode,ddr_bandwidth, cpu_temp, dimm_temp_range_rate, - dimm_pow_conumption,dimm_thermal_sensor, set_gmi3_link_width, - set_pcie_lnk_rate, set_df_pstate_range) - - if (cpu_options and (len(self.cpu_handles) == 0)): - logging.error("No CPU devices present") - sys.exit(-1) - - if ((len(self.core_handles) and ((((not gpus) and (not cpus) and (not cores)) or cores) - and not gpu_options and not cpu_options))): + # Print out CPU first + if args.cpu: + self.metric_cpu(args, multiple_devices, cpu, cpu_power_metrics, cpu_prochot, + cpu_freq_metrics, cpu_c0_res, cpu_lclk_dpm_level, + cpu_pwr_svi_telemtry_rails, cpu_io_bandwidth, cpu_xgmi_bandwidth, + cpu_metrics_ver, cpu_metrics_table, cpu_socket_energy, + cpu_ddr_bandwidth, cpu_temp, cpu_dimm_temp_range_rate, + cpu_dimm_pow_consumption, cpu_dimm_thermal_sensor) + if args.core: + self.logger.output = {} self.logger.clear_multiple_devices_ouput() - self.metric_core(args, multiple_devices, core, boost_limit, - curr_active_freq_core_limit, set_core_boost_limit, - core_energy) + self.metric_core(args, multiple_devices, core, core_boost_limit, + core_curr_active_freq_core_limit, core_energy) + if args.gpu: + self.logger.output = {} + self.logger.clear_multiple_devices_ouput() + self.metric_gpu(args, multiple_devices, watching_output, gpu, + usage, watch, watch_time, iterations, power, + clock, temperature, ecc, ecc_block, pcie, + fan, voltage_curve, overdrive, perf_level, + xgmi_err, energy, mem_usage, schedule, + guard, guest_data, fb_usage, xgmi) + elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized + if args.cpu == None and args.core == None: + # If no args are set, print out all CPU and Core metrics info + if not cpu_args_enabled and not core_args_enabled: + args.cpu = self.cpu_handles + args.core = self.core_handles - if (core_options and (len(self.cpu_handles) == 0)): - logging.error("No Core devices present") - sys.exit(-1) + if args.cpu == None and cpu_args_enabled: + args.cpu = self.cpu_handles + if args.core == None and core_args_enabled: + args.core = self.core_handles + + if args.cpu: + self.metric_cpu(args, multiple_devices, cpu, cpu_power_metrics, cpu_prochot, + cpu_freq_metrics, cpu_c0_res, cpu_lclk_dpm_level, + cpu_pwr_svi_telemtry_rails, cpu_io_bandwidth, cpu_xgmi_bandwidth, + cpu_metrics_ver, cpu_metrics_table, cpu_socket_energy, + cpu_ddr_bandwidth, cpu_temp, cpu_dimm_temp_range_rate, + cpu_dimm_pow_consumption, cpu_dimm_thermal_sensor) + if args.core: + self.logger.output = {} + self.logger.clear_multiple_devices_ouput() + self.metric_core(args, multiple_devices, core, core_boost_limit, + core_curr_active_freq_core_limit, core_energy) + elif self.helpers.is_amdgpu_initialized(): # Only GPU is initialized + if args.gpu == None: + args.gpu = self.device_handles + + self.logger.clear_multiple_devices_ouput() + self.metric_gpu(args, multiple_devices, watching_output, gpu, + usage, watch, watch_time, iterations, power, + clock, temperature, ecc, ecc_block, pcie, + fan, voltage_curve, overdrive, perf_level, + xgmi_err, energy, mem_usage, schedule) - if (len(self.cpu_handles) == 0 and len(self.device_handles) == 0 and - len(self.core_handles) == 0): - logging.error("No CPU and GPU devices present") - sys.exit(-1) def process(self, args, multiple_devices=False, watching_output=False, gpu=None, general=None, engine=None, pid=None, name=None, @@ -2400,7 +2252,7 @@ class AMDSMICommands(): Args: args (Namespace): Namespace containing the parsed CLI args multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. - watching_output (bool, optional): True if watch option has been set. Defaults to False. + watching_output (bool, optional): True if watch argument has been set. Defaults to False. gpu (device_handle, optional): device_handle for target device. Defaults to None. general (bool, optional): Value override for args.general. Defaults to None. engine (bool, optional): Value override for args.engine. Defaults to None. @@ -2862,7 +2714,246 @@ class AMDSMICommands(): self.logger.print_output(multiple_device_enabled=True) - def set_value(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None, + def set_core(self, args, multiple_devices=False, core=None, core_boost_limit=None): + """Issue set commands to target core(s) + + Args: + args (Namespace): Namespace containing the parsed CLI args + multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. + core (device_handle, optional): device_handle for target device. Defaults to None. + core_boost_limit (list, optional): Value override for args.core_boost_limit. Defaults to None. Defaults to None. + + Raises: + ValueError: Value error if no core value is provided + IndexError: Index error if core list is empty + + Return: + Nothing + """ + if core: + args.core = core + if core_boost_limit: + args.core_boost_limit = core_boost_limit + + if args.core == None: + raise ValueError('No Core provided, specific Core targets(S) are needed') + + # Handle multiple cores + handled_multiple_cores, device_handle = self.helpers.handle_cores(args, self.logger, self.set_core) + if handled_multiple_cores: + return # This function is recursive + + # Error if no subcommand args are passed + if not any([args.core_boost_limit]): + command = " ".join(sys.argv[1:]) + raise AmdSmiRequiredCommandException(command, self.logger.format) + + args.core = device_handle + # build core string for errors + try: + core_id = self.helpers.get_core_id_from_device_handle(args.core) + except IndexError: + core_id = f'ID Unavailable for {args.core}' + + static_dict = {} + if args.core_boost_limit: + static_dict["set_core_boost_limit"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_core_boostlimit(args.core, args.core_boost_limit[0][0]) + static_dict["set_core_boost_limit"]["Response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_core_boost_limit"]["Response"] = f"Error occured for Core {core_id} - {e.get_error_info()}" + logging.debug("Failed to set core boost limit for cpu %s | %s", core_id, e.get_error_info()) + + multiple_devices_csv_override = False + self.logger.store_core_output(args.core, 'values', static_dict) + if multiple_devices: + self.logger.store_multiple_device_output() + return # Skip printing when there are multiple devices + self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) + + + def set_cpu(self, args, multiple_devices=False, cpu=None, cpu_pwr_limit=None, + cpu_xgmi_link_width=None, cpu_lclk_dpm_level=None, cpu_pwr_eff_mode=None, + cpu_gmi3_link_width=None, cpu_pcie_link_rate=None, cpu_df_pstate_range=None, + cpu_enable_apb=None, cpu_disable_apb=None, soc_boost_limit=None): + """Issue set commands to target cpu(s) + + Args: + args (Namespace): Namespace containing the parsed CLI args + multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. + cpu (cpu_handle, optional): device_handle for target device. Defaults to None. + cpu_pwr_limit (int, optional): Value override for args.cpu_pwr_limit. Defaults to None. + cpu_xgmi_link_width (List[int], optional): Value override for args.cpu_xgmi_link_width. Defaults to None. + cpu_lclk_dpm_level (List[int], optional): Value override for args.cpu_lclk_dpm_level. Defaults to None. + cpu_pwr_eff_mode (int, optional): Value override for args.cpu_pwr_eff_mode. Defaults to None. + cpu_gmi3_link_width (List[int], optional): Value override for args.cpu_gmi3_link_width. Defaults to None. + cpu_pcie_link_rate (int, optional): Value override for args.cpu_pcie_link_rate. Defaults to None. + cpu_df_pstate_range (List[int], optional): Value override for args.cpu_df_pstate_range. Defaults to None. + cpu_enable_apb (bool, optional): Value override for args.cpu_enable_apb. Defaults to None. + cpu_disable_apb (int, optional): Value override for args.cpu_disable_apb. Defaults to None. + soc_boost_limit (int, optional): Value override for args.soc_boost_limit. Defaults to None. + + Raises: + ValueError: Value error if no cpu value is provided + IndexError: Index error if cpu list is empty + + Return: + Nothing + """ + if cpu: + args.cpu = cpu + if cpu_pwr_limit: + args.cpu_pwr_limit = cpu_pwr_limit + if cpu_xgmi_link_width: + args.cpu_xgmi_link_width = cpu_xgmi_link_width + if cpu_lclk_dpm_level: + args.cpu_lclk_dpm_level = cpu_lclk_dpm_level + if cpu_pwr_eff_mode: + args.cpu_pwr_eff_mode = cpu_pwr_eff_mode + if cpu_gmi3_link_width: + args.cpu_gmi3_link_width = cpu_gmi3_link_width + if cpu_pcie_link_rate: + args.cpu_pcie_link_rate = cpu_pcie_link_rate + if cpu_df_pstate_range: + args.cpu_df_pstate_range = cpu_df_pstate_range + if cpu_enable_apb: + args.cpu_enable_apb = cpu_enable_apb + if cpu_disable_apb: + args.cpu_disable_apb = cpu_disable_apb + if soc_boost_limit: + args.soc_boost_limit = soc_boost_limit + + if args.cpu == None: + raise ValueError('No CPU provided, specific CPU targets(S) are needed') + + #Handle multiple CPU's + handled_multiple_cpus, device_handle = self.helpers.handle_cpus(args, self.logger, self.set_cpu) + if handled_multiple_cpus: + return # This function is recursive + + args.cpu = device_handle + #Error if no subcommand args are passed + if not any([args.cpu_pwr_limit, args.cpu_xgmi_link_width, args.cpu_lclk_dpm_level, + args.cpu_pwr_eff_mode, args.cpu_gmi3_link_width, args.cpu_pcie_link_rate, + args.cpu_df_pstate_range, args.cpu_enable_apb, args.cpu_disable_apb, + args.soc_boost_limit]): + command = " ".join(sys.argv[1:]) + raise AmdSmiRequiredCommandException(command, self.logger.format) + + # Build CPU string for errors + try: + cpu_id = self.helpers.get_cpu_id_from_device_handle(args.cpu) + except IndexError: + cpu_id = f'ID Unavailable for {args.cpu}' + + static_dict = {} + + if args.cpu_pwr_limit: + static_dict["set_pwr_limit"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_socket_power_cap(args.cpu, args.cpu_pwr_limit[0][0]) + static_dict["set_pwr_limit"]["Response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_pwr_limit"]["Response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set power limit for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_xgmi_link_width: + static_dict["set_xgmi_link_width"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_xgmi_width(args.cpu, args.cpu_xgmi_link_width[0][0], + args.cpu_xgmi_link_width[0][1]) + static_dict["set_xgmi_link_width"]["Response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_xgmi_link_width"]["Response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set xgmi link width for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_lclk_dpm_level: + static_dict["set_lclk_dpm_level"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_socket_lclk_dpm_level(args.cpu, args.cpu_lclk_dpm_level[0][0], + args.cpu_lclk_dpm_level[0][1], + args.cpu_lclk_dpm_level[0][2]) + static_dict["set_lclk_dpm_level"]["Response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_lclk_dpm_level"]["Response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set lclk dpm level for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_pwr_eff_mode: + static_dict["set_pwr_eff_mode"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_pwr_efficiency_mode(args.cpu, args.cpu_pwr_eff_mode[0][0]) + static_dict["set_pwr_eff_mode"]["Response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_pwr_eff_mode"]["Response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set power efficiency mode for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_gmi3_link_width: + static_dict["set_gmi3_link_width"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_gmi3_link_width_range(args.cpu, args.cpu_gmi3_link_width[0][0], + args.cpu_gmi3_link_width[0][1]) + static_dict["set_gmi3_link_width"]["response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_gmi3_link_width"]["response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set gmi3 link width for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_pcie_link_rate: + static_dict["set_pcie_link_rate"] = {} + try: + resp = amdsmi_interface.amdsmi_set_cpu_pcie_link_rate(args.cpu, args.cpu_pcie_link_rate[0][0]) + static_dict["set_pcie_link_rate"]["prev_mode"] = resp + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_pcie_link_rate"]["prev_mode"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set pcie link rate for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_df_pstate_range: + static_dict["set_df_pstate_range"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_df_pstate_range(args.cpu, args.cpu_df_pstate_range[0][0], + args.cpu_df_pstate_range[0][1]) + static_dict["set_df_pstate_range"]["response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["set_df_pstate_range"]["response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set df pstate range for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_enable_apb: + static_dict["apbenable"] = {} + try: + amdsmi_interface.amdsmi_cpu_apb_enable(args.cpu) + static_dict["apbenable"]["state"] = "Enabled DF - Pstate performance boost algorithm" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["apbenable"]["state"] = "N/A" + logging.debug("Failed to enable APB for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.cpu_disable_apb: + static_dict["apbdisable"] = {} + try: + amdsmi_interface.amdsmi_cpu_apb_disable(args.cpu, args.cpu_disable_apb[0][0]) + static_dict["apbdisable"]["state"] = "Disabled DF - Pstate performance boost algorithm" + except amdsmi_exception.AmdSmiLibraryException as e: + static_dict["apbdisable"]["state"] = "N/A" + logging.debug("Failed to enable APB for cpu %s | %s", cpu_id, e.get_error_info()) + + if args.soc_boost_limit: + static_dict["set_soc_boost_limit"] = {} + try: + amdsmi_interface.amdsmi_set_cpu_socket_boostlimit(args.cpu, args.soc_boost_limit[0][0]) + static_dict["set_soc_boost_limit"]["Response"] = "Set Operation successful" + except amdsmi_exception.AmdSmiLibraryException as e: + #static_dict["set_soc_boost_limit"]["Response"] = "N/A" + static_dict["set_soc_boost_limit"]["Response"] = f"Error occured for CPU {cpu_id} - {e.get_error_info()}" + logging.debug("Failed to set socket boost limit for cpu %s | %s", cpu_id, e.get_error_info()) + + multiple_devices_csv_override = False + self.logger.store_cpu_output(args.cpu, 'values', static_dict) + if multiple_devices: + self.logger.store_multiple_device_output() + return # Skip printing when there are multiple devices + self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override) + + + def set_gpu(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None, profile=None, perf_determinism=None, compute_partition=None, memory_partition=None, power_cap=None): """Issue reset commands to target gpu(s) @@ -2909,7 +3000,7 @@ class AMDSMICommands(): raise ValueError('No GPU provided, specific GPU target(s) are needed') # Handle multiple GPUs - handled_multiple_gpus, device_handle = self.helpers.handle_gpus(args, self.logger, self.set_value) + handled_multiple_gpus, device_handle = self.helpers.handle_gpus(args, self.logger, self.set_gpu) if handled_multiple_gpus: return # This function is recursive @@ -3019,6 +3110,132 @@ class AMDSMICommands(): self.logger.print_output() + def set_value(self, args, multiple_devices=False, gpu=None, fan=None, perf_level=None, + profile=None, perf_determinism=None, compute_partition=None, + memory_partition=None, power_cap=None, + cpu=None, cpu_pwr_limit=None, cpu_xgmi_link_width=None, cpu_lclk_dpm_level=None, + cpu_pwr_eff_mode=None, cpu_gmi3_link_width=None, cpu_pcie_link_rate=None, + cpu_df_pstate_range=None, cpu_enable_apb=None, cpu_disable_apb=None, + soc_boost_limit=None, core=None, core_boost_limit=None): + """Issue reset commands to target gpu(s) + + Args: + args (Namespace): Namespace containing the parsed CLI args + multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False. + gpu (device_handle, optional): device_handle for target device. Defaults to None. + fan (int, optional): Value override for args.fan. Defaults to None. + perf_level (amdsmi_interface.AmdSmiDevPerfLevel, optional): Value override for args.perf_level. Defaults to None. + profile (bool, optional): Value override for args.profile. Defaults to None. + perf_determinism (int, optional): Value override for args.perf_determinism. Defaults to None. + compute_partition (amdsmi_interface.AmdSmiComputePartitionType, optional): Value override for args.compute_partition. Defaults to None. + memory_partition (amdsmi_interface.AmdSmiMemoryPartitionType, optional): Value override for args.memory_partition. Defaults to None. + power_cap (int, optional): Value override for args.power_cap. Defaults to None. + + cpu (cpu_handle, optional): device_handle for target device. Defaults to None. + cpu_pwr_limit (int, optional): Value override for args.cpu_pwr_limit. Defaults to None. + cpu_xgmi_link_width (List[int], optional): Value override for args.cpu_xgmi_link_width. Defaults to None. + cpu_lclk_dpm_level (List[int], optional): Value override for args.cpu_lclk_dpm_level. Defaults to None. + cpu_pwr_eff_mode (int, optional): Value override for args.cpu_pwr_eff_mode. Defaults to None. + cpu_gmi3_link_width (List[int], optional): Value override for args.cpu_gmi3_link_width. Defaults to None. + cpu_pcie_link_rate (int, optional): Value override for args.cpu_pcie_link_rate. Defaults to None. + cpu_df_pstate_range (List[int], optional): Value override for args.cpu_df_pstate_range. Defaults to None. + cpu_enable_apb (bool, optional): Value override for args.cpu_enable_apb. Defaults to None. + cpu_disable_apb (int, optional): Value override for args.cpu_disable_apb. Defaults to None. + soc_boost_limit (int, optional): Value override for args.soc_boost_limit. Defaults to None. + + core (device_handle, optional): device_handle for target core. Defaults to None. + core_boost_limit (int, optional): Value override for args.core_boost_limit. Defaults to None + + Raises: + ValueError: Value error if no gpu value is provided + IndexError: Index error if gpu list is empty + + Return: + Nothing + """ + # Mutually exculsive args + if gpu: + args.gpu = gpu + if cpu: + args.cpu = cpu + if core: + args.core = core + + # Check if a GPU argument has been set + gpu_args_enabled = False + gpu_attributes = ["fan", "perf_level", "profile", "perf_determinism", "compute_partition", + "memory_partition", "power_cap"] + for attr in gpu_attributes: + if hasattr(args, attr): + gpu_args_enabled |= bool(getattr(args, attr)) + + # Check if a CPU argument has been set + cpu_args_enabled = False + cpu_attributes = ["cpu_pwr_limit", "cpu_xgmi_link_width", "cpu_lclk_dpm_level", "cpu_pwr_eff_mode", + "cpu_gmi3_link_width", "cpu_pcie_link_rate", "cpu_df_pstate_range", + "cpu_enable_apb", "cpu_disable_apb", "soc_boost_limit"] + for attr in cpu_attributes: + if hasattr(args, attr): + cpu_args_enabled |= bool(getattr(args, attr)) + + # Check if a Core argument has been set + core_args_enabled = False + core_attributes = ["core_boost_limit"] + for attr in core_attributes: + if hasattr(args, attr): + core_args_enabled |= bool(getattr(args, attr)) + + # Only allow one device's arguments to be set at a time + if gpu_args_enabled == cpu_args_enabled == core_args_enabled == False: + raise ValueError('No GPU, CPU, or CORE arguments provided, specific target(s) are needed') + elif gpu_args_enabled == cpu_args_enabled == core_args_enabled == True: + raise ValueError('Cannot set GPU, CPU, and CORE arguments at the same time') + elif not (gpu_args_enabled ^ cpu_args_enabled ^ core_args_enabled): + raise ValueError('Cannot set GPU, CPU, or CORE arguments at the same time') + + # Handle CPU and GPU intialization cases + if self.helpers.is_amd_hsmp_initialized() and self.helpers.is_amdgpu_initialized(): + # Print out all CPU and all GPU static info only if no device was specified. + # If a GPU or CPU argument is provided only print out the specified device. + if args.cpu == None and args.gpu == None and args.core == None: + raise ValueError('No GPU, CPU, or CORE provided, specific target(s) are needed') + + if args.cpu: + self.set_cpu(args, multiple_devices, cpu, cpu_pwr_limit, + cpu_xgmi_link_width, cpu_lclk_dpm_level, cpu_pwr_eff_mode, + cpu_gmi3_link_width, cpu_pcie_link_rate, cpu_df_pstate_range, + cpu_enable_apb, cpu_disable_apb, soc_boost_limit) + if args.core: + self.logger.output = {} + self.logger.clear_multiple_devices_ouput() + self.set_core(args, multiple_devices, core, core_boost_limit) + if args.gpu: + self.logger.output = {} + self.logger.clear_multiple_devices_ouput() + self.set_gpu(args, multiple_devices, gpu, fan, perf_level, + profile, perf_determinism, compute_partition, + memory_partition, power_cap) + elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized + if args.cpu == None and args.core == None: + raise ValueError('No CPU or CORE provided, specific target(s) are needed') + if args.cpu: + self.set_cpu(args, multiple_devices, cpu, cpu_pwr_limit, + cpu_xgmi_link_width, cpu_lclk_dpm_level, cpu_pwr_eff_mode, + cpu_gmi3_link_width, cpu_pcie_link_rate, cpu_df_pstate_range, + cpu_enable_apb, cpu_disable_apb, soc_boost_limit) + if args.core: + self.logger.output = {} + self.logger.clear_multiple_devices_ouput() + self.set_core(args, multiple_devices, core, core_boost_limit) + elif self.helpers.is_amdgpu_initialized(): # Only GPU is initialized + if args.gpu == None: + raise ValueError('No GPU provided, specific GPU target(s) are needed') + self.logger.clear_multiple_devices_ouput() + self.set_gpu(args, multiple_devices, gpu, fan, perf_level, + profile, perf_determinism, compute_partition, + memory_partition, power_cap) + + def reset(self, args, multiple_devices=False, gpu=None, gpureset=None, clocks=None, fans=None, profile=None, xgmierr=None, perf_determinism=None, compute_partition=None, memory_partition=None, power_cap=None): diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py index 23ec7ce58d..a685a7e8dd 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_helpers.py @@ -116,6 +116,18 @@ class AMDSMIHelpers(): return self._is_windows + def get_amdsmi_init_flag(self): + return AMDSMI_INIT_FLAG + + + def is_amdgpu_initialized(self): + return AMDSMI_INIT_FLAG & amdsmi_interface.amdsmi_wrapper.AMDSMI_INIT_AMD_GPUS + + + def is_amd_hsmp_initialized(self): + return AMDSMI_INIT_FLAG & amdsmi_interface.amdsmi_wrapper.AMDSMI_INIT_AMD_CPUS + + def get_cpu_choices(self): """Return dictionary of possible CPU choices and string of the output: Dictionary will be in format: cpus[ID]: Device Handle) @@ -136,11 +148,11 @@ class AMDSMIHelpers(): except amdsmi_interface.AmdSmiLibraryException as e: if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): - logging.info('Unable to get device choices, driver not initialized (amdhsmp not found in modules)') + logging.info('Unable to get device choices, driver not initialized (amd_hsmp not found in modules)') else: raise e if len(cpu_handles) == 0: - logging.info('Unable to find any devices, check if driver is initialized (amdhsmp not found in modules)') + logging.info('Unable to find any devices, check if driver is initialized (amd_hsmp not found in modules)') else: # Handle spacing for the gpu_choices_str max_padding = int(math.log10(len(cpu_handles))) + 1 @@ -181,11 +193,11 @@ class AMDSMIHelpers(): except amdsmi_interface.AmdSmiLibraryException as e: if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): - logging.info('Unable to get device choices, driver not initialized (amdhsmp not found in modules)') + logging.info('Unable to get device choices, driver not initialized (amd_hsmp not found in modules)') else: raise e if len(core_handles) == 0: - logging.info('Unable to find any devices, check if driver is initialized (amdhsmp not found in modules)') + logging.info('Unable to find any devices, check if driver is initialized (amd_hsmp not found in modules)') else: # Handle spacing for the gpu_choices_str max_padding = int(math.log10(len(core_handles))) + 1 @@ -463,6 +475,7 @@ class AMDSMIHelpers(): else: return False, args.cpu + def handle_cores(self, args, logger, subcommand): """This function will run execute the subcommands based on the number of cores passed in via args. @@ -567,6 +580,7 @@ class AMDSMIHelpers(): amdsmi_interface.amdsmi_wrapper.amdsmi_processor_handle, "Unable to find cpu ID from device_handle") + def get_core_id_from_device_handle(self, input_device_handle): """Get the core index from the device_handle. amdsmi_interface.amdsmi_get_cpusocket_handles() returns the list of device_handles in order of cpu_index diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_init.py b/projects/amdsmi/amdsmi_cli/amdsmi_init.py index dc742d091a..e5b7484422 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_init.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_init.py @@ -42,6 +42,7 @@ sys.tracebacklimit = -1 # Disable traceback when raising errors # On initial import set initialized variable AMDSMI_INITIALIZED = False +AMDSMI_INIT_FLAG = amdsmi_interface.AmdSmiInitFlags.INIT_ALL_PROCESSORS AMD_VENDOR_ID = 4098 def check_amdgpu_driver(): @@ -53,8 +54,8 @@ def check_amdgpu_driver(): return False -def check_amdhsmp_driver(): - """ Returns true if amd hsmp is found in the list of initialized modules """ +def check_amd_hsmp_driver(): + """ Returns true if amd_hsmp is found in the list of initialized modules """ amd_cpu_status_file = Path("/sys/module/amd_hsmp/initstate") if amd_cpu_status_file.exists(): if amd_cpu_status_file.read_text(encoding="ascii").strip() == "live": @@ -62,32 +63,36 @@ def check_amdhsmp_driver(): return False -def init_amdsmi(flag=amdsmi_interface.AmdSmiInitFlags.INIT_AMD_GPUS): +def init_amdsmi(): """ Initializes AMDSMI - Raises: - err: AmdSmiLibraryException if not successful - """ - gpu_flag = False; - cpu_flag = False; + Checks for the presence of the amdgpu and amd_hsmp drivers and initializes the + AMD SMI library based on the live drivers found. - # Check if both the amdgpu and amdhsmp driver is up and handle error gracefully - if check_amdgpu_driver() and check_amdhsmp_driver(): - # init AMD APUS + Return: + init_flag: the flag used to initialize the AMD SMI library without error + + Raises: + err: AmdSmiLibraryException if not successful in initializing any drivers + """ + init_flag = amdsmi_interface.AmdSmiInitFlags.INIT_ALL_PROCESSORS + if check_amdgpu_driver() and check_amd_hsmp_driver(): + init_flag = amdsmi_interface.AmdSmiInitFlags.INIT_AMD_APUS + logging.debug("Both amdgpu and amd_hsmp driver's initstate is live") try: - amdsmi_interface.amdsmi_init(amdsmi_interface.AmdSmiInitFlags.INIT_AMD_APUS) + amdsmi_interface.amdsmi_init(init_flag) except (amdsmi_interface.AmdSmiLibraryException, amdsmi_interface.AmdSmiParameterException) as e: if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): - logging.error("Drivers not loaded (amdgpu and hsmp drivers not found in modules)") + logging.error("Drivers not loaded (amdgpu and amd_hsmp drivers not found in modules)") sys.exit(-1) else: raise e - # # Check if amdgpu driver is up & Handle error gracefully elif check_amdgpu_driver(): - # Only init AMD GPUs for now, waiting for future support for AMD CPUs + init_flag = amdsmi_interface.AmdSmiInitFlags.INIT_AMD_GPUS + logging.debug("amdgpu driver initstate is live") try: - amdsmi_interface.amdsmi_init(amdsmi_interface.AmdSmiInitFlags.INIT_AMD_GPUS) + amdsmi_interface.amdsmi_init(init_flag) except (amdsmi_interface.AmdSmiLibraryException, amdsmi_interface.AmdSmiParameterException) as e: if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): @@ -95,25 +100,24 @@ def init_amdsmi(flag=amdsmi_interface.AmdSmiInitFlags.INIT_AMD_GPUS): sys.exit(-1) else: raise e - logging.debug("AMDSMI initialized successfully, but initstate was not live") - - elif check_amdhsmp_driver(): - # Only init AMD CPUs + logging.debug("amdgpu driver initialized successfully, but amd_hsmp initstate was not live") + elif check_amd_hsmp_driver(): + init_flag = amdsmi_interface.AmdSmiInitFlags.INIT_AMD_CPUS + logging.debug("amd_hsmp driver initstate is live") try: - amdsmi_interface.amdsmi_init(amdsmi_interface.AmdSmiInitFlags.INIT_AMD_CPUS) - cpu_flag = True + amdsmi_interface.amdsmi_init(init_flag) except (amdsmi_interface.AmdSmiLibraryException, amdsmi_interface.AmdSmiParameterException) as e: if e.err_code in (amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT, amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_DRIVER_NOT_LOADED): - logging.error("Driver not loaded (hsmp not found in modules)") + logging.error("Driver not loaded (amd_hsmp not found in modules)") sys.exit(-1) else: raise e - else: - pass + logging.debug("amd_hsmp driver initialized successfully, but amdgpu initstate was not live") - logging.debug("AMDSMI initialized successfully") + logging.debug(f"AMDSMI initialized with atleast one driver successfully | init flag: {init_flag}") + return init_flag def shut_down_amdsmi(): """Shutdown AMDSMI instance @@ -134,7 +138,7 @@ def signal_handler(sig, frame): if not AMDSMI_INITIALIZED: - init_amdsmi() + AMDSMI_INIT_FLAG = init_amdsmi() AMDSMI_INITIALIZED = True signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py index 0b65cc250d..4bbd71724f 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py @@ -25,8 +25,8 @@ import json import re import time from typing import Dict -import yaml from enum import Enum +import yaml from amdsmi_helpers import AMDSMIHelpers import amdsmi_cli_exceptions @@ -255,6 +255,7 @@ class AMDSMILogger(): core_id = self.helpers.get_core_id_from_device_handle(device_handle) self._store_core_output_amdsmi(core_id=core_id, argument=argument, data=data) + def _store_core_output_amdsmi(self, core_id, argument, data): if argument == 'timestamp': # Make sure timestamp is the first element in the output self.output['timestamp'] = int(time.time()) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index d29e691ad5..2db2d7661f 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -72,9 +72,23 @@ class AMDSMIParser(argparse.ArgumentParser): # Helper variables self.helpers = AMDSMIHelpers() - self.gpu_choices, self.gpu_choices_str = self.helpers.get_gpu_choices() - self.cpu_choices, self.cpu_choices_str = self.helpers.get_cpu_choices() - self.core_choices, self.core_choices_str = self.helpers.get_core_choices() + + # Get choices based on driver initialized + if self.helpers.is_amdgpu_initialized(): + self.gpu_choices, self.gpu_choices_str = self.helpers.get_gpu_choices() + else: + self.gpu_choices = {} + self.gpu_choices_str = "" + + if self.helpers.is_amd_hsmp_initialized(): + self.cpu_choices, self.cpu_choices_str = self.helpers.get_cpu_choices() + self.core_choices, self.core_choices_str = self.helpers.get_core_choices() + else: + self.cpu_choices = {} + self.cpu_choices_str = "" + self.core_choices = {} + self.core_choices_str = "" + self.vf_choices = ['3', '2', '1'] version_string = f"Version: {__version__}" @@ -324,16 +338,28 @@ class AMDSMIParser(argparse.ArgumentParser): def _validate_cpu_core(self, value): - if (int(value) < 0): - outputformat = self.helpers.get_output_format() - raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(value, outputformat) + if isinstance(value, str): + if value.lower() == "all": + return value + if value.isdigit(): + if int(value) < 0: + outputformat = self.helpers.get_output_format() + raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(value, outputformat) + else: + outputformat = self.helpers.get_output_format() + raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(value, outputformat) + + if isinstance(value, int): + if int(value) < 0: + outputformat = self.helpers.get_output_format() + raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(value, outputformat) return value def _validate_positive(self, value): i_value = int(value) - if (i_value < 0): + if i_value < 0: outputformat = self.helpers.get_output_format() raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(i_value, outputformat) @@ -351,510 +377,24 @@ class AMDSMIParser(argparse.ArgumentParser): # Mutually Exclusive Args within the subparser device_args = subcommand_parser.add_mutually_exclusive_group(required=required) - device_args.add_argument('-g', '--gpu', action=self._gpu_select(self.gpu_choices), - nargs='+', help=gpu_help) - device_args.add_argument('-U', '--cpu', type=self._validate_cpu_core, - action=self._cpu_select(self.cpu_choices), - nargs='+', help=cpu_help) - device_args.add_argument('-O', '--core', type=self._validate_cpu_core, - action=self._core_select(self.core_choices), - nargs='+', help=core_help) + + if self.helpers.is_amdgpu_initialized(): + device_args.add_argument('-g', '--gpu', action=self._gpu_select(self.gpu_choices), + nargs='+', help=gpu_help) + + if self.helpers.is_amd_hsmp_initialized(): + device_args.add_argument('-U', '--cpu', type=self._validate_cpu_core, + action=self._cpu_select(self.cpu_choices), + nargs='+', help=cpu_help) + device_args.add_argument('-O', '--core', type=self._validate_cpu_core, + action=self._core_select(self.core_choices), + nargs='+', help=core_help) if self.helpers.is_hypervisor(): device_args.add_argument('-v', '--vf', action='store', nargs='+', help=vf_help, choices=self.vf_choices) - def _add_version_parser(self, subparsers, func): - # Subparser help text - version_help = "Display version information" - - # Create version subparser - version_parser = subparsers.add_parser('version', help=version_help, description=None) - version_parser._optionals.title = None - version_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - version_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(version_parser) - - - def _add_list_parser(self, subparsers, func): - # Subparser help text - list_help = "List GPU information" - list_subcommand_help = "Lists all the devices on the system and the links between devices.\ - \nLists all the sockets and for each socket, GPUs and/or CPUs associated to\ - \nthat socket alongside some basic information for each device.\ - \nIn virtualization environments, it can also list VFs associated to each\ - \nGPU with some basic information for each VF." - - # Create list subparser - list_parser = subparsers.add_parser('list', help=list_help, description=list_subcommand_help) - list_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - list_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(list_parser) - self._add_device_arguments(list_parser, required=False) - - - def _add_static_parser(self, subparsers, func): - # Subparser help text - static_help = "Gets static information about the specified GPU" - static_subcommand_help = "If no GPU is specified, returns static information for all GPUs on the system.\ - \nIf no static argument is provided, all static information will be displayed." - static_optionals_title = "Static Arguments" - - # Optional arguments help text - asic_help = "All asic information" - bus_help = "All bus information" - vbios_help = "All video bios information (if available)" - limit_help = "All limit metric values (i.e. power and thermal limits)" - driver_help = "Displays driver version" - vram_help = "All vram information" - cache_help = "All cache information" - board_help = "All board information" - - # Options arguments help text for Hypervisors and Baremetal - ras_help = "Displays RAS features information" - numa_help = "All numa node information" # Linux Baremetal only - partition_help = "Partition information" - - # Options arguments help text for Hypervisors - dfc_help = "All DFC FW table information" - fb_help = "Displays Frame Buffer information" - num_vf_help = "Displays number of supported and enabled VFs" - - # Options arguments help text for cpu - smu_help = "All SMU FW information" - interface_help = "Displays hsmp interface version" - - # Create static subparser - static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help) - static_parser._optionals.title = static_optionals_title - static_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - static_parser.set_defaults(func=func) - cpu_group = static_parser.add_argument_group("CPU Option") - - # Add Universal Arguments - self._add_command_modifiers(static_parser) - self._add_device_arguments(static_parser, required=False) - - # Optional Args - static_parser.add_argument('-a', '--asic', action='store_true', required=False, help=asic_help) - static_parser.add_argument('-b', '--bus', action='store_true', required=False, help=bus_help) - static_parser.add_argument('-V', '--vbios', action='store_true', required=False, help=vbios_help) - static_parser.add_argument('-d', '--driver', action='store_true', required=False, help=driver_help) - static_parser.add_argument('-v', '--vram', action='store_true', required=False, help=vram_help) - static_parser.add_argument('-c', '--cache', action='store_true', required=False, help=cache_help) - static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) - cpu_group.add_argument('-s', '--smu', action='store_true', required=False, help=smu_help) - cpu_group.add_argument('-i', '--interface_ver', action='store_true', required=False, help=interface_help) - # Options to display on Hypervisors and Baremetal - if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): - static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) - static_parser.add_argument('-p', '--partition', action='store_true', required=False, help=partition_help) - static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help) - - if self.helpers.is_linux() and not self.helpers.is_virtual_os(): - static_parser.add_argument('-u', '--numa', action='store_true', required=False, help=numa_help) - - # Options to only display on a Hypervisor - if self.helpers.is_hypervisor(): - static_parser.add_argument('-d', '--dfc-ucode', action='store_true', required=False, help=dfc_help) - static_parser.add_argument('-f', '--fb-info', action='store_true', required=False, help=fb_help) - static_parser.add_argument('-n', '--num-vf', action='store_true', required=False, help=num_vf_help) - - - def _add_firmware_parser(self, subparsers, func): - # Subparser help text - firmware_help = "Gets firmware information about the specified GPU" - firmware_subcommand_help = "If no GPU is specified, return firmware information for all GPUs on the system." - firmware_optionals_title = "Firmware Arguments" - - # Optional arguments help text - fw_list_help = "All FW list information" - err_records_help = "All error records information" - - # Create firmware subparser - firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help, aliases=['ucode']) - firmware_parser._optionals.title = firmware_optionals_title - firmware_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - firmware_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(firmware_parser) - self._add_device_arguments(firmware_parser, required=False) - - # Optional Args - firmware_parser.add_argument('-f', '--ucode-list', '--fw-list', dest='fw_list', action='store_true', required=False, help=fw_list_help, default=True) - - # Options to only display on a Hypervisor - if self.helpers.is_hypervisor(): - firmware_parser.add_argument('-e', '--error-records', action='store_true', required=False, help=err_records_help) - - - def _add_bad_pages_parser(self, subparsers, func): - if not (self.helpers.is_baremetal() and self.helpers.is_linux()): - # The bad_pages subcommand is only applicable to Linux Baremetal systems - return - - # Subparser help text - bad_pages_help = "Gets bad page information about the specified GPU" - bad_pages_subcommand_help = "If no GPU is specified, return bad page information for all GPUs on the system." - bad_pages_optionals_title = "Bad Pages Arguments" - - # Optional arguments help text - pending_help = "Displays all pending retired pages" - retired_help = "Displays retired pages" - un_res_help = "Displays unreservable pages" - - # Create bad_pages subparser - bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help) - bad_pages_parser._optionals.title = bad_pages_optionals_title - bad_pages_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - bad_pages_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(bad_pages_parser) - self._add_device_arguments(bad_pages_parser, required=False) - - # Optional Args - bad_pages_parser.add_argument('-p', '--pending', action='store_true', required=False, help=pending_help) - bad_pages_parser.add_argument('-r', '--retired', action='store_true', required=False, help=retired_help) - bad_pages_parser.add_argument('-u', '--un-res', action='store_true', required=False, help=un_res_help) - - - def _add_metric_parser(self, subparsers, func): - # Subparser help text - metric_help = "Gets metric/performance information about the specified GPU" - metric_subcommand_help = "If no GPU is specified, returns metric information for all GPUs on the system.\ - \nIf no metric argument is provided all metric information will be displayed." - metric_optionals_title = "Metric arguments" - - # Optional arguments help text - usage_help = "Displays engine usage information" - - # Help text for Arguments only Available on Linux Virtual OS and Baremetal platforms - mem_usage_help = "Memory usage per block" - - # Help text for Arguments only on Hypervisor and Baremetal platforms - power_help = "Current power usage" - clock_help = "Average, max, and current clock frequencies" - temperature_help = "Current temperatures" - ecc_help = "Total number of ECC errors" - ecc_block_help = "Number of ECC errors per block" - pcie_help = "Current PCIe speed, width, and replay count" - - # Help text for Arguments only on Linux Baremetal platforms - fan_help = "Current fan speed" - vc_help = "Display voltage curve" - overdrive_help = "Current GPU clock overdrive level" - perf_level_help = "Current DPM performance level" - xgmi_err_help = "XGMI error information since last read" - energy_help = "Amount of energy consumed" - - # Help text for Arguments only on Hypervisors - schedule_help = "All scheduling information" - guard_help = "All guard information" - guest_data_help = "All guest data information" - fb_usage_help = "Displays total and used Frame Buffer usage information" - xgmi_help = "Table of current XGMI metrics information" - - # Help text for cpu options - cpu_power_metrics_help = "Cpu power metrics" - cpu_proc_help = "Displays prochot status" - cpu_freq_help = "Displays currentFclkMemclk frequencies and cclk frequency limit" - cpu_c0_res_help = "Displays C0 residency" - cpu_lclk_dpm_help = "Displays lclk dpm level range. Requires socket ID and nbio id as inputs" - cpu_pwr_svi_telemtry_rails_help = "Displays svi based telemetry for all rails" - cpu_io_bandwidth_help = "Displays current IO bandwidth for the selected CPU.\ - \n input parameters are bandwidth type(1) and link ID encodings\ - \n i.e. P2, P3, G0 - G7" - cpu_xgmi_bandwidth_help = "Displays current XGMI bandwidth for the selected CPU\ - \n input parameters are bandwidth type(1,2,4) and link ID encodings\ - \n i.e. P2, P3, G0 - G7" - cpu_enable_apb_help = "Enables the DF p-state performance boost algorithm" - cpu_disable_apb_help = "Disables the DF p-state performance boost algorithm." - "Input parameter is DFPstate (0 -3 )" - set_cpu_pow_limit_help = "Set power limit for the given socket. Input parameter is \ -power limit value." - set_cpu_xgmi_link_width_help = "Set max and Min linkwidth. Input parameters are \ -min and max link width values" - set_cpu_lclk_dpm_level_help = "Sets the max and min dpm level on a given NBIO. Inpur parameters are \ -die_index, min dpm, max dpm." - core_boost_limit_help = "Get booslimit for the selected cores" - core_curr_active_freq_core_limit_help = "Get Current CCLK limit set per Core" - set_soc_boost_limit_help = "Sets the boost limit for the given socket. Input parameter is \ -socket limit value" - set_core_boost_limit_help = "Sets the boost limit for the given core. Input parameter is \ -core limit value" - cpu_metrics_ver_help = "Displays metrics table version" - cpu_metrics_table_help = "Displays metric table" - core_energy_help = "Displays core energy for the selected core" - socket_energy_help = "Displays socket energy for the selected socket" - set_cpu_pwr_eff_mode_help = "Sets the power efficency mode policy. Input parameter is mode." - cpu_ddr_bandwidth_help = "Displays per socket max ddr bw, current utilized bw and current utilized ddr bw in percentage" - cpu_temp_help = "Displays cpu socket temperature" - cpu_dimm_temp_range_rate_help = "Displays dimm temperature range and refresh rate" - cpu_dimm_pow_conumption_help = "Displays dimm power consumption" - cpu_dimm_thermal_sensor_help = "Displays dimm thermal sensor" - set_cpu_gmi3_link_width_help = "Sets max and min gmi3 link width range" - set_cpu_pcie_lnk_rate_help = "Sets pcie link rate" - set_cpu_df_pstate_range_help = "Sets max and min df-pstates" - - # Create metric subparser - metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help) - metric_parser._optionals.title = metric_optionals_title - metric_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - metric_parser.set_defaults(func=func) - cpu_group = metric_parser.add_argument_group("CPU Option") - set_group = metric_parser.add_argument_group("Set Options") - - # Add Universal Arguments - self._add_command_modifiers(metric_parser) - self._add_device_arguments(metric_parser, required=False) - - # Add Watch args - self._add_watch_arguments(metric_parser) - - # Optional Args for Linux Virtual OS and Baremetal systems - if not self.helpers.is_hypervisor() and not self.helpers.is_windows(): - metric_parser.add_argument('-m', '--mem-usage', action='store_true', required=False, help=mem_usage_help) - - # Optional Args for Hypervisors and Baremetal systems - if self.helpers.is_hypervisor() or self.helpers.is_baremetal() or self.helpers.is_linux(): - metric_parser.add_argument('-u', '--usage', action='store_true', required=False, help=usage_help) - metric_parser.add_argument('-p', '--power', action='store_true', required=False, help=power_help) - metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help) - metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help) - metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) - metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help) - - # Optional Args for Linux Baremetal Systems - if self.helpers.is_baremetal() and self.helpers.is_linux(): - metric_parser.add_argument('-k', '--ecc-block', action='store_true', required=False, help=ecc_block_help) - metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help) - metric_parser.add_argument('-C', '--voltage-curve', action='store_true', required=False, help=vc_help) - metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help) - metric_parser.add_argument('-l', '--perf-level', action='store_true', required=False, help=perf_level_help) - metric_parser.add_argument('-x', '--xgmi-err', action='store_true', required=False, help=xgmi_err_help) - metric_parser.add_argument('-E', '--energy', action='store_true', required=False, help=energy_help) - - # Options to only display to Hypervisors - if self.helpers.is_hypervisor(): - metric_parser.add_argument('-s', '--schedule', action='store_true', required=False, help=schedule_help) - metric_parser.add_argument('-G', '--guard', action='store_true', required=False, help=guard_help) - metric_parser.add_argument('-u', '--guest-data', action='store_true', required=False, help=guest_data_help) - metric_parser.add_argument('-f', '--fb_usage', action='store_true', required=False, help=fb_usage_help) - metric_parser.add_argument('-m', '--xgmi', action='store_true', required=False, help=xgmi_help) - - cpu_group.add_argument('--cpu_power_metrics', action='store_true', required=False, help=cpu_power_metrics_help) - cpu_group.add_argument('--cpu_prochot', action='store_true', required=False, help=cpu_proc_help) - cpu_group.add_argument('--cpu_freq_metrics', action='store_true', required=False, help=cpu_freq_help) - cpu_group.add_argument('--cpu_c0_res', action='store_true', required=False, help=cpu_c0_res_help) - cpu_group.add_argument('--cpu_lclk_dpm_level', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("NBIOID"), help=cpu_lclk_dpm_help) - cpu_group.add_argument('--cpu_pwr_svi_telemtry_rails', action='store_true', required=False, - help=cpu_pwr_svi_telemtry_rails_help) - cpu_group.add_argument('--cpu_io_bandwidth', action='append', required=False, nargs=2, - metavar=("IO_BW","LINKID_NAME"), help=cpu_io_bandwidth_help) - cpu_group.add_argument('--cpu_xgmi_bandwidth', action='append', required=False, nargs=2, - metavar=("XGMI_BW","LINKID_NAME"), help=cpu_xgmi_bandwidth_help) - cpu_group.add_argument('--cpu_enable_apb', action='store_true', required=False, help=cpu_enable_apb_help) - cpu_group.add_argument('--cpu_disable_apb', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("DF_PSTATE"), help=cpu_disable_apb_help) - set_group.add_argument('--set_cpu_pow_limit', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("POW_LIMIT"),help=set_cpu_pow_limit_help) - set_group.add_argument('--set_cpu_xgmi_link_width', action='append', required=False, type=self._validate_positive, - nargs=2, metavar=("MIN_WIDTH", "MAX_WIDTH"), help=set_cpu_xgmi_link_width_help) - set_group.add_argument('--set_cpu_lclk_dpm_level', action='append', required=False, type=self._validate_positive, - nargs=3, metavar=("NBIOID", "MIN_DPM", "MAX_DPM"),help=set_cpu_lclk_dpm_level_help) - cpu_group.add_argument('--core_boost_limit', action='store_true', required=False, help=core_boost_limit_help) - cpu_group.add_argument('--core_curr_active_freq_core_limit', action='store_true', required=False, - help=core_curr_active_freq_core_limit_help) - set_group.add_argument('--set_soc_boost_limit', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("BOOST_LIMIT"), help=set_soc_boost_limit_help) - set_group.add_argument('--set_core_boost_limit', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("BOOST_LIMIT"), help=set_core_boost_limit_help) - cpu_group.add_argument('--cpu_metrics_ver', action='store_true', required=False, help=cpu_metrics_ver_help) - cpu_group.add_argument('--cpu_metrics_table', action='store_true', required=False, help=cpu_metrics_table_help) - cpu_group.add_argument('--core_energy', action='store_true', required=False, help=core_energy_help) - cpu_group.add_argument('--socket_energy', action='store_true', required=False, help=socket_energy_help) - set_group.add_argument('--set_cpu_pwr_eff_mode', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("MODE"), help=set_cpu_pwr_eff_mode_help) - cpu_group.add_argument('--cpu_ddr_bandwidth', action='store_true', required=False, help=cpu_ddr_bandwidth_help) - cpu_group.add_argument('--cpu_temp', action='store_true', required=False, help=cpu_temp_help) - cpu_group.add_argument('--cpu_dimm_temp_range_rate', action='append', required=False, type=lambda x: int(x, 0), - nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_temp_range_rate_help) - cpu_group.add_argument('--cpu_dimm_pow_conumption', action='append', required=False, type=lambda x: int(x, 0), - nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_pow_conumption_help) - cpu_group.add_argument('--cpu_dimm_thermal_sensor', action='append', required=False, type=lambda x: int(x, 0), - nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_thermal_sensor_help) - set_group.add_argument('--set_cpu_gmi3_link_width', action='append', required=False, type=self._validate_positive, - nargs=2, metavar=("MIN_LW", "MAX_LW"), help=set_cpu_gmi3_link_width_help) - set_group.add_argument('--set_cpu_pcie_lnk_rate', action='append', required=False, type=self._validate_positive, - nargs=1, metavar=("LINK_RATE"), help=set_cpu_pcie_lnk_rate_help) - set_group.add_argument('--set_cpu_df_pstate_range', action='append', required=False, type=self._validate_positive, - nargs=2, metavar=("MAX_PSTATE", "MIN_PSTATE"), help=set_cpu_df_pstate_range_help) - - def _add_process_parser(self, subparsers, func): - if self.helpers.is_hypervisor(): - # Don't add this subparser on Hypervisors - # This subparser is only available to Guest and Baremetal systems - return - - # Subparser help text - process_help = "Lists general process information running on the specified GPU" - process_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system.\ - \nIf no process argument is provided all process information will be displayed." - process_optionals_title = "Process arguments" - - # Optional Arguments help text - general_help = "pid, process name, memory usage" - engine_help = "All engine usages" - pid_help = "Gets all process information about the specified process based on Process ID" - name_help = "Gets all process information about the specified process based on Process Name.\ - \nIf multiple processes have the same name information is returned for all of them." - - - # Create process subparser - process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help) - process_parser._optionals.title = process_optionals_title - process_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - process_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(process_parser) - self._add_device_arguments(process_parser, required=False) - - # Add Watch args - self._add_watch_arguments(process_parser) - - # Optional Args - process_parser.add_argument('-G', '--general', action='store_true', required=False, help=general_help) - process_parser.add_argument('-e', '--engine', action='store_true', required=False, help=engine_help) - process_parser.add_argument('-p', '--pid', action='store', type=self._not_negative_int, required=False, help=pid_help) - process_parser.add_argument('-n', '--name', action='store', required=False, help=name_help) - - - def _add_profile_parser(self, subparsers, func): - if not (self.helpers.is_windows() and self.helpers.is_hypervisor()): - # This subparser only applies to Hypervisors - return - - # Subparser help text - profile_help = "Displays information about all profiles and current profile" - profile_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system." - profile_optionals_title = "Profile Arguments" - - # Create profile subparser - profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help) - profile_parser._optionals.title = profile_optionals_title - profile_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - profile_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(profile_parser) - self._add_device_arguments(profile_parser, required=False) - - - def _add_event_parser(self, subparsers, func): - # Subparser help text - event_help = "Displays event information for the given GPU" - event_subcommand_help = "If no GPU is specified, returns event information for all GPUs on the system." - event_optionals_title = "Event Arguments" - - # Create event subparser - event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help) - event_parser._optionals.title = event_optionals_title - event_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - event_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(event_parser) - self._add_device_arguments(event_parser, required=False) - - - def _add_topology_parser(self, subparsers, func): - if not(self.helpers.is_baremetal() and self.helpers.is_linux()): - # This subparser is only applicable to Baremetal Linux - return - - # Subparser help text - topology_help = "Displays topology information of the devices" - topology_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system.\ - \nIf no topology argument is provided all topology information will be displayed." - topology_optionals_title = "Topology arguments" - - # Help text for Arguments only on Guest and BM platforms - access_help = "Displays link accessibility between GPUs" - weight_help = "Displays relative weight between GPUs" - hops_help = "Displays the number of hops between GPUs" - link_type_help = "Displays the link type between GPUs" - numa_bw_help = "Display max and min bandwidth between nodes" - - # Create topology subparser - topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help) - topology_parser._optionals.title = topology_optionals_title - topology_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - topology_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(topology_parser) - self._add_device_arguments(topology_parser, required=False) - - # Optional Args - topology_parser.add_argument('-a', '--access', action='store_true', required=False, help=access_help) - topology_parser.add_argument('-w', '--weight', action='store_true', required=False, help=weight_help) - topology_parser.add_argument('-o', '--hops', action='store_true', required=False, help=hops_help) - topology_parser.add_argument('-t', '--link-type', action='store_true', required=False, help=link_type_help) - topology_parser.add_argument('-b', '--numa-bw', action='store_true', required=False, help=numa_bw_help) - - - def _add_set_value_parser(self, subparsers, func): - if not(self.helpers.is_baremetal() and self.helpers.is_linux()): - # This subparser is only applicable to Baremetal Linux - return - - # Subparser help text - set_value_help = "Set options for devices" - set_value_subcommand_help = "A GPU must be specified to set a configuration.\ - \nA set argument must be provided; Multiple set arguments are accepted" - set_value_optionals_title = "Set Arguments" - - # Help text for Arguments only on BM platforms - set_fan_help = "Set GPU fan speed (0-255 or 0-100%%)" - set_perf_level_help = "Set performance level" - set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes" - set_perf_det_help = "Set GPU clock frequency limit and performance level to determinism to get minimal performance variation" - compute_partition_choices_str = ", ".join(self.helpers.get_compute_partition_types()) - memory_partition_choices_str = ", ".join(self.helpers.get_memory_partition_types()) - set_compute_partition_help = f"Set one of the following the compute partition modes:\n\t{compute_partition_choices_str}" - set_memory_partition_help = f"Set one of the following the memory partition modes:\n\t{memory_partition_choices_str}" - set_power_cap_help = "Set power capacity limit" - - # Create set_value subparser - set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) - set_value_parser._optionals.title = set_value_optionals_title - set_value_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) - set_value_parser.set_defaults(func=func) - - # Add Universal Arguments - self._add_command_modifiers(set_value_parser) - # Device args are required as safeguard from the user applying the operation to all gpus unintentionally - self._add_device_arguments(set_value_parser, required=True) - - # Optional Args - set_value_parser.add_argument('-f', '--fan', action=self._validate_fan_speed(), required=False, help=set_fan_help, metavar='%') - set_value_parser.add_argument('-l', '--perf-level', action='store', choices=self.helpers.get_perf_levels()[0], type=str.upper, required=False, help=set_perf_level_help, metavar='LEVEL') - set_value_parser.add_argument('-P', '--profile', action='store', required=False, help=set_profile_help, metavar='SETPROFILE') - set_value_parser.add_argument('-d', '--perf-determinism', action='store', type=self._not_negative_int, required=False, help=set_perf_det_help, metavar='SCLKMAX') - set_value_parser.add_argument('-C', '--compute-partition', action='store', choices=self.helpers.get_compute_partition_types(), type=str.upper, required=False, help=set_compute_partition_help, metavar='PARTITION') - set_value_parser.add_argument('-M', '--memory-partition', action='store', choices=self.helpers.get_memory_partition_types(), type=str.upper, required=False, help=set_memory_partition_help, metavar='PARTITION') - set_value_parser.add_argument('-o', '--power-cap', action='store', type=self._positive_int, required=False, help=set_power_cap_help, metavar='WATTS') - - def _validate_set_clock(self, validate_clock_type=True): """ Validate Clock input""" amdsmi_helpers = self.helpers @@ -948,11 +488,546 @@ core limit value" return _ValidateOverdrivePercent + def _add_version_parser(self, subparsers, func): + # Subparser help text + version_help = "Display version information" + + # Create version subparser + version_parser = subparsers.add_parser('version', help=version_help, description=None) + version_parser._optionals.title = None + version_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + version_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(version_parser) + + + def _add_list_parser(self, subparsers, func): + if not self.helpers.is_amdgpu_initialized(): + # The list subcommand is only applicable to systems with amdgpu initialized + return + + # Subparser help text + list_help = "List GPU information" + list_subcommand_help = "Lists all the devices on the system and the links between devices.\ + \nLists all the sockets and for each socket, GPUs and/or CPUs associated to\ + \nthat socket alongside some basic information for each device.\ + \nIn virtualization environments, it can also list VFs associated to each\ + \nGPU with some basic information for each VF." + + # Create list subparser + list_parser = subparsers.add_parser('list', help=list_help, description=list_subcommand_help) + list_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + list_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(list_parser) + self._add_device_arguments(list_parser, required=False) + + + def _add_static_parser(self, subparsers, func): + # Subparser help text + static_help = "Gets static information about the specified GPU" + static_subcommand_help = "If no GPU is specified, returns static information for all GPUs on the system.\ + \nIf no static argument is provided, all static information will be displayed." + static_optionals_title = "Static Arguments" + + # Optional arguments help text + asic_help = "All asic information" + bus_help = "All bus information" + vbios_help = "All video bios information (if available)" + limit_help = "All limit metric values (i.e. power and thermal limits)" + driver_help = "Displays driver version" + vram_help = "All vram information" + cache_help = "All cache information" + board_help = "All board information" + + # Options arguments help text for Hypervisors and Baremetal + ras_help = "Displays RAS features information" + numa_help = "All numa node information" # Linux Baremetal only + partition_help = "Partition information" + + # Options arguments help text for Hypervisors + dfc_help = "All DFC FW table information" + fb_help = "Displays Frame Buffer information" + num_vf_help = "Displays number of supported and enabled VFs" + + # Options arguments help text for CPUs + smu_help = "All SMU FW information" + interface_help = "Displays hsmp interface version" + + # Create static subparser + static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help) + static_parser._optionals.title = static_optionals_title + static_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + static_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_device_arguments(static_parser, required=False) + + # Handle GPU Options + if self.helpers.is_amdgpu_initialized(): + static_parser.add_argument('-a', '--asic', action='store_true', required=False, help=asic_help) + static_parser.add_argument('-b', '--bus', action='store_true', required=False, help=bus_help) + static_parser.add_argument('-V', '--vbios', action='store_true', required=False, help=vbios_help) + static_parser.add_argument('-d', '--driver', action='store_true', required=False, help=driver_help) + static_parser.add_argument('-v', '--vram', action='store_true', required=False, help=vram_help) + static_parser.add_argument('-c', '--cache', action='store_true', required=False, help=cache_help) + static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) + + # Options to display on Hypervisors and Baremetal + if self.helpers.is_hypervisor() or self.helpers.is_baremetal(): + static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) + static_parser.add_argument('-p', '--partition', action='store_true', required=False, help=partition_help) + static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help) + + if self.helpers.is_linux() and not self.helpers.is_virtual_os(): + static_parser.add_argument('-u', '--numa', action='store_true', required=False, help=numa_help) + + # Options to only display on a Hypervisor TODO: Add hypervisor driver check + if self.helpers.is_hypervisor(): + static_parser.add_argument('-d', '--dfc-ucode', action='store_true', required=False, help=dfc_help) + static_parser.add_argument('-f', '--fb-info', action='store_true', required=False, help=fb_help) + static_parser.add_argument('-n', '--num-vf', action='store_true', required=False, help=num_vf_help) + + # Handle CPU Options + if self.helpers.is_amd_hsmp_initialized(): + cpu_group = static_parser.add_argument_group("CPU Arguments") + cpu_group.add_argument('-s', '--smu', action='store_true', required=False, help=smu_help) + cpu_group.add_argument('-i', '--interface-ver', action='store_true', required=False, help=interface_help) + + # Add command modifiers to the bottom + self._add_command_modifiers(static_parser) + + + def _add_firmware_parser(self, subparsers, func): + if not self.helpers.is_amdgpu_initialized(): + # The firmware subcommand is only applicable to systems with amdgpu initialized + return + + # Subparser help text + firmware_help = "Gets firmware information about the specified GPU" + firmware_subcommand_help = "If no GPU is specified, return firmware information for all GPUs on the system." + firmware_optionals_title = "Firmware Arguments" + + # Optional arguments help text + fw_list_help = "All FW list information" + err_records_help = "All error records information" + + # Create firmware subparser + firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help, aliases=['ucode']) + firmware_parser._optionals.title = firmware_optionals_title + firmware_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + firmware_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(firmware_parser) + self._add_device_arguments(firmware_parser, required=False) + + # Optional Args + firmware_parser.add_argument('-f', '--ucode-list', '--fw-list', dest='fw_list', action='store_true', required=False, help=fw_list_help, default=True) + + # Options to only display on a Hypervisor + if self.helpers.is_hypervisor(): + firmware_parser.add_argument('-e', '--error-records', action='store_true', required=False, help=err_records_help) + + + def _add_bad_pages_parser(self, subparsers, func): + if not (self.helpers.is_baremetal() and self.helpers.is_linux()): + # The bad_pages subcommand is only applicable to Linux Baremetal systems + return + + if not self.helpers.is_amdgpu_initialized(): + # The bad_pages subcommand is only applicable to systems with amdgpu initialized + return + + + # Subparser help text + bad_pages_help = "Gets bad page information about the specified GPU" + bad_pages_subcommand_help = "If no GPU is specified, return bad page information for all GPUs on the system." + bad_pages_optionals_title = "Bad Pages Arguments" + + # Optional arguments help text + pending_help = "Displays all pending retired pages" + retired_help = "Displays retired pages" + un_res_help = "Displays unreservable pages" + + # Create bad_pages subparser + bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help) + bad_pages_parser._optionals.title = bad_pages_optionals_title + bad_pages_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + bad_pages_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(bad_pages_parser) + self._add_device_arguments(bad_pages_parser, required=False) + + # Optional Args + bad_pages_parser.add_argument('-p', '--pending', action='store_true', required=False, help=pending_help) + bad_pages_parser.add_argument('-r', '--retired', action='store_true', required=False, help=retired_help) + bad_pages_parser.add_argument('-u', '--un-res', action='store_true', required=False, help=un_res_help) + + + def _add_metric_parser(self, subparsers, func): + # Subparser help text + metric_help = "Gets metric/performance information about the specified GPU" + metric_subcommand_help = "If no GPU is specified, returns metric information for all GPUs on the system.\ + \nIf no metric argument is provided all metric information will be displayed." + metric_optionals_title = "Metric arguments" + + # Optional arguments help text + usage_help = "Displays engine usage information" + + # Help text for Arguments only Available on Linux Virtual OS and Baremetal platforms + mem_usage_help = "Memory usage per block" + + # Help text for Arguments only on Hypervisor and Baremetal platforms + power_help = "Current power usage" + clock_help = "Average, max, and current clock frequencies" + temperature_help = "Current temperatures" + ecc_help = "Total number of ECC errors" + ecc_block_help = "Number of ECC errors per block" + pcie_help = "Current PCIe speed, width, and replay count" + + # Help text for Arguments only on Linux Baremetal platforms + fan_help = "Current fan speed" + vc_help = "Display voltage curve" + overdrive_help = "Current GPU clock overdrive level" + perf_level_help = "Current DPM performance level" + xgmi_err_help = "XGMI error information since last read" + energy_help = "Amount of energy consumed" + + # Help text for Arguments only on Hypervisors + schedule_help = "All scheduling information" + guard_help = "All guard information" + guest_data_help = "All guest data information" + fb_usage_help = "Displays total and used Frame Buffer usage information" + xgmi_help = "Table of current XGMI metrics information" + + # Help text for cpu options + cpu_power_metrics_help = "CPU power metrics" + cpu_proc_help = "Displays prochot status" + cpu_freq_help = "Displays currentFclkMemclk frequencies and cclk frequency limit" + cpu_c0_res_help = "Displays C0 residency" + cpu_lclk_dpm_help = "Displays lclk dpm level range. Requires socket ID and NBOID as inputs" + cpu_pwr_svi_telemtry_rails_help = "Displays svi based telemetry for all rails" + cpu_io_bandwidth_help = "Displays current IO bandwidth for the selected CPU.\ + \n input parameters are bandwidth type(1) and link ID encodings\ + \n i.e. P2, P3, G0 - G7" + cpu_xgmi_bandwidth_help = "Displays current XGMI bandwidth for the selected CPU\ + \n input parameters are bandwidth type(1,2,4) and link ID encodings\ + \n i.e. P2, P3, G0 - G7" + cpu_metrics_ver_help = "Displays metrics table version" + cpu_metrics_table_help = "Displays metric table" + cpu_socket_energy_help = "Displays socket energy for the selected CPU socket" + cpu_ddr_bandwidth_help = "Displays per socket max ddr bw, current utilized bw,\ + \n and current utilized ddr bw in percentage" + cpu_temp_help = "Displays cpu socket temperature" + cpu_dimm_temp_range_rate_help = "Displays dimm temperature range and refresh rate" + cpu_dimm_pow_consumption_help = "Displays dimm power consumption" + cpu_dimm_thermal_sensor_help = "Displays dimm thermal sensor" + + # Help text for core options + core_energy_help = "Displays core energy for the selected core" + core_boost_limit_help = "Get boost limit for the selected cores" + core_curr_active_freq_core_limit_help = "Get Current CCLK limit set per Core" + + # Create metric subparser + metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help) + metric_parser._optionals.title = metric_optionals_title + metric_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + metric_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_device_arguments(metric_parser, required=False) + + # Add Watch args + self._add_watch_arguments(metric_parser) + + # Optional Args for Linux Virtual OS and Baremetal systems + if not self.helpers.is_hypervisor() and not self.helpers.is_windows(): + metric_parser.add_argument('-m', '--mem-usage', action='store_true', required=False, help=mem_usage_help) + + if self.helpers.is_amdgpu_initialized(): + # Optional Args for Hypervisors and Baremetal systems + if self.helpers.is_hypervisor() or self.helpers.is_baremetal() or self.helpers.is_linux(): + metric_parser.add_argument('-u', '--usage', action='store_true', required=False, help=usage_help) + metric_parser.add_argument('-p', '--power', action='store_true', required=False, help=power_help) + metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help) + metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help) + metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) + metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help) + + # Optional Args for Linux Baremetal Systems + if self.helpers.is_baremetal() and self.helpers.is_linux(): + metric_parser.add_argument('-k', '--ecc-block', action='store_true', required=False, help=ecc_block_help) + metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help) + metric_parser.add_argument('-C', '--voltage-curve', action='store_true', required=False, help=vc_help) + metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help) + metric_parser.add_argument('-l', '--perf-level', action='store_true', required=False, help=perf_level_help) + metric_parser.add_argument('-x', '--xgmi-err', action='store_true', required=False, help=xgmi_err_help) + metric_parser.add_argument('-E', '--energy', action='store_true', required=False, help=energy_help) + + # Options to only display to Hypervisors + if self.helpers.is_hypervisor(): + metric_parser.add_argument('-s', '--schedule', action='store_true', required=False, help=schedule_help) + metric_parser.add_argument('-G', '--guard', action='store_true', required=False, help=guard_help) + metric_parser.add_argument('-u', '--guest-data', action='store_true', required=False, help=guest_data_help) + metric_parser.add_argument('-f', '--fb-usage', action='store_true', required=False, help=fb_usage_help) + metric_parser.add_argument('-m', '--xgmi', action='store_true', required=False, help=xgmi_help) + + if self.helpers.is_amd_hsmp_initialized(): + # Optional Args for CPUs + cpu_group = metric_parser.add_argument_group("CPU Arguments") + cpu_group.add_argument('--cpu-power-metrics', action='store_true', required=False, help=cpu_power_metrics_help) + cpu_group.add_argument('--cpu-prochot', action='store_true', required=False, help=cpu_proc_help) + cpu_group.add_argument('--cpu-freq-metrics', action='store_true', required=False, help=cpu_freq_help) + cpu_group.add_argument('--cpu-c0-res', action='store_true', required=False, help=cpu_c0_res_help) + cpu_group.add_argument('--cpu-lclk-dpm-level', action='append', required=False, type=self._validate_positive, + nargs=1, metavar=("NBIOID"), help=cpu_lclk_dpm_help) + cpu_group.add_argument('--cpu-pwr-svi-telemtry-rails', action='store_true', required=False, + help=cpu_pwr_svi_telemtry_rails_help) + cpu_group.add_argument('--cpu-io-bandwidth', action='append', required=False, nargs=2, + metavar=("IO_BW", "LINKID_NAME"), help=cpu_io_bandwidth_help) + cpu_group.add_argument('--cpu-xgmi-bandwidth', action='append', required=False, nargs=2, + metavar=("XGMI_BW", "LINKID_NAME"), help=cpu_xgmi_bandwidth_help) + cpu_group.add_argument('--cpu-metrics-ver', action='store_true', required=False, help=cpu_metrics_ver_help) + cpu_group.add_argument('--cpu-metrics-table', action='store_true', required=False, help=cpu_metrics_table_help) + cpu_group.add_argument('--cpu-socket-energy', action='store_true', required=False, help=cpu_socket_energy_help) + cpu_group.add_argument('--cpu-ddr-bandwidth', action='store_true', required=False, help=cpu_ddr_bandwidth_help) + cpu_group.add_argument('--cpu-temp', action='store_true', required=False, help=cpu_temp_help) + cpu_group.add_argument('--cpu-dimm-temp-range-rate', action='append', required=False, type=lambda x: int(x, 0), + nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_temp_range_rate_help) + cpu_group.add_argument('--cpu-dimm-pow-consumption', action='append', required=False, type=lambda x: int(x, 0), + nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_pow_consumption_help) + cpu_group.add_argument('--cpu-dimm-thermal-sensor', action='append', required=False, type=lambda x: int(x, 0), + nargs=1, metavar=("DIMM_ADDR"), help=cpu_dimm_thermal_sensor_help) + + # Optional Args for CPU cores + core_group = metric_parser.add_argument_group("CPU Core Arguments") + core_group.add_argument('--core-boost-limit', action='store_true', required=False, help=core_boost_limit_help) + core_group.add_argument('--core-curr-active-freq-core-limit', action='store_true', required=False, + help=core_curr_active_freq_core_limit_help) + core_group.add_argument('--core-energy', action='store_true', required=False, help=core_energy_help) + + # Add command modifiers to the bottom + self._add_command_modifiers(metric_parser) + + + def _add_process_parser(self, subparsers, func): + if self.helpers.is_hypervisor(): + # Don't add this subparser on Hypervisors + # This subparser is only available to Guest and Baremetal systems + return + + if not self.helpers.is_amdgpu_initialized(): + # The process subcommand is currently only applicable to systems with amdgpu initialized + return + + # Subparser help text + process_help = "Lists general process information running on the specified GPU" + process_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system.\ + \nIf no process argument is provided all process information will be displayed." + process_optionals_title = "Process arguments" + + # Optional Arguments help text + general_help = "pid, process name, memory usage" + engine_help = "All engine usages" + pid_help = "Gets all process information about the specified process based on Process ID" + name_help = "Gets all process information about the specified process based on Process Name.\ + \nIf multiple processes have the same name information is returned for all of them." + + + # Create process subparser + process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help) + process_parser._optionals.title = process_optionals_title + process_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + process_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(process_parser) + self._add_device_arguments(process_parser, required=False) + + # Add Watch args + self._add_watch_arguments(process_parser) + + # Optional Args + process_parser.add_argument('-G', '--general', action='store_true', required=False, help=general_help) + process_parser.add_argument('-e', '--engine', action='store_true', required=False, help=engine_help) + process_parser.add_argument('-p', '--pid', action='store', type=self._not_negative_int, required=False, help=pid_help) + process_parser.add_argument('-n', '--name', action='store', required=False, help=name_help) + + + def _add_profile_parser(self, subparsers, func): + if not (self.helpers.is_windows() and self.helpers.is_hypervisor()): + # This subparser only applies to Hypervisors + return + + # Subparser help text + profile_help = "Displays information about all profiles and current profile" + profile_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system." + profile_optionals_title = "Profile Arguments" + + # Create profile subparser + profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help) + profile_parser._optionals.title = profile_optionals_title + profile_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + profile_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(profile_parser) + self._add_device_arguments(profile_parser, required=False) + + + def _add_event_parser(self, subparsers, func): + if not self.helpers.is_amdgpu_initialized(): + # The event subcommand is only applicable to systems with amdgpu initialized + return + + # Subparser help text + event_help = "Displays event information for the given GPU" + event_subcommand_help = "If no GPU is specified, returns event information for all GPUs on the system." + event_optionals_title = "Event Arguments" + + # Create event subparser + event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help) + event_parser._optionals.title = event_optionals_title + event_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + event_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(event_parser) + self._add_device_arguments(event_parser, required=False) + + + def _add_topology_parser(self, subparsers, func): + if not(self.helpers.is_baremetal() and self.helpers.is_linux()): + # This subparser is only applicable to Baremetal Linux + return + + if not self.helpers.is_amdgpu_initialized(): + # The topology subcommand is only applicable to systems with amdgpu initialized + return + + # Subparser help text + topology_help = "Displays topology information of the devices" + topology_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system.\ + \nIf no topology argument is provided all topology information will be displayed." + topology_optionals_title = "Topology arguments" + + # Help text for Arguments only on Guest and BM platforms + access_help = "Displays link accessibility between GPUs" + weight_help = "Displays relative weight between GPUs" + hops_help = "Displays the number of hops between GPUs" + link_type_help = "Displays the link type between GPUs" + numa_bw_help = "Display max and min bandwidth between nodes" + + # Create topology subparser + topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help) + topology_parser._optionals.title = topology_optionals_title + topology_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + topology_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(topology_parser) + self._add_device_arguments(topology_parser, required=False) + + # Optional Args + topology_parser.add_argument('-a', '--access', action='store_true', required=False, help=access_help) + topology_parser.add_argument('-w', '--weight', action='store_true', required=False, help=weight_help) + topology_parser.add_argument('-o', '--hops', action='store_true', required=False, help=hops_help) + topology_parser.add_argument('-t', '--link-type', action='store_true', required=False, help=link_type_help) + topology_parser.add_argument('-b', '--numa-bw', action='store_true', required=False, help=numa_bw_help) + + + def _add_set_value_parser(self, subparsers, func): + if not(self.helpers.is_baremetal() and self.helpers.is_linux()): + # This subparser is only applicable to Baremetal Linux + return + + # Subparser help text + set_value_help = "Set options for devices" + set_value_subcommand_help = "A GPU must be specified to set a configuration.\ + \nA set argument must be provided; Multiple set arguments are accepted" + set_value_optionals_title = "Set Arguments" + + # Help text for Arguments only on BM platforms + set_fan_help = "Set GPU fan speed (0-255 or 0-100%%)" + set_perf_level_help = "Set performance level" + set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes" + set_perf_det_help = "Set GPU clock frequency limit and performance level to determinism to get minimal performance variation" + compute_partition_choices_str = ", ".join(self.helpers.get_compute_partition_types()) + memory_partition_choices_str = ", ".join(self.helpers.get_memory_partition_types()) + set_compute_partition_help = f"Set one of the following the compute partition modes:\n\t{compute_partition_choices_str}" + set_memory_partition_help = f"Set one of the following the memory partition modes:\n\t{memory_partition_choices_str}" + set_power_cap_help = "Set power capacity limit" + + # Help text for CPU set options + set_cpu_pwr_limit_help = "Set power limit for the given socket. Input parameter is power limit value." + set_cpu_xgmi_link_width_help = "Set max and Min linkwidth. Input parameters are min and max link width values" + set_cpu_lclk_dpm_level_help = "Sets the max and min dpm level on a given NBIO.\ + \n Input parameters are die_index, min dpm, max dpm." + set_cpu_pwr_eff_mode_help = "Sets the power efficency mode policy. Input parameter is mode." + set_cpu_gmi3_link_width_help = "Sets max and min gmi3 link width range" + set_cpu_pcie_link_rate_help = "Sets pcie link rate" + set_cpu_df_pstate_range_help = "Sets max and min df-pstates" + set_cpu_enable_apb_help = "Enables the DF p-state performance boost algorithm" + set_cpu_disable_apb_help = "Disables the DF p-state performance boost algorithm. Input parameter is DFPstate (0-3)" + set_soc_boost_limit_help = "Sets the boost limit for the given socket. Input parameter is socket BOOST_LIMIT value" + + # Help text for CPU Core set options + set_core_boost_limit_help = "Sets the boost limit for the given core. Input parameter is core BOOST_LIMIT value" + + # Create set_value subparser + set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) + set_value_parser._optionals.title = set_value_optionals_title + set_value_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + set_value_parser.set_defaults(func=func) + + # Device args are required as safeguard from the user applying the operation to all gpus unintentionally + self._add_device_arguments(set_value_parser, required=True) + + if self.helpers.is_amdgpu_initialized(): + # Optional GPU Args + set_value_parser.add_argument('-f', '--fan', action=self._validate_fan_speed(), required=False, help=set_fan_help, metavar='%') + set_value_parser.add_argument('-l', '--perf-level', action='store', choices=self.helpers.get_perf_levels()[0], type=str.upper, required=False, help=set_perf_level_help, metavar='LEVEL') + set_value_parser.add_argument('-P', '--profile', action='store', required=False, help=set_profile_help, metavar='SETPROFILE') + set_value_parser.add_argument('-d', '--perf-determinism', action='store', type=self._not_negative_int, required=False, help=set_perf_det_help, metavar='SCLKMAX') + set_value_parser.add_argument('-C', '--compute-partition', action='store', choices=self.helpers.get_compute_partition_types(), type=str.upper, required=False, help=set_compute_partition_help, metavar='PARTITION') + set_value_parser.add_argument('-M', '--memory-partition', action='store', choices=self.helpers.get_memory_partition_types(), type=str.upper, required=False, help=set_memory_partition_help, metavar='PARTITION') + set_value_parser.add_argument('-o', '--power-cap', action='store', type=self._positive_int, required=False, help=set_power_cap_help, metavar='WATTS') + + if self.helpers.is_amd_hsmp_initialized(): + # Optional CPU Args + cpu_group = set_value_parser.add_argument_group("CPU Arguments") + cpu_group.add_argument('--cpu-pwr-limit', action='append', required=False, type=self._validate_positive, nargs=1, metavar=("PWR_LIMIT"), help=set_cpu_pwr_limit_help) + cpu_group.add_argument('--cpu-xgmi-link-width', action='append', required=False, type=self._validate_positive, nargs=2, metavar=("MIN_WIDTH", "MAX_WIDTH"), help=set_cpu_xgmi_link_width_help) + cpu_group.add_argument('--cpu-lclk-dpm-level', action='append', required=False, type=self._validate_positive, nargs=3, metavar=("NBIOID", "MIN_DPM", "MAX_DPM"), help=set_cpu_lclk_dpm_level_help) + cpu_group.add_argument('--cpu-pwr-eff-mode', action='append', required=False, type=self._validate_positive, nargs=1, metavar=("MODE"), help=set_cpu_pwr_eff_mode_help) + cpu_group.add_argument('--cpu-gmi3-link-width', action='append', required=False, type=self._validate_positive, nargs=2, metavar=("MIN_LW", "MAX_LW"), help=set_cpu_gmi3_link_width_help) + cpu_group.add_argument('--cpu-pcie-link-rate', action='append', required=False, type=self._validate_positive, nargs=1, metavar=("LINK_RATE"), help=set_cpu_pcie_link_rate_help) + cpu_group.add_argument('--cpu-df-pstate-range', action='append', required=False, type=self._validate_positive, nargs=2, metavar=("MAX_PSTATE", "MIN_PSTATE"), help=set_cpu_df_pstate_range_help) + cpu_group.add_argument('--cpu-enable-apb', action='store_true', required=False, help=set_cpu_enable_apb_help) + cpu_group.add_argument('--cpu-disable-apb', action='append', required=False, type=self._validate_positive, nargs=1, metavar=("DF_PSTATE"), help=set_cpu_disable_apb_help) + cpu_group.add_argument('--soc-boost-limit', action='append', required=False, type=self._validate_positive, nargs=1, metavar=("BOOST_LIMIT"), help=set_soc_boost_limit_help) + + # Optional CPU Core Args + core_group = set_value_parser.add_argument_group("CPU Core Arguments") + core_group.add_argument('--core-boost-limit', action='append', required=False, type=self._validate_positive, nargs=1, metavar=("BOOST_LIMIT"), help=set_core_boost_limit_help) + + # Add command modifiers to the bottom + self._add_command_modifiers(set_value_parser) + + def _add_reset_parser(self, subparsers, func): if not(self.helpers.is_baremetal() and self.helpers.is_linux()): # This subparser is only applicable to Baremetal Linux return + if not self.helpers.is_amdgpu_initialized(): + # The reset subcommand is only applicable to systems with amdgpu initialized + return + # Subparser help text reset_help = "Reset options for devices" reset_subcommand_help = "A GPU must be specified to reset a configuration.\ @@ -998,6 +1073,10 @@ core limit value" # This subparser is only applicable to Linux return + if not self.helpers.is_amdgpu_initialized(): + # The monitor subcommand is only applicable to systems with amdgpu initialized + return + # Subparser help text monitor_help = "Monitor metrics for target devices" monitor_subcommand_help = "Monitor a target device for the specified arguments.\ diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 0233c3cf24..1b599d5632 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -67,12 +67,12 @@ extern "C" { * Initialization flags may be OR'd together and passed to ::amdsmi_init(). */ typedef enum { - AMDSMI_INIT_ALL_PROCESSORS = 0x0, // Default option + AMDSMI_INIT_ALL_PROCESSORS = 0xFFFFFFFF, //!< Initialize all processors AMDSMI_INIT_AMD_CPUS = (1 << 0), AMDSMI_INIT_AMD_GPUS = (1 << 1), AMDSMI_INIT_NON_AMD_CPUS = (1 << 2), AMDSMI_INIT_NON_AMD_GPUS = (1 << 3), - AMDSMI_INIT_AMD_APUS = (AMDSMI_INIT_AMD_CPUS | AMDSMI_INIT_AMD_GPUS) + AMDSMI_INIT_AMD_APUS = (AMDSMI_INIT_AMD_CPUS | AMDSMI_INIT_AMD_GPUS) // Default option } amdsmi_init_flags_t; /* Maximum size definitions AMDSMI */ diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index b4c79a351d..a1747f31a6 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -73,7 +73,7 @@ except AmdSmiException as e: ### amdsmi_init -Description: Initialize amdsmi lib and connect to driver +Description: Dynamically initialize amdsmi with amd_hsmp and amdgpu drivers Input parameters: `None` @@ -87,7 +87,12 @@ Example: ```python try: - amdsmi_init() + init_flag = amdsmi_init() + # Print out integer bitmask of initialized drivers + # 1 is for amd_hsmp + # 2 is for amdgpu + # 3 is for amd_hsmp and amdgpu + print(init_flag) # continue with amdsmi except AmdSmiException as e: print("Init failed") diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 8b49fd9b2c..7656b9fa8b 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -196,14 +196,14 @@ _libraries['FIXME_STUB'] = FunctionFactoryStub() # ctypes.CDLL('FIXME_STUB') # values for enumeration 'amdsmi_init_flags_t' amdsmi_init_flags_t__enumvalues = { - 0: 'AMDSMI_INIT_ALL_PROCESSORS', + 4294967295: 'AMDSMI_INIT_ALL_PROCESSORS', 1: 'AMDSMI_INIT_AMD_CPUS', 2: 'AMDSMI_INIT_AMD_GPUS', 4: 'AMDSMI_INIT_NON_AMD_CPUS', 8: 'AMDSMI_INIT_NON_AMD_GPUS', 3: 'AMDSMI_INIT_AMD_APUS', } -AMDSMI_INIT_ALL_PROCESSORS = 0 +AMDSMI_INIT_ALL_PROCESSORS = 4294967295 AMDSMI_INIT_AMD_CPUS = 1 AMDSMI_INIT_AMD_GPUS = 2 AMDSMI_INIT_NON_AMD_CPUS = 4 diff --git a/projects/amdsmi/src/amd_smi/amd_smi_system.cc b/projects/amdsmi/src/amd_smi/amd_smi_system.cc index e46eb71784..7b0da49bf5 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_system.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_system.cc @@ -261,7 +261,7 @@ amdsmi_status_t AMDSmiSystem::cleanup() { processors_.clear(); sockets_.clear(); esmi_exit(); - init_flag_ = AMDSMI_INIT_ALL_PROCESSORS; + init_flag_ &= ~AMDSMI_INIT_AMD_CPUS; } #endif if (init_flag_ & AMDSMI_INIT_AMD_GPUS) { @@ -270,7 +270,7 @@ amdsmi_status_t AMDSmiSystem::cleanup() { } processors_.clear(); sockets_.clear(); - init_flag_ = AMDSMI_INIT_ALL_PROCESSORS; + init_flag_ &= ~AMDSMI_INIT_AMD_GPUS; rsmi_status_t ret = rsmi_shut_down(); if (ret != RSMI_STATUS_SUCCESS) { return amd::smi::rsmi_to_amdsmi_status(ret); From 21cf0c1b5c9c213ec7b2affae6353d9f792c9f5b Mon Sep 17 00:00:00 2001 From: "Bill(Shuzhou) Liu" Date: Thu, 15 Feb 2024 12:41:50 -0600 Subject: [PATCH 06/15] Unify the amdsmi_get_pcie_info python interface Make the python interface consistent with the C interface. Change-Id: Idda08f888947c757e475d5a024b0ec3d8e1d846a [ROCm/amdsmi commit: db33cda0c1aab631cd72e5b069077089dc0d8aaf] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 15 +++++++------ .../amdsmi/example/amd_smi_drm_example.cc | 4 ++-- projects/amdsmi/include/amd_smi/amdsmi.h | 4 ++-- projects/amdsmi/py-interface/README.md | 4 ++-- .../amdsmi/py-interface/amdsmi_interface.py | 21 ++++++++++++++----- .../amdsmi/py-interface/amdsmi_wrapper.py | 6 +++--- projects/amdsmi/src/amd_smi/amd_smi.cc | 4 ++-- 7 files changed, 36 insertions(+), 22 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index bb717e498d..6b62982f7c 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -353,7 +353,10 @@ class AMDSMICommands(): try: link_caps = amdsmi_interface.amdsmi_get_pcie_info(args.gpu) - bus_info.update(link_caps) + bus_info['max_pcie_speed'] = link_caps['pcie_static']['max_pcie_speed'] + bus_info['pcie_slot_type'] = link_caps['pcie_static']['slot_type'] + bus_info['pcie_interface_version'] = link_caps['pcie_static']['pcie_interface_version'] + if bus_info['max_pcie_speed'] % 1000 != 0: pcie_speed_GTs_value = round(bus_info['max_pcie_speed'] / 1000, 1) else: @@ -1396,17 +1399,17 @@ class AMDSMICommands(): try: pcie_link_status = amdsmi_interface.amdsmi_get_pcie_info(args.gpu) - if pcie_link_status['pcie_speed'] % 1000 != 0: - pcie_speed_GTs_value = round(pcie_link_status['pcie_speed'] / 1000, 1) + if pcie_link_status['pcie_metric']['pcie_speed'] % 1000 != 0: + pcie_speed_GTs_value = round(pcie_link_status['pcie_metric']['pcie_speed'] / 1000, 1) else: - pcie_speed_GTs_value = round(pcie_link_status['pcie_speed'] / 1000) + pcie_speed_GTs_value = round(pcie_link_status['pcie_metric']['pcie_speed'] / 1000) pcie_dict['current_speed'] = pcie_speed_GTs_value - pcie_dict['current_lanes'] = pcie_link_status['pcie_lanes'] + pcie_dict['current_lanes'] = pcie_link_status['pcie_metric']['pcie_width'] if self.logger.is_human_readable_format(): unit = 'GT/s' - pcie_dict['current_lanes'] = f"{pcie_link_status['pcie_lanes']} lanes" + pcie_dict['current_lanes'] = f"{pcie_link_status['pcie_metric']['pcie_width']} lanes" pcie_dict['current_speed'] = f"{pcie_dict['current_speed']} GT/s" except amdsmi_exception.AmdSmiLibraryException as e: diff --git a/projects/amdsmi/example/amd_smi_drm_example.cc b/projects/amdsmi/example/amd_smi_drm_example.cc index e18fc1cfce..ea28b8ebba 100644 --- a/projects/amdsmi/example/amd_smi_drm_example.cc +++ b/projects/amdsmi/example/amd_smi_drm_example.cc @@ -403,12 +403,12 @@ int main() { ret = amdsmi_get_pcie_info(processor_handles[j], &pcie_info); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_pcie_info:\n"); - printf("\tCurrent PCIe lanes: %d\n", pcie_info.pcie_metric.pcie_lanes); + printf("\tCurrent PCIe lanes: %d\n", pcie_info.pcie_metric.pcie_width); printf("\tCurrent PCIe speed: %d\n", pcie_info.pcie_metric.pcie_speed); printf("\tCurrent PCIe Interface Version: %d\n", pcie_info.pcie_static.pcie_interface_version); printf("\tPCIe slot type: %d\n", pcie_info.pcie_static.slot_type); - printf("\tPCIe max lanes: %d\n", pcie_info.pcie_static.max_pcie_lanes); + printf("\tPCIe max lanes: %d\n", pcie_info.pcie_static.max_pcie_width); printf("\tPCIe max speed: %d\n", pcie_info.pcie_static.max_pcie_speed); // Get VRAM temperature limit diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 1b599d5632..7a4b209124 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -500,15 +500,15 @@ typedef enum { typedef struct { struct pcie_static_ { - uint16_t max_pcie_lanes; //!< maximum number of PCIe lanes + uint16_t max_pcie_width; //!< maximum number of PCIe lanes uint32_t max_pcie_speed; //!< maximum PCIe speed uint32_t pcie_interface_version; //!< PCIe interface version amdsmi_card_form_factor_t slot_type; //!< card form factor uint64_t reserved[10]; } pcie_static; struct pcie_metric_ { + uint16_t pcie_width; //!< current PCIe width uint32_t pcie_speed; //!< current PCIe speed in MT/s - uint16_t pcie_lanes; //!< current PCIe width uint32_t pcie_bandwidth; //!< current PCIe bandwidth Mb/s uint64_t pcie_replay_count; //!< total number of the replays issued on the PCIe link uint64_t pcie_l0_to_recovery_count; //!< total number of times the PCIe link transitioned from L0 to the recovery state diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index a1747f31a6..d812dc7375 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -791,7 +791,7 @@ Output: Dictionary with fields Field | Description ---|--- -`pcie_lanes`| pcie lanes in use +`pcie_width`| pcie lanes in use `pcie_speed`| current pcie speed `pcie_interface_version`| current pcie generation @@ -811,7 +811,7 @@ try: else: for device in devices: pcie_link_status = amdsmi_get_pcie_info(device) - print(pcie_link_status["pcie_lanes"]) + print(pcie_link_status["pcie_width"]) print(pcie_link_status["pcie_speed"]) print(pcie_link_status["pcie_interface_version"]) except AmdSmiException as e: diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 6b22359404..a7ebc41f08 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -2134,13 +2134,24 @@ def amdsmi_get_pcie_info( ) ) - return {"pcie_speed": pcie_info.pcie_metric.pcie_speed, - "pcie_lanes": pcie_info.pcie_metric.pcie_lanes, - "pcie_interface_version": pcie_info.pcie_static.pcie_interface_version, + return { + "pcie_static": { + "max_pcie_width": pcie_info.pcie_static.max_pcie_width, "max_pcie_speed": pcie_info.pcie_static.max_pcie_speed, - "max_pcie_lanes": pcie_info.pcie_static.max_pcie_lanes, "pcie_interface_version": pcie_info.pcie_static.pcie_interface_version, - "pcie_slot_type": pcie_info.pcie_static.slot_type} + "slot_type": pcie_info.pcie_static.slot_type, + }, + "pcie_metric": { + "pcie_width": pcie_info.pcie_metric.pcie_width, + "pcie_speed": pcie_info.pcie_metric.pcie_speed, + "pcie_bandwidth": pcie_info.pcie_metric.pcie_bandwidth, + "pcie_replay_count": pcie_info.pcie_metric.pcie_replay_count, + "pcie_l0_to_recovery_count": pcie_info.pcie_metric.pcie_l0_to_recovery_count, + "pcie_replay_roll_over_count": pcie_info.pcie_metric.pcie_replay_roll_over_count, + "pcie_nak_sent_count": pcie_info.pcie_metric.pcie_nak_sent_count, + "pcie_nak_received_count": pcie_info.pcie_metric.pcie_nak_received_count, + } + } def amdsmi_get_processor_handle_from_bdf(bdf): diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 7656b9fa8b..eafde217c7 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -751,9 +751,9 @@ class struct_pcie_metric_(Structure): struct_pcie_metric_._pack_ = 1 # source:False struct_pcie_metric_._fields_ = [ - ('pcie_speed', ctypes.c_uint32), - ('pcie_lanes', ctypes.c_uint16), + ('pcie_width', ctypes.c_uint16), ('PADDING_0', ctypes.c_ubyte * 2), + ('pcie_speed', ctypes.c_uint32), ('pcie_bandwidth', ctypes.c_uint32), ('PADDING_1', ctypes.c_ubyte * 4), ('pcie_replay_count', ctypes.c_uint64), @@ -769,7 +769,7 @@ class struct_pcie_static_(Structure): struct_pcie_static_._pack_ = 1 # source:False struct_pcie_static_._fields_ = [ - ('max_pcie_lanes', ctypes.c_uint16), + ('max_pcie_width', ctypes.c_uint16), ('PADDING_0', ctypes.c_ubyte * 2), ('max_pcie_speed', ctypes.c_uint32), ('pcie_interface_version', ctypes.c_uint32), diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index 2f68823540..e576f67226 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -1964,7 +1964,7 @@ amdsmi_status_t amdsmi_get_pcie_info(amdsmi_processor_handle processor_handle, a printf("Failed to open file: %s \n", path_max_link_width.c_str()); return AMDSMI_STATUS_API_FAILED; } - info->pcie_static.max_pcie_lanes = (uint16_t)pcie_width; + info->pcie_static.max_pcie_width = (uint16_t)pcie_width; std::string path_max_link_speed = "/sys/class/drm/" + gpu_device->get_gpu_path() + "/device/max_link_speed"; @@ -2028,7 +2028,7 @@ amdsmi_status_t amdsmi_get_pcie_info(amdsmi_processor_handle processor_handle, a if (status != AMDSMI_STATUS_SUCCESS) return status; - info->pcie_metric.pcie_lanes = metric_info.pcie_link_width; + info->pcie_metric.pcie_width = metric_info.pcie_link_width; // gpu metrics is inconsistent with pcie_speed values, if 0-6 then it needs to be translated if (metric_info.pcie_link_speed <= 6) { status = smi_amdgpu_get_pcie_speed_from_pcie_type(metric_info.pcie_link_speed, &info->pcie_metric.pcie_speed); // mapping to MT/s From 13e9ab4ad6ddc8c5c799833d1d42621c135dd7b0 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Wed, 21 Feb 2024 21:46:32 -0600 Subject: [PATCH 07/15] SWDEV-445396 - Aligned Static Command with Host Signed-off-by: Maisam Arif Change-Id: I4182b9104e173f54830fc44819a61d74d31d65d7 [ROCm/amdsmi commit: a719ae970706e5f1848218d5c7c828a6f07ccbd4] --- projects/amdsmi/amdsmi_cli/README.md | 228 +++++++----------- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 40 ++- projects/amdsmi/py-interface/README.md | 4 +- .../amdsmi/py-interface/amdsmi_interface.py | 15 +- .../amdsmi/py-interface/amdsmi_wrapper.py | 24 +- 5 files changed, 133 insertions(+), 178 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index 0fa72b8534..cfa66890ee 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -637,8 +637,8 @@ BOARD: MODEL_NUMBER: N/A PRODUCT_SERIAL: N/A FRU_ID: N/A - MANUFACTURER_NAME: N/A PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A LIMIT: MAX_POWER: 550 W CURRENT_POWER: 0 W @@ -649,13 +649,13 @@ LIMIT: SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C SHUTDOWN_VRAM_TEMPERATURE: 105 °C DRIVER: - DRIVER_NAME: amdgpu - DRIVER_VERSION: 6.5.2 + NAME: amdgpu + VERSION: 6.5.2 VRAM: - VRAM_TYPE: HBM - VRAM_VENDOR: HYNIX - VRAM_SIZE_MB: 96432 MB -CACHE: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB +CACHE_INFO: CACHE_0: CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE CACHE_SIZE: 32 KB @@ -688,34 +688,20 @@ RAS: DOUBLE_BIT_SCHEMA: DISABLED POISON_SCHEMA: ENABLED ECC_BLOCK_STATE: - BLOCK: UMC - STATUS: DISABLED - BLOCK: SDMA - STATUS: ENABLED - BLOCK: GFX - STATUS: ENABLED - BLOCK: MMHUB - STATUS: ENABLED - BLOCK: ATHUB - STATUS: DISABLED - BLOCK: PCIE_BIF - STATUS: DISABLED - BLOCK: HDP - STATUS: DISABLED - BLOCK: XGMI_WAFL - STATUS: DISABLED - BLOCK: DF - STATUS: DISABLED - BLOCK: SMN - STATUS: DISABLED - BLOCK: SEM - STATUS: DISABLED - BLOCK: MP0 - STATUS: DISABLED - BLOCK: MP1 - STATUS: DISABLED - BLOCK: FUSE - STATUS: DISABLED + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED PARTITION: COMPUTE_PARTITION: SPX MEMORY_PARTITION: NPS1 @@ -748,8 +734,8 @@ BOARD: MODEL_NUMBER: N/A PRODUCT_SERIAL: N/A FRU_ID: N/A - MANUFACTURER_NAME: N/A PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A LIMIT: MAX_POWER: 550 W CURRENT_POWER: 0 W @@ -760,14 +746,13 @@ LIMIT: SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C SHUTDOWN_VRAM_TEMPERATURE: 105 °C DRIVER: - DRIVER_NAME: amdgpu - DRIVER_VERSION: 6.5.2 + NAME: amdgpu + VERSION: 6.5.2 VRAM: - VRAM_TYPE: HBM - VRAM_VENDOR: HYNIX - VRAM_SIZE_MB: 96432 MB -CACHE: - CACHE: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB +CACHE_INFO: CACHE_0: CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE CACHE_SIZE: 32 KB @@ -799,34 +784,20 @@ RAS: DOUBLE_BIT_SCHEMA: DISABLED POISON_SCHEMA: ENABLED ECC_BLOCK_STATE: - BLOCK: UMC - STATUS: DISABLED - BLOCK: SDMA - STATUS: ENABLED - BLOCK: GFX - STATUS: ENABLED - BLOCK: MMHUB - STATUS: ENABLED - BLOCK: ATHUB - STATUS: DISABLED - BLOCK: PCIE_BIF - STATUS: DISABLED - BLOCK: HDP - STATUS: DISABLED - BLOCK: XGMI_WAFL - STATUS: DISABLED - BLOCK: DF - STATUS: DISABLED - BLOCK: SMN - STATUS: DISABLED - BLOCK: SEM - STATUS: DISABLED - BLOCK: MP0 - STATUS: DISABLED - BLOCK: MP1 - STATUS: DISABLED - BLOCK: FUSE - STATUS: DISABLED + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED PARTITION: COMPUTE_PARTITION: SPX MEMORY_PARTITION: NPS1 @@ -859,8 +830,8 @@ BOARD: MODEL_NUMBER: N/A PRODUCT_SERIAL: N/A FRU_ID: N/A - MANUFACTURER_NAME: N/A PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A LIMIT: MAX_POWER: 550 W CURRENT_POWER: 0 W @@ -871,14 +842,13 @@ LIMIT: SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C SHUTDOWN_VRAM_TEMPERATURE: 105 °C DRIVER: - DRIVER_NAME: amdgpu - DRIVER_VERSION: 6.5.2 + NAME: amdgpu + VERSION: 6.5.2 VRAM: - VRAM_TYPE: HBM - VRAM_VENDOR: HYNIX - VRAM_SIZE_MB: 96432 MB -CACHE: - CACHE: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB +CACHE_INFO: CACHE_0: CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE CACHE_SIZE: 32 KB @@ -910,34 +880,20 @@ RAS: DOUBLE_BIT_SCHEMA: DISABLED POISON_SCHEMA: ENABLED ECC_BLOCK_STATE: - BLOCK: UMC - STATUS: DISABLED - BLOCK: SDMA - STATUS: ENABLED - BLOCK: GFX - STATUS: ENABLED - BLOCK: MMHUB - STATUS: ENABLED - BLOCK: ATHUB - STATUS: DISABLED - BLOCK: PCIE_BIF - STATUS: DISABLED - BLOCK: HDP - STATUS: DISABLED - BLOCK: XGMI_WAFL - STATUS: DISABLED - BLOCK: DF - STATUS: DISABLED - BLOCK: SMN - STATUS: DISABLED - BLOCK: SEM - STATUS: DISABLED - BLOCK: MP0 - STATUS: DISABLED - BLOCK: MP1 - STATUS: DISABLED - BLOCK: FUSE - STATUS: DISABLED + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED PARTITION: COMPUTE_PARTITION: SPX MEMORY_PARTITION: NPS1 @@ -970,8 +926,8 @@ BOARD: MODEL_NUMBER: N/A PRODUCT_SERIAL: N/A FRU_ID: N/A - MANUFACTURER_NAME: N/A PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A LIMIT: MAX_POWER: 550 W CURRENT_POWER: 0 W @@ -982,15 +938,13 @@ LIMIT: SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C SHUTDOWN_VRAM_TEMPERATURE: 105 °C DRIVER: - DRIVER_NAME: amdgpu - DRIVER_VERSION: 6.5.2 + NAME: amdgpu + VERSION: 6.5.2 VRAM: - VRAM_TYPE: HBM - VRAM_VENDOR: HYNIX - VRAM_SIZE_MB: 96432 MB -CACHE: - CACHE_0: -CACHE: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB +CACHE_INFO: CACHE_0: CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE CACHE_SIZE: 32 KB @@ -1022,34 +976,20 @@ RAS: DOUBLE_BIT_SCHEMA: DISABLED POISON_SCHEMA: ENABLED ECC_BLOCK_STATE: - BLOCK: UMC - STATUS: DISABLED - BLOCK: SDMA - STATUS: ENABLED - BLOCK: GFX - STATUS: ENABLED - BLOCK: MMHUB - STATUS: ENABLED - BLOCK: ATHUB - STATUS: DISABLED - BLOCK: PCIE_BIF - STATUS: DISABLED - BLOCK: HDP - STATUS: DISABLED - BLOCK: XGMI_WAFL - STATUS: DISABLED - BLOCK: DF - STATUS: DISABLED - BLOCK: SMN - STATUS: DISABLED - BLOCK: SEM - STATUS: DISABLED - BLOCK: MP0 - STATUS: DISABLED - BLOCK: MP1 - STATUS: DISABLED - BLOCK: FUSE - STATUS: DISABLED + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED PARTITION: COMPUTE_PARTITION: SPX MEMORY_PARTITION: NPS1 diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 6b62982f7c..6529269a6d 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -399,8 +399,8 @@ class AMDSMICommands(): static_dict['board'] = {"model_number": "N/A", "product_serial": "N/A", "fru_id": "N/A", - "manufacturer_name": "N/A", - "product_name": "N/A"} + "product_name": "N/A", + "manufacturer_name": "N/A"} try: board_info = amdsmi_interface.amdsmi_get_gpu_board_info(args.gpu) for key, value in board_info.items(): @@ -524,17 +524,21 @@ class AMDSMICommands(): limit_info['shutdown_vram_temperature'] = shutdown_temp_vram_limit static_dict['limit'] = limit_info if args.driver: - driver_info = {"driver_name" : "N/A", - "driver_version" : "N/A" - } + driver_info_dict = {"name" : "N/A", + "version" : "N/A"} try: driver_info = amdsmi_interface.amdsmi_get_gpu_driver_info(args.gpu) + driver_info_dict["name"] = driver_info["driver_name"] + driver_info_dict["version"] = driver_info["driver_version"] except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get driver info for gpu %s | %s", gpu_id, e.get_error_info()) - static_dict['driver'] = driver_info + static_dict['driver'] = driver_info_dict if args.vram: + vram_info_dict = {"type" : "N/A", + "vendor" : "N/A", + "size" : "N/A"} try: vram_info = amdsmi_interface.amdsmi_get_gpu_vram_info(args.gpu) @@ -556,16 +560,24 @@ class AMDSMICommands(): # Remove amdsmi enum prefix vram_vendor = vram_vendor.replace('AMDSMI_VRAM_VENDOR__', '') - vram_info['vram_type'] = vram_type - vram_info['vram_vendor'] = vram_vendor + # Assign cleaned values to vram_info_dict + vram_info_dict['type'] = vram_type + vram_info_dict['vendor'] = vram_vendor + + # Populate vram size with unit + vram_info_dict['size'] = vram_info['vram_size_mb'] + vram_size_unit = "MB" if self.logger.is_human_readable_format(): - vram_info['vram_size_mb'] = f"{vram_info['vram_size_mb']} MB" + vram_info_dict['size'] = f"{vram_info['vram_size_mb']} {vram_size_unit}" + + if self.logger.is_json_format(): + vram_info_dict['size'] = {"value" : vram_info['vram_size_mb'], + "unit" : vram_size_unit} except amdsmi_exception.AmdSmiLibraryException as e: - vram_info = "N/A" logging.debug("Failed to get vram info for gpu %s | %s", gpu_id, e.get_error_info()) - static_dict['vram'] = vram_info + static_dict['vram'] = vram_info_dict if args.cache: try: cache_info_list = amdsmi_interface.amdsmi_get_gpu_cache_info(args.gpu)['cache'] @@ -628,7 +640,11 @@ class AMDSMICommands(): logging.debug("Failed to get ras info for gpu %s | %s", gpu_id, e.get_error_info()) try: - ras_dict["ecc_block_state"] = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) + ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) + ecc_block_state_dict = {} + for state in ras_states: + ecc_block_state_dict[state["block"]] = state["status"] + ras_dict["ecc_block_state"] = ecc_block_state_dict except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info()) diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index d812dc7375..b28c50ec4b 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -989,8 +989,8 @@ Field | Description `model_number` | Board serial number `product_serial` | Product serial `fru_id` | FRU ID -`manufacturer_name` | Manufacturer name `product_name` | Product name +`manufacturer_name` | Manufacturer name Exceptions that can be thrown by `amdsmi_get_gpu_board_info` function: @@ -1007,8 +1007,8 @@ try: print(board_info["model_number"]) print(board_info["product_serial"]) print(board_info["fru_id"]) - print(board_info["manufacturer_name"]) print(board_info["product_name"]) + print(board_info["manufacturer_name"]) except AmdSmiException as e: print(e) ``` diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index a7ebc41f08..98844c700f 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -1851,8 +1851,8 @@ def amdsmi_get_gpu_board_info( "model_number": board_info.model_number.decode("utf-8").strip(), "product_serial": board_info.product_serial.decode("utf-8").strip(), "fru_id": board_info.fru_id.decode("utf-8").strip(), - "manufacturer_name" : board_info.manufacturer_name.decode("utf-8").strip(), - "product_name": board_info.product_name.decode("utf-8").strip() + "product_name": board_info.product_name.decode("utf-8").strip(), + "manufacturer_name": board_info.manufacturer_name.decode("utf-8").strip() } @@ -2002,8 +2002,6 @@ def amdsmi_get_gpu_driver_info( length = ctypes.c_int() length.value = _AMDSMI_MAX_DRIVER_VERSION_LENGTH - version = ctypes.create_string_buffer(_AMDSMI_MAX_DRIVER_VERSION_LENGTH) - info = amdsmi_wrapper.amdsmi_driver_info_t() _check_res( amdsmi_wrapper.amdsmi_get_gpu_driver_info( @@ -2013,7 +2011,8 @@ def amdsmi_get_gpu_driver_info( return { "driver_name": info.driver_name.decode("utf-8"), - "driver_version": info.driver_version.decode("utf-8") + "driver_version": info.driver_version.decode("utf-8"), + "driver_date": info.driver_date.decode("utf-8") } @@ -2110,13 +2109,13 @@ def amdsmi_get_gpu_vram_usage( processor_handle, amdsmi_wrapper.amdsmi_processor_handle ) - vram_info = amdsmi_wrapper.amdsmi_vram_usage_t() + vram_usage = amdsmi_wrapper.amdsmi_vram_usage_t() _check_res( amdsmi_wrapper.amdsmi_get_gpu_vram_usage( - processor_handle, ctypes.byref(vram_info)) + processor_handle, ctypes.byref(vram_usage)) ) - return {"vram_total": vram_info.vram_total, "vram_used": vram_info.vram_used} + return {"vram_total": vram_usage.vram_total, "vram_used": vram_usage.vram_used} def amdsmi_get_pcie_info( diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index eafde217c7..91bdc8bd4d 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -2570,10 +2570,10 @@ __all__ = \ 'amdsmi_gpu_counter_group_supported', 'amdsmi_gpu_create_counter', 'amdsmi_gpu_destroy_counter', 'amdsmi_gpu_metrics_t', 'amdsmi_gpu_read_counter', 'amdsmi_gpu_xgmi_error_status', - 'amdsmi_hsmp_metrics_table_t', 'amdsmi_init', - 'amdsmi_init_flags_t', 'amdsmi_init_gpu_event_notification', - 'amdsmi_io_bw_encoding_t', 'amdsmi_io_link_type_t', - 'amdsmi_is_P2P_accessible', + 'amdsmi_hsmp_freqlimit_src_names', 'amdsmi_hsmp_metrics_table_t', + 'amdsmi_init', 'amdsmi_init_flags_t', + 'amdsmi_init_gpu_event_notification', 'amdsmi_io_bw_encoding_t', + 'amdsmi_io_link_type_t', 'amdsmi_is_P2P_accessible', 'amdsmi_is_gpu_power_management_enabled', 'amdsmi_link_id_bw_type_t', 'amdsmi_link_metrics_t', 'amdsmi_link_type_t', 'amdsmi_memory_page_status_t', @@ -2619,14 +2619,14 @@ __all__ = \ 'amdsmi_voltage_type_t', 'amdsmi_vram_info_t', 'amdsmi_vram_type_t', 'amdsmi_vram_usage_t', 'amdsmi_vram_vendor_type_t', 'amdsmi_xgmi_info_t', - 'amdsmi_xgmi_status_t', 'amdsmi_hsmp_freqlimit_src_names', - 'processor_type_t', 'size_t', 'struct__links', - 'struct_amd_metrics_table_header_t', 'struct_amdsmi_asic_info_t', - 'struct_amdsmi_board_info_t', 'struct_amdsmi_clk_info_t', - 'struct_amdsmi_counter_value_t', 'struct_amdsmi_ddr_bw_metrics_t', - 'struct_amdsmi_dimm_power_t', 'struct_amdsmi_dimm_thermal_t', - 'struct_amdsmi_dpm_level_t', 'struct_amdsmi_driver_info_t', - 'struct_amdsmi_engine_usage_t', 'struct_amdsmi_error_count_t', + 'amdsmi_xgmi_status_t', 'processor_type_t', 'size_t', + 'struct__links', 'struct_amd_metrics_table_header_t', + 'struct_amdsmi_asic_info_t', 'struct_amdsmi_board_info_t', + 'struct_amdsmi_clk_info_t', 'struct_amdsmi_counter_value_t', + 'struct_amdsmi_ddr_bw_metrics_t', 'struct_amdsmi_dimm_power_t', + 'struct_amdsmi_dimm_thermal_t', 'struct_amdsmi_dpm_level_t', + 'struct_amdsmi_driver_info_t', 'struct_amdsmi_engine_usage_t', + 'struct_amdsmi_error_count_t', 'struct_amdsmi_evt_notification_data_t', 'struct_amdsmi_freq_volt_region_t', 'struct_amdsmi_frequencies_t', 'struct_amdsmi_frequency_range_t', 'struct_amdsmi_fw_info_t', From 49dd38f1173aaa7fb42066a1b8c8f2f7d21fc2e9 Mon Sep 17 00:00:00 2001 From: "Oliveira, Daniel" Date: Fri, 16 Feb 2024 20:38:18 -0600 Subject: [PATCH 08/15] fix: [rocm/amd_smi_lib] TestFrequenciesRead & TestPciReadWrite test cases failed Fixes asserts in unit tests, and 'pp_dpm_pcie' condition Code changes related to the following: * rsmi_dev_pci_bandwidth_set() * Functional tests Change-Id: Id5e6851393fa3b51bb8cad87daca1efaf500a7e0 Signed-off-by: Oliveira, Daniel [ROCm/amdsmi commit: 475424525edaafbb7f2ca354ac4c9f21dfefcebd] --- projects/amdsmi/rocm_smi/src/rocm_smi.cc | 5 ++++- .../functional/frequencies_read.cc | 3 ++- .../amd_smi_test/functional/pci_read_write.cc | 21 ++++++++++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi.cc b/projects/amdsmi/rocm_smi/src/rocm_smi.cc index 98e25be381..fdf64a9374 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi.cc @@ -2642,7 +2642,10 @@ rsmi_dev_pci_bandwidth_set(uint32_t dv_ind, uint64_t bw_bitmask) { int32_t ret_i; ret_i = dev->writeDevInfo(amd::smi::kDevPCIEClk, freq_enable_str); - + // + // NOTE: kDevPCIEClk sysfs file maybe not exist for all cases. + // If it doesn't exist (pp_dpm_pcie), it shouldn't be an error + // and will get translated to RSMI_STATUS_NOT_SUPPORTED. return amd::smi::ErrnoToRsmiStatus(ret_i); CATCH diff --git a/projects/amdsmi/tests/amd_smi_test/functional/frequencies_read.cc b/projects/amdsmi/tests/amd_smi_test/functional/frequencies_read.cc index 6aec518e26..aba165cc50 100755 --- a/projects/amdsmi/tests/amd_smi_test/functional/frequencies_read.cc +++ b/projects/amdsmi/tests/amd_smi_test/functional/frequencies_read.cc @@ -181,8 +181,9 @@ void TestFrequenciesRead::Run(void) { std::cout << b.transfer_rate.num_supported << std::endl; print_frequencies(&b.transfer_rate, b.lanes); // Verify api support checking functionality is working + // NOTE: We expect AMDSMI_STATUS_NOT_SUPPORTED, if rsmi_pcie_bandwidth_t* is NULL err = amdsmi_get_gpu_pci_bandwidth(processor_handles_[i], nullptr); - ASSERT_EQ(err, AMDSMI_STATUS_INVAL); + ASSERT_EQ(err, AMDSMI_STATUS_NOT_SUPPORTED); } } } diff --git a/projects/amdsmi/tests/amd_smi_test/functional/pci_read_write.cc b/projects/amdsmi/tests/amd_smi_test/functional/pci_read_write.cc index 4c147ad4cf..0f658aec03 100755 --- a/projects/amdsmi/tests/amd_smi_test/functional/pci_read_write.cc +++ b/projects/amdsmi/tests/amd_smi_test/functional/pci_read_write.cc @@ -163,8 +163,9 @@ void TestPciReadWrite::Run(void) { std::endl; } // Verify api support checking functionality is working + // NOTE: We expect AMDSMI_STATUS_NOT_SUPPORTED, if rsmi_pcie_bandwidth_t* is NULL ret = amdsmi_get_gpu_pci_bandwidth(processor_handles_[dv_ind], nullptr); - ASSERT_EQ(ret, AMDSMI_STATUS_INVAL); + ASSERT_EQ(ret, AMDSMI_STATUS_NOT_SUPPORTED); // First set the bitmask to all supported bandwidths freq_bitmask = ~(~0u << bw.transfer_rate.num_supported); @@ -183,7 +184,14 @@ void TestPciReadWrite::Run(void) { " ..." << std::endl; } ret = amdsmi_set_gpu_pci_bandwidth(processor_handles_[dv_ind], freq_bitmask); - CHK_ERR_ASRT(ret) + if (ret != amdsmi_status_t::AMDSMI_STATUS_NOT_SUPPORTED) { + CHK_ERR_ASRT(ret) + } + else { + auto status_string(""); + amdsmi_status_code_to_string(ret, &status_string); + std::cout << "\t\t** amdsmi_set_gpu_pci_bandwidth(): " << status_string << "\n"; + } ret = amdsmi_get_gpu_pci_bandwidth(processor_handles_[dv_ind], &bw); CHK_ERR_ASRT(ret) @@ -194,7 +202,14 @@ void TestPciReadWrite::Run(void) { std::cout << "\tResetting mask to all bandwidths." << std::endl; } ret = amdsmi_set_gpu_pci_bandwidth(processor_handles_[dv_ind], 0xFFFFFFFF); - CHK_ERR_ASRT(ret) + if (ret != amdsmi_status_t::AMDSMI_STATUS_NOT_SUPPORTED) { + CHK_ERR_ASRT(ret) + } + else { + auto status_string(""); + amdsmi_status_code_to_string(ret, &status_string); + std::cout << "\t\t** amdsmi_set_gpu_pci_bandwidth(): " << status_string << "\n"; + } ret = amdsmi_set_gpu_perf_level(processor_handles_[dv_ind], AMDSMI_DEV_PERF_LEVEL_AUTO); CHK_ERR_ASRT(ret) From 8c4518eb661aac394ab42c11595a8d07dc73d6b1 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 22 Feb 2024 02:39:31 -0600 Subject: [PATCH 09/15] SWDEV-445664 - Aligned Metric Command with Host Signed-off-by: Maisam Arif Change-Id: I905ee72272bb4c5ccde3e237d2663ec6e0e55034 [ROCm/amdsmi commit: 542bfc0c77c41ecb9873936f86ae6828fcb0a727] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 377 +++++++++--------- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 6 +- 2 files changed, 197 insertions(+), 186 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 6529269a6d..6cc5fd8218 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -353,6 +353,7 @@ class AMDSMICommands(): try: link_caps = amdsmi_interface.amdsmi_get_pcie_info(args.gpu) + bus_info['max_pcie_width'] = link_caps['pcie_static']['max_pcie_width'] bus_info['max_pcie_speed'] = link_caps['pcie_static']['max_pcie_speed'] bus_info['pcie_slot_type'] = link_caps['pcie_static']['slot_type'] bus_info['pcie_interface_version'] = link_caps['pcie_static']['pcie_interface_version'] @@ -374,11 +375,18 @@ class AMDSMICommands(): else: bus_info['slot_type'] = "N/A" + if bus_info['pcie_interface_version'] > 0: + bus_info['pcie_interface_version'] = f"Gen {bus_info['pcie_interface_version']}" + + # Set the unit for pcie_speed + pcie_speed_unit ='GT/s' if self.logger.is_human_readable_format(): - unit ='GT/s' - bus_info['max_pcie_speed'] = f"{bus_info['max_pcie_speed']} {unit}" - if bus_info['pcie_interface_version'] > 0: - bus_info['pcie_interface_version'] = f"Gen {bus_info['pcie_interface_version']}" + bus_info['max_pcie_speed'] = f"{bus_info['max_pcie_speed']} {pcie_speed_unit}" + + if self.logger.is_json_format(): + bus_info['max_pcie_speed'] = {"value" : bus_info['max_pcie_speed'], + "unit" : pcie_speed_unit} + except amdsmi_exception.AmdSmiLibraryException as e: bus_info = "N/A" logging.debug("Failed to get bus info for gpu %s | %s", gpu_id, e.get_error_info()) @@ -395,21 +403,6 @@ class AMDSMICommands(): except amdsmi_exception.AmdSmiLibraryException as e: static_dict['vbios'] = "N/A" logging.debug("Failed to get vbios info for gpu %s | %s", gpu_id, e.get_error_info()) - if args.board: - static_dict['board'] = {"model_number": "N/A", - "product_serial": "N/A", - "fru_id": "N/A", - "product_name": "N/A", - "manufacturer_name": "N/A"} - try: - board_info = amdsmi_interface.amdsmi_get_gpu_board_info(args.gpu) - for key, value in board_info.items(): - if isinstance(value, str): - if value.strip() == '': - board_info[key] = "N/A" - static_dict['board'] = board_info - except amdsmi_exception.AmdSmiLibraryException as e: - logging.debug("Failed to get board info for gpu %s | %s", gpu_id, e.get_error_info()) if 'limit' in current_platform_args: if args.limit: # Power limits @@ -417,11 +410,11 @@ class AMDSMICommands(): power_limit_error = False power_cap_info = amdsmi_interface.amdsmi_get_power_cap_info(args.gpu) max_power_limit = power_cap_info['max_power_cap'] - current_power_limit = power_cap_info['power_cap'] + socket_power_limit = power_cap_info['power_cap'] except amdsmi_exception.AmdSmiLibraryException as e: power_limit_error = True max_power_limit = "N/A" - current_power_limit = "N/A" + socket_power_limit = "N/A" logging.debug("Failed to get power cap info for gpu %s | %s", gpu_id, e.get_error_info()) # Edge temperature limits @@ -491,29 +484,29 @@ class AMDSMICommands(): logging.debug("Failed to get vram temperature shutdown metrics for gpu %s | %s", gpu_id, e.get_error_info()) if self.logger.is_human_readable_format(): - unit = 'W' + pcie_speed_unit = 'W' if not power_limit_error: - max_power_limit = f"{max_power_limit} {unit}" - current_power_limit = f"{current_power_limit} {unit}" + max_power_limit = f"{max_power_limit} {pcie_speed_unit}" + socket_power_limit = f"{socket_power_limit} {pcie_speed_unit}" - unit = '\N{DEGREE SIGN}C' + pcie_speed_unit = '\N{DEGREE SIGN}C' if not slowdown_temp_edge_limit_error: - slowdown_temp_edge_limit = f"{slowdown_temp_edge_limit} {unit}" + slowdown_temp_edge_limit = f"{slowdown_temp_edge_limit} {pcie_speed_unit}" if not slowdown_temp_hotspot_limit_error: - slowdown_temp_hotspot_limit = f"{slowdown_temp_hotspot_limit} {unit}" + slowdown_temp_hotspot_limit = f"{slowdown_temp_hotspot_limit} {pcie_speed_unit}" if not slowdown_temp_vram_limit_error: - slowdown_temp_vram_limit = f"{slowdown_temp_vram_limit} {unit}" + slowdown_temp_vram_limit = f"{slowdown_temp_vram_limit} {pcie_speed_unit}" if not shutdown_temp_edge_limit_error: - shutdown_temp_edge_limit = f"{shutdown_temp_edge_limit} {unit}" + shutdown_temp_edge_limit = f"{shutdown_temp_edge_limit} {pcie_speed_unit}" if not shutdown_temp_hotspot_limit_error: - shutdown_temp_hotspot_limit = f"{shutdown_temp_hotspot_limit} {unit}" + shutdown_temp_hotspot_limit = f"{shutdown_temp_hotspot_limit} {pcie_speed_unit}" if not shutdown_temp_vram_limit_error: - shutdown_temp_vram_limit = f"{shutdown_temp_vram_limit} {unit}" + shutdown_temp_vram_limit = f"{shutdown_temp_vram_limit} {pcie_speed_unit}" limit_info = {} # Power limits limit_info['max_power'] = max_power_limit - limit_info['current_power'] = current_power_limit + limit_info['socket_power'] = socket_power_limit # Shutdown limits limit_info['slowdown_edge_temperature'] = slowdown_temp_edge_limit @@ -535,6 +528,93 @@ class AMDSMICommands(): logging.debug("Failed to get driver info for gpu %s | %s", gpu_id, e.get_error_info()) static_dict['driver'] = driver_info_dict + if args.board: + static_dict['board'] = {"model_number": "N/A", + "product_serial": "N/A", + "fru_id": "N/A", + "product_name": "N/A", + "manufacturer_name": "N/A"} + try: + board_info = amdsmi_interface.amdsmi_get_gpu_board_info(args.gpu) + for key, value in board_info.items(): + if isinstance(value, str): + if value.strip() == '': + board_info[key] = "N/A" + static_dict['board'] = board_info + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get board info for gpu %s | %s", gpu_id, e.get_error_info()) + if 'ras' in current_platform_args: + if args.ras: + ras_dict = {"eeprom_version": "N/A", + "parity_schema" : "N/A", + "single_bit_schema" : "N/A", + "double_bit_schema" : "N/A", + "poison_schema" : "N/A", + "ecc_block_state": "N/A"} + + try: + ras_info = amdsmi_interface.amdsmi_get_gpu_ras_feature_info(args.gpu) + for key, value in ras_info.items(): + if isinstance(value, int): + if value == 65535: + logging.debug(f"Failed to get ras {key} for gpu {gpu_id}") + ras_info[key] = "N/A" + continue + if key != "eeprom_version": + if value: + ras_info[key] = "ENABLED" + else: + ras_info[key] = "DISABLED" + + ras_dict.update(ras_info) + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get ras info for gpu %s | %s", gpu_id, e.get_error_info()) + + try: + ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) + ecc_block_state_dict = {} + for state in ras_states: + ecc_block_state_dict[state["block"]] = state["status"] + ras_dict["ecc_block_state"] = ecc_block_state_dict + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info()) + + static_dict["ras"] = ras_dict + if 'partition' in current_platform_args: + if args.partition: + try: + compute_partition = amdsmi_interface.amdsmi_get_gpu_compute_partition(args.gpu) + except amdsmi_exception.AmdSmiLibraryException as e: + compute_partition = "N/A" + logging.debug("Failed to get compute partition info for gpu %s | %s", gpu_id, e.get_error_info()) + + try: + memory_partition = amdsmi_interface.amdsmi_get_gpu_memory_partition(args.gpu) + except amdsmi_exception.AmdSmiLibraryException as e: + memory_partition = "N/A" + logging.debug("Failed to get memory partition info for gpu %s | %s", gpu_id, e.get_error_info()) + + static_dict['partition'] = {"compute_partition": compute_partition, + "memory_partition": memory_partition} + if 'numa' in current_platform_args: + if args.numa: + try: + numa_node_number = amdsmi_interface.amdsmi_topo_get_numa_node_number(args.gpu) + except amdsmi_exception.AmdSmiLibraryException as e: + numa_node_number = "N/A" + logging.debug("Failed to get numa node number for gpu %s | %s", gpu_id, e.get_error_info()) + + try: + numa_affinity = amdsmi_interface.amdsmi_get_gpu_topo_numa_affinity(args.gpu) + # -1 means No numa node is assigned to the GPU, so there is no numa affinity + if self.logger.is_human_readable_format() and numa_affinity == -1: + numa_affinity = "NONE" + except amdsmi_exception.AmdSmiLibraryException as e: + numa_affinity = "N/A" + logging.debug("Failed to get numa affinity for gpu %s | %s", gpu_id, e.get_error_info()) + + static_dict['numa'] = {'node' : numa_node_number, + 'affinity' : numa_affinity} if args.vram: vram_info_dict = {"type" : "N/A", "vendor" : "N/A", @@ -612,78 +692,6 @@ class AMDSMICommands(): logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()) static_dict['cache_info'] = cache_info_list - if 'ras' in current_platform_args: - if args.ras: - ras_dict = {"eeprom_version": "N/A", - "parity_schema" : "N/A", - "single_bit_schema" : "N/A", - "double_bit_schema" : "N/A", - "poison_schema" : "N/A", - "ecc_block_state": "N/A"} - - try: - ras_info = amdsmi_interface.amdsmi_get_gpu_ras_feature_info(args.gpu) - for key, value in ras_info.items(): - if isinstance(value, int): - if value == 65535: - logging.debug(f"Failed to get ras {key} for gpu {gpu_id}") - ras_info[key] = "N/A" - continue - if key != "eeprom_version": - if value: - ras_info[key] = "ENABLED" - else: - ras_info[key] = "DISABLED" - - ras_dict.update(ras_info) - except amdsmi_exception.AmdSmiLibraryException as e: - logging.debug("Failed to get ras info for gpu %s | %s", gpu_id, e.get_error_info()) - - try: - ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(args.gpu) - ecc_block_state_dict = {} - for state in ras_states: - ecc_block_state_dict[state["block"]] = state["status"] - ras_dict["ecc_block_state"] = ecc_block_state_dict - except amdsmi_exception.AmdSmiLibraryException as e: - logging.debug("Failed to get ras block features for gpu %s | %s", gpu_id, e.get_error_info()) - - static_dict["ras"] = ras_dict - if 'partition' in current_platform_args: - if args.partition: - try: - compute_partition = amdsmi_interface.amdsmi_get_gpu_compute_partition(args.gpu) - except amdsmi_exception.AmdSmiLibraryException as e: - compute_partition = "N/A" - logging.debug("Failed to get compute partition info for gpu %s | %s", gpu_id, e.get_error_info()) - - try: - memory_partition = amdsmi_interface.amdsmi_get_gpu_memory_partition(args.gpu) - except amdsmi_exception.AmdSmiLibraryException as e: - memory_partition = "N/A" - logging.debug("Failed to get memory partition info for gpu %s | %s", gpu_id, e.get_error_info()) - - static_dict['partition'] = {"compute_partition": compute_partition, - "memory_partition": memory_partition} - if 'numa' in current_platform_args: - if args.numa: - try: - numa_node_number = amdsmi_interface.amdsmi_topo_get_numa_node_number(args.gpu) - except amdsmi_exception.AmdSmiLibraryException as e: - numa_node_number = "N/A" - logging.debug("Failed to get numa node number for gpu %s | %s", gpu_id, e.get_error_info()) - - try: - numa_affinity = amdsmi_interface.amdsmi_get_gpu_topo_numa_affinity(args.gpu) - # -1 means No numa node is assigned to the GPU, so there is no numa affinity - if self.logger.is_human_readable_format() and numa_affinity == -1: - numa_affinity = "NONE" - except amdsmi_exception.AmdSmiLibraryException as e: - numa_affinity = "N/A" - logging.debug("Failed to get numa affinity for gpu %s | %s", gpu_id, e.get_error_info()) - - static_dict['numa'] = {'node' : numa_node_number, - 'affinity' : numa_affinity} # Convert and store output by pid for csv format multiple_devices_csv_override = False @@ -1008,7 +1016,7 @@ class AMDSMICommands(): def metric_gpu(self, args, multiple_devices=False, watching_output=False, gpu=None, usage=None, watch=None, watch_time=None, iterations=None, power=None, - clock=None, temperature=None, ecc=None, ecc_block=None, pcie=None, + clock=None, temperature=None, ecc=None, ecc_blocks=None, pcie=None, fan=None, voltage_curve=None, overdrive=None, perf_level=None, xgmi_err=None, energy=None, mem_usage=None, schedule=None, guard=None, guest_data=None, fb_usage=None, xgmi=None,): @@ -1027,7 +1035,7 @@ class AMDSMICommands(): clock (bool, optional): Value override for args.clock. Defaults to None. temperature (bool, optional): Value override for args.temperature. Defaults to None. ecc (bool, optional): Value override for args.ecc. Defaults to None. - ecc_block (bool, optional): Value override for args.ecc. Defaults to None. + ecc_blocks (bool, optional): Value override for args.ecc. Defaults to None. pcie (bool, optional): Value override for args.pcie. Defaults to None. fan (bool, optional): Value override for args.fan. Defaults to None. voltage_curve (bool, optional): Value override for args.voltage_curve. Defaults to None. @@ -1085,8 +1093,8 @@ class AMDSMICommands(): current_platform_values += [args.usage, args.power, args.clock, args.temperature, args.ecc, args.pcie] if self.helpers.is_baremetal() and self.helpers.is_linux(): - if ecc_block: - args.ecc_block = ecc_block + if ecc_blocks: + args.ecc_blocks = ecc_blocks if fan: args.fan = fan if voltage_curve: @@ -1099,8 +1107,8 @@ class AMDSMICommands(): args.xgmi_err = xgmi_err if energy: args.energy = energy - current_platform_args += ["ecc_block", "fan", "voltage_curve", "overdrive", "perf_level", "xgmi_err", "energy"] - current_platform_values += [args.ecc_block, args.fan, args.voltage_curve, args.overdrive, args.perf_level, args.xgmi_err, args.energy] + current_platform_args += ["ecc_blocks", "fan", "voltage_curve", "overdrive", "perf_level", "xgmi_err", "energy"] + current_platform_values += [args.ecc_blocks, args.fan, args.voltage_curve, args.overdrive, args.perf_level, args.xgmi_err, args.energy] if self.helpers.is_hypervisor(): if schedule: @@ -1209,11 +1217,10 @@ class AMDSMICommands(): logging.debug("Failed to get gpu activity for gpu %s | %s", gpu_id, e.get_error_info()) if "power" in current_platform_args: if args.power: - power_dict = {'current_power': "N/A", - 'current_gfx_voltage': "N/A", - 'current_soc_voltage': "N/A", - 'current_mem_voltage': "N/A", - 'power_limit': "N/A", + power_dict = {'socket_power': "N/A", + 'gfx_voltage': "N/A", + 'soc_voltage': "N/A", + 'mem_voltage': "N/A", 'power_management': "N/A", 'throttle_status': "N/A"} @@ -1228,16 +1235,15 @@ class AMDSMICommands(): elif "power" in key: power_info[key] = f"{value} W" - power_dict['current_power'] = power_info['current_socket_power'] + power_dict['socket_power'] = power_info['current_socket_power'] - if power_dict['current_power'] == "N/A": + if power_dict['socket_power'] == "N/A": # For older gpu's when current power doesn't populate we use the average socket power instead - power_dict['current_power'] = power_info['average_socket_power'] + power_dict['socket_power'] = power_info['average_socket_power'] - power_dict['current_gfx_voltage'] = power_info['gfx_voltage'] - power_dict['current_soc_voltage'] = power_info['soc_voltage'] - power_dict['current_mem_voltage'] = power_info['mem_voltage'] - power_dict['power_limit'] = power_info['power_limit'] + power_dict['gfx_voltage'] = power_info['gfx_voltage'] + power_dict['soc_voltage'] = power_info['soc_voltage'] + power_dict['mem_voltage'] = power_info['mem_voltage'] except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get power info for gpu %s | %s", gpu_id, e.get_error_info()) @@ -1282,7 +1288,11 @@ class AMDSMICommands(): vlck0_clock_name = clock_name try: - clock_info = amdsmi_interface.amdsmi_get_clock_info(args.gpu, clock_type) + clock_info_dict = amdsmi_interface.amdsmi_get_clock_info(args.gpu, clock_type) + clock_info = {"clk" : clock_info_dict["cur_clk"]} + del clock_info_dict["cur_clk"] + clock_info.update(clock_info_dict) + if clock_info['sleep_clk'] == 0xFFFFFFFF: clock_info['sleep_clk'] = "N/A" @@ -1303,28 +1313,28 @@ class AMDSMICommands(): continue else: # Handle all other failed to get clock info - clocks[clock_name] = {"cur_clk": "N/A", + clocks[clock_name] = {"clk": "N/A", "max_clk": "N/A", "min_clk": "N/A", "sleep_clk": "N/A"} logging.debug("Failed to get %s clock info for gpu %s | %s", clock_name, gpu_id, e.get_error_info()) try: - is_clk_locked = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['gfxclk_lock_status'] - if is_clk_locked != "N/A": - if is_clk_locked: - is_clk_locked = "LOCKED" + gfxclk_lock_status = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['gfxclk_lock_status'] + if gfxclk_lock_status != "N/A": + if gfxclk_lock_status: + gfxclk_lock_status = "ENABLED" else: - is_clk_locked = "UNLOCKED" + gfxclk_lock_status = "DISABLED" except amdsmi_exception.AmdSmiLibraryException as e: - is_clk_locked = "N/A" + gfxclk_lock_status = "N/A" logging.debug("Failed to get gfx clock lock status info for gpu %s | %s", gpu_id, e.get_error_info()) if "gfx" in clocks: if isinstance(clocks['gfx'], dict): - clocks['gfx']['is_clk_locked'] = is_clk_locked + clocks['gfx']['clk_locked'] = gfxclk_lock_status else: - clocks['gfx'] = {"is_clk_locked": is_clk_locked} + clocks['gfx'] = {"clk_locked": gfxclk_lock_status} values_dict['clock'] = clocks if "temperature" in current_platform_args: @@ -1372,37 +1382,10 @@ class AMDSMICommands(): temperatures[temperature_key] = f"{temperature_value} {unit}" values_dict['temperature'] = temperatures - if "ecc" in current_platform_args: - if args.ecc: - ecc_count = {} - try: - ecc_count = amdsmi_interface.amdsmi_get_gpu_total_ecc_count(args.gpu) - ecc_count['total_correctable'] = ecc_count.pop('correctable_count') - ecc_count['total_uncorrectable'] = ecc_count.pop('uncorrectable_count') - except amdsmi_exception.AmdSmiLibraryException as e: - ecc_count['total_correctable'] = "N/A" - ecc_count['total_uncorrectable'] = "N/A" - ecc_count['cache_correctable'] = "N/A" - ecc_count['cache_uncorrectable'] = "N/A" - logging.debug("Failed to get total ecc count for gpu %s | %s", gpu_id, e.get_error_info()) - - if ecc_count['total_correctable'] != "N/A": - # Get the UMC error count for getting total cache correctable errors - umc_block = amdsmi_interface.AmdSmiGpuBlock['UMC'] - try: - umc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, umc_block) - ecc_count['cache_correctable'] = ecc_count['total_correctable'] - umc_count['correctable_count'] - ecc_count['cache_uncorrectable'] = ecc_count['total_uncorrectable'] - umc_count['uncorrectable_count'] - except amdsmi_exception.AmdSmiLibraryException as e: - ecc_count['cache_correctable'] = "N/A" - ecc_count['cache_uncorrectable'] = "N/A" - logging.debug("Failed to get cache ecc count for gpu %s at block %s | %s", gpu_id, umc_block, e.get_error_info()) - - values_dict['ecc'] = ecc_count if "pcie" in current_platform_args: if args.pcie: - pcie_dict = {"current_lanes": "N/A", - "current_speed": "N/A", + pcie_dict = {"width": "N/A", + "speed": "N/A", "replay_count" : "N/A", "l0_to_recovery_count" : "N/A", "replay_roll_over_count" : "N/A", @@ -1420,13 +1403,13 @@ class AMDSMICommands(): else: pcie_speed_GTs_value = round(pcie_link_status['pcie_metric']['pcie_speed'] / 1000) - pcie_dict['current_speed'] = pcie_speed_GTs_value - pcie_dict['current_lanes'] = pcie_link_status['pcie_metric']['pcie_width'] + pcie_dict['width'] = pcie_link_status['pcie_metric']['pcie_width'] + pcie_dict['speed'] = pcie_speed_GTs_value if self.logger.is_human_readable_format(): unit = 'GT/s' - pcie_dict['current_lanes'] = f"{pcie_link_status['pcie_metric']['pcie_width']} lanes" - pcie_dict['current_speed'] = f"{pcie_dict['current_speed']} GT/s" + pcie_dict['width'] = f"{pcie_link_status['pcie_metric']['pcie_width']} lanes" + pcie_dict['speed'] = f"{pcie_dict['speed']} GT/s" except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get pcie link status for gpu %s | %s", gpu_id, e.get_error_info()) @@ -1492,8 +1475,35 @@ class AMDSMICommands(): logging.debug("Failed to get pcie bandwidth for gpu %s | %s", gpu_id, e.get_error_info()) values_dict['pcie'] = pcie_dict - if "ecc_block" in current_platform_args: - if args.ecc_block: + if "ecc" in current_platform_args: + if args.ecc: + ecc_count = {} + try: + ecc_count = amdsmi_interface.amdsmi_get_gpu_total_ecc_count(args.gpu) + ecc_count['total_correctable_count'] = ecc_count.pop('correctable_count') + ecc_count['total_uncorrectable_count'] = ecc_count.pop('uncorrectable_count') + except amdsmi_exception.AmdSmiLibraryException as e: + ecc_count['total_correctable_count'] = "N/A" + ecc_count['total_uncorrectable_count'] = "N/A" + ecc_count['cache_correctable_count'] = "N/A" + ecc_count['cache_uncorrectable_count'] = "N/A" + logging.debug("Failed to get total ecc count for gpu %s | %s", gpu_id, e.get_error_info()) + + if ecc_count['total_correctable_count'] != "N/A": + # Get the UMC error count for getting total cache correctable errors + umc_block = amdsmi_interface.AmdSmiGpuBlock['UMC'] + try: + umc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, umc_block) + ecc_count['cache_correctable_count'] = ecc_count['total_correctable_count'] - umc_count['correctable_count'] + ecc_count['cache_uncorrectable_count'] = ecc_count['total_uncorrectable_count'] - umc_count['uncorrectable_count'] + except amdsmi_exception.AmdSmiLibraryException as e: + ecc_count['cache_correctable_count'] = "N/A" + ecc_count['cache_uncorrectable_count'] = "N/A" + logging.debug("Failed to get cache ecc count for gpu %s at block %s | %s", gpu_id, umc_block, e.get_error_info()) + + values_dict['ecc'] = ecc_count + if "ecc_blocks" in current_platform_args: + if args.ecc_blocks: ecc_dict = {} uncountable_blocks = ["ATHUB", "DF", "SMN", "SEM", "MP0", "MP1", "FUSE"] try: @@ -1505,16 +1515,16 @@ class AMDSMICommands(): if gpu_block.name not in uncountable_blocks: try: ecc_count = amdsmi_interface.amdsmi_get_gpu_ecc_count(args.gpu, gpu_block) - ecc_dict[state['block']] = {'correctable' : ecc_count['correctable_count'], - 'uncorrectable': ecc_count['uncorrectable_count']} + ecc_dict[state['block']] = {'correctable_count' : ecc_count['correctable_count'], + 'uncorrectable_count' : ecc_count['uncorrectable_count']} except amdsmi_exception.AmdSmiLibraryException as e: - ecc_dict[state['block']] = {'correctable' : "N/A", - 'uncorrectable': "N/A"} + ecc_dict[state['block']] = {'correctable_count' : "N/A", + 'uncorrectable_count' : "N/A"} logging.debug("Failed to get ecc count for gpu %s at block %s | %s", gpu_id, gpu_block, e.get_error_info()) - values_dict['ecc_block'] = ecc_dict + values_dict['ecc_blocks'] = ecc_dict except amdsmi_exception.AmdSmiLibraryException as e: - values_dict['ecc_block'] = "N/A" + values_dict['ecc_blocks'] = "N/A" logging.debug("Failed to get ecc block features for gpu %s | %s", gpu_id, e.get_error_info()) if "fan" in current_platform_args: if args.fan: @@ -2074,7 +2084,7 @@ class AMDSMICommands(): def metric(self, args, multiple_devices=False, watching_output=False, gpu=None, usage=None, watch=None, watch_time=None, iterations=None, power=None, - clock=None, temperature=None, ecc=None, ecc_block=None, pcie=None, + clock=None, temperature=None, ecc=None, ecc_blocks=None, pcie=None, fan=None, voltage_curve=None, overdrive=None, perf_level=None, xgmi_err=None, energy=None, mem_usage=None, schedule=None, guard=None, guest_data=None, fb_usage=None, xgmi=None, @@ -2101,7 +2111,7 @@ class AMDSMICommands(): clock (bool, optional): Value override for args.clock. Defaults to None. temperature (bool, optional): Value override for args.temperature. Defaults to None. ecc (bool, optional): Value override for args.ecc. Defaults to None. - ecc_block (bool, optional): Value override for args.ecc. Defaults to None. + ecc_blocks (bool, optional): Value override for args.ecc. Defaults to None. pcie (bool, optional): Value override for args.pcie. Defaults to None. fan (bool, optional): Value override for args.fan. Defaults to None. voltage_curve (bool, optional): Value override for args.voltage_curve. Defaults to None. @@ -2158,7 +2168,7 @@ class AMDSMICommands(): # Check if a GPU argument has been set gpu_args_enabled = False gpu_attributes = ["usage", "watch", "watch_time", "iterations", "power", "clock", - "temperature", "ecc", "ecc_block", "pcie", "fan", "voltage_curve", + "temperature", "ecc", "ecc_blocks", "pcie", "fan", "voltage_curve", "overdrive", "perf_level", "xgmi_err", "energy", "mem_usage", "schedule", "guard", "guest_data", "fb_usage", "xgmi"] for attr in gpu_attributes: @@ -2183,12 +2193,13 @@ class AMDSMICommands(): if hasattr(args, attr): core_args_enabled |= bool(getattr(args, attr)) - logging.debug("gpu_args_enabled: %s, cpu_args_enabled: %s, core_args_enabled: %s", - gpu_args_enabled, cpu_args_enabled, core_args_enabled) - logging.debug("args.gpu: %s, args.cpu: %s, args.core: %s", args.gpu, args.cpu, args.core) - # Handle CPU and GPU driver intialization cases if self.helpers.is_amd_hsmp_initialized() and self.helpers.is_amdgpu_initialized(): + + logging.debug("gpu_args_enabled: %s, cpu_args_enabled: %s, core_args_enabled: %s", + gpu_args_enabled, cpu_args_enabled, core_args_enabled) + logging.debug("args.gpu: %s, args.cpu: %s, args.core: %s", args.gpu, args.cpu, args.core) + # If a GPU or CPU argument is provided only print out the specified device. if args.cpu == None and args.gpu == None and args.core == None: # If no args are set, print out all CPU, GPU, and Core metrics info @@ -2223,7 +2234,7 @@ class AMDSMICommands(): self.logger.clear_multiple_devices_ouput() self.metric_gpu(args, multiple_devices, watching_output, gpu, usage, watch, watch_time, iterations, power, - clock, temperature, ecc, ecc_block, pcie, + clock, temperature, ecc, ecc_blocks, pcie, fan, voltage_curve, overdrive, perf_level, xgmi_err, energy, mem_usage, schedule, guard, guest_data, fb_usage, xgmi) @@ -2258,7 +2269,7 @@ class AMDSMICommands(): self.logger.clear_multiple_devices_ouput() self.metric_gpu(args, multiple_devices, watching_output, gpu, usage, watch, watch_time, iterations, power, - clock, temperature, ecc, ecc_block, pcie, + clock, temperature, ecc, ecc_blocks, pcie, fan, voltage_curve, overdrive, perf_level, xgmi_err, energy, mem_usage, schedule) @@ -3206,7 +3217,7 @@ class AMDSMICommands(): # Only allow one device's arguments to be set at a time if gpu_args_enabled == cpu_args_enabled == core_args_enabled == False: - raise ValueError('No GPU, CPU, or CORE arguments provided, specific target(s) are needed') + raise ValueError('No GPU, CPU, or CORE arguments provided, specific arguments are needed') elif gpu_args_enabled == cpu_args_enabled == core_args_enabled == True: raise ValueError('Cannot set GPU, CPU, and CORE arguments at the same time') elif not (gpu_args_enabled ^ cpu_args_enabled ^ core_args_enabled): diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 2db2d7661f..6d068db647 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -686,7 +686,7 @@ class AMDSMIParser(argparse.ArgumentParser): clock_help = "Average, max, and current clock frequencies" temperature_help = "Current temperatures" ecc_help = "Total number of ECC errors" - ecc_block_help = "Number of ECC errors per block" + ecc_blocks_help = "Number of ECC errors per block" pcie_help = "Current PCIe speed, width, and replay count" # Help text for Arguments only on Linux Baremetal platforms @@ -755,12 +755,12 @@ class AMDSMIParser(argparse.ArgumentParser): metric_parser.add_argument('-p', '--power', action='store_true', required=False, help=power_help) metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help) metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help) - metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help) + metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) # Optional Args for Linux Baremetal Systems if self.helpers.is_baremetal() and self.helpers.is_linux(): - metric_parser.add_argument('-k', '--ecc-block', action='store_true', required=False, help=ecc_block_help) + metric_parser.add_argument('-k', '--ecc-blocks', action='store_true', required=False, help=ecc_blocks_help) metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help) metric_parser.add_argument('-C', '--voltage-curve', action='store_true', required=False, help=vc_help) metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help) From 8425ea9d50b7a4f176959d46361b7c447aedb88b Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 22 Feb 2024 03:18:10 -0600 Subject: [PATCH 10/15] JSON Alignment with Host for singular device output Signed-off-by: Maisam Arif Change-Id: I12acbae8b385dac75ccc37e04d40a29153ba1944 [ROCm/amdsmi commit: 9146e9c6eb21b16596faed0be285126be2c75256] --- projects/amdsmi/amdsmi_cli/amdsmi_logger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py index 4bbd71724f..240aba67d1 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py @@ -401,7 +401,7 @@ class AMDSMILogger(): if multiple_device_enabled: json_output = self.multiple_device_output else: - json_output = self.output + json_output = [self.output] if self.destination == 'stdout': if json_output: From 4cf9c0eb0381e5d816f0b5ad51b38f06997a0ab4 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 22 Feb 2024 03:27:53 -0600 Subject: [PATCH 11/15] SWDEV-436992 - Added Units of Measure to JSON Output Signed-off-by: Maisam Arif Change-Id: I0aba1533bc2919b7354ef6cad5ae4ae5d23e92a7 [ROCm/amdsmi commit: 794354dad9ed3ad8c9759ad907d08b093fe3c65f] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 310 +++++++++++++----- 1 file changed, 227 insertions(+), 83 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 6cc5fd8218..964fea4401 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -483,25 +483,52 @@ class AMDSMICommands(): shutdown_temp_vram_limit = "N/A" logging.debug("Failed to get vram temperature shutdown metrics for gpu %s | %s", gpu_id, e.get_error_info()) + # Assign units + power_unit = 'W' + temp_unit_human_readable = '\N{DEGREE SIGN}C' + temp_unit_json = 'C' if self.logger.is_human_readable_format(): - pcie_speed_unit = 'W' if not power_limit_error: - max_power_limit = f"{max_power_limit} {pcie_speed_unit}" - socket_power_limit = f"{socket_power_limit} {pcie_speed_unit}" + max_power_limit = f"{max_power_limit} {power_unit}" + socket_power_limit = f"{socket_power_limit} {power_unit}" - pcie_speed_unit = '\N{DEGREE SIGN}C' if not slowdown_temp_edge_limit_error: - slowdown_temp_edge_limit = f"{slowdown_temp_edge_limit} {pcie_speed_unit}" + slowdown_temp_edge_limit = f"{slowdown_temp_edge_limit} {temp_unit_human_readable}" if not slowdown_temp_hotspot_limit_error: - slowdown_temp_hotspot_limit = f"{slowdown_temp_hotspot_limit} {pcie_speed_unit}" + slowdown_temp_hotspot_limit = f"{slowdown_temp_hotspot_limit} {temp_unit_human_readable}" if not slowdown_temp_vram_limit_error: - slowdown_temp_vram_limit = f"{slowdown_temp_vram_limit} {pcie_speed_unit}" + slowdown_temp_vram_limit = f"{slowdown_temp_vram_limit} {temp_unit_human_readable}" if not shutdown_temp_edge_limit_error: - shutdown_temp_edge_limit = f"{shutdown_temp_edge_limit} {pcie_speed_unit}" + shutdown_temp_edge_limit = f"{shutdown_temp_edge_limit} {temp_unit_human_readable}" if not shutdown_temp_hotspot_limit_error: - shutdown_temp_hotspot_limit = f"{shutdown_temp_hotspot_limit} {pcie_speed_unit}" + shutdown_temp_hotspot_limit = f"{shutdown_temp_hotspot_limit} {temp_unit_human_readable}" if not shutdown_temp_vram_limit_error: - shutdown_temp_vram_limit = f"{shutdown_temp_vram_limit} {pcie_speed_unit}" + shutdown_temp_vram_limit = f"{shutdown_temp_vram_limit} {temp_unit_human_readable}" + if self.logger.is_json_format(): + if not power_limit_error: + max_power_limit = {"value" : max_power_limit, + "unit" : power_unit} + socket_power_limit = {"value" : socket_power_limit, + "unit" : power_unit} + + if not slowdown_temp_edge_limit_error: + slowdown_temp_edge_limit = {"value" : slowdown_temp_edge_limit, + "unit" : temp_unit_json} + if not slowdown_temp_hotspot_limit_error: + slowdown_temp_hotspot_limit = {"value" : slowdown_temp_hotspot_limit, + "unit" : temp_unit_json} + if not slowdown_temp_vram_limit_error: + slowdown_temp_vram_limit = {"value" : slowdown_temp_vram_limit, + "unit" : temp_unit_json} + if not shutdown_temp_edge_limit_error: + shutdown_temp_edge_limit = {"value" : shutdown_temp_edge_limit, + "unit" : temp_unit_json} + if not shutdown_temp_hotspot_limit_error: + shutdown_temp_hotspot_limit = {"value" : shutdown_temp_hotspot_limit, + "unit" : temp_unit_json} + if not shutdown_temp_vram_limit_error: + shutdown_temp_vram_limit = {"value" : shutdown_temp_vram_limit, + "unit" : temp_unit_json} limit_info = {} # Power limits @@ -668,6 +695,7 @@ class AMDSMICommands(): new_cache_info.update(cache_info) cache_info_list[index] = new_cache_info + cache_size_unit = "KB" if self.logger.is_human_readable_format(): cache_info_dict_format = {} for cache_dict in cache_info_list: @@ -678,15 +706,19 @@ class AMDSMICommands(): cache_info_dict_format[cache_index].pop("cache") # Add cache_size unit - cache_info_dict_format[cache_index]["cache_size"] = f"{cache_info_dict_format[cache_index]['cache_size']} KB" + cache_size = f"{cache_info_dict_format[cache_index]['cache_size']} {cache_size_unit}" + cache_info_dict_format[cache_index]["cache_size"] = cache_size # take cache_properties out of list -> display as string, removing brackets cache_info_dict_format[cache_index]["cache_properties"] = ", ".join(cache_info_dict_format[cache_index]["cache_properties"]) cache_info_list = cache_info_dict_format - logging.debug(f"After human_readable | cache_info = {cache_info_list}") - + # Add cache_size_unit to json output + if self.logger.is_json_format(): + for cache_dict in cache_info_list: + cache_dict["cache_size"] = {"value" : cache_dict["cache_size"], + "unit" : cache_size_unit} except amdsmi_exception.AmdSmiLibraryException as e: cache_info_list = "N/A" logging.debug("Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()) @@ -1198,18 +1230,25 @@ class AMDSMICommands(): engine_usage['jpeg_activity'] = gpu_metric_info.pop('jpeg_activity') for key, value in engine_usage.items(): + activity_unit = '%' if self.logger.is_human_readable_format(): - unit = '%' if isinstance(value, list): for index, activity in enumerate(value): if activity != "N/A": - engine_usage[key][index] = f"{activity} {unit}" - + engine_usage[key][index] = f"{activity} {activity_unit}" # Convert list to a string for human readable format engine_usage[key] = '[' + ", ".join(engine_usage[key]) + ']' - elif value != "N/A": - engine_usage[key] = f"{value} {unit}" + engine_usage[key] = f"{value} {activity_unit}" + if self.logger.is_json_format(): + if isinstance(value, list): + for index, activity in enumerate(value): + if activity != "N/A": + engine_usage[key][index] = {"value" : activity, + "unit" : activity_unit} + elif value != "N/A": + engine_usage[key] = {"value" : value, + "unit" : activity_unit} values_dict['usage'] = engine_usage except amdsmi_exception.AmdSmiLibraryException as e: @@ -1225,15 +1264,24 @@ class AMDSMICommands(): 'throttle_status': "N/A"} try: + voltage_unit = "mV" + power_unit = "W" power_info = amdsmi_interface.amdsmi_get_power_info(args.gpu) for key, value in power_info.items(): if value == 0xFFFF: power_info[key] = "N/A" elif self.logger.is_human_readable_format(): if "voltage" in key: - power_info[key] = f"{value} mV" + power_info[key] = f"{value} {voltage_unit}" elif "power" in key: - power_info[key] = f"{value} W" + power_info[key] = f"{value} {power_unit}" + elif self.logger.is_json_format(): + if "voltage" in key: + power_info[key] = {"value" : value, + "unit" : voltage_unit} + elif "power" in key: + power_info[key] = {"value" : value, + "unit" : power_unit} power_dict['socket_power'] = power_info['current_socket_power'] @@ -1296,11 +1344,14 @@ class AMDSMICommands(): if clock_info['sleep_clk'] == 0xFFFFFFFF: clock_info['sleep_clk'] = "N/A" - if self.logger.is_human_readable_format(): - unit = 'MHz' - for key, value in clock_info.items(): - if isinstance(value, int): - clock_info[key] = f"{value} {unit}" + clock_freq_unit = 'MHz' + for key, value in clock_info.items(): + if isinstance(value, int): + if self.logger.is_human_readable_format(): + clock_info[key] = f"{value} {clock_freq_unit}" + if self.logger.is_json_format(): + clock_info[key] = {"value" : value, + "unit" : clock_freq_unit} clocks[clock_name] = clock_info except amdsmi_exception.AmdSmiLibraryException as e: @@ -1375,11 +1426,15 @@ class AMDSMICommands(): 'hotspot': temperature_hotspot_current, 'mem': temperature_vram_current} - if self.logger.is_human_readable_format(): - unit = '\N{DEGREE SIGN}C' - for temperature_key, temperature_value in temperatures.items(): - if 'N/A' not in str(temperature_value): - temperatures[temperature_key] = f"{temperature_value} {unit}" + temp_unit_human_readable = '\N{DEGREE SIGN}C' + temp_unit_json = 'C' + for temperature_key, temperature_value in temperatures.items(): + if 'N/A' not in str(temperature_value): + if self.logger.is_human_readable_format(): + temperatures[temperature_key] = f"{temperature_value} {temp_unit_human_readable}" + if self.logger.is_json_format(): + temperatures[temperature_key] = {"value" : temperature_value, + "unit" : temp_unit_json} values_dict['temperature'] = temperatures if "pcie" in current_platform_args: @@ -1406,10 +1461,12 @@ class AMDSMICommands(): pcie_dict['width'] = pcie_link_status['pcie_metric']['pcie_width'] pcie_dict['speed'] = pcie_speed_GTs_value + pcie_speed_unit = 'GT/s' if self.logger.is_human_readable_format(): - unit = 'GT/s' - pcie_dict['width'] = f"{pcie_link_status['pcie_metric']['pcie_width']} lanes" - pcie_dict['speed'] = f"{pcie_dict['speed']} GT/s" + pcie_dict['speed'] = f"{pcie_dict['speed']} {pcie_speed_unit}" + if self.logger.is_json_format(): + pcie_dict['speed'] = {"value" : pcie_dict['speed'], + "unit" : pcie_speed_unit} except amdsmi_exception.AmdSmiLibraryException as e: logging.debug("Failed to get pcie link status for gpu %s | %s", gpu_id, e.get_error_info()) @@ -1458,15 +1515,24 @@ class AMDSMICommands(): sent = pcie_bw['sent'] * pcie_bw['max_pkt_sz'] received = pcie_bw['received'] * pcie_bw['max_pkt_sz'] - if self.logger.is_human_readable_format(): - if sent > 0: - sent = sent // 1024 // 1024 - sent = f"{sent} MB/s" + bw_unit = "MB/s" + packet_size_unit = "B" + if sent > 0: + sent = sent // 1024 // 1024 + if received > 0: + received = received // 1024 // 1024 - if received > 0: - received = received // 1024 // 1024 - received = f"{received} MB/s" - pcie_bw['max_pkt_sz'] = f"{pcie_bw['max_pkt_sz']} B" + if self.logger.is_human_readable_format(): + sent = f"{sent} {bw_unit}" + received = f"{received} {bw_unit}" + pcie_bw['max_pkt_sz'] = f"{pcie_bw['max_pkt_sz']} {packet_size_unit}" + if self.logger.is_json_format(): + sent = {"value" : sent, + "unit" : bw_unit} + received = {"value" : received, + "unit" : bw_unit} + pcie_bw['max_pkt_sz'] = {"value" : pcie_bw['max_pkt_sz'], + "unit" : packet_size_unit} pcie_dict['current_bandwidth_sent'] = sent pcie_dict['current_bandwidth_received'] = received @@ -1544,9 +1610,12 @@ class AMDSMICommands(): fan_usage = "N/A" if fan_max > 0 and fan_dict["speed"] != "N/A": fan_usage = round((float(fan_speed) / float(fan_max)) * 100, 2) + fan_usage_unit = '%' if self.logger.is_human_readable_format(): - unit = '%' - fan_usage = f"{fan_usage} {unit}" + fan_usage = f"{fan_usage} {fan_usage_unit}" + if self.logger.is_json_format(): + fan_usage = {"value" : fan_usage, + "unit" : fan_usage_unit} fan_dict["max"] = fan_max fan_dict["usage"] = fan_usage except amdsmi_exception.AmdSmiLibraryException as e: @@ -1584,9 +1653,12 @@ class AMDSMICommands(): try: overdrive_level = amdsmi_interface.amdsmi_get_gpu_overdrive_level(args.gpu) + od_unit = '%' if self.logger.is_human_readable_format(): - unit = '%' - overdrive_level = f"{overdrive_level} {unit}" + overdrive_level = f"{overdrive_level} {od_unit}" + if self.logger.is_json_format(): + overdrive_level = {"value" : overdrive_level, + "unit" : od_unit} values_dict['overdrive'] = overdrive_level except amdsmi_exception.AmdSmiLibraryException as e: @@ -1617,9 +1689,12 @@ class AMDSMICommands(): energy /= 1000000 energy = round(energy, 3) + energy_unit = 'J' if self.logger.is_human_readable_format(): - unit = 'J' - energy = f"{energy} {unit}" + energy = f"{energy} {energy_unit}" + if self.logger.is_json_format(): + energy = {"value" : energy, + "unit" : energy_unit} values_dict['energy'] = {"total_energy_consumption" : energy} except amdsmi_interface.AmdSmiLibraryException as e: @@ -1627,7 +1702,6 @@ class AMDSMICommands(): logging.debug("Failed to get energy usage for gpu %s | %s", args.gpu, e.get_error_info()) if "mem_usage" in current_platform_args: if args.mem_usage: - unit = 'MB' memory_usage = {'total_vram': "N/A", 'used_vram': "N/A", 'free_vram': "N/A", @@ -1687,10 +1761,14 @@ class AMDSMICommands(): if memory_usage['total_gtt'] != "N/A" and memory_usage['used_gtt'] != "N/A": memory_usage['free_gtt'] = memory_usage['total_gtt'] - memory_usage['used_gtt'] - if self.logger.is_human_readable_format(): - for key, value in memory_usage.items(): - if value != "N/A": - memory_usage[key] = f"{value} {unit}" + memory_unit = 'MB' + for key, value in memory_usage.items(): + if value != "N/A": + if self.logger.is_human_readable_format(): + memory_usage[key] = f"{value} {memory_unit}" + if self.logger.is_json_format(): + memory_usage[key] = {"value" : value, + "unit" : memory_unit} values_dict['mem_usage'] = memory_usage @@ -3619,9 +3697,13 @@ class AMDSMICommands(): else: # Fallback to average_socket_power for older gpu_metrics versions monitor_values['power_usage'] = gpu_metrics_info['average_socket_power'] + power_unit = 'W' if self.logger.is_human_readable_format() and monitor_values['power_usage'] != "N/A": - unit = 'W' - monitor_values['power_usage'] = f"{monitor_values['power_usage']} {unit}" + monitor_values['power_usage'] = f"{monitor_values['power_usage']} {power_unit}" + if self.logger.is_json_format() and monitor_values['power_usage'] != "N/A": + monitor_values['power_usage'] = {"value" : monitor_values['power_usage'], + "unit" : power_unit} + except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['power_usage'] = "N/A" logging.debug("Failed to get power usage on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3642,11 +3724,20 @@ class AMDSMICommands(): monitor_values['memory_temperature'] = "N/A" logging.debug("Failed to get memory temperature on gpu %s | %s", gpu_id, e.get_error_info()) - if self.logger.is_human_readable_format() and monitor_values['hotspot_temperature'] != "N/A": - monitor_values['hotspot_temperature'] = f"{monitor_values['hotspot_temperature']} \N{DEGREE SIGN}C" - - if self.logger.is_human_readable_format() and monitor_values['memory_temperature'] != "N/A": - monitor_values['memory_temperature'] = f"{monitor_values['memory_temperature']} \N{DEGREE SIGN}C" + temp_unit_human_readable = '\N{DEGREE SIGN}C' + temp_unit_json = 'C' + if monitor_values['hotspot_temperature'] != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['hotspot_temperature'] = f"{monitor_values['hotspot_temperature']} {temp_unit_human_readable}" + if self.logger.is_json_format(): + monitor_values['hotspot_temperature'] = {"value" : monitor_values['hotspot_temperature'], + "unit" : temp_unit_json} + if monitor_values['memory_temperature'] != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['memory_temperature'] = f"{monitor_values['memory_temperature']} {temp_unit_human_readable}" + if self.logger.is_json_format(): + monitor_values['memory_temperature'] = {"value" : monitor_values['memory_temperature'], + "unit" : temp_unit_json} self.logger.table_header += 'GPU_TEMP'.rjust(10) self.logger.table_header += 'MEM_TEMP'.rjust(10) @@ -3654,8 +3745,13 @@ class AMDSMICommands(): try: gfx_util = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['average_gfx_activity'] monitor_values['gfx'] = gfx_util - if self.logger.is_human_readable_format() and gfx_util != "N/A": - monitor_values['gfx'] = f"{monitor_values['gfx']} %" + activity_unit = '%' + if gfx_util != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['gfx'] = f"{monitor_values['gfx']} {activity_unit}" + if self.logger.is_json_format(): + monitor_values['gfx'] = {"value" : monitor_values['gfx'], + "unit" : activity_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['gfx'] = "N/A" logging.debug("Failed to get gfx utilization on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3665,8 +3761,14 @@ class AMDSMICommands(): try: gfx_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_gfxclk'] monitor_values['gfx_clock'] = gfx_clock - if self.logger.is_human_readable_format() and gfx_clock != "N/A": - monitor_values['gfx_clock'] = f"{monitor_values['gfx_clock']} MHz" + freq_unit = 'MHz' + if gfx_clock != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['gfx_clock'] = f"{monitor_values['gfx_clock']} {freq_unit}" + if self.logger.is_json_format(): + monitor_values['gfx_clock'] = {"value" : monitor_values['gfx_clock'], + "unit" : freq_unit} + except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['gfx_clock'] = "N/A" logging.debug("Failed to get gfx clock on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3676,8 +3778,13 @@ class AMDSMICommands(): try: mem_util = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['average_umc_activity'] monitor_values['mem'] = mem_util - if self.logger.is_human_readable_format() and mem_util != "N/A": - monitor_values['mem'] = f"{monitor_values['mem']} %" + activity_unit = '%' + if mem_util != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['mem'] = f"{monitor_values['mem']} {activity_unit}" + if self.logger.is_json_format(): + monitor_values['mem'] = {"value" : monitor_values['mem'], + "unit" : activity_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['mem'] = "N/A" logging.debug("Failed to get mem utilization on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3687,8 +3794,13 @@ class AMDSMICommands(): try: mem_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_uclk'] monitor_values['mem_clock'] = mem_clock - if self.logger.is_human_readable_format() and mem_clock != "N/A": - monitor_values['mem_clock'] = f"{monitor_values['mem_clock']} MHz" + freq_unit = 'MHz' + if mem_clock != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['mem_clock'] = f"{monitor_values['mem_clock']} {freq_unit}" + if self.logger.is_json_format(): + monitor_values['mem_clock'] = {"value" : monitor_values['mem_clock'], + "unit" : freq_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['mem_clock'] = "N/A" logging.debug("Failed to get mem clock on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3710,8 +3822,14 @@ class AMDSMICommands(): encoding_activity_avg = "N/A" monitor_values['encoder'] = encoding_activity_avg - if self.logger.is_human_readable_format() and monitor_values['encoder'] != "N/A": - monitor_values['encoder'] = f"{monitor_values['encoder']} %" + + activity_unit = '%' + if monitor_values['encoder'] != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['encoder'] = f"{monitor_values['encoder']} {activity_unit}" + if self.logger.is_json_format(): + monitor_values['encoder'] = {"value" : monitor_values['encoder'], + "unit" : activity_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['encoder'] = "N/A" logging.debug("Failed to get encoder utilization on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3721,8 +3839,13 @@ class AMDSMICommands(): try: encoder_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_vclk0'] monitor_values['encoder_clock'] = encoder_clock - if self.logger.is_human_readable_format() and encoder_clock != "N/A": - monitor_values['encoder_clock'] = f"{monitor_values['encoder_clock']} MHz" + freq_unit = 'MHz' + if encoder_clock != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['encoder_clock'] = f"{monitor_values['encoder_clock']} {freq_unit}" + if self.logger.is_json_format(): + monitor_values['encoder_clock'] = {"value" : monitor_values['encoder_clock'], + "unit" : freq_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['encoder_clock'] = "N/A" logging.debug("Failed to get encoder clock on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3743,8 +3866,14 @@ class AMDSMICommands(): try: decoder_clock = amdsmi_interface.amdsmi_get_gpu_metrics_info(args.gpu)['current_dclk0'] monitor_values['decoder_clock'] = decoder_clock - if self.logger.is_human_readable_format(): - monitor_values['decoder_clock'] = f"{monitor_values['decoder_clock']} MHz" + + freq_unit = 'MHz' + if decoder_clock != "N/A": + if self.logger.is_human_readable_format(): + monitor_values['decoder_clock'] = f"{monitor_values['decoder_clock']} {freq_unit}" + if self.logger.is_json_format(): + monitor_values['decoder_clock'] = {"value" : monitor_values['decoder_clock'], + "unit" : freq_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['decoder_clock'] = "N/A" logging.debug("Failed to get decoder clock on gpu %s | %s", gpu_id, e.get_error_info()) @@ -3789,9 +3918,15 @@ class AMDSMICommands(): vram_usage = amdsmi_interface.amdsmi_get_gpu_vram_usage(args.gpu) monitor_values['vram_used'] = vram_usage['vram_used'] monitor_values['vram_total'] = vram_usage['vram_total'] + vram_usage_unit = "MB" if self.logger.is_human_readable_format(): - monitor_values['vram_used'] = f"{monitor_values['vram_used']} MB" - monitor_values['vram_total'] = f"{monitor_values['vram_total']} MB" + monitor_values['vram_used'] = f"{monitor_values['vram_used']} {vram_usage_unit}" + monitor_values['vram_total'] = f"{monitor_values['vram_total']} {vram_usage_unit}" + if self.logger.is_json_format(): + monitor_values['vram_used'] = {"value" : monitor_values['vram_used'], + "unit" : vram_usage_unit} + monitor_values['vram_total'] = {"value" : monitor_values['vram_total'], + "unit" : vram_usage_unit} except amdsmi_exception.AmdSmiLibraryException as e: monitor_values['vram_used'] = "N/A" monitor_values['vram_total'] = "N/A" @@ -3805,15 +3940,24 @@ class AMDSMICommands(): sent = pcie_bw['sent'] * pcie_bw['max_pkt_sz'] received = pcie_bw['received'] * pcie_bw['max_pkt_sz'] - if self.logger.is_human_readable_format(): - if sent > 0: - sent = sent // 1024 // 1024 - sent = f"{sent} MB/s" + bw_unit = "MB/s" + packet_size_unit = "B" + if sent > 0: + sent = sent // 1024 // 1024 + if received > 0: + received = received // 1024 // 1024 - if received > 0: - received = received // 1024 // 1024 - received = f"{received} MB/s" - pcie_bw['max_pkt_sz'] = f"{pcie_bw['max_pkt_sz']} B" + if self.logger.is_human_readable_format(): + sent = f"{sent} {bw_unit}" + received = f"{received} {bw_unit}" + pcie_bw['max_pkt_sz'] = f"{pcie_bw['max_pkt_sz']} {packet_size_unit}" + if self.logger.is_json_format(): + sent = {"value" : sent, + "unit" : bw_unit} + received = {"value" : received, + "unit" : bw_unit} + pcie_bw['max_pkt_sz'] = {"value" : pcie_bw['max_pkt_sz'], + "unit" : packet_size_unit} monitor_values['pcie_tx'] = sent monitor_values['pcie_rx'] = received From d41232363c637f0367d991f2e4dd52a4aba77ad4 Mon Sep 17 00:00:00 2001 From: Deepak Mewar Date: Thu, 22 Feb 2024 10:17:03 +0000 Subject: [PATCH 12/15] DCSM-371 - Observing previous mode details as null for amdsmi_set_cpu_pcie_link_rate Signed-off-by: Deepak Mewar Change-Id: I79a61d7b10aaff27b07e3d108a9b817c5ead6cf3 [ROCm/amdsmi commit: f48e3f48a3358a5303e129e445b8bf4175309240] --- projects/amdsmi/py-interface/amdsmi_interface.py | 2 ++ projects/amdsmi/src/amd_smi/amd_smi.cc | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 98844c700f..74a190da06 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -1291,6 +1291,8 @@ def amdsmi_set_cpu_pcie_link_rate( processor_handle, rate_ctrl, ctypes.byref(prev_mode)) ) + return f"{prev_mode.value}" + def amdsmi_set_cpu_df_pstate_range( processor_handle: amdsmi_wrapper.amdsmi_processor_handle, max_pstate: int, min_pstate: int diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index e576f67226..7032b1a59a 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -2915,6 +2915,7 @@ amdsmi_status_t amdsmi_set_cpu_pcie_link_rate(amdsmi_processor_handle processor_ { amdsmi_status_t status; uint8_t sock_ind; + uint8_t p_mode; AMDSMI_CHECK_INIT(); @@ -2928,10 +2929,12 @@ amdsmi_status_t amdsmi_set_cpu_pcie_link_rate(amdsmi_processor_handle processor_ sock_ind = (uint8_t)std::stoi(proc_id, NULL, 0); status = static_cast(esmi_pcie_link_rate_set(sock_ind, - rate_ctrl, prev_mode)); + rate_ctrl, &p_mode)); if (status != AMDSMI_STATUS_SUCCESS) return amdsmi_errno_to_esmi_status(status); + *prev_mode = p_mode; + return AMDSMI_STATUS_SUCCESS; } From 06d32ac405d2559860ade76b87a66d2d3ffc945d Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 22 Feb 2024 13:45:02 -0600 Subject: [PATCH 13/15] Align to Host left adjusted topology output Signed-off-by: Maisam Arif Change-Id: I8e56156200d5eface7f069ccf82a6b7503e1a48c [ROCm/amdsmi commit: 16c34e91ac14bc3bbe89c81e0a75c494b8b0ef49] --- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 30 +++++++++++++++---- projects/amdsmi/amdsmi_cli/amdsmi_logger.py | 4 +-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 964fea4401..102bab41b6 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -2630,7 +2630,11 @@ class AMDSMICommands(): if args.access: tabular_output = [] for src_gpu_index, src_gpu in enumerate(args.gpu): - tabular_output_dict = {'gpu': amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu)} + gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu) + if self.logger.is_human_readable_format(): + tabular_output_dict = {'gpu' : f"{gpu_bdf} "} + else: + tabular_output_dict = {'gpu' : gpu_bdf} src_gpu_links = {} for dest_gpu in args.gpu: dest_gpu_id = self.helpers.get_gpu_id_from_device_handle(dest_gpu) @@ -2662,7 +2666,11 @@ class AMDSMICommands(): if args.weight: tabular_output = [] for src_gpu_index, src_gpu in enumerate(args.gpu): - tabular_output_dict = {'gpu': amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu)} + gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu) + if self.logger.is_human_readable_format(): + tabular_output_dict = {'gpu' : f"{gpu_bdf} "} + else: + tabular_output_dict = {'gpu' : gpu_bdf} src_gpu_weight = {} for dest_gpu in args.gpu: dest_gpu_id = self.helpers.get_gpu_id_from_device_handle(dest_gpu) @@ -2695,7 +2703,11 @@ class AMDSMICommands(): if args.hops: tabular_output = [] for src_gpu_index, src_gpu in enumerate(args.gpu): - tabular_output_dict = {'gpu': amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu)} + gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu) + if self.logger.is_human_readable_format(): + tabular_output_dict = {'gpu' : f"{gpu_bdf} "} + else: + tabular_output_dict = {'gpu' : gpu_bdf} src_gpu_hops = {} for dest_gpu in args.gpu: dest_gpu_id = self.helpers.get_gpu_id_from_device_handle(dest_gpu) @@ -2728,7 +2740,11 @@ class AMDSMICommands(): if args.link_type: tabular_output = [] for src_gpu_index, src_gpu in enumerate(args.gpu): - tabular_output_dict = {'gpu': amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu)} + gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu) + if self.logger.is_human_readable_format(): + tabular_output_dict = {'gpu' : f"{gpu_bdf} "} + else: + tabular_output_dict = {'gpu' : gpu_bdf} src_gpu_link_type = {} for dest_gpu in args.gpu: dest_gpu_id = self.helpers.get_gpu_id_from_device_handle(dest_gpu) @@ -2766,7 +2782,11 @@ class AMDSMICommands(): if args.numa_bw: tabular_output = [] for src_gpu_index, src_gpu in enumerate(args.gpu): - tabular_output_dict = {'gpu': amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu)} + gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(src_gpu) + if self.logger.is_human_readable_format(): + tabular_output_dict = {'gpu' : f"{gpu_bdf} "} + else: + tabular_output_dict = {'gpu' : gpu_bdf} src_gpu_link_type = {} for dest_gpu in args.gpu: dest_gpu_id = self.helpers.get_gpu_id_from_device_handle(dest_gpu) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py index 240aba67d1..b77ffe6187 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py @@ -118,8 +118,8 @@ class AMDSMILogger(): table_values += value.rjust(12) elif key in ('throttle_status', 'pcie_replay'): table_values += value.rjust(13) - elif 'gpu_' in key: # handle topology tables - table_values += value.rjust(13) + elif 'gpu_' in key: # This is just for handling topology tables + table_values += value.ljust(13) else: table_values += value.rjust(10) return table_values.rstrip() From 60a86065c01806ca13110425d9e769225f2c619b Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 22 Feb 2024 23:08:37 -0600 Subject: [PATCH 14/15] SWDEV-436792 - Add XGMI Table Signed-off-by: Maisam Arif Change-Id: Ia7a43b2b6d01fd32ece00cc26c28ba3088f3aa9e [ROCm/amdsmi commit: 4ca326d8244a351725f53c2f2929fdefcf42d881] --- projects/amdsmi/amdsmi_cli/amdsmi_cli.py | 3 +- projects/amdsmi/amdsmi_cli/amdsmi_commands.py | 209 +++++++++++++++++- projects/amdsmi/amdsmi_cli/amdsmi_logger.py | 19 +- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 31 ++- 4 files changed, 257 insertions(+), 5 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_cli.py b/projects/amdsmi/amdsmi_cli/amdsmi_cli.py index 263bd0c794..8311b86cb5 100755 --- a/projects/amdsmi/amdsmi_cli/amdsmi_cli.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_cli.py @@ -69,7 +69,8 @@ if __name__ == "__main__": amd_smi_commands.set_value, amd_smi_commands.reset, amd_smi_commands.monitor, - amd_smi_commands.rocm_smi) + amd_smi_commands.rocm_smi, + amd_smi_commands.xgmi) try: try: argcomplete.autocomplete(amd_smi_parser) diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 102bab41b6..2d6464813b 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -1515,7 +1515,7 @@ class AMDSMICommands(): sent = pcie_bw['sent'] * pcie_bw['max_pkt_sz'] received = pcie_bw['received'] * pcie_bw['max_pkt_sz'] - bw_unit = "MB/s" + bw_unit = "Mb/s" packet_size_unit = "B" if sent > 0: sent = sent // 1024 // 1024 @@ -3960,7 +3960,7 @@ class AMDSMICommands(): sent = pcie_bw['sent'] * pcie_bw['max_pkt_sz'] received = pcie_bw['received'] * pcie_bw['max_pkt_sz'] - bw_unit = "MB/s" + bw_unit = "Mb/s" packet_size_unit = "B" if sent > 0: sent = sent // 1024 // 1024 @@ -4005,6 +4005,211 @@ class AMDSMICommands(): print("Placeholder for rocm-smi legacy commands") + def xgmi(self, args, multiple_devices=False, gpu=None, metric=None): + """ Get topology information for target gpus + params: + args - argparser args to pass to subcommand + multiple_devices (bool) - True if checking for multiple devices + gpu (device_handle) - device_handle for target device + metric (bool) - Value override for args.metric + + return: + Nothing + """ + # Not supported with partitions + + # Set args.* to passed in arguments + if gpu: + args.gpu = gpu + if metric: + args.metric = metric + + # Handle No GPU passed + if args.gpu == None: + args.gpu = self.device_handles + + if not isinstance(args.gpu, list): + args.gpu = [args.gpu] + + # Handle all args being false + if not any([args.metric]): + args.metric = True + + # Clear the table header + self.logger.table_header = ''.rjust(7) + + # Populate the possible gpus and their bdfs + xgmi_values = [] + for gpu in args.gpu: + logging.debug("check1 device_handle: %s", gpu) + gpu_id = self.helpers.get_gpu_id_from_device_handle(gpu) + gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(gpu) + xgmi_values.append({"gpu" : gpu_id, + "bdf" : gpu_bdf}) + # Populate header with just bdfs + self.logger.table_header += gpu_bdf.rjust(13) + + if args.metric: + # prepend link metrics header to the table header + link_metrics_header = " " + "bdf".ljust(13) + \ + "bit_rate".ljust(9) + "max_bandwidth".ljust(14) + \ + "link_type".ljust(10) + self.logger.table_header = link_metrics_header + self.logger.table_header.strip() + + # Populate dictionary according to format + for xgmi_dict in xgmi_values: + src_gpu_id = xgmi_dict['gpu'] + src_gpu_bdf = xgmi_dict['bdf'] + src_gpu = amdsmi_interface.amdsmi_get_processor_handle_from_bdf(src_gpu_bdf) #TODO VERIFY this is correct + logging.debug("check2 device_handle: %s", src_gpu) + # This should be the same order as the check1 + + xgmi_dict['link_metrics'] = { + "bit_rate" : "N/A", + "max_bandwidth" : "N/A", + "link_type" : "N/A", + "links" : [] + } + + try: + pcie_info = amdsmi_interface.amdsmi_get_pcie_info(src_gpu)['pcie_static'] + if pcie_info['max_pcie_speed'] % 1000 != 0: + pcie_speed_GTs_value = round(pcie_info['max_pcie_speed'] / 1000, 1) + else: + pcie_speed_GTs_value = round(pcie_info['max_pcie_speed'] / 1000) + + bitrate = pcie_speed_GTs_value + max_bandwidth = bitrate * pcie_info['max_pcie_width'] + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get bitrate and bandwidth for GPU %s | %s", src_gpu_id, + e.get_error_info()) + + # Populate bitrate and max_bandwidth with units logic + bw_unit = 'Gb/s' + if self.logger.is_human_readable_format(): + xgmi_dict['link_metrics']['bit_rate'] = f"{bitrate} {bw_unit}" + xgmi_dict['link_metrics']['max_bandwidth'] = f"{max_bandwidth} {bw_unit}" + elif self.logger.is_json_format(): + xgmi_dict['link_metrics']['bit_rate'] = {"value" : bitrate, + "unit" : bw_unit} + xgmi_dict['link_metrics']['max_bandwidth'] = {"value" : max_bandwidth, + "unit" : bw_unit} + elif self.logger.is_csv_format(): + xgmi_dict['link_metrics']['bit_rate'] = bitrate + xgmi_dict['link_metrics']['max_bandwidth'] = max_bandwidth + + # Populate link metrics + for dest_gpu in args.gpu: + dest_gpu_id = self.helpers.get_gpu_id_from_device_handle(dest_gpu) + dest_gpu_bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(dest_gpu) + dest_link_dict = { + "gpu" : dest_gpu_id, + "bdf" : dest_gpu_bdf, + "read" : "N/A", + "write" : "N/A" + } + + # Don't make a call to check link status for the same gpu + if dest_gpu_bdf == src_gpu_bdf: + dest_link_dict['read'] = "N/A" + dest_link_dict['write'] = "N/A" + xgmi_dict['link_metrics']['links'].append(dest_link_dict) + continue + + try: + # Get the read write relative to the source gpu + metrics_info = amdsmi_interface.amdsmi_get_gpu_metrics_info(src_gpu) + read = metrics_info['xgmi_read_data_acc'][dest_gpu_id] + write = metrics_info['xgmi_write_data_acc'][dest_gpu_id] + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get read data for %s to %s | %s", + self.helpers.get_gpu_id_from_device_handle(src_gpu), + self.helpers.get_gpu_id_from_device_handle(dest_gpu), + e.get_error_info()) + + data_unit = 'KB' + if self.logger.is_human_readable_format(): + dest_link_dict['read'] = f"{read} {data_unit}" + dest_link_dict['write'] = f"{write} {data_unit}" + elif self.logger.is_json_format(): + dest_link_dict['read'] = {"value" : read, + "unit" : data_unit} + dest_link_dict['write'] = {"value" : write, + "unit" : data_unit} + elif self.logger.is_csv_format(): + dest_link_dict['read'] = read + dest_link_dict['write'] = write + + try: + link_type = amdsmi_interface.amdsmi_topo_get_link_type(src_gpu, dest_gpu)['type'] + if xgmi_dict['link_metrics']['link_type'] != "XGMI" and isinstance(link_type, int): + if link_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_UNDEFINED: + xgmi_dict['link_metrics']['link_type'] = "UNKNOWN" + elif link_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_PCIEXPRESS: + xgmi_dict['link_metrics']['link_type'] = "PCIE" + elif link_type == amdsmi_interface.amdsmi_wrapper.AMDSMI_IOLINK_TYPE_XGMI: + xgmi_dict['link_metrics']['link_type'] = "XGMI" + except amdsmi_exception.AmdSmiLibraryException as e: + logging.debug("Failed to get link type for %s to %s | %s", + self.helpers.get_gpu_id_from_device_handle(src_gpu), + self.helpers.get_gpu_id_from_device_handle(dest_gpu), + e.get_error_info()) + + xgmi_dict['link_metrics']['links'].append(dest_link_dict) + + # Handle printing for tabular format + if self.logger.is_human_readable_format(): + # Populate tabular output + tabular_output = [] + for xgmi_dict in xgmi_values: + tabular_output_dict = {} + + # Create GPU row and add to tabular_output + for key, value in xgmi_dict.items(): + if key == "gpu": + tabular_output_dict["gpu#"] = f"GPU{value}" + if key == "bdf": + tabular_output_dict["bdf"] = value + if key == "link_metrics": + for link_key, link_value in value.items(): + if link_key == "bit_rate": + tabular_output_dict["bit_rate"] = link_value + if link_key == "max_bandwidth": + tabular_output_dict["max_bandwidth"] = link_value + if link_key == "link_type": + tabular_output_dict["link_type"] = link_value + tabular_output.append(tabular_output_dict) + + # Create Read and Write rows and add to tabular_output + read_output_dict = {"RW" : "Read"} + write_output_dict = {"RW" : "Write"} + for key, value in xgmi_dict.items(): + if key == "link_metrics": + for link_key, link_value in value.items(): + if link_key == "links": + for link in link_value: + read_output_dict[f"bdf_{link['gpu']}"] = link["read"] + write_output_dict[f"bdf_{link['gpu']}"] = link["write"] + tabular_output.append(read_output_dict) + tabular_output.append(write_output_dict) + + # Print out the tabular output + self.logger.multiple_device_output = tabular_output + self.logger.table_title = "LINK METRIC TABLE" + self.logger.print_output(multiple_device_enabled=True, tabular=True) + + self.logger.multiple_device_output = xgmi_values + + if self.logger.is_csv_format(): # @TODO Test topology override needed + new_output = [] + for elem in self.logger.multiple_device_output: + new_output.append(self.logger.flatten_dict(elem, topology_override=True)) + self.logger.multiple_device_output = new_output + + if not self.logger.is_human_readable_format(): + self.logger.print_output(multiple_device_enabled=True) + + def _event_thread(self, commands, i): devices = commands.device_handles if len(devices) == 0: diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py index b77ffe6187..473235b44c 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_logger.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_logger.py @@ -118,8 +118,25 @@ class AMDSMILogger(): table_values += value.rjust(12) elif key in ('throttle_status', 'pcie_replay'): table_values += value.rjust(13) - elif 'gpu_' in key: # This is just for handling topology tables + # Only for handling topology tables + elif 'gpu_' in key: table_values += value.ljust(13) + # Only for handling xgmi tables + elif key == "gpu#": + table_values += value.ljust(7) + elif key == "bdf": + table_values += value.ljust(13) + elif "bdf_" in key: + table_values += value.ljust(13) + elif key == "bit_rate": + table_values += value.ljust(9) + elif key == "max_bandwidth": + table_values += value.ljust(14) + elif key == "link_type": + table_values += value.ljust(10) + elif key == "RW": + table_values += " " + value.ljust(52) + # Default spacing else: table_values += value.rjust(10) return table_values.rstrip() diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index 6d068db647..d7787eafea 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -68,7 +68,7 @@ class AMDSMIParser(argparse.ArgumentParser): """ def __init__(self, version, list, static, firmware, bad_pages, metric, process, profile, event, topology, set_value, reset, monitor, - rocmsmi): + rocmsmi, xgmi): # Helper variables self.helpers = AMDSMIHelpers() @@ -126,6 +126,7 @@ class AMDSMIParser(argparse.ArgumentParser): self._add_reset_parser(self.subparsers, reset) self._add_monitor_parser(self.subparsers, monitor) self._add_rocm_smi_parser(self.subparsers, rocmsmi) + self._add_xgmi_parser(self.subparsers, xgmi) def _not_negative_int(self, int_value): @@ -1165,6 +1166,34 @@ class AMDSMIParser(argparse.ArgumentParser): rocm_smi_parser.add_argument('-f', '--showclkfrq', action='store_true', required=False, help=showclkfrq_help) + def _add_xgmi_parser(self, subparsers, func): + if not self.helpers.is_amdgpu_initialized(): + # The xgmi subcommand is only applicable to systems with amdgpu initialized + return + + # Subparser help text + xgmi_help = "Displays xgmi information of the devices" + xgmi_subcommand_help = "If no GPU is specified, returns information for all GPUs on the system.\ + \nIf no xgmi argument is provided all xgmi information will be displayed." + xgmi_optionals_title = "XGMI arguments" + + # Help text for Arguments only on Guest and BM platforms + metrics_help = "Metric XGMI information" + + # Create xgmi subparser + xgmi_parser = subparsers.add_parser('xgmi', help=xgmi_help, description=xgmi_subcommand_help) + xgmi_parser._optionals.title = xgmi_optionals_title + xgmi_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog) + xgmi_parser.set_defaults(func=func) + + # Add Universal Arguments + self._add_command_modifiers(xgmi_parser) + self._add_device_arguments(xgmi_parser, required=False) + + # Optional Args + xgmi_parser.add_argument('-m', '--metric', action='store_true', required=False, help=metrics_help) + + def error(self, message): outputformat = self.helpers.get_output_format() From 45c9118db0576ea8a4cbc9a2187eba130468fa0f Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 22 Feb 2024 23:40:00 -0600 Subject: [PATCH 15/15] Updated README and removed cpu core option from Static subparser Signed-off-by: Maisam Arif Change-Id: I039c0f0ed2f7094aafe8849baea3cec887b7e8ff [ROCm/amdsmi commit: fa7a2838d8362d575e0ac74720a0cc6b31bbcfc1] --- projects/amdsmi/amdsmi_cli/README.md | 1125 +++++++++---------- projects/amdsmi/amdsmi_cli/amdsmi_parser.py | 7 +- 2 files changed, 566 insertions(+), 566 deletions(-) diff --git a/projects/amdsmi/amdsmi_cli/README.md b/projects/amdsmi/amdsmi_cli/README.md index cfa66890ee..24d2a6a1de 100644 --- a/projects/amdsmi/amdsmi_cli/README.md +++ b/projects/amdsmi/amdsmi_cli/README.md @@ -11,11 +11,12 @@ Recommended: At least one AMD GPU with AMD driver installed ### Requirements * python 3.6.8+ 64-bit -* amdgpu driver must be loaded for amdsmi_init() to pass +* amdgpu or amd_hsmp driver must be loaded for amdsmi_init() to pass ### Installation * Install amdgpu driver +* Optionally install amd_hsmp driver for ESMI CPU functions * Install amd-smi-lib package through package manager * amd-smi --help @@ -78,8 +79,7 @@ amd-smi will report the version and current platform detected when running the c ~$ amd-smi usage: amd-smi [-h] ... -AMD System Management Interface | Version: 24.3.0.0 | ROCm version: 6.1.0 | Platform: Linux -Baremetal +AMD System Management Interface | Version: 23.4.2.0 | ROCm version: 6.1.0 | Platform: Linux Baremetal options: -h, --help show this help message and exit @@ -98,6 +98,7 @@ AMD-SMI Commands: set Set options for devices reset Reset options for devices monitor Monitor metrics for target devices + xgmi Displays xgmi information of the devices ``` More detailed verison information is available from `amd-smi version` @@ -147,51 +148,48 @@ Command Modifiers: ```bash ~$ amd-smi static --help -usage: amd-smi static [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] - [-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ...]] [-a] [-b] - [-V] [-d] [-v] [-c] [-B] [-s] [-i] [-r] [-p] [-l] [-u] +usage: amd-smi static [-h] [-g GPU [GPU ...] | -U CPU [CPU ...]] [-a] [-b] [-V] [-d] [-v] + [-c] [-B] [-r] [-p] [-l] [-u] [-s] [-i] [--json | --csv] + [--file FILE] [--loglevel LEVEL] If no GPU is specified, returns static information for all GPUs on the system. If no static argument is provided, all static information will be displayed. Static Arguments: - -h, --help show this help message and exit - -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID: 0 | BDF: 0000:01:00.0 | UUID: 71ff74a0-0000-1000-8066-0a3c71d5f817 - ID: 1 | BDF: 0001:01:00.0 | UUID: b4ff74a0-0000-1000-80b2-fa0be8628b1a - ID: 2 | BDF: 0002:01:00.0 | UUID: a9ff74a0-0000-1000-8007-3066a98ba4a6 - ID: 3 | BDF: 0003:01:00.0 | UUID: 53ff74a0-0000-1000-80a0-a1ff3830f499 - all | Selects all devices - -U, --cpu CPU [CPU ...] Select a CPU ID from the possible choices: - ID: 0 - ID: 1 - ID: 2 - ID: 3 - all | Selects all devices - -O, --core CORE [CORE ...] Select a Core ID from the possible choices: - ID: 0 - 95 - all | Selects all devices - -a, --asic All asic information - -b, --bus All bus information - -V, --vbios All video bios information (if available) - -d, --driver Displays driver version - -v, --vram All vram information - -c, --cache All cache information - -B, --board All board information - -r, --ras Displays RAS features information - -p, --partition Partition information - -l, --limit All limit metric values (i.e. power and thermal limits) - -u, --numa All numa node information + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID: 0 | BDF: 0000:01:00.0 | UUID: 71ff74a0-0000-1000-8066-0a3c71d5f817 + ID: 1 | BDF: 0001:01:00.0 | UUID: b4ff74a0-0000-1000-80b2-fa0be8628b1a + ID: 2 | BDF: 0002:01:00.0 | UUID: a9ff74a0-0000-1000-8007-3066a98ba4a6 + ID: 3 | BDF: 0003:01:00.0 | UUID: 53ff74a0-0000-1000-80a0-a1ff3830f499 + all | Selects all devices + -U, --cpu CPU [CPU ...] Select a CPU ID from the possible choices: + ID: 0 + ID: 1 + ID: 2 + ID: 3 + all | Selects all devices + -a, --asic All asic information + -b, --bus All bus information + -V, --vbios All video bios information (if available) + -d, --driver Displays driver version + -v, --vram All vram information + -c, --cache All cache information + -B, --board All board information + -r, --ras Displays RAS features information + -p, --partition Partition information + -l, --limit All limit metric values (i.e. power and thermal limits) + -u, --numa All numa node information CPU Arguments: - -s, --smu All SMU FW information - -i, --interface_ver Displays hsmp interface version + -s, --smu All SMU FW information + -i, --interface-ver Displays hsmp interface version Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel LEVEL Set the logging level from the possible choices: + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: DEBUG, INFO, WARNING, ERROR, CRITICAL ``` @@ -268,111 +266,92 @@ Command Modifiers: ```bash ~$ amd-smi metric --help -usage: amd-smi metric [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] - [-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ...]] +usage: amd-smi metric [-h] [-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ...]] [-w INTERVAL] [-W TIME] [-i ITERATIONS] [-m] [-u] [-p] [-c] [-t] - [-e] [-P] [-k] [-f] [-C] [-o] [-l] [-x] [-E] [--cpu_power_metrics] - [--cpu_prochot] [--cpu_freq_metrics] [--cpu_c0_res] - [--cpu_lclk_dpm_level NBIOID] [--cpu_pwr_svi_telemtry_rails] - [--cpu_io_bandwidth IO_BW LINKID_NAME] - [--cpu_xgmi_bandwidth XGMI_BW LINKID_NAME] [--cpu_enable_apb] - [--cpu_disable_apb DF_PSTATE] [--set_cpu_pwr_limit PWR_LIMIT] - [--set_cpu_xgmi_link_width MIN_WIDTH MAX_WIDTH] - [--set_cpu_lclk_dpm_level NBIOID MIN_DPM MAX_DPM] - [--core_boost_limit] [--core_curr_active_freq_core_limit] - [--set_soc_boost_limit BOOST_LIMIT] - [--set_core_boost_limit BOOST_LIMIT] [--cpu_metrics_ver] - [--cpu_metrics_table] [--core_energy] [--socket_energy] - [--set_cpu_pwr_eff_mode MODE] [--cpu_ddr_bandwidth] [--cpu_temp] - [--cpu_dimm_temp_range_rate DIMM_ADDR] - [--cpu_dimm_pow_consumption DIMM_ADDR] - [--cpu_dimm_thermal_sensor DIMM_ADDR] - [--set_cpu_gmi3_link_width MIN_LW MAX_LW] - [--set_cpu_pcie_link_rate LINK_RATE] - [--set_cpu_df_pstate_range MAX_PSTATE MIN_PSTATE] + [-P] [-e] [-k] [-f] [-C] [-o] [-l] [-x] [-E] [--cpu-power-metrics] + [--cpu-prochot] [--cpu-freq-metrics] [--cpu-c0-res] + [--cpu-lclk-dpm-level NBIOID] [--cpu-pwr-svi-telemtry-rails] + [--cpu-io-bandwidth IO_BW LINKID_NAME] + [--cpu-xgmi-bandwidth XGMI_BW LINKID_NAME] [--cpu-metrics-ver] + [--cpu-metrics-table] [--cpu-socket-energy] [--cpu-ddr-bandwidth] + [--cpu-temp] [--cpu-dimm-temp-range-rate DIMM_ADDR] + [--cpu-dimm-pow-consumption DIMM_ADDR] + [--cpu-dimm-thermal-sensor DIMM_ADDR] [--core-boost-limit] + [--core-curr-active-freq-core-limit] [--core-energy] + [--json | --csv] [--file FILE] [--loglevel LEVEL] -If no GPU is specified, returns metric information for all GPUs on the system. +If no GPU is specified, returns metric information for all GPUs on the system. If no metric argument is provided all metric information will be displayed. Metric arguments: - -h, --help show this help message and exit - -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID: 0 | BDF: 0000:01:00.0 | UUID: 71ff74a0-0000-1000-8066-0a3c71d5f817 - ID: 1 | BDF: 0001:01:00.0 | UUID: b4ff74a0-0000-1000-80b2-fa0be8628b1a - ID: 2 | BDF: 0002:01:00.0 | UUID: a9ff74a0-0000-1000-8007-3066a98ba4a6 - ID: 3 | BDF: 0003:01:00.0 | UUID: 53ff74a0-0000-1000-80a0-a1ff3830f499 - all | Selects all devices + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID: 0 | BDF: 0000:01:00.0 | UUID: 71ff74a0-0000-1000-8066-0a3c71d5f817 + ID: 1 | BDF: 0001:01:00.0 | UUID: b4ff74a0-0000-1000-80b2-fa0be8628b1a + ID: 2 | BDF: 0002:01:00.0 | UUID: a9ff74a0-0000-1000-8007-3066a98ba4a6 + ID: 3 | BDF: 0003:01:00.0 | UUID: 53ff74a0-0000-1000-80a0-a1ff3830f499 + all | Selects all devices -U, --cpu CPU [CPU ...] Select a CPU ID from the possible choices: - ID: 0 - ID: 1 - ID: 2 - ID: 3 - all | Selects all devices - -O, --core CORE [CORE ...] Select a Core ID from the possible choices: - ID: 0 - 95 - all | Selects all devices - -w, --watch INTERVAL Reprint the command in a loop of INTERVAL seconds - -W, --watch_time TIME The total TIME to watch the given command - -i, --iterations ITERATIONS Total number of ITERATIONS to loop on the given command - -m, --mem-usage Memory usage per block - -u, --usage Displays engine usage information - -p, --power Current power usage - -c, --clock Average, max, and current clock frequencies - -t, --temperature Current temperatures - -e, --ecc Total number of ECC errors - -P, --pcie Current PCIe speed, width, and replay count - -k, --ecc-block Number of ECC errors per block - -f, --fan Current fan speed - -C, --voltage-curve Display voltage curve - -o, --overdrive Current GPU clock overdrive level - -l, --perf-level Current DPM performance level - -x, --xgmi-err XGMI error information since last read - -E, --energy Amount of energy consumed + ID: 0 + ID: 1 + ID: 2 + ID: 3 + all | Selects all devices + -O, --core CORE [CORE ...] Select a Core ID from the possible choices: + ID: 0 - 95 + all | Selects all devices + -w, --watch INTERVAL Reprint the command in a loop of INTERVAL seconds + -W, --watch_time TIME The total TIME to watch the given command + -i, --iterations ITERATIONS Total number of ITERATIONS to loop on the given command + -m, --mem-usage Memory usage per block + -u, --usage Displays engine usage information + -p, --power Current power usage + -c, --clock Average, max, and current clock frequencies + -t, --temperature Current temperatures + -P, --pcie Current PCIe speed, width, and replay count + -e, --ecc Total number of ECC errors + -k, --ecc-blocks Number of ECC errors per block + -f, --fan Current fan speed + -C, --voltage-curve Display voltage curve + -o, --overdrive Current GPU clock overdrive level + -l, --perf-level Current DPM performance level + -x, --xgmi-err XGMI error information since last read + -E, --energy Amount of energy consumed CPU Arguments: - --cpu_power_metrics Cpu power metrics - --cpu_prochot Displays prochot status - --cpu_freq_metrics Displays currentFclkMemclk frequencies and cclk frequency limit - --cpu_c0_res Displays C0 residency - --cpu_lclk_dpm_level NBIOID Displays lclk dpm level range. Requires socket ID and nbio id as inputs - --cpu_pwr_svi_telemtry_rails Displays svi based telemetry for all rails - --cpu_io_bandwidth IO_BW LINKID_NAME Displays current IO bandwidth for the selected CPU. - input parameters are bandwidth type(1) and link ID encodings - i.e. P2, P3, G0 - G7 - --cpu_xgmi_bandwidth XGMI_BW LINKID_NAME Displays current XGMI bandwidth for the selected CPU - input parameters are bandwidth type(1,2,4) and link ID encodings - i.e. P2, P3, G0 - G7 - --cpu_enable_apb Enables the DF p-state performance boost algorithm - --cpu_disable_apb DF_PSTATE Disables the DF p-state performance boost algorithm. - --core_boost_limit Get booslimit for the selected cores - --core_curr_active_freq_core_limit Get Current CCLK limit set per Core - --cpu_metrics_ver Displays metrics table version - --cpu_metrics_table Displays metric table - --core_energy Displays core energy for the selected core - --socket_energy Displays socket energy for the selected socket - --cpu_ddr_bandwidth Displays per socket max ddr bw, current utilized bw and current utilized ddr bw in percentage - --cpu_temp Displays cpu socket temperature - --cpu_dimm_temp_range_rate DIMM_ADDR Displays dimm temperature range and refresh rate - --cpu_dimm_pow_consumption DIMM_ADDR Displays dimm power consumption - --cpu_dimm_thermal_sensor DIMM_ADDR Displays dimm thermal sensor + --cpu-power-metrics CPU power metrics + --cpu-prochot Displays prochot status + --cpu-freq-metrics Displays currentFclkMemclk frequencies and cclk frequency limit + --cpu-c0-res Displays C0 residency + --cpu-lclk-dpm-level NBIOID Displays lclk dpm level range. Requires socket ID and NBOID as inputs + --cpu-pwr-svi-telemtry-rails Displays svi based telemetry for all rails + --cpu-io-bandwidth IO_BW LINKID_NAME Displays current IO bandwidth for the selected CPU. + input parameters are bandwidth type(1) and link ID encodings + i.e. P2, P3, G0 - G7 + --cpu-xgmi-bandwidth XGMI_BW LINKID_NAME Displays current XGMI bandwidth for the selected CPU + input parameters are bandwidth type(1,2,4) and link ID encodings + i.e. P2, P3, G0 - G7 + --cpu-metrics-ver Displays metrics table version + --cpu-metrics-table Displays metric table + --cpu-socket-energy Displays socket energy for the selected CPU socket + --cpu-ddr-bandwidth Displays per socket max ddr bw, current utilized bw, + and current utilized ddr bw in percentage + --cpu-temp Displays cpu socket temperature + --cpu-dimm-temp-range-rate DIMM_ADDR Displays dimm temperature range and refresh rate + --cpu-dimm-pow-consumption DIMM_ADDR Displays dimm power consumption + --cpu-dimm-thermal-sensor DIMM_ADDR Displays dimm thermal sensor -Set Options: - --set_cpu_pwr_limit PWR_LIMIT Set power limit for the given socket. Input parameter is power limit value. - --set_cpu_xgmi_link_width MIN_WIDTH MAX_WIDTH Set max and Min linkwidth. Input parameters are min and max link width values - --set_cpu_lclk_dpm_level NBIOID MIN_DPM MAX_DPM Sets the max and min dpm level on a given NBIO. Inpur parameters are die_index, min dpm, max dpm. - --set_soc_boost_limit BOOST_LIMIT Sets the boost limit for the given socket. Input parameter is socket limit value - --set_core_boost_limit BOOST_LIMIT Sets the boost limit for the given core. Input parameter is core limit value - --set_cpu_pwr_eff_mode MODE Sets the power efficency mode policy. Input parameter is mode. - --set_cpu_gmi3_link_width MIN_LW MAX_LW Sets max and min gmi3 link width range - --set_cpu_pcie_link_rate LINK_RATE Sets pcie link rate - --set_cpu_df_pstate_range MAX_PSTATE MIN_PSTATE Sets max and min df-pstates +CPU Core Arguments: + --core-boost-limit Get boost limit for the selected cores + --core-curr-active-freq-core-limit Get Current CCLK limit set per Core + --core-energy Displays core energy for the selected core Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel LEVEL Set the logging level from the possible choices: - DEBUG, INFO, WARNING, ERROR, CRITICAL + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash @@ -458,7 +437,7 @@ usage: amd-smi topology [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] [-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ...]] [-a] [-w] [-o] [-t] [-b] -If no GPU is specified, returns information for all GPUs on the system. +If no GPU is specified, returns information for all GPUs on the system. If no topology argument is provided all topology information will be displayed. Topology arguments: @@ -493,48 +472,69 @@ Command Modifiers: ``` ```bash -~$ amd-smi set --help -usage: amd-smi set [-h] [--json | --csv] [--file FILE] [--loglevel LEVEL] - (-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ...]) [-f %] +usage: amd-smi set [-h] (-g GPU [GPU ...] | -U CPU [CPU ...] | -O CORE [CORE ...]) [-f %] [-l LEVEL] [-P SETPROFILE] [-d SCLKMAX] [-C PARTITION] [-M PARTITION] - [-o WATTS] + [-o WATTS] [--cpu-pwr-limit PWR_LIMIT] + [--cpu-xgmi-link-width MIN_WIDTH MAX_WIDTH] + [--cpu-lclk-dpm-level NBIOID MIN_DPM MAX_DPM] [--cpu-pwr-eff-mode MODE] + [--cpu-gmi3-link-width MIN_LW MAX_LW] [--cpu-pcie-link-rate LINK_RATE] + [--cpu-df-pstate-range MAX_PSTATE MIN_PSTATE] [--cpu-enable-apb] + [--cpu-disable-apb DF_PSTATE] [--soc-boost-limit BOOST_LIMIT] + [--core-boost-limit BOOST_LIMIT] [--json | --csv] [--file FILE] + [--loglevel LEVEL] -A GPU must be specified to set a configuration. +A GPU must be specified to set a configuration. A set argument must be provided; Multiple set arguments are accepted Set Arguments: - -h, --help show this help message and exit - -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: - ID: 0 | BDF: 0000:01:00.0 | UUID: 71ff74a0-0000-1000-8066-0a3c71d5f817 - ID: 1 | BDF: 0001:01:00.0 | UUID: b4ff74a0-0000-1000-80b2-fa0be8628b1a - ID: 2 | BDF: 0002:01:00.0 | UUID: a9ff74a0-0000-1000-8007-3066a98ba4a6 - ID: 3 | BDF: 0003:01:00.0 | UUID: 53ff74a0-0000-1000-80a0-a1ff3830f499 - all | Selects all devices - -U, --cpu CPU [CPU ...] Select a CPU ID from the possible choices: - ID: 0 - ID: 1 - ID: 2 - ID: 3 - all | Selects all devices - -O, --core CORE [CORE ...] Select a Core ID from the possible choices: - ID: 0 - 95 - all | Selects all devices - -f, --fan % Set GPU fan speed (0-255 or 0-100%) - -l, --perf-level LEVEL Set performance level - -P, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes - -d, --perf-determinism SCLKMAX Set GPU clock frequency limit and performance level to determinism to get minimal performance variation - -C, --compute-partition PARTITION Set one of the following the compute partition modes: - CPX, SPX, DPX, TPX, QPX - -M, --memory-partition PARTITION Set one of the following the memory partition modes: - NPS1, NPS2, NPS4, NPS8 - -o, --power-cap WATTS Set power capacity limit + -h, --help show this help message and exit + -g, --gpu GPU [GPU ...] Select a GPU ID, BDF, or UUID from the possible choices: + ID: 0 | BDF: 0000:01:00.0 | UUID: 71ff74a0-0000-1000-8066-0a3c71d5f817 + ID: 1 | BDF: 0001:01:00.0 | UUID: b4ff74a0-0000-1000-80b2-fa0be8628b1a + ID: 2 | BDF: 0002:01:00.0 | UUID: a9ff74a0-0000-1000-8007-3066a98ba4a6 + ID: 3 | BDF: 0003:01:00.0 | UUID: 53ff74a0-0000-1000-80a0-a1ff3830f499 + all | Selects all devices + -U, --cpu CPU [CPU ...] Select a CPU ID from the possible choices: + ID: 0 + ID: 1 + ID: 2 + ID: 3 + all | Selects all devices + -O, --core CORE [CORE ...] Select a Core ID from the possible choices: + ID: 0 - 95 + all | Selects all devices + -f, --fan % Set GPU fan speed (0-255 or 0-100%) + -l, --perf-level LEVEL Set performance level + -P, --profile SETPROFILE Set power profile level (#) or a quoted string of custom profile attributes + -d, --perf-determinism SCLKMAX Set GPU clock frequency limit and performance level to determinism to get minimal performance variation + -C, --compute-partition PARTITION Set one of the following the compute partition modes: + CPX, SPX, DPX, TPX, QPX + -M, --memory-partition PARTITION Set one of the following the memory partition modes: + NPS1, NPS2, NPS4, NPS8 + -o, --power-cap WATTS Set power capacity limit + +CPU Arguments: + --cpu-pwr-limit PWR_LIMIT Set power limit for the given socket. Input parameter is power limit value. + --cpu-xgmi-link-width MIN_WIDTH MAX_WIDTH Set max and Min linkwidth. Input parameters are min and max link width values + --cpu-lclk-dpm-level NBIOID MIN_DPM MAX_DPM Sets the max and min dpm level on a given NBIO. + Input parameters are die_index, min dpm, max dpm. + --cpu-pwr-eff-mode MODE Sets the power efficency mode policy. Input parameter is mode. + --cpu-gmi3-link-width MIN_LW MAX_LW Sets max and min gmi3 link width range + --cpu-pcie-link-rate LINK_RATE Sets pcie link rate + --cpu-df-pstate-range MAX_PSTATE MIN_PSTATE Sets max and min df-pstates + --cpu-enable-apb Enables the DF p-state performance boost algorithm + --cpu-disable-apb DF_PSTATE Disables the DF p-state performance boost algorithm. Input parameter is DFPstate (0-3) + --soc-boost-limit BOOST_LIMIT Sets the boost limit for the given socket. Input parameter is socket BOOST_LIMIT value + +CPU Core Arguments: + --core-boost-limit BOOST_LIMIT Sets the boost limit for the given core. Input parameter is core BOOST_LIMIT value Command Modifiers: - --json Displays output in JSON format (human readable by default). - --csv Displays output in CSV format (human readable by default). - --file FILE Saves output into a file on the provided path (stdout by default). - --loglevel LEVEL Set the logging level from the possible choices: - DEBUG, INFO, WARNING, ERROR, CRITICAL + --json Displays output in JSON format (human readable by default). + --csv Displays output in CSV format (human readable by default). + --file FILE Saves output into a file on the provided path (stdout by default). + --loglevel LEVEL Set the logging level from the possible choices: + DEBUG, INFO, WARNING, ERROR, CRITICAL ``` ```bash @@ -588,414 +588,413 @@ Here is some example output from the tool: ```bash ~$ amd-smi static CPU: 0 -SMU: - FW_VERSION: 85:81:0 -INTERFACE_VERSION: - PROTO VERSION: 6 + SMU: + FW_VERSION: 85:81:0 + INTERFACE_VERSION: + PROTO VERSION: 6 CPU: 1 -SMU: - FW_VERSION: 85:81:0 -INTERFACE_VERSION: - PROTO VERSION: 6 + SMU: + FW_VERSION: 85:81:0 + INTERFACE_VERSION: + PROTO VERSION: 6 CPU: 2 -SMU: - FW_VERSION: 85:81:0 -INTERFACE_VERSION: - PROTO VERSION: 6 + SMU: + FW_VERSION: 85:81:0 + INTERFACE_VERSION: + PROTO VERSION: 6 CPU: 3 -SMU: - FW_VERSION: 85:81:0 -INTERFACE_VERSION: - PROTO VERSION: 6 - + SMU: + FW_VERSION: 85:81:0 + INTERFACE_VERSION: + PROTO VERSION: 6 GPU: 0 -ASIC: - MARKET_NAME: MI300A - VENDOR_ID: 0x1002 - VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] - SUBVENDOR_ID: 0 - DEVICE_ID: 0x74a0 - REV_ID: 0x0 - ASIC_SERIAL: 0x71660A3C71D5F817 - OAM_ID: 0 -BUS: - BDF: 0000:01:00.0 - MAX_PCIE_SPEED: 32 GT/s - MAX_PCIE_LANES: 16 - PCIE_INTERFACE_VERSION: Gen 5 - SLOT_TYPE: PCIE -VBIOS: - NAME: N/A - BUILD_DATE: N/A - PART_NUMBER: N/A - VERSION: N/A -BOARD: - MODEL_NUMBER: N/A - PRODUCT_SERIAL: N/A - FRU_ID: N/A - PRODUCT_NAME: N/A - MANUFACTURER_NAME: N/A -LIMIT: - MAX_POWER: 550 W - CURRENT_POWER: 0 W - SLOWDOWN_EDGE_TEMPERATURE: N/A - SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C - SLOWDOWN_VRAM_TEMPERATURE: 95 °C - SHUTDOWN_EDGE_TEMPERATURE: N/A - SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C - SHUTDOWN_VRAM_TEMPERATURE: 105 °C -DRIVER: - NAME: amdgpu - VERSION: 6.5.2 -VRAM: - TYPE: HBM - VENDOR: N/A - SIZE: 96432 MB -CACHE_INFO: - CACHE_0: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 464 - CACHE_1: - CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE - CACHE_SIZE: 64 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 160 - CACHE_2: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32768 KB - CACHE_LEVEL: 2 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 - CACHE_3: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 262144 KB - CACHE_LEVEL: 3 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 - -RAS: - EEPROM_VERSION: 0x0 - PARITY_SCHEMA: DISABLED - SINGLE_BIT_SCHEMA: DISABLED - DOUBLE_BIT_SCHEMA: DISABLED - POISON_SCHEMA: ENABLED - ECC_BLOCK_STATE: - UMC: DISABLED - SDMA: ENABLED - GFX: ENABLED - MMHUB: ENABLED - ATHUB: DISABLED - PCIE_BIF: DISABLED - HDP: DISABLED - XGMI_WAFL: DISABLED - DF: DISABLED - SMN: DISABLED - SEM: DISABLED - MP0: DISABLED - MP1: DISABLED - FUSE: DISABLED -PARTITION: - COMPUTE_PARTITION: SPX - MEMORY_PARTITION: NPS1 -NUMA: - NODE: 0 - AFFINITY: 0 + ASIC: + MARKET_NAME: MI300A + VENDOR_ID: 0x1002 + VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] + SUBVENDOR_ID: 0x1002 + DEVICE_ID: 0x74a0 + REV_ID: 0x0 + ASIC_SERIAL: 0x71660A3C71D5F817 + OAM_ID: 0 + BUS: + BDF: 0000:01:00.0 + MAX_PCIE_WIDTH: 16 + MAX_PCIE_SPEED: 32 GT/s + PCIE_INTERFACE_VERSION: Gen 5 + SLOT_TYPE: PCIE + VBIOS: + NAME: N/A + BUILD_DATE: N/A + PART_NUMBER: N/A + VERSION: N/A + LIMIT: + MAX_POWER: 550 W + SOCKET_POWER: 550 W + SLOWDOWN_EDGE_TEMPERATURE: N/A + SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C + SLOWDOWN_VRAM_TEMPERATURE: 95 °C + SHUTDOWN_EDGE_TEMPERATURE: N/A + SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C + SHUTDOWN_VRAM_TEMPERATURE: 105 °C + DRIVER: + NAME: amdgpu + VERSION: 6.7.0 + BOARD: + MODEL_NUMBER: N/A + PRODUCT_SERIAL: N/A + FRU_ID: N/A + PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A + RAS: + EEPROM_VERSION: 0x0 + PARITY_SCHEMA: DISABLED + SINGLE_BIT_SCHEMA: DISABLED + DOUBLE_BIT_SCHEMA: DISABLED + POISON_SCHEMA: ENABLED + ECC_BLOCK_STATE: + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED + PARTITION: + COMPUTE_PARTITION: SPX + MEMORY_PARTITION: NPS1 + NUMA: + NODE: 0 + AFFINITY: 0 + VRAM: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB + CACHE_INFO: + CACHE_0: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 464 + CACHE_1: + CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE + CACHE_SIZE: 64 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 160 + CACHE_2: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32768 KB + CACHE_LEVEL: 2 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 + CACHE_3: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 262144 KB + CACHE_LEVEL: 3 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 GPU: 1 -ASIC: - MARKET_NAME: MI300A - VENDOR_ID: 0x1002 - VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] - SUBVENDOR_ID: 0 - DEVICE_ID: 0x74a0 - REV_ID: 0x0 - ASIC_SERIAL: 0xB4B2FA0BE8628B1A - OAM_ID: 1 -BUS: - BDF: 0001:01:00.0 - MAX_PCIE_SPEED: 32 GT/s - MAX_PCIE_LANES: 16 - PCIE_INTERFACE_VERSION: Gen 5 - SLOT_TYPE: PCIE -VBIOS: - NAME: N/A - BUILD_DATE: N/A - PART_NUMBER: N/A - VERSION: N/A -BOARD: - MODEL_NUMBER: N/A - PRODUCT_SERIAL: N/A - FRU_ID: N/A - PRODUCT_NAME: N/A - MANUFACTURER_NAME: N/A -LIMIT: - MAX_POWER: 550 W - CURRENT_POWER: 0 W - SLOWDOWN_EDGE_TEMPERATURE: N/A - SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C - SLOWDOWN_VRAM_TEMPERATURE: 95 °C - SHUTDOWN_EDGE_TEMPERATURE: N/A - SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C - SHUTDOWN_VRAM_TEMPERATURE: 105 °C -DRIVER: - NAME: amdgpu - VERSION: 6.5.2 -VRAM: - TYPE: HBM - VENDOR: N/A - SIZE: 96432 MB -CACHE_INFO: - CACHE_0: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 464 - CACHE_1: - CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE - CACHE_SIZE: 64 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 160 - CACHE_2: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32768 KB - CACHE_LEVEL: 2 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 - CACHE_3: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 262144 KB - CACHE_LEVEL: 3 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 -RAS: - EEPROM_VERSION: 0x0 - PARITY_SCHEMA: DISABLED - SINGLE_BIT_SCHEMA: DISABLED - DOUBLE_BIT_SCHEMA: DISABLED - POISON_SCHEMA: ENABLED - ECC_BLOCK_STATE: - UMC: DISABLED - SDMA: ENABLED - GFX: ENABLED - MMHUB: ENABLED - ATHUB: DISABLED - PCIE_BIF: DISABLED - HDP: DISABLED - XGMI_WAFL: DISABLED - DF: DISABLED - SMN: DISABLED - SEM: DISABLED - MP0: DISABLED - MP1: DISABLED - FUSE: DISABLED -PARTITION: - COMPUTE_PARTITION: SPX - MEMORY_PARTITION: NPS1 -NUMA: - NODE: 1 - AFFINITY: 1 + ASIC: + MARKET_NAME: MI300A + VENDOR_ID: 0x1002 + VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] + SUBVENDOR_ID: 0x1002 + DEVICE_ID: 0x74a0 + REV_ID: 0x0 + ASIC_SERIAL: 0xB4B2FA0BE8628B1A + OAM_ID: 1 + BUS: + BDF: 0001:01:00.0 + MAX_PCIE_WIDTH: 16 + MAX_PCIE_SPEED: 32 GT/s + PCIE_INTERFACE_VERSION: Gen 5 + SLOT_TYPE: PCIE + VBIOS: + NAME: N/A + BUILD_DATE: N/A + PART_NUMBER: N/A + VERSION: N/A + LIMIT: + MAX_POWER: 550 W + SOCKET_POWER: 550 W + SLOWDOWN_EDGE_TEMPERATURE: N/A + SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C + SLOWDOWN_VRAM_TEMPERATURE: 95 °C + SHUTDOWN_EDGE_TEMPERATURE: N/A + SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C + SHUTDOWN_VRAM_TEMPERATURE: 105 °C + DRIVER: + NAME: amdgpu + VERSION: 6.7.0 + BOARD: + MODEL_NUMBER: N/A + PRODUCT_SERIAL: N/A + FRU_ID: N/A + PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A + RAS: + EEPROM_VERSION: 0x0 + PARITY_SCHEMA: DISABLED + SINGLE_BIT_SCHEMA: DISABLED + DOUBLE_BIT_SCHEMA: DISABLED + POISON_SCHEMA: ENABLED + ECC_BLOCK_STATE: + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED + PARTITION: + COMPUTE_PARTITION: SPX + MEMORY_PARTITION: NPS1 + NUMA: + NODE: 1 + AFFINITY: 1 + VRAM: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB + CACHE_INFO: + CACHE_0: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 464 + CACHE_1: + CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE + CACHE_SIZE: 64 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 160 + CACHE_2: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32768 KB + CACHE_LEVEL: 2 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 + CACHE_3: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 262144 KB + CACHE_LEVEL: 3 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 GPU: 2 -ASIC: - MARKET_NAME: MI300A - VENDOR_ID: 0x1002 - VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] - SUBVENDOR_ID: 0 - DEVICE_ID: 0x74a0 - REV_ID: 0x0 - ASIC_SERIAL: 0xA9073066A98BA4A6 - OAM_ID: 2 -BUS: - BDF: 0002:01:00.0 - MAX_PCIE_SPEED: 32 GT/s - MAX_PCIE_LANES: 16 - PCIE_INTERFACE_VERSION: Gen 5 - SLOT_TYPE: PCIE -VBIOS: - NAME: N/A - BUILD_DATE: N/A - PART_NUMBER: N/A - VERSION: N/A -BOARD: - MODEL_NUMBER: N/A - PRODUCT_SERIAL: N/A - FRU_ID: N/A - PRODUCT_NAME: N/A - MANUFACTURER_NAME: N/A -LIMIT: - MAX_POWER: 550 W - CURRENT_POWER: 0 W - SLOWDOWN_EDGE_TEMPERATURE: N/A - SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C - SLOWDOWN_VRAM_TEMPERATURE: 95 °C - SHUTDOWN_EDGE_TEMPERATURE: N/A - SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C - SHUTDOWN_VRAM_TEMPERATURE: 105 °C -DRIVER: - NAME: amdgpu - VERSION: 6.5.2 -VRAM: - TYPE: HBM - VENDOR: N/A - SIZE: 96432 MB -CACHE_INFO: - CACHE_0: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 464 - CACHE_1: - CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE - CACHE_SIZE: 64 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 160 - CACHE_2: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32768 KB - CACHE_LEVEL: 2 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 - CACHE_3: - CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE - CACHE_SIZE: 262144 KB - CACHE_LEVEL: 3 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 -RAS: - EEPROM_VERSION: 0x0 - PARITY_SCHEMA: DISABLED - SINGLE_BIT_SCHEMA: DISABLED - DOUBLE_BIT_SCHEMA: DISABLED - POISON_SCHEMA: ENABLED - ECC_BLOCK_STATE: - UMC: DISABLED - SDMA: ENABLED - GFX: ENABLED - MMHUB: ENABLED - ATHUB: DISABLED - PCIE_BIF: DISABLED - HDP: DISABLED - XGMI_WAFL: DISABLED - DF: DISABLED - SMN: DISABLED - SEM: DISABLED - MP0: DISABLED - MP1: DISABLED - FUSE: DISABLED -PARTITION: - COMPUTE_PARTITION: SPX - MEMORY_PARTITION: NPS1 -NUMA: - NODE: 2 - AFFINITY: 2 + ASIC: + MARKET_NAME: MI300A + VENDOR_ID: 0x1002 + VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] + SUBVENDOR_ID: 0x1002 + DEVICE_ID: 0x74a0 + REV_ID: 0x0 + ASIC_SERIAL: 0xA9073066A98BA4A6 + OAM_ID: 2 + BUS: + BDF: 0002:01:00.0 + MAX_PCIE_WIDTH: 16 + MAX_PCIE_SPEED: 32 GT/s + PCIE_INTERFACE_VERSION: Gen 5 + SLOT_TYPE: PCIE + VBIOS: + NAME: N/A + BUILD_DATE: N/A + PART_NUMBER: N/A + VERSION: N/A + LIMIT: + MAX_POWER: 550 W + SOCKET_POWER: 550 W + SLOWDOWN_EDGE_TEMPERATURE: N/A + SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C + SLOWDOWN_VRAM_TEMPERATURE: 95 °C + SHUTDOWN_EDGE_TEMPERATURE: N/A + SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C + SHUTDOWN_VRAM_TEMPERATURE: 105 °C + DRIVER: + NAME: amdgpu + VERSION: 6.7.0 + BOARD: + MODEL_NUMBER: N/A + PRODUCT_SERIAL: N/A + FRU_ID: N/A + PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A + RAS: + EEPROM_VERSION: 0x0 + PARITY_SCHEMA: DISABLED + SINGLE_BIT_SCHEMA: DISABLED + DOUBLE_BIT_SCHEMA: DISABLED + POISON_SCHEMA: ENABLED + ECC_BLOCK_STATE: + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED + PARTITION: + COMPUTE_PARTITION: SPX + MEMORY_PARTITION: NPS1 + NUMA: + NODE: 2 + AFFINITY: 2 + VRAM: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB + CACHE_INFO: + CACHE_0: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 464 + CACHE_1: + CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE + CACHE_SIZE: 64 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 160 + CACHE_2: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32768 KB + CACHE_LEVEL: 2 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 + CACHE_3: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 262144 KB + CACHE_LEVEL: 3 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 GPU: 3 -ASIC: - MARKET_NAME: MI300A - VENDOR_ID: 0x1002 - VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] - SUBVENDOR_ID: 0 - DEVICE_ID: 0x74a0 - REV_ID: 0x0 - ASIC_SERIAL: 0x53A0A1FF3830F499 - OAM_ID: 3 -BUS: - BDF: 0003:01:00.0 - MAX_PCIE_SPEED: 32 GT/s - MAX_PCIE_LANES: 16 - PCIE_INTERFACE_VERSION: Gen 5 - SLOT_TYPE: PCIE -VBIOS: - NAME: N/A - BUILD_DATE: N/A - PART_NUMBER: N/A - VERSION: N/A -BOARD: - MODEL_NUMBER: N/A - PRODUCT_SERIAL: N/A - FRU_ID: N/A - PRODUCT_NAME: N/A - MANUFACTURER_NAME: N/A -LIMIT: - MAX_POWER: 550 W - CURRENT_POWER: 0 W - SLOWDOWN_EDGE_TEMPERATURE: N/A - SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C - SLOWDOWN_VRAM_TEMPERATURE: 95 °C - SHUTDOWN_EDGE_TEMPERATURE: N/A - SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C - SHUTDOWN_VRAM_TEMPERATURE: 105 °C -DRIVER: - NAME: amdgpu - VERSION: 6.5.2 -VRAM: - TYPE: HBM - VENDOR: N/A - SIZE: 96432 MB -CACHE_INFO: - CACHE_0: - CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE - CACHE_SIZE: 32 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 464 - CACHE_1: - CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE - CACHE_SIZE: 64 KB - CACHE_LEVEL: 1 - MAX_NUM_CU_SHARED: 2 - NUM_CACHE_INSTANCE: 160 - CACHE_2: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 32768 KB - CACHE_LEVEL: 2 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 - CACHE_3: - CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE - CACHE_SIZE: 262144 KB - CACHE_LEVEL: 3 - MAX_NUM_CU_SHARED: 304 - NUM_CACHE_INSTANCE: 1 -RAS: - EEPROM_VERSION: 0x0 - PARITY_SCHEMA: DISABLED - SINGLE_BIT_SCHEMA: DISABLED - DOUBLE_BIT_SCHEMA: DISABLED - POISON_SCHEMA: ENABLED - ECC_BLOCK_STATE: - UMC: DISABLED - SDMA: ENABLED - GFX: ENABLED - MMHUB: ENABLED - ATHUB: DISABLED - PCIE_BIF: DISABLED - HDP: DISABLED - XGMI_WAFL: DISABLED - DF: DISABLED - SMN: DISABLED - SEM: DISABLED - MP0: DISABLED - MP1: DISABLED - FUSE: DISABLED -PARTITION: - COMPUTE_PARTITION: SPX - MEMORY_PARTITION: NPS1 -NUMA: - NODE: 3 - AFFINITY: 3 + ASIC: + MARKET_NAME: MI300A + VENDOR_ID: 0x1002 + VENDOR_NAME: Advanced Micro Devices Inc. [AMD/ATI] + SUBVENDOR_ID: 0x1002 + DEVICE_ID: 0x74a0 + REV_ID: 0x0 + ASIC_SERIAL: 0x53A0A1FF3830F499 + OAM_ID: 3 + BUS: + BDF: 0003:01:00.0 + MAX_PCIE_WIDTH: 16 + MAX_PCIE_SPEED: 32 GT/s + PCIE_INTERFACE_VERSION: Gen 5 + SLOT_TYPE: PCIE + VBIOS: + NAME: N/A + BUILD_DATE: N/A + PART_NUMBER: N/A + VERSION: N/A + LIMIT: + MAX_POWER: 550 W + SOCKET_POWER: 550 W + SLOWDOWN_EDGE_TEMPERATURE: N/A + SLOWDOWN_HOTSPOT_TEMPERATURE: 100 °C + SLOWDOWN_VRAM_TEMPERATURE: 95 °C + SHUTDOWN_EDGE_TEMPERATURE: N/A + SHUTDOWN_HOTSPOT_TEMPERATURE: 110 °C + SHUTDOWN_VRAM_TEMPERATURE: 105 °C + DRIVER: + NAME: amdgpu + VERSION: 6.7.0 + BOARD: + MODEL_NUMBER: N/A + PRODUCT_SERIAL: N/A + FRU_ID: N/A + PRODUCT_NAME: N/A + MANUFACTURER_NAME: N/A + RAS: + EEPROM_VERSION: 0x0 + PARITY_SCHEMA: DISABLED + SINGLE_BIT_SCHEMA: DISABLED + DOUBLE_BIT_SCHEMA: DISABLED + POISON_SCHEMA: ENABLED + ECC_BLOCK_STATE: + UMC: DISABLED + SDMA: ENABLED + GFX: ENABLED + MMHUB: ENABLED + ATHUB: DISABLED + PCIE_BIF: DISABLED + HDP: DISABLED + XGMI_WAFL: DISABLED + DF: DISABLED + SMN: DISABLED + SEM: DISABLED + MP0: DISABLED + MP1: DISABLED + FUSE: DISABLED + PARTITION: + COMPUTE_PARTITION: SPX + MEMORY_PARTITION: NPS1 + NUMA: + NODE: 3 + AFFINITY: 3 + VRAM: + TYPE: HBM + VENDOR: N/A + SIZE: 96432 MB + CACHE_INFO: + CACHE_0: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 464 + CACHE_1: + CACHE_PROPERTIES: INST_CACHE, SIMD_CACHE + CACHE_SIZE: 64 KB + CACHE_LEVEL: 1 + MAX_NUM_CU_SHARED: 2 + NUM_CACHE_INSTANCE: 160 + CACHE_2: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 32768 KB + CACHE_LEVEL: 2 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 + CACHE_3: + CACHE_PROPERTIES: DATA_CACHE, SIMD_CACHE + CACHE_SIZE: 262144 KB + CACHE_LEVEL: 3 + MAX_NUM_CU_SHARED: 304 + NUM_CACHE_INSTANCE: 1 + ``` ## Disclaimer diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py index d7787eafea..3140cd52a0 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -387,9 +387,10 @@ class AMDSMIParser(argparse.ArgumentParser): device_args.add_argument('-U', '--cpu', type=self._validate_cpu_core, action=self._cpu_select(self.cpu_choices), nargs='+', help=cpu_help) - device_args.add_argument('-O', '--core', type=self._validate_cpu_core, - action=self._core_select(self.core_choices), - nargs='+', help=core_help) + if subcommand_parser._optionals.title != "Static Arguments": + device_args.add_argument('-O', '--core', type=self._validate_cpu_core, + action=self._core_select(self.core_choices), + nargs='+', help=core_help) if self.helpers.is_hypervisor(): device_args.add_argument('-v', '--vf', action='store', nargs='+',