From 53130a9c3c971f72922484cf288fd2f8732dcf14 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Tue, 17 Sep 2024 13:20:04 -0500 Subject: [PATCH] Fixed amdsmi_get_utilization_count() wrapper generation Signed-off-by: Maisam Arif Change-Id: Ifd59fca042c4b3b0fc53e100b6892c6b4f7b3e95 [ROCm/amdsmi commit: 639daa3d90b48d59f61adb181a8b9ae7686dd765] --- projects/amdsmi/CHANGELOG.md | 2 ++ .../docs/how-to/using-amdsmi-for-python.md | 18 +++++++----- projects/amdsmi/py-interface/README.md | 18 +++++++----- .../amdsmi/py-interface/amdsmi_interface.py | 8 ++++++ .../amdsmi/py-interface/amdsmi_wrapper.py | 28 +++++++++---------- projects/amdsmi/tools/generator.py | 25 ++++++++++++++--- 6 files changed, 67 insertions(+), 32 deletions(-) diff --git a/projects/amdsmi/CHANGELOG.md b/projects/amdsmi/CHANGELOG.md index 3099351e99..a5ac39f1ab 100644 --- a/projects/amdsmi/CHANGELOG.md +++ b/projects/amdsmi/CHANGELOG.md @@ -8,6 +8,8 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr ### Changes +- **Added more supported utilization count types to `amdsmi_get_utilization_count()`**. + - **Added Pytest functionality to test amdsmi API calls in Python**. - **Changed the `power` parameter in `amdsmi_get_energy_count()` to `energy_accumulator`**. diff --git a/projects/amdsmi/docs/how-to/using-amdsmi-for-python.md b/projects/amdsmi/docs/how-to/using-amdsmi-for-python.md index 6cec1385a2..797486ca8e 100644 --- a/projects/amdsmi/docs/how-to/using-amdsmi-for-python.md +++ b/projects/amdsmi/docs/how-to/using-amdsmi-for-python.md @@ -1925,19 +1925,19 @@ except AmdSmiException as e: ### amdsmi_get_utilization_count -Description: Get coarse grain utilization counter of the specified device +Description: Get coarse/fine grain utilization counter of the specified device Input parameters: * `processor_handle` handle for the given device -* `counter_types` variable number of counter types desired +* `counter_types` List of AmdSmiUtilizationCounterType counters requested Output: List containing dictionaries with fields Field | Description ---|--- `timestamp` | The timestamp when the counter is retreived - Resolution: 1 ns -`Dictionary for each counter` |
Subfield Description
`type`Type of utilization counter
`value`Value gotten for utilization counter
+`Dictionary for each counter` |
Subfield Description
`type`Counter that was requested
`value`Value gotten for utilization counter
Exceptions that can be thrown by `amdsmi_get_utilization_count` function: @@ -1957,13 +1957,17 @@ try: utilization = amdsmi_get_utilization_count( device, AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY - ) + ) print(utilization) utilization = amdsmi_get_utilization_count( device, - AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY, - AmdSmiUtilizationCounterType.COARSE_GRAIN_MEM_ACTIVITY - ) + [AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY, + AmdSmiUtilizationCounterType.COARSE_GRAIN_MEM_ACTIVITY, + AmdSmiUtilizationCounterType.COARSE_DECODER_ACTIVITY, + AmdSmiUtilizationCounterType.FINE_GRAIN_GFX_ACTIVITY, + AmdSmiUtilizationCounterType.FINE_GRAIN_MEM_ACTIVITY, + AmdSmiUtilizationCounterType.FINE_DECODER_ACTIVITY] + ) print(utilization) except AmdSmiException as e: print(e) diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index 6cec1385a2..797486ca8e 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -1925,19 +1925,19 @@ except AmdSmiException as e: ### amdsmi_get_utilization_count -Description: Get coarse grain utilization counter of the specified device +Description: Get coarse/fine grain utilization counter of the specified device Input parameters: * `processor_handle` handle for the given device -* `counter_types` variable number of counter types desired +* `counter_types` List of AmdSmiUtilizationCounterType counters requested Output: List containing dictionaries with fields Field | Description ---|--- `timestamp` | The timestamp when the counter is retreived - Resolution: 1 ns -`Dictionary for each counter` |
Subfield Description
`type`Type of utilization counter
`value`Value gotten for utilization counter
+`Dictionary for each counter` |
Subfield Description
`type`Counter that was requested
`value`Value gotten for utilization counter
Exceptions that can be thrown by `amdsmi_get_utilization_count` function: @@ -1957,13 +1957,17 @@ try: utilization = amdsmi_get_utilization_count( device, AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY - ) + ) print(utilization) utilization = amdsmi_get_utilization_count( device, - AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY, - AmdSmiUtilizationCounterType.COARSE_GRAIN_MEM_ACTIVITY - ) + [AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY, + AmdSmiUtilizationCounterType.COARSE_GRAIN_MEM_ACTIVITY, + AmdSmiUtilizationCounterType.COARSE_DECODER_ACTIVITY, + AmdSmiUtilizationCounterType.FINE_GRAIN_GFX_ACTIVITY, + AmdSmiUtilizationCounterType.FINE_GRAIN_MEM_ACTIVITY, + AmdSmiUtilizationCounterType.FINE_DECODER_ACTIVITY] + ) print(utilization) 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 f86c0f0723..13ddbc1312 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -3402,6 +3402,14 @@ def amdsmi_get_utilization_count( raise AmdSmiParameterException( processor_handle, amdsmi_wrapper.amdsmi_processor_handle ) + + # Enforce List typing + if not isinstance(counter_types, list): + counter_types = [counter_types] + + counter_types = list(set(counter_types)) + + # Validate Inputs if len(counter_types) == 0: raise AmdSmiLibraryException(amdsmi_wrapper.AMDSMI_STATUS_INVAL) counters = [] diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index c7f994f804..c2b3f8f5b3 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -759,6 +759,19 @@ amdsmi_card_form_factor_t = ctypes.c_uint32 # enum class struct_amdsmi_pcie_info_t(Structure): pass +class struct_pcie_static_(Structure): + pass + +struct_pcie_static_._pack_ = 1 # source:False +struct_pcie_static_._fields_ = [ + ('max_pcie_width', ctypes.c_uint16), + ('PADDING_0', ctypes.c_ubyte * 2), + ('max_pcie_speed', ctypes.c_uint32), + ('pcie_interface_version', ctypes.c_uint32), + ('slot_type', amdsmi_card_form_factor_t), + ('reserved', ctypes.c_uint64 * 10), +] + class struct_pcie_metric_(Structure): pass @@ -777,19 +790,6 @@ struct_pcie_metric_._fields_ = [ ('reserved', ctypes.c_uint64 * 13), ] -class struct_pcie_static_(Structure): - pass - -struct_pcie_static_._pack_ = 1 # source:False -struct_pcie_static_._fields_ = [ - ('max_pcie_width', ctypes.c_uint16), - ('PADDING_0', ctypes.c_ubyte * 2), - ('max_pcie_speed', ctypes.c_uint32), - ('pcie_interface_version', ctypes.c_uint32), - ('slot_type', amdsmi_card_form_factor_t), - ('reserved', ctypes.c_uint64 * 10), -] - struct_amdsmi_pcie_info_t._pack_ = 1 # source:False struct_amdsmi_pcie_info_t._fields_ = [ ('pcie_static', struct_pcie_static_), @@ -2069,7 +2069,7 @@ amdsmi_set_gpu_fan_speed.restype = amdsmi_status_t amdsmi_set_gpu_fan_speed.argtypes = [amdsmi_processor_handle, uint32_t, uint64_t] amdsmi_get_utilization_count = _libraries['libamd_smi.so'].amdsmi_get_utilization_count amdsmi_get_utilization_count.restype = amdsmi_status_t -amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, struct_amdsmi_utilization_counter_t * 0, uint32_t, ctypes.POINTER(ctypes.c_uint64)] +amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_utilization_counter_t), uint32_t, ctypes.POINTER(ctypes.c_uint64)] amdsmi_get_gpu_perf_level = _libraries['libamd_smi.so'].amdsmi_get_gpu_perf_level amdsmi_get_gpu_perf_level.restype = amdsmi_status_t amdsmi_get_gpu_perf_level.argtypes = [amdsmi_processor_handle, ctypes.POINTER(amdsmi_dev_perf_level_t)] diff --git a/projects/amdsmi/tools/generator.py b/projects/amdsmi/tools/generator.py index b170d4924a..6014746094 100644 --- a/projects/amdsmi/tools/generator.py +++ b/projects/amdsmi/tools/generator.py @@ -70,12 +70,23 @@ def parseArgument(): return args['output'], args['input'], args['library'], args['extra_args'] -def replace_line(full_path_file_name, string_to_repalce, new_string): +def replace_line(full_path_file_name, string_to_replace, new_string): + """ + Replaces a specific string in a file with a new string. + + Args: + full_path_file_name (str): The full path of the file to modify. + string_to_replace (str): The string to be replaced. + new_string (str): The new string to replace the old string with. + + Returns: + None + """ fh, abs_path = tempfile.mkstemp() with os.fdopen(fh, 'w') as new_file: with open(full_path_file_name, 'r+', encoding='UTF-8') as old_file: for line in old_file: - new_file.write(line.replace(string_to_repalce, new_string)) + new_file.write(line.replace(string_to_replace, new_string)) shutil.copymode(full_path_file_name, abs_path) os.remove(full_path_file_name) @@ -179,8 +190,14 @@ except OSError as error: struct_amdsmi_bdf_t_line = "'struct_amdsmi_bdf_t'," replace_line(output_file, struct_anon_all_line, struct_amdsmi_bdf_t_line) - struct_anon_all_line = f"amdsmi.h:{line_number}:3)', " - replace_line(output_file, struct_anon_all_line, "") + struct_anon_all_line_to_remove = f"amdsmi.h:{line_number}:3)', " + replace_line(output_file, struct_anon_all_line_to_remove, "") + + # Custom handling to ensure amdsmi_get_utilization_count doesn't multiply the struct by 0 + print(f"Replacing amdsmi_get_utilization_count line in {output_file}") + utilization_count_line_bad = "amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, struct_amdsmi_utilization_counter_t * 0, uint32_t, ctypes.POINTER(ctypes.c_uint64)]" + utilization_count_line_good = "amdsmi_get_utilization_count.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_utilization_counter_t), uint32_t, ctypes.POINTER(ctypes.c_uint64)]" + replace_line(output_file, utilization_count_line_bad, utilization_count_line_good) if __name__ == "__main__": main()