From 8308ede9e830d28d020de6deffe9885a51d96aeb Mon Sep 17 00:00:00 2001 From: Khader Basha Shaik Date: Fri, 4 Oct 2024 12:20:02 +0000 Subject: [PATCH] amdsmi [CPU]: Add implementation to get cpu handles and core handles API - Update the API names, parameters to return cpu handles and core handles in the system. - Update the amdsmi_wrapper.py. - Update the amdsmi_interface.py to use the processor handles and core handles API. Change-Id: Ie24f62f345864f8b6773fdb3c6369993bca7e25b --- include/amd_smi/amdsmi.h | 49 +++++++------- py-interface/amdsmi_interface.py | 92 +++++++++----------------- py-interface/amdsmi_wrapper.py | 29 +++----- src/amd_smi/amd_smi.cc | 109 +++++++++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 105 deletions(-) diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index 0b11641daf..bf629275fd 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -1973,33 +1973,32 @@ amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count, #ifdef ENABLE_ESMI_LIB /** - * @brief Get the list of cpu socket handles in the system. + * @brief Get the list of cpu handles in the system. * * @platform{cpu_bm} * * @details Depends on AMDSMI_INIT_AMD_CPUS flag passed to ::amdsmi_init. - * The socket handles can be used to query the processor handles in that socket, which - * will be used in other APIs to get processor detail information. + * The processor handles can be used in other APIs to get processor detail information. * - * @param[in,out] socket_count As input, the value passed - * through this parameter is the number of ::amdsmi_cpusocket_handle that - * may be safely written to the memory pointed to by @p socket_handles. This is the - * limit on how many socket handles will be written to @p socket_handles. On return, @p - * socket_count will contain the number of socket handles written to @p socket_handles, - * or the number of socket handles that could have been written if enough memory had been + * @param[in,out] cpu_count As input, the value passed + * through this parameter is the number of ::amdsmi_processor_handle that + * may be safely written to the memory pointed to by @p processor_handles. This is the + * limit on how many processor handles will be written to @p processor_handles. On return, @p + * socket_count will contain the number of processor handles written to @p processor_handles, + * or the number of processor handles that could have been written if enough memory had been * provided. - * If @p socket_handles is NULL, as output, @p socket_count will contain - * how many sockets are available to read in the system. + * If @p processor_handles is NULL, as output, @p cpu_count will contain + * how many processors are available to read in the system. * * @param[in,out] socket_handles A pointer to a block of memory to which the - * ::amdsmi_cpusocket_handle values will be written. This value may be NULL. - * In this case, this function can be used to query how many sockets are + * ::amdsmi_processor_handle values will be written. This value may be NULL. + * In this case, this function can be used to query how many processors are * available to read in the system. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_cpusocket_handles(uint32_t *socket_count, - amdsmi_cpusocket_handle* socket_handles); +amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count, + amdsmi_processor_handle *processor_handles); #endif /** @@ -2134,21 +2133,20 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle, #ifdef ENABLE_ESMI_LIB /** - * @brief Get the list of the cpu core handles associated to a cpu socket. + * @brief Get the list of the cpu core handles in a system. * * @platform{cpu_bm} * - * @details This function retrieves the cpu core handles of a cpu socket. - * @param[in] socket_handle The cpu socket to query - * @param[in,out] processor_count As input, the value passed + * @details This function retrieves the cpu core handles of a system. + * @param[in,out] cores_count As input, the value passed * through this parameter is the number of ::amdsmi_processor_handle's that * may be safely written to the memory pointed to by @p processor_handles. This is the - * limit on how many processor handles will be written to @p processor_handles. On return, @p - * processor_count will contain the number of processor handles written to @p processor_handles, - * or the number of processor handles that could have been written if enough memory had been + * limit on how many core handles will be written to @p processor_handles. On return, @p + * cores_count will contain the number of core processor handles written to @p processor_handles, + * or the number of core processor handles that could have been written if enough memory had been * provided. * If @p processor_handles is NULL, as output, @p processor_count will contain - * how many cpu cores are available to read for the cpu socket. + * how many cpu cores are available to read in the system. * * @param[in,out] processor_handles A pointer to a block of memory to which the * ::amdsmi_processor_handle values will be written. This value may be NULL. @@ -2157,9 +2155,8 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle, * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_cpucore_handles(amdsmi_cpusocket_handle socket_handle, - uint32_t *processor_count, - amdsmi_processor_handle* processor_handles); +amdsmi_status_t amdsmi_get_cpucore_handles(uint32_t *cores_count, + amdsmi_processor_handle* processor_handles); #endif /** diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index 7cc37897b3..fa96a01819 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -668,36 +668,22 @@ def amdsmi_get_cpusocket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: Returns: `List`: List containing all of the found cpu socket handles. """ - socket_handles = amdsmi_get_socket_handles() - cpu_handles = [] - type = amdsmi_wrapper.AMDSMI_PROCESSOR_TYPE_AMD_CPU - for socket in socket_handles: - cpu_count = ctypes.c_uint32() - null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - null_ptr, - ctypes.byref(cpu_count), - ) - ) - processor_handles = ( - amdsmi_wrapper.amdsmi_processor_handle * cpu_count.value)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - processor_handles, - ctypes.byref(cpu_count) - ) - ) - cpu_handles.extend( - [ - amdsmi_wrapper.amdsmi_processor_handle(processor_handles[dev_idx]) - for dev_idx in range(cpu_count.value) - ] - ) + cpu_count = ctypes.c_uint32(0) + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_handles( + ctypes.byref(cpu_count), null_ptr) + ) + proc_handles = (amdsmi_wrapper.amdsmi_processor_handle * + cpu_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpu_handles( + ctypes.byref(cpu_count), proc_handles) + ) + cpu_handles = [ + amdsmi_wrapper.amdsmi_processor_handle(proc_handles[sock_idx]) + for sock_idx in range(cpu_count.value) + ] return cpu_handles @@ -761,37 +747,23 @@ def amdsmi_get_processor_handles() -> List[amdsmi_wrapper.amdsmi_processor_handl return devices def amdsmi_get_cpucore_handles() -> List[amdsmi_wrapper.amdsmi_processor_handle]: - socket_handles = amdsmi_get_socket_handles() - core_handles = [] - type = amdsmi_wrapper.AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE + cores_count = ctypes.c_uint32(0) + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpucore_handles( + ctypes.byref(cores_count), null_ptr) + ) + proc_handles = (amdsmi_wrapper.amdsmi_processor_handle * + cores_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_cpucore_handles( + ctypes.byref(cores_count), proc_handles) + ) + core_handles = [ + amdsmi_wrapper.amdsmi_processor_handle(proc_handles[sock_idx]) + for sock_idx in range(cores_count.value) + ] - for socket in socket_handles: - core_count = ctypes.c_uint32() - null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_processor_handle)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - null_ptr, - ctypes.byref(core_count), - ) - ) - c_handles = ( - amdsmi_wrapper.amdsmi_processor_handle * core_count.value)() - _check_res( - amdsmi_wrapper.amdsmi_get_processor_handles_by_type( - socket, - type, - c_handles, - ctypes.byref(core_count) - ) - ) - core_handles.extend( - [ - amdsmi_wrapper.amdsmi_processor_handle(c_handles[dev_idx]) - for dev_idx in range(core_count.value) - ] - ) return core_handles diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index b16593187d..e52e147fc1 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -181,16 +181,6 @@ try: except OSError as error: print(error) print("Unable to find amdsmi library try installing amd-smi-lib from your package manager") -class FunctionFactoryStub: - def __getattr__(self, _): - return ctypes.CFUNCTYPE(lambda y:y) - -# libraries['FIXME_STUB'] explanation -# As you did not list (-l libraryname.so) a library that exports this function -# This is a non-working stub instead. -# You can either re-run clan2py with -l /path/to/library.so -# Or manually fix this by comment the ctypes.CDLL loading -_libraries['FIXME_STUB'] = FunctionFactoryStub() # ctypes.CDLL('FIXME_STUB') @@ -2081,9 +2071,9 @@ amdsmi_shut_down.argtypes = [] amdsmi_get_socket_handles = _libraries['libamd_smi.so'].amdsmi_get_socket_handles amdsmi_get_socket_handles.restype = amdsmi_status_t amdsmi_get_socket_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] -amdsmi_get_cpusocket_handles = _libraries['FIXME_STUB'].amdsmi_get_cpusocket_handles -amdsmi_get_cpusocket_handles.restype = amdsmi_status_t -amdsmi_get_cpusocket_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] +amdsmi_get_cpu_handles = _libraries['libamd_smi.so'].amdsmi_get_cpu_handles +amdsmi_get_cpu_handles.restype = amdsmi_status_t +amdsmi_get_cpu_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] size_t = ctypes.c_uint64 amdsmi_get_socket_info = _libraries['libamd_smi.so'].amdsmi_get_socket_info amdsmi_get_socket_info.restype = amdsmi_status_t @@ -2100,9 +2090,9 @@ amdsmi_get_processor_handles_by_type.argtypes = [amdsmi_socket_handle, processor amdsmi_get_processor_handles = _libraries['libamd_smi.so'].amdsmi_get_processor_handles amdsmi_get_processor_handles.restype = amdsmi_status_t amdsmi_get_processor_handles.argtypes = [amdsmi_socket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] -amdsmi_get_cpucore_handles = _libraries['FIXME_STUB'].amdsmi_get_cpucore_handles +amdsmi_get_cpucore_handles = _libraries['libamd_smi.so'].amdsmi_get_cpucore_handles amdsmi_get_cpucore_handles.restype = amdsmi_status_t -amdsmi_get_cpucore_handles.argtypes = [amdsmi_cpusocket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] +amdsmi_get_cpucore_handles.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] amdsmi_get_processor_type = _libraries['libamd_smi.so'].amdsmi_get_processor_type amdsmi_get_processor_type.restype = amdsmi_status_t amdsmi_get_processor_type.argtypes = [amdsmi_processor_handle, ctypes.POINTER(processor_type_t)] @@ -2818,8 +2808,9 @@ __all__ = \ 'amdsmi_get_cpu_dimm_power_consumption', 'amdsmi_get_cpu_dimm_temp_range_and_refresh_rate', 'amdsmi_get_cpu_dimm_thermal_sensor', 'amdsmi_get_cpu_family', - 'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_hsmp_proto_ver', - 'amdsmi_get_cpu_model', 'amdsmi_get_cpu_prochot_status', + 'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_handles', + 'amdsmi_get_cpu_hsmp_proto_ver', 'amdsmi_get_cpu_model', + 'amdsmi_get_cpu_prochot_status', 'amdsmi_get_cpu_pwr_svi_telemetry_all_rails', 'amdsmi_get_cpu_smu_fw_version', 'amdsmi_get_cpu_socket_c0_residency', @@ -2830,8 +2821,8 @@ __all__ = \ 'amdsmi_get_cpu_socket_power', 'amdsmi_get_cpu_socket_power_cap', 'amdsmi_get_cpu_socket_power_cap_max', 'amdsmi_get_cpu_socket_temperature', 'amdsmi_get_cpucore_handles', - 'amdsmi_get_cpusocket_handles', 'amdsmi_get_energy_count', - 'amdsmi_get_esmi_err_msg', 'amdsmi_get_fw_info', + 'amdsmi_get_energy_count', 'amdsmi_get_esmi_err_msg', + 'amdsmi_get_fw_info', 'amdsmi_get_gpu_accelerator_partition_profile', 'amdsmi_get_gpu_activity', 'amdsmi_get_gpu_asic_info', 'amdsmi_get_gpu_available_counters', diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 0fdd032ddb..be2b34361f 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -3842,6 +3842,115 @@ amdsmi_status_t amdsmi_get_cpu_model(uint32_t *cpu_model) return AMDSMI_STATUS_SUCCESS; } +amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count, + amdsmi_processor_handle *processor_handles) +{ + uint32_t soc_count = 0, index = 0, cpu_per_soc = 0; + processor_type_t processor_type = AMDSMI_PROCESSOR_TYPE_AMD_CPU; + std::vector cpu_handles; + amdsmi_status_t status; + + AMDSMI_CHECK_INIT(); + if (cpu_count == nullptr) + return AMDSMI_STATUS_INVAL; + + status = amdsmi_get_socket_handles(&soc_count, nullptr); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the sockets + std::vector sockets(soc_count); + // Get the sockets of the system + status = amdsmi_get_socket_handles(&soc_count, &sockets[0]); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + for (index = 0 ; index < soc_count; index++) + { + cpu_per_soc = 0; + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + nullptr, &cpu_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the cpus + std::vector plist(cpu_per_soc); + // Get the cpus for each socket + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + &plist[0], &cpu_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + cpu_handles.insert(cpu_handles.end(), plist.begin(), plist.end()); + } + + // Get the cpu count + *cpu_count = cpu_handles.size(); + if (processor_handles == nullptr) + return AMDSMI_STATUS_SUCCESS; + + // Copy the cpu socket handles + for (uint32_t i = 0; i < *cpu_count; i++) + processor_handles[i] = reinterpret_cast(cpu_handles[i]); + + return status; +} + +amdsmi_status_t amdsmi_get_cpucore_handles(uint32_t *cores_count, + amdsmi_processor_handle* processor_handles) +{ + uint32_t soc_count = 0, index = 0, cores_per_soc = 0; + processor_type_t processor_type = AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE; + std::vector core_handles; + amdsmi_status_t status; + + AMDSMI_CHECK_INIT(); + if (cores_count == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + // Get sockets count + status = amdsmi_get_socket_handles(&soc_count, nullptr); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the sockets + std::vector sockets(soc_count); + // Get the sockets of the system + status = amdsmi_get_socket_handles(&soc_count, &sockets[0]); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + for (index = 0 ; index < soc_count; index++) + { + cores_per_soc = 0; + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + nullptr, &cores_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + // Allocate the memory for the cores + std::vector plist(cores_per_soc); + // Get the coress for each socket + status = amdsmi_get_processor_handles_by_type(sockets[index], processor_type, + &plist[0], &cores_per_soc); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + core_handles.insert(core_handles.end(), plist.begin(), plist.end()); + } + + // Get the cores count + *cores_count = core_handles.size(); + if (processor_handles == nullptr) + return AMDSMI_STATUS_SUCCESS; + + // Copy the core handles + for (uint32_t i = 0; i < *cores_count; i++) + processor_handles[i] = reinterpret_cast(core_handles[i]); + + return status; +} + amdsmi_status_t amdsmi_get_esmi_err_msg(amdsmi_status_t status, const char **status_string) { for (auto& iter : amd::smi::esmi_status_map) {