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()