diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md
index 86b37ea9d6..e463e48e48 100644
--- a/projects/amdsmi/py-interface/README.md
+++ b/projects/amdsmi/py-interface/README.md
@@ -1132,3 +1132,362 @@ except SmiException as e:
Description: Detroys event listener object, closes all open files and directories
Input parameters: `None`
+
+
+## amdsmi_dev_supported_func_iterator_open
+Description: Get a function name iterator of supported AMDSMI functions for a device
+
+Input parameters:
+
+* `device_handle` device which to query
+
+Output: Handle for a function iterator
+
+Exceptions that can be thrown by `amdsmi_dev_supported_func_iterator_open` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ obj_handle = amdsmi_dev_supported_func_iterator_open(device)
+ print(obj_handle)
+ amdsmi_dev_supported_func_iterator_close(obj_handle)
+except AmdSmiException as e:
+ print(e)
+```
+
+## amdsmi_dev_supported_variant_iterator_open
+Description: Get a variant iterator for a given handle
+
+Input parameters:
+
+* `obj_handle` Object handle for witch to return a variant handle
+
+Output: Variant iterator handle
+
+Exceptions that can be thrown by `amdsmi_dev_supported_variant_iterator_open` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ obj_handle = amdsmi_dev_supported_func_iterator_open(device)
+ var_iter = amdsmi_dev_supported_variant_iterator_open(obj_handle)
+ print(var_iter)
+ amdsmi_dev_supported_func_iterator_close(obj_handle)
+ amdsmi_dev_supported_func_iterator_close(var_iter)
+except AmdSmiException as e:
+ print(e)
+```
+
+## amdsmi_func_iter_next
+Description: Advance an object identifier iterator
+
+Input parameters:
+
+* `obj_handle` Object handle to advance
+
+Output: Next iterator handle
+
+Exceptions that can be thrown by `amdsmi_func_iter_next` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ obj_handle = amdsmi_dev_supported_func_iterator_open(device)
+ print(obj_handle)
+ obj_handle = amdsmi_func_iter_next(obj_handle)
+ print(obj_handle)
+ amdsmi_dev_supported_func_iterator_close(obj_handle)
+except AmdSmiException as e:
+ print(e)
+```
+
+## amdsmi_dev_supported_func_iterator_close
+Description: Close a variant iterator handle
+
+Input parameters:
+
+* `obj_handle` Object handle to be closed
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_supported_func_iterator_close` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ obj_handle = amdsmi_dev_supported_func_iterator_open(device)
+ amdsmi_dev_supported_func_iterator_close(obj_handle)
+except AmdSmiException as e:
+ print(e)
+```
+
+## amdsmi_func_iter_value_get
+Description: Get the value associated with a function/variant iterator
+
+Input parameters:
+
+* `obj_handle` Object handle to query
+
+Output: Data associated with a function/variant iterator
+
+Field | Description
+---|---
+`id`| Internal ID of the function/variant
+`name`| Descriptive name of the function/variant
+`amd_id_0` |
| Subfield | Description |
| `memory_type` | Memory type |
| `temp_metric` | Temperature metric |
| `evnt_type` | Event type |
| `evnt_group` | Event group |
| `clk_type` | Clock type |
| `fw_block` | Firmware block |
| `gpu_block_type` | GPU block type |
+
+Exceptions that can be thrown by `amdsmi_func_iter_value_get` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ obj_handle = amdsmi_dev_supported_func_iterator_open(device)
+ value = amdsmi_func_iter_value_get(obj_handle)
+ print(value)
+ amdsmi_dev_supported_func_iterator_close(obj_handle)
+except AmdSmiException as e:
+ print(e)
+```
+
+## amdsmi_dev_pci_bandwidth_set
+Description: Control the set of allowed PCIe bandwidths that can be used
+
+Input parameters:
+* `device_handle` handle for the given device
+* `bw_bitmask` A bitmask indicating the indices of the bandwidths that are
+to be enabled (1) and disabled (0)
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_pci_bandwidth_set` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ amdsmi_dev_pci_bandwidth_set(device, 0)
+except AmdSmiException as e:
+ print(e)
+```
+## amdsmi_dev_power_cap_set
+Description: Set the power cap value
+
+Input parameters:
+* `device_handle` handle for the given device
+* `sensor_ind` a 0-based sensor index. Normally, this will be 0. If a
+device has more than one sensor, it could be greater than 0
+* `cap` int that indicates the desired power cap, in microwatts
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_power_cap_set` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ power_cap = 250 * 1000000
+ amdsmi_dev_power_cap_set(device, 0, power_cap)
+except AmdSmiException as e:
+ print(e)
+```
+## amdsmi_dev_power_profile_set
+Description: Set the power profile
+
+Input parameters:
+* `device_handle` handle for the given device
+* `reserved` Not currently used, set to 0
+* `profile` a amdsmi_power_profile_preset_masks_t that hold the mask of
+the desired new power profile
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_power_profile_set` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ profile = ...
+ amdsmi_dev_power_profile_set(device, 0, profile)
+except AmdSmiException as e:
+ print(e)
+```
+## amdsmi_dev_clk_range_set
+Description: This function sets the clock range information
+
+Input parameters:
+* `device_handle` handle for the given device
+* `min_clk_value` minimum clock value for desired clock range
+* `max_clk_value` maximum clock value for desired clock range
+* `clk_type`AMDSMI_CLK_TYPE_SYS | AMDSMI_CLK_TYPE_MEM range type
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_clk_range_set` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ amdsmi_dev_clk_range_set(device, 0, 1000, AmdSmiClockType.AMDSMI_CLK_TYPE_SYS)
+except AmdSmiException as e:
+ print(e)
+```
+## amdsmi_dev_od_clk_info_set
+Description: This function sets the clock frequency information
+
+Input parameters:
+* `device_handle` handle for the given device
+* `level` AMDSMI_FREQ_IND_MIN|AMDSMI_FREQ_IND_MAX to set the minimum (0)
+or maximum (1) speed
+* `clk_value` value to apply to the clock range
+* `clk_type` AMDSMI_CLK_TYPE_SYS | AMDSMI_CLK_TYPE_MEM range type
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_od_clk_info_set` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ amdsmi_dev_od_clk_info_set(
+ device,
+ AmdSmiFreqInd.AMDSMI_FREQ_IND_MAX,
+ 1000,
+ AmdSmiClockType.AMDSMI_CLK_TYPE_SYS
+ )
+except AmdSmiException as e:
+ print(e)
+```
+## amdsmi_dev_od_volt_info_set
+Description: This function sets 1 of the 3 voltage curve points
+
+Input parameters:
+* `device_handle` handle for the given device
+* `vpoint` voltage point [0|1|2] on the voltage curve
+* `clk_value` clock value component of voltage curve point
+* `volt_value` voltage value component of voltage curve point
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_od_volt_info_set` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ amdsmi_dev_od_volt_info_set(device, 1, 1000, 980)
+except AmdSmiException as e:
+ print(e)
+```
+## amdsmi_dev_perf_level_set_v1
+Description: Set the PowerPlay performance level associated with the device
+with provided device handle with the provided value
+
+Input parameters:
+* `device_handle` handle for the given device
+* `perf_lvl` the value to which the performance level should be set
+
+Output: None
+
+Exceptions that can be thrown by `amdsmi_dev_perf_level_set_v1` function:
+* `AmdSmiLibraryException`
+* `AmdSmiRetryException`
+* `AmdSmiParameterException`
+
+Example:
+```python
+try:
+ devices = amdsmi_get_device_handles()
+ if len(devices) == 0:
+ print("No GPUs on machine")
+ else:
+ for device in devices:
+ amdsmi_dev_perf_level_set_v1(device, AmdSmiDevPerfLevel.AMDSMI_DEV_PERF_LEVEL_HIGH)
+except AmdSmiException as e:
+ print(e)
+```
\ No newline at end of file
diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py
index 81ed597e7e..4a2c7855a2 100644
--- a/projects/amdsmi/py-interface/__init__.py
+++ b/projects/amdsmi/py-interface/__init__.py
@@ -71,6 +71,23 @@ from .amdsmi_interface import amdsmi_get_board_info
# # Ras Information
from .amdsmi_interface import amdsmi_get_ras_block_features_enabled
+# # Supported Function Checks
+from .amdsmi_interface import amdsmi_dev_supported_func_iterator_open
+from .amdsmi_interface import amdsmi_dev_supported_variant_iterator_open
+from .amdsmi_interface import amdsmi_dev_supported_func_iterator_close
+from .amdsmi_interface import amdsmi_func_iter_next
+from .amdsmi_interface import amdsmi_func_iter_value_get
+
+# # Unsupported Functions In Virtual Environment
+from .amdsmi_interface import amdsmi_dev_pci_bandwidth_set
+from .amdsmi_interface import amdsmi_dev_power_cap_set
+from .amdsmi_interface import amdsmi_dev_power_profile_set
+from .amdsmi_interface import amdsmi_dev_clk_range_set
+from .amdsmi_interface import amdsmi_dev_od_clk_info_set
+from .amdsmi_interface import amdsmi_dev_od_volt_info_set
+from .amdsmi_interface import amdsmi_dev_perf_level_set_v1
+
+
# # Events
# from .smi_interface import EventListen
diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py
index ab09fb8ce3..90c930a24c 100644
--- a/projects/amdsmi/py-interface/amdsmi_interface.py
+++ b/projects/amdsmi/py-interface/amdsmi_interface.py
@@ -405,9 +405,7 @@ def _amdsmi_get_socket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]:
socket_count = ctypes.c_uint32(0)
null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_socket_handle)()
_check_res(
- amdsmi_wrapper.amdsmi_get_socket_handles(
- ctypes.byref(socket_count), null_ptr
- )
+ amdsmi_wrapper.amdsmi_get_socket_handles(ctypes.byref(socket_count), null_ptr)
)
socket_handles = (amdsmi_wrapper.amdsmi_socket_handle * socket_count.value)()
_check_res(
@@ -1026,3 +1024,259 @@ def amdsmi_get_device_handle_from_bdf(
)
return device_handle
+
+
+def amdsmi_dev_supported_func_iterator_open(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle,
+) -> amdsmi_wrapper.amdsmi_func_id_iter_handle_t:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ obj_handle = amdsmi_wrapper.amdsmi_func_id_iter_handle_t()
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_supported_func_iterator_open(
+ device_handle, ctypes.byref(obj_handle)
+ )
+ )
+
+ return obj_handle
+
+
+def amdsmi_dev_supported_variant_iterator_open(
+ obj_handle: amdsmi_wrapper.amdsmi_func_id_iter_handle_t,
+) -> amdsmi_wrapper.amdsmi_func_id_iter_handle_t:
+ if not isinstance(obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t):
+ raise AmdSmiParameterException(
+ obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t
+ )
+
+ var_iter = amdsmi_wrapper.amdsmi_func_id_iter_handle_t()
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_supported_variant_iterator_open(
+ obj_handle, ctypes.byref(var_iter)
+ )
+ )
+
+ return var_iter
+
+
+def amdsmi_dev_supported_func_iterator_close(
+ obj_handle: amdsmi_wrapper.amdsmi_func_id_iter_handle_t,
+) -> None:
+ if not isinstance(obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t):
+ raise AmdSmiParameterException(
+ obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t
+ )
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_supported_func_iterator_close(
+ obj_handle, ctypes.byref(obj_handle)
+ )
+ )
+
+
+def amdsmi_func_iter_next(
+ obj_handle: amdsmi_wrapper.amdsmi_func_id_iter_handle_t,
+) -> amdsmi_wrapper.amdsmi_func_id_iter_handle_t:
+ if not isinstance(obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t):
+ raise AmdSmiParameterException(
+ obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t
+ )
+
+ _check_res(amdsmi_wrapper.amdsmi_func_iter_next(obj_handle))
+
+ return obj_handle
+
+
+def amdsmi_func_iter_value_get(
+ obj_handle: amdsmi_wrapper.amdsmi_func_id_iter_handle_t,
+) -> amdsmi_wrapper.amdsmi_func_id_value_t:
+ if not isinstance(obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t):
+ raise AmdSmiParameterException(
+ obj_handle, amdsmi_wrapper.amdsmi_func_id_iter_handle_t
+ )
+
+ value = amdsmi_wrapper.amdsmi_func_id_value_t()
+ _check_res(
+ amdsmi_wrapper.amdsmi_func_iter_value_get(obj_handle, ctypes.byref(value))
+ )
+
+ return {
+ "id": value.id,
+ "name": amdsmi_wrapper.string_cast(value.name),
+ "amd_id_0": {
+ "memory_type": value.amd_id_0.memory_type,
+ "temp_metric": value.amd_id_0.temp_metric,
+ "evnt_type": value.amd_id_0.evnt_type,
+ "evnt_group": value.amd_id_0.evnt_group,
+ "clk_type": value.amd_id_0.clk_type,
+ "fw_block": value.amd_id_0.fw_block,
+ "gpu_block_type": value.amd_id_0.gpu_block_type,
+ },
+ }
+
+
+def amdsmi_dev_pci_bandwidth_set(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle, bitmask: int
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(bitmask, int):
+ raise AmdSmiParameterException(bitmask, int)
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_pci_bandwidth_set(
+ device_handle, ctypes.c_uint64(bitmask)
+ )
+ )
+
+
+def amdsmi_dev_power_cap_set(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle, sensor_ind: int, cap: int
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(sensor_ind, int):
+ raise AmdSmiParameterException(sensor_ind, int)
+
+ if not isinstance(cap, int):
+ raise AmdSmiParameterException(cap, int)
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_power_cap_set(
+ device_handle, ctypes.c_uint32(sensor_ind), ctypes.c_uint64(cap)
+ )
+ )
+
+
+def amdsmi_dev_power_profile_set(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle,
+ reserved: int,
+ profile: AmdSmiPowerProfilePresetMasks,
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(reserved, int):
+ raise AmdSmiParameterException(reserved, int)
+
+ if not isinstance(profile, AmdSmiPowerProfilePresetMasks):
+ raise AmdSmiParameterException(profile, AmdSmiPowerProfilePresetMasks)
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_power_profile_set(
+ device_handle, ctypes.c_uint32(reserved), profile
+ )
+ )
+
+
+def amdsmi_dev_clk_range_set(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle,
+ min_clk_value: int,
+ max_clk_value: int,
+ clk_type: AmdSmiClockType,
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(min_clk_value, int):
+ raise AmdSmiParameterException(min_clk_value, int)
+
+ if not isinstance(max_clk_value, int):
+ raise AmdSmiParameterException(min_clk_value, int)
+
+ if not isinstance(clk_type, AmdSmiClockType):
+ raise AmdSmiParameterException(clk_type, AmdSmiClockType)
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_clk_range_set(
+ device_handle,
+ ctypes.c_uint64(min_clk_value),
+ ctypes.c_uint64(max_clk_value),
+ clk_type,
+ )
+ )
+
+
+def amdsmi_dev_od_clk_info_set(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle,
+ level: AmdSmiFreqInd,
+ value: int,
+ clk_type: AmdSmiClockType,
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(level, AmdSmiFreqInd):
+ raise AmdSmiParameterException(level, AmdSmiFreqInd)
+
+ if not isinstance(value, int):
+ raise AmdSmiParameterException(value, int)
+
+ if not isinstance(clk_type, AmdSmiClockType):
+ raise AmdSmiParameterException(clk_type, AmdSmiClockType)
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_od_clk_info_set(
+ device_handle, level, ctypes.c_uint64(value), clk_type
+ )
+ )
+
+
+def amdsmi_dev_od_volt_info_set(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle,
+ vpoint: int,
+ clk_value: int,
+ volt_value: int,
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(vpoint, int):
+ raise AmdSmiParameterException(vpoint, int)
+
+ if not isinstance(clk_value, int):
+ raise AmdSmiParameterException(clk_value, int)
+
+ if not isinstance(volt_value, int):
+ raise AmdSmiParameterException(volt_value, int)
+
+ _check_res(
+ amdsmi_wrapper.amdsmi_dev_od_volt_info_set(
+ device_handle,
+ ctypes.c_uint32(vpoint),
+ ctypes.c_uint64(clk_value),
+ ctypes.c_uint64(volt_value),
+ )
+ )
+
+
+def amdsmi_dev_perf_level_set_v1(
+ device_handle: amdsmi_wrapper.amdsmi_device_handle,
+ perf_lvl: AmdSmiDevPerfLevel,
+) -> None:
+ if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle):
+ raise AmdSmiParameterException(
+ device_handle, amdsmi_wrapper.amdsmi_device_handle
+ )
+
+ if not isinstance(perf_lvl, AmdSmiDevPerfLevel):
+ raise AmdSmiParameterException(perf_lvl, AmdSmiDevPerfLevel)
+
+ _check_res(amdsmi_wrapper.amdsmi_dev_perf_level_set_v1(device_handle, perf_lvl))