diff --git a/projects/amdsmi/example/amd_smi_drm_example.cc b/projects/amdsmi/example/amd_smi_drm_example.cc index bfc93e5692..f885704578 100644 --- a/projects/amdsmi/example/amd_smi_drm_example.cc +++ b/projects/amdsmi/example/amd_smi_drm_example.cc @@ -129,7 +129,7 @@ int main() { // Get handle from BDF amdsmi_device_handle dev_handle; - ret = amdsmi_get_device_handle_from_bdf(bdf, &device_handles[0], device_count, &dev_handle); + ret = amdsmi_get_device_handle_from_bdf(bdf, &dev_handle); CHK_AMDSMI_RET(ret) // Get ASIC info diff --git a/projects/amdsmi/include/amd_smi/amd_smi.h b/projects/amdsmi/include/amd_smi/amd_smi.h index e17277c422..1980593f7a 100644 --- a/projects/amdsmi/include/amd_smi/amd_smi.h +++ b/projects/amdsmi/include/amd_smi/amd_smi.h @@ -1291,19 +1291,12 @@ amdsmi_status_t amdsmi_get_device_type(amdsmi_device_handle device_handle, * * @param[in] bdf The bdf to match with corresponding device handle. * - * @param[in] device_handles a list of devices handles on the socket. - * - * @param[in] device_count a count of handles in device_handles. - * * @param[out] device_handle device handle with the matching bdf. * * @retval ::AMDSMI_STATUS_SUCCESS call was successful * @retval ::AMDSMI_STATUS_INVAL the provided arguments are not valid */ -amdsmi_status_t amdsmi_get_device_handle_from_bdf(amdsmi_bdf_t bdf, - amdsmi_device_handle* device_handles, - uint32_t device_count, - amdsmi_device_handle* device_handle); +amdsmi_status_t amdsmi_get_device_handle_from_bdf(amdsmi_bdf_t bdf, amdsmi_device_handle* device_handle); /** @} */ // end of Discovery diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 27c5032dd9..0ec73700c0 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -20,6 +20,7 @@ # import ctypes +import re from typing import Union, Any, Dict, List, Tuple from enum import IntEnum from collections.abc import Iterable @@ -456,6 +457,7 @@ def _format_bdf(amdsmi_bdf: amdsmi_wrapper.amdsmi_bdf_t) -> str: return domain + ":" + bus + ":" + device + "." + function + def _check_res(ret_code) -> None: """ Wrapper for amdsmi function calls. Checks the status returned @@ -478,6 +480,33 @@ def _check_res(ret_code) -> None: raise AmdSmiLibraryException(ret_code) +def _parse_bdf(bdf): + if bdf is None: + return None + extended_regex = re.compile( + r'^([0-9a-fA-F]{4}):([0-9a-fA-F]{2}):([0-1][0-9a-fA-F])\.([0-7])$') + if extended_regex.match(bdf) is None: + simple_regex = re.compile( + r'^([0-9a-fA-F]{2}):([0-1][0-9a-fA-F])\.([0-7])$') + if simple_regex.match(bdf) is None: + return None + else: + return [0] + [int(x, 16) for x in simple_regex.match(bdf).groups()] + else: + return [int(x, 16) for x in extended_regex.match(bdf).groups()] + + +def _make_amdsmi_bdf_from_list(bdf): + if len(bdf) != 4: + return None + amdsmi_bdf = amdsmi_wrapper.amdsmi_bdf() + amdsmi_bdf.amdsmi_bdf_0.function_number = bdf[3] + amdsmi_bdf.amdsmi_bdf_0.device_number = bdf[2] + amdsmi_bdf.amdsmi_bdf_0.bus_number = bdf[1] + amdsmi_bdf.amdsmi_bdf_0.domain_number = bdf[0] + return amdsmi_bdf + + def amdsmi_get_socket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: """ Function that gets socket handles. Wraps the same named function call. @@ -1114,36 +1143,15 @@ def amdsmi_get_pcie_link_caps( return {"pcie_lanes": pcie_info.pcie_lanes, "pcie_speed": pcie_info.pcie_speed} -def amdsmi_get_device_handle_from_bdf( - bdf_info: Union[amdsmi_wrapper.amdsmi_bdf_t, str], -) -> amdsmi_wrapper.amdsmi_device_handle: - if not isinstance(bdf_info, amdsmi_wrapper.amdsmi_bdf_t) and not isinstance( - bdf_info, str - ): - raise AmdSmiParameterException(bdf_info, amdsmi_wrapper.amdsmi_bdf_t) - if isinstance(bdf_info, str): - bdf = amdsmi_wrapper.amdsmi_bdf_t() - bdf.amdsmi_bdf_0.domain_number = int(bdf_info[:4]) - bdf.amdsmi_bdf_0.bus_number = int(bdf_info[5:7]) - bdf.amdsmi_bdf_0.device_number = int(bdf_info[8:10]) - bdf.amdsmi_bdf_0.function_number = int(bdf_info[11]) - bdf_info = bdf - - device_handles_pylist = amdsmi_get_device_handles() - device_handles = (amdsmi_wrapper.amdsmi_device_handle * len(device_handles_pylist))( - *device_handles_pylist - ) +def amdsmi_get_device_handle_from_bdf(bdf): + bdf = _parse_bdf(bdf) + if bdf is None: + raise AmdSmiBdfFormatException(bdf) + amdsmi_bdf = _make_amdsmi_bdf_from_list(bdf) device_handle = amdsmi_wrapper.amdsmi_device_handle() - _check_res( - amdsmi_wrapper.amdsmi_get_device_handle_from_bdf( - bdf_info, - device_handles, - ctypes.c_uint32(len(device_handles_pylist)), - ctypes.byref(device_handle), - ) - ) - + _check_res(amdsmi_wrapper.amdsmi_get_device_handle_from_bdf( + amdsmi_bdf, ctypes.byref(device_handle))) return device_handle diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 1224c4b242..833eba8d6d 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -1760,7 +1760,7 @@ _lib.amdsmi_get_device_type.argtypes = [amdsmi_device_handle,POINTER(device_type _lib.amdsmi_get_device_type.restype = amdsmi_status_t amdsmi_get_device_type = _lib.amdsmi_get_device_type -_lib.amdsmi_get_device_handle_from_bdf.argtypes = [amdsmi_bdf_t,POINTER(amdsmi_device_handle),c_uint32,POINTER(amdsmi_device_handle)] +_lib.amdsmi_get_device_handle_from_bdf.argtypes = [amdsmi_bdf_t,POINTER(amdsmi_device_handle)] _lib.amdsmi_get_device_handle_from_bdf.restype = amdsmi_status_t amdsmi_get_device_handle_from_bdf = _lib.amdsmi_get_device_handle_from_bdf diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index db228dd0dc..95757c476e 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -1831,28 +1831,52 @@ amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_device_handle dev, amdsmi_pcie_ } amdsmi_status_t amdsmi_get_device_handle_from_bdf(amdsmi_bdf_t bdf, - amdsmi_device_handle* device_handles, - uint32_t device_count, - amdsmi_device_handle* device_handle){ - if (device_handles == nullptr) { + amdsmi_device_handle* device_handle) +{ + amdsmi_status_t status; + uint32_t socket_count = 0; + + uint32_t device_count = AMDSMI_MAX_DEVICES; + amdsmi_device_handle devs[AMDSMI_MAX_DEVICES]; + + if (device_handle == nullptr) { return AMDSMI_STATUS_INVAL; } - amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; - for(auto idx = 0; idx < device_count; idx++) { - amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; - status = get_gpu_device_from_handle(device_handles[idx], &gpu_device); + status = amdsmi_get_socket_handles(&socket_count, nullptr); + if (status != AMDSMI_STATUS_SUCCESS) { + return status; + } + + amdsmi_socket_handle sockets[socket_count]; + + status = amdsmi_get_socket_handles(&socket_count, &sockets[0]); + if (status != AMDSMI_STATUS_SUCCESS) { + return status; + } + + for (unsigned int i = 0; i < socket_count; i++) { + status = amdsmi_get_device_handles(sockets[i], &device_count, devs); if (status != AMDSMI_STATUS_SUCCESS) { return status; } - amdsmi_bdf_t found_bdf = gpu_device->get_bdf(); - if (bdf.bus_number == found_bdf.bus_number && - bdf.device_number == found_bdf.device_number && - bdf.domain_number == found_bdf.domain_number && - bdf.function_number == found_bdf.function_number) { - *device_handle = device_handles[idx]; - return AMDSMI_STATUS_SUCCESS; + + for (auto idx = 0; idx < device_count; idx++) { + amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; + status = get_gpu_device_from_handle(devs[idx], &gpu_device); + if (status != AMDSMI_STATUS_SUCCESS) { + return status; } + amdsmi_bdf_t found_bdf = gpu_device->get_bdf(); + if (bdf.bus_number == found_bdf.bus_number && + bdf.device_number == found_bdf.device_number && + bdf.domain_number == found_bdf.domain_number && + bdf.function_number == found_bdf.function_number) { + *device_handle = devs[idx]; + return AMDSMI_STATUS_SUCCESS; + } + } } + return AMDSMI_STATUS_API_FAILED; }