diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index f5fd8de096..12086b0604 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -1389,6 +1389,8 @@ try: except AmdSmiException as e: print(e) ``` + + ## amdsmi_dev_clk_range_set Description: This function sets the clock range information @@ -1417,6 +1419,286 @@ try: except AmdSmiException as e: print(e) ``` + + +## amdsmi_dev_pci_id_get +Description: Get the unique PCI device identifier associated for a device + +Input parameters: + +* `device_handle` device which to query + +Output: device bdf +The format of bdfid will be as follows: + +BDFID = ((DOMAIN & 0xffffffff) << 32) | ((BUS & 0xff) << 8) | + ((DEVICE & 0x1f) <<3 ) | (FUNCTION & 0x7) + +| Name | Field | +---------- | ------- | +| Domain | [64:32] | +| Reserved | [31:16] | +| Bus | [15: 8] | +| Device | [ 7: 3] | +| Function | [ 2: 0] | + + +Exceptions that can be thrown by `amdsmi_dev_pci_id_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + bdfid = amdsmi_dev_pci_id_get(device) + print(bdfid) +except AmdSmiException as e: + print(e) +``` + + +## amdsmi_dev_pci_bandwidth_get +Description: Get the list of possible PCIe bandwidths that are available. + +Input parameters: + +* `device_handle` device which to query + +Output: Dictionary with the possible T/s values and associated number of lanes + +Field | Content +---|--- +`transfer_rate` | transfer_rate dictionary +`lanes` | lanes + + +transfer_rate dictionary + +Field | Content +---|--- +`num_supported` | num_supported +`current` | current +`frequency` | list of frequency + +Exceptions that can be thrown by `amdsmi_dev_pci_bandwidth_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + bandwidth = amdsmi_dev_pci_bandwidth_get(device) + print(bandwidth) +except AmdSmiException as e: + print(e) +``` + +## amdsmi_dev_pci_throughput_get +Description: Get PCIe traffic information + +Input parameters: + +* `device_handle` device which to query + +Output: Dictionary with the fields + +Field | Content +---|--- +`sent` | number of bytes sent in 1 second +`received` | the number of bytes received +`max_pkt_sz` | maximum packet size + +Exceptions that can be thrown by `amdsmi_dev_pci_throughput_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + pci = amdsmi_dev_pci_throughput_get(device) + print(pci) +except AmdSmiException as e: + print(e) +``` + +## amdsmi_dev_pci_replay_counter_get + +Description: Get PCIe replay counter + +Input parameters: + +* `device_handle` device which to query + +Output: counter value +The sum of the NAK's received and generated by the GPU + +Exceptions that can be thrown by `amdsmi_dev_pci_replay_counter_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + counter = amdsmi_dev_pci_replay_counter_get(device) + print(counter) +except AmdSmiException as e: + print(e) +``` + +## amdsmi_topo_numa_affinity_get + +Description: Get the NUMA node associated with a device + +Input parameters: + +* `device_handle` device which to query + +Output: NUMA node value + +Exceptions that can be thrown by `amdsmi_topo_numa_affinity_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + numa_node = amdsmi_topo_numa_affinity_get(device) + print(numa_node) +except AmdSmiException as e: + print(e) +``` + +## amdsmi_dev_power_ave_get + +Description: Get the average power consumption of the device + +Input parameters: + +* `device_handle` device which to query +* `sensor_id` a 0-based sensor index. Normally, this will be 0. +If a device has more than one sensor, it could be greater than 0. + +Output: the average power consumption + +Exceptions that can be thrown by `amdsmi_dev_power_ave_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + power = amdsmi_dev_power_ave_get(device) + print(power) +except AmdSmiException as e: + print(e) +``` + + +## amdsmi_dev_energy_count_get + +Description: Get the energy accumulator counter of the device. + +Input parameters: + +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Content +---|--- +`power` | power +`counter_resolution` | counter resolution +`timestamp` | timestamp + +Exceptions that can be thrown by `amdsmi_dev_energy_count_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + power = amdsmi_dev_energy_count_get(device) + print(power) +except AmdSmiException as e: + print(e) +``` + + +## amdsmi_dev_memory_total_get + +Description: Get the total amount of memory that exists + +Input parameters: + +* `device_handle` device which to query +* `mem_type` enum AmdSmiMemoryType + +Output: total amount of memory + +Exceptions that can be thrown by `amdsmi_dev_memory_total_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + memory = amdsmi_dev_memory_total_get(device) + print(memory) +except AmdSmiException as e: + print(e) +``` + + + + ## amdsmi_dev_od_clk_info_set Description: This function sets the clock frequency information @@ -1451,6 +1733,39 @@ try: except AmdSmiException as e: print(e) ``` + + +## amdsmi_dev_memory_usage_get + +Description: Get the current memory usage + +Input parameters: + +* `device_handle` device which to query +* `mem_type` enum AmdSmiMemoryType + +Output: the amount of memory currently being used + +Exceptions that can be thrown by `amdsmi_dev_memory_usage_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + memory = amdsmi_dev_memory_usage_get(device) + print(memory) +except AmdSmiException as e: + print(e) +``` + + ## amdsmi_dev_od_volt_info_set Description: This function sets 1 of the 3 voltage curve points @@ -1479,6 +1794,39 @@ try: except AmdSmiException as e: print(e) ``` + + +## amdsmi_dev_memory_busy_percent_get + +Description: Get percentage of time any device memory is being used + +Input parameters: + +* `device_handle` device which to query + +Output: percentage of time that any device memory is being used for the specified device. + +Exceptions that can be thrown by `amdsmi_dev_memory_busy_percent_get` function: +* `AmdSmiLibraryException` +* `AmdSmiRetryException` +* `AmdSmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + busy_percent = amdsmi_dev_memory_busy_percent_get(device) + print(busy_percent) +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 diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py index 5b61f15053..999dbb8c14 100644 --- a/projects/amdsmi/py-interface/__init__.py +++ b/projects/amdsmi/py-interface/__init__.py @@ -136,6 +136,23 @@ from .amdsmi_interface import amdsmi_compute_process_gpus_get from .amdsmi_interface import amdsmi_dev_xgmi_error_status from .amdsmi_interface import amdsmi_dev_xgmi_error_reset +# # PCIE information +from .amdsmi_interface import amdsmi_dev_pci_id_get +from .amdsmi_interface import amdsmi_dev_pci_bandwidth_get +from .amdsmi_interface import amdsmi_dev_pci_throughput_get +from .amdsmi_interface import amdsmi_dev_pci_replay_counter_get +from .amdsmi_interface import amdsmi_topo_numa_affinity_get + +# # Power information +from .amdsmi_interface import amdsmi_dev_power_ave_get +from .amdsmi_interface import amdsmi_dev_energy_count_get + +# # Memory information +from .amdsmi_interface import amdsmi_dev_memory_total_get +from .amdsmi_interface import amdsmi_dev_memory_usage_get +from .amdsmi_interface import amdsmi_dev_memory_busy_percent_get +from .amdsmi_interface import amdsmi_dev_memory_reserved_pages_get + # # Events from .amdsmi_interface import AmdSmiEventReader diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 6e0374b05a..5f222fc6cf 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -22,6 +22,7 @@ import ctypes from typing import Union, Any, Dict, List, Tuple from enum import IntEnum +from collections.abc import Iterable from . import amdsmi_wrapper from .amdsmi_exception import * @@ -311,23 +312,24 @@ class AmdSmiEventReader: device_handle, amdsmi_wrapper.amdsmi_device_handle ) if not isinstance(event_types, Iterable): - raise AmdSmiParameterException(event_types, Iterable) + raise AmdSmiParameterException( + event_types, Iterable + ) for event_type in event_types: if not isinstance(event_type, AmdSmiEvtNotificationType): - raise AmdSmiParameterException(event_type, AmdSmiEvtNotificationType) + raise AmdSmiParameterException( + event_type, AmdSmiEvtNotificationType + ) self.device_handle = device_handle mask = 0 for event_type in event_types: - mask |= 1 << (int(event_type) - 1) + mask |= (1 << (int(event_type) - 1)) _check_res(amdsmi_wrapper.amdsmi_event_notification_init(device_handle)) - _check_res( - amdsmi_wrapper.amdsmi_event_notification_mask_set( - device_handle, ctypes.c_uint64(mask) - ) - ) + _check_res(amdsmi_wrapper.amdsmi_event_notification_mask_set( + device_handle, ctypes.c_uint64(mask))) def read(self, timestamp, num_elem=10): self.event_info = (amdsmi_wrapper.amdsmi_evt_notification_data_t * num_elem)() @@ -357,7 +359,8 @@ class AmdSmiEventReader: return ret def stop(self): - _check_res(amdsmi_wrapper.amdsmi_event_notification_stop(self.device_handle)) + _check_res(amdsmi_wrapper.amdsmi_event_notification_stop( + self.device_handle)) def __enter__(self): return self @@ -383,14 +386,19 @@ def _parse_fw_info(fw_info: amdsmi_wrapper.amdsmi_fw_info_t) -> Dict[str, Any]: `dict`: All of the firmware info formatted into a dictionary. """ if not isinstance(fw_info, amdsmi_wrapper.amdsmi_fw_info_t): - raise AmdSmiParameterException(fw_info, amdsmi_wrapper.amdsmi_fw_info_t) + raise AmdSmiParameterException( + fw_info, amdsmi_wrapper.amdsmi_fw_info_t) formatted_fw_info = dict() + raise AmdSmiParameterException( + fw_info, amdsmi_wrapper.amdsmi_fw_info_t) + formatted_fw_info = {"num_fw_info": fw_info.num_fw_info} for index, value in amdsmi_wrapper.amdsmi_fw_block__enumvalues.items(): if value == "FW_ID_FIRST": value = "FW_ID_SMU" if value == "FW_ID__MAX": continue - formatted_fw_info.update({value: fw_info.fw_info_list[index - 1].fw_version}) + formatted_fw_info.update( + {value: fw_info.fw_info_list[index - 1].fw_version}) return formatted_fw_info @@ -408,10 +416,12 @@ def _format_bad_page_info(bad_page_info, bad_page_count: ctypes.c_uint32) -> Lis `list`: List containing formatted bad pages. """ if not isinstance( - bad_page_info, ctypes.POINTER(amdsmi_wrapper.amdsmi_retired_page_record_t) + bad_page_info, ctypes.POINTER( + amdsmi_wrapper.amdsmi_retired_page_record_t) ): raise AmdSmiParameterException( - bad_page_info, ctypes.POINTER(amdsmi_wrapper.amdsmi_retired_page_record_t) + bad_page_info, ctypes.POINTER( + amdsmi_wrapper.amdsmi_retired_page_record_t) ) table_records = list() @@ -481,9 +491,11 @@ 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)() + socket_handles = (amdsmi_wrapper.amdsmi_socket_handle * + socket_count.value)() _check_res( amdsmi_wrapper.amdsmi_get_socket_handles( ctypes.byref(socket_count), socket_handles @@ -510,7 +522,8 @@ def amdsmi_get_device_handles() -> List[amdsmi_wrapper.amdsmi_device_handle]: null_ptr, ) ) - device_handles = (amdsmi_wrapper.amdsmi_device_handle * device_count.value)() + device_handles = ( + amdsmi_wrapper.amdsmi_device_handle * device_count.value)() _check_res( amdsmi_wrapper.amdsmi_get_device_handles( socket, @@ -548,7 +561,8 @@ def amdsmi_get_device_type( dev_type = amdsmi_wrapper.device_type_t() _check_res( - amdsmi_wrapper.amdsmi_get_device_type(device_handle, ctypes.byref(dev_type)) + amdsmi_wrapper.amdsmi_get_device_type( + device_handle, ctypes.byref(dev_type)) ) return dev_type @@ -561,7 +575,8 @@ def amdsmi_get_device_bdf(device_handle: amdsmi_wrapper.amdsmi_device_handle) -> bdf_info = amdsmi_wrapper.amdsmi_bdf_t() _check_res( - amdsmi_wrapper.amdsmi_get_device_bdf(device_handle, ctypes.byref(bdf_info)) + amdsmi_wrapper.amdsmi_get_device_bdf( + device_handle, ctypes.byref(bdf_info)) ) return _format_bdf(bdf_info) @@ -577,7 +592,8 @@ def amdsmi_get_asic_info( asic_info = amdsmi_wrapper.amdsmi_asic_info_t() _check_res( - amdsmi_wrapper.amdsmi_get_asic_info(device_handle, ctypes.byref(asic_info)) + amdsmi_wrapper.amdsmi_get_asic_info( + device_handle, ctypes.byref(asic_info)) ) return { @@ -618,7 +634,8 @@ def amdsmi_get_caps_info( gpu_caps = amdsmi_wrapper.amdsmi_gpu_caps_t() _check_res( - amdsmi_wrapper.amdsmi_get_caps_info(device_handle, ctypes.byref(gpu_caps)) + amdsmi_wrapper.amdsmi_get_caps_info( + device_handle, ctypes.byref(gpu_caps)) ) return { @@ -644,7 +661,8 @@ def amdsmi_get_vbios_info( vbios_info = amdsmi_wrapper.amdsmi_vbios_info_t() _check_res( - amdsmi_wrapper.amdsmi_get_vbios_info(device_handle, ctypes.byref(vbios_info)) + amdsmi_wrapper.amdsmi_get_vbios_info( + device_handle, ctypes.byref(vbios_info)) ) return { @@ -735,7 +753,8 @@ def amdsmi_get_power_limit( power_limit = amdsmi_wrapper.amdsmi_power_limit_t() _check_res( - amdsmi_wrapper.amdsmi_get_power_limit(device_handle, ctypes.byref(power_limit)) + amdsmi_wrapper.amdsmi_get_power_limit( + device_handle, ctypes.byref(power_limit)) ) return {"limit": power_limit.limit} @@ -771,7 +790,8 @@ def amdsmi_get_bad_page_info( ) num_pages = ctypes.c_uint32() - retired_page_record = ctypes.POINTER(amdsmi_wrapper.amdsmi_retired_page_record_t)() + retired_page_record = ctypes.POINTER( + amdsmi_wrapper.amdsmi_retired_page_record_t)() _check_res( amdsmi_wrapper.amdsmi_get_bad_page_info( device_handle, ctypes.byref(num_pages), retired_page_record @@ -843,7 +863,8 @@ def amdsmi_get_board_info( board_info = amdsmi_wrapper.amdsmi_board_info_t() _check_res( - amdsmi_wrapper.amdsmi_get_board_info(device_handle, ctypes.byref(board_info)) + amdsmi_wrapper.amdsmi_get_board_info( + device_handle, ctypes.byref(board_info)) ) return { @@ -896,14 +917,16 @@ def amdsmi_get_process_list( ) max_processes = amdsmi_wrapper.c_uint32(0) - process_list = (amdsmi_wrapper.amdsmi_process_handle * max_processes.value)() + process_list = (amdsmi_wrapper.amdsmi_process_handle * + max_processes.value)() _check_res( amdsmi_wrapper.amdsmi_get_process_list( device_handle, process_list, ctypes.byref(max_processes) ) ) - process_list = (amdsmi_wrapper.amdsmi_process_handle * max_processes.value)() + process_list = (amdsmi_wrapper.amdsmi_process_handle * + max_processes.value)() _check_res( amdsmi_wrapper.amdsmi_get_process_list( device_handle, process_list, ctypes.byref(max_processes) @@ -1024,7 +1047,8 @@ def amdsmi_get_fw_info( ) fw_info = amdsmi_wrapper.amdsmi_fw_info_t() - _check_res(amdsmi_wrapper.amdsmi_get_fw_info(device_handle, ctypes.byref(fw_info))) + _check_res(amdsmi_wrapper.amdsmi_get_fw_info( + device_handle, ctypes.byref(fw_info))) return _parse_fw_info(fw_info) @@ -1039,7 +1063,8 @@ def amdsmi_get_vram_usage( vram_info = amdsmi_wrapper.amdsmi_vram_info_t() _check_res( - amdsmi_wrapper.amdsmi_get_vram_usage(device_handle, ctypes.byref(vram_info)) + amdsmi_wrapper.amdsmi_get_vram_usage( + device_handle, ctypes.byref(vram_info)) ) return {"vram_used": vram_info.vram_used, "vram_total": vram_info.vram_total} @@ -1073,7 +1098,8 @@ def amdsmi_get_pcie_link_caps( pcie_info = amdsmi_wrapper.amdsmi_pcie_info_t() _check_res( - amdsmi_wrapper.amdsmi_get_pcie_link_caps(device_handle, ctypes.byref(pcie_info)) + amdsmi_wrapper.amdsmi_get_pcie_link_caps( + device_handle, ctypes.byref(pcie_info)) ) return {"pcie_lanes": pcie_info.pcie_lanes, "pcie_speed": pcie_info.pcie_speed} @@ -1654,6 +1680,21 @@ def amdsmi_dev_supported_func_iterator_open( return obj_handle +def amdsmi_dev_pci_id_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + bdfid = ctypes.c_uint64() + _check_res( + amdsmi_wrapper.amdsmi_dev_pci_id_get( + device_handle, ctypes.byref(bdfid)) + ) + + return bdfid.value + + 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: @@ -1710,7 +1751,8 @@ def amdsmi_func_iter_value_get( value = amdsmi_wrapper.amdsmi_func_id_value_t() _check_res( - amdsmi_wrapper.amdsmi_func_iter_value_get(obj_handle, ctypes.byref(value)) + amdsmi_wrapper.amdsmi_func_iter_value_get( + obj_handle, ctypes.byref(value)) ) return { @@ -1746,6 +1788,89 @@ def amdsmi_dev_pci_bandwidth_set( ) +def _format_transfer_rate(transfer_rate): + return { + 'num_supported': transfer_rate.num_supported, + 'current': transfer_rate.current, + 'frequency': list(transfer_rate.frequency) + } + + +def amdsmi_dev_pci_bandwidth_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + bandwidth = amdsmi_wrapper.amdsmi_pcie_bandwidth_t() + + _check_res( + amdsmi_wrapper.amdsmi_dev_pci_bandwidth_get( + device_handle, ctypes.byref(bandwidth)) + ) + + transfer_rate = _format_transfer_rate(bandwidth.transfer_rate) + + return { + 'transfer_rate': transfer_rate, + 'lanes': list(bandwidth.lanes) + } + + +def amdsmi_dev_pci_throughput_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + sent = ctypes.c_uint64() + received = ctypes.c_uint64() + max_pkt_sz = ctypes.c_uint64() + + _check_res( + amdsmi_wrapper.amdsmi_dev_pci_throughput_get(device_handle, ctypes.byref( + sent), ctypes.byref(received), ctypes.byref(max_pkt_sz)) + ) + + return { + 'sent': sent.value, + 'received': received.value, + 'max_pkt_sz': max_pkt_sz.value + } + + +def amdsmi_dev_pci_replay_counter_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + counter = ctypes.c_uint64() + + _check_res( + amdsmi_wrapper.amdsmi_dev_pci_replay_counter_get( + device_handle, ctypes.byref(counter)) + ) + + return counter.value + + +def amdsmi_topo_numa_affinity_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + numa_node = ctypes.c_uint32() + + _check_res( + amdsmi_wrapper.amdsmi_topo_numa_affinity_get( + device_handle, ctypes.byref(numa_node)) + ) + + return numa_node.value + + def amdsmi_dev_power_cap_set( device_handle: amdsmi_wrapper.amdsmi_device_handle, sensor_ind: int, cap: int ) -> None: @@ -1767,6 +1892,22 @@ def amdsmi_dev_power_cap_set( ) +def amdsmi_dev_power_ave_get(device_handle: amdsmi_wrapper.amdsmi_device_handle, sensor_id: ctypes.c_uint32): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + power = ctypes.c_uint64() + + _check_res( + amdsmi_wrapper.amdsmi_dev_power_ave_get( + device_handle, sensor_id, ctypes.byref(power)) + ) + + return power.value + + def amdsmi_dev_power_profile_set( device_handle: amdsmi_wrapper.amdsmi_device_handle, reserved: int, @@ -1790,6 +1931,28 @@ def amdsmi_dev_power_profile_set( ) +def amdsmi_dev_energy_count_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + power = ctypes.c_uint64() + counter_resolution = ctypes.c_float() + timestamp = ctypes.c_uint64() + + _check_res( + amdsmi_wrapper.amdsmi_dev_energy_count_get(device_handle, ctypes.byref( + power), ctypes.byref(counter_resolution), ctypes.byref(timestamp)) + ) + + return { + 'power': power.value, + 'counter_resolution': counter_resolution.value, + 'timestamp': timestamp.value, + } + + def amdsmi_dev_clk_range_set( device_handle: amdsmi_wrapper.amdsmi_device_handle, min_clk_value: int, @@ -1820,6 +1983,27 @@ def amdsmi_dev_clk_range_set( ) +def amdsmi_dev_memory_total_get(device_handle: amdsmi_wrapper.amdsmi_device_handle, mem_type: AmdSmiMemoryType): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + if not isinstance(mem_type, AmdSmiMemoryType): + raise AmdSmiParameterException( + mem_type, AmdSmiMemoryType + ) + + total = ctypes.c_uint64() + + _check_res( + amdsmi_wrapper.amdsmi_dev_memory_total_get( + device_handle, mem_type, ctypes.byref(total)) + ) + + return total.value + + def amdsmi_dev_od_clk_info_set( device_handle: amdsmi_wrapper.amdsmi_device_handle, level: AmdSmiFreqInd, @@ -1847,6 +2031,27 @@ def amdsmi_dev_od_clk_info_set( ) +def amdsmi_dev_memory_usage_get(device_handle: amdsmi_wrapper.amdsmi_device_handle, mem_type: AmdSmiMemoryType): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + if not isinstance(mem_type, AmdSmiMemoryType): + raise AmdSmiParameterException( + mem_type, AmdSmiMemoryType + ) + + used = ctypes.c_uint64() + + _check_res( + amdsmi_wrapper.amdsmi_dev_memory_usage_get( + device_handle, mem_type, ctypes.byref(used)) + ) + + return used.value + + def amdsmi_dev_od_volt_info_set( device_handle: amdsmi_wrapper.amdsmi_device_handle, vpoint: int, @@ -1877,6 +2082,22 @@ def amdsmi_dev_od_volt_info_set( ) +def amdsmi_dev_memory_busy_percent_get(device_handle: amdsmi_wrapper.amdsmi_device_handle): + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + busy_percent = ctypes.c_uint32() + + _check_res( + amdsmi_wrapper.amdsmi_dev_memory_busy_percent_get( + device_handle, ctypes.byref(busy_percent)) + ) + + return busy_percent.value + + def amdsmi_dev_perf_level_set_v1( device_handle: amdsmi_wrapper.amdsmi_device_handle, perf_lvl: AmdSmiDevPerfLevel, @@ -1889,7 +2110,8 @@ def amdsmi_dev_perf_level_set_v1( 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)) + _check_res(amdsmi_wrapper.amdsmi_dev_perf_level_set_v1( + device_handle, perf_lvl)) def amdsmi_dev_fan_rpms_get( @@ -2450,3 +2672,29 @@ def amdsmi_dev_xgmi_error_reset( ) _check_res(amdsmi_wrapper.amdsmi_dev_xgmi_error_reset(device_handle)) + + +def amdsmi_dev_memory_reserved_pages_get( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Union[list, str]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + num_pages = ctypes.c_uint32() + retired_page_record = ctypes.POINTER( + amdsmi_wrapper.amdsmi_retired_page_record_t)() + _check_res( + amdsmi_wrapper.amdsmi_dev_memory_reserved_pages_get( + device_handle, ctypes.byref(num_pages), retired_page_record + ) + ) + + table_records = _format_bad_page_info(retired_page_record, num_pages) + if num_pages.value == 0: + return "No bad pages found." + else: + table_records = _format_bad_page_info(retired_page_record, num_pages) + + return table_records