[SWDEV-482949] Add CPU model name querying support (#33)

- Add support to check CPU vendor info which will be called by RDC to
discovery CPU information
- Move esmi headers declaration to impl/amd_smi_common.h
- remove duplicated amdsmi_cpu_util_t

---------

Signed-off-by: Perry Yuan <perry.yuan@amd.com>
Signed-off-by: Deepak Mewar <deepak.mewar@amd.com>
Signed-off-by: Maisam Arif <Maisam.Arif@amd.com>
Co-authored-by: Deepak Mewar <deepak.mewar@amd.com>

[ROCm/amdsmi commit: 68e44c7f66]
This commit is contained in:
Yuan, Perry
2025-03-29 10:21:39 +08:00
committed by GitHub
parent 952bff9126
commit b92ffd2bcf
10 changed files with 244 additions and 21 deletions
+5
View File
@@ -8,6 +8,10 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr
### Added
- **Added cpu model name for RDC**.
- Added new C and Python API `amdsmi_get_cpu_model_name`
- Not sourced from esmi library.
- **Added support for GPU metrics 1.8**.
- Added new fields for `amdsmi_gpu_xcp_metrics_t` including:
- Adding the following metrics to allow new calculations for violation status:
@@ -22,6 +26,7 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr
- **Added Power Cap to amd-smi monitor**.
- 'amd-smi monitor -p' will display the power cap along with power.
```shell
$ amd-smi monitor -p
GPU POWER PWR_CAP
@@ -5127,6 +5127,26 @@ except AmdSmiException as e:
print(e)
```
### amdsmi_get_cpu_model_name
Description: Get cpu model name.
Output: cpu model name
Exceptions that can be thrown by `amdsmi_get_cpu_model_name` function:
* `AmdSmiLibraryException`
Example:
```python
try:
cpu_model_name = amdsmi_get_cpu_model_name()
print(cpu_model_name)
except AmdSmiException as e:
print(e)
```
## No amdsmi_init APIs
### amdsmi_get_lib_version
+64 -3
View File
@@ -34,9 +34,6 @@
#ifdef __cplusplus
extern "C" {
#include <cstdint>
#ifdef ENABLE_ESMI_LIB
#include <e_smi/e_smi.h>
#endif
#else // __cplusplus
#include <stdint.h>
#endif // __cplusplus
@@ -935,6 +932,19 @@ typedef enum {
AMDSMI_LINK_TYPE_UNKNOWN
} amdsmi_link_type_t;
/**
* @brief This structure holds CPU utilization information.
*
* @cond @tag{cpu_bm} @endcond
*/
typedef struct {
uint32_t cpu_util_total;
uint32_t cpu_util_user;
uint32_t cpu_util_nice;
uint32_t cpu_util_sys;
uint32_t cpu_util_irq;
} amdsmi_cpu_util_t;
/**
* @brief Link Metrics
*
@@ -2221,6 +2231,32 @@ static char* const amdsmi_hsmp_freqlimit_src_names[] = {
"HSMP Agent"
};
/**
* @brief cpu info data
*
* @cond @tag{cpu_bm} @endcond
*/
typedef struct {
char model_name[AMDSMI_MAX_STRING_LENGTH];
uint32_t cpu_family_id;
uint32_t model_id;
uint32_t threads_per_core;
uint32_t cores_per_socket;
bool frequency_boost;
uint32_t vendor_id; //< Use 32 bit to be compatible with other platform.
char vendor_name[AMDSMI_MAX_STRING_LENGTH];
uint32_t subvendor_id; //< The subsystem vendor id
uint64_t device_id; //< The device id of a GPU
uint32_t rev_id;
char asic_serial[AMDSMI_MAX_STRING_LENGTH];
uint32_t socket_id; //< 0xFFFF if not supported
uint32_t core_id;
uint32_t num_of_cpu_cores; //< 0xFFFFFFFF if not supported
uint32_t socket_count;
uint32_t core_count;
uint32_t reserved[17];
} amdsmi_cpu_info_t;
#endif
/*****************************************************************************/
@@ -2437,6 +2473,7 @@ amdsmi_status_t amdsmi_get_processor_handles_by_type(amdsmi_socket_handle socket
processor_type_t processor_type,
amdsmi_processor_handle* processor_handles,
uint32_t* processor_count);
#endif
/**
@@ -6805,6 +6842,30 @@ amdsmi_status_t amdsmi_get_cpu_family(uint32_t *cpu_family);
*/
amdsmi_status_t amdsmi_get_cpu_model(uint32_t *cpu_model);
/**
* @brief Retrieve the CPU processor model name based on the processor index.
*
* @platform{cpu_bm}
*
* @details
* This function obtains the CPU model name associated with the specified processor index
* from the list of available processor handles. Before invoking this function, ensure that
* the list of processor handles is properly initialized and that the processor type is specified.
* This function is to be utilized for RDC and is not part of ESMI library.
*
* @param[in] processor_handle Cpu socket which to query
*
* @param[out] cpu_info
* A pointer to an `amdsmi_cpu_info_t` structure that will be populated with the
* CPU processor model information upon successful execution of the function.
*
* @return
* ::amdsmi_status_t indicating the result of the operation.
* - ::AMDSMI_STATUS_SUCCESS on successful retrieval of the model name.
* - A non-zero error code if the operation fails.
*/
amdsmi_status_t amdsmi_get_cpu_model_name(amdsmi_processor_handle processor_handle, amdsmi_cpu_info_t *cpu_info);
/**
* @brief Get a description of provided AMDSMI error status for esmi errors.
*
@@ -27,6 +27,13 @@
#include "rocm_smi/rocm_smi.h"
#include "amd_smi/amdsmi.h"
#ifdef ENABLE_ESMI_LIB
extern "C" {
#include <cstdint>
#include <e_smi/e_smi.h>
}
#endif
namespace amd {
namespace smi {
@@ -61,7 +61,8 @@ class AMDSmiSystem {
amdsmi_status_t clean_up_drm() { return drm_.cleanup();}
amdsmi_status_t init_drm() { return drm_.init();}
amdsmi_status_t get_cpu_model_name(uint32_t socket_id, std::string *model_name);
private:
AMDSmiSystem() : init_flag_(AMDSMI_INIT_AMD_GPUS) {}
+1
View File
@@ -77,6 +77,7 @@ try:
from .amdsmi_interface import amdsmi_first_online_core_on_cpu_socket
from .amdsmi_interface import amdsmi_get_cpu_family
from .amdsmi_interface import amdsmi_get_cpu_model
from .amdsmi_interface import amdsmi_get_cpu_model_name
except AttributeError:
pass
@@ -1676,6 +1676,23 @@ def amdsmi_get_cpu_model():
)
return model.value
def amdsmi_get_cpu_model_name(
processor_handle: amdsmi_wrapper.amdsmi_processor_handle
):
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
raise AmdSmiParameterException(
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
)
cpu_info = amdsmi_wrapper.amdsmi_cpu_info_t()
_check_res(
amdsmi_wrapper.amdsmi_get_cpu_model_name(
processor_handle, cpu_info
)
)
return f"{cpu_info.model_name}"
def amdsmi_init(flag=AmdSmiInitFlags.INIT_AMD_GPUS):
if not isinstance(flag, AmdSmiInitFlags):
raise AmdSmiParameterException(flag, AmdSmiInitFlags)
+63 -16
View File
@@ -856,6 +856,21 @@ 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),
('max_pcie_interface_version', ctypes.c_uint32),
('PADDING_1', ctypes.c_ubyte * 4),
('reserved', ctypes.c_uint64 * 9),
]
class struct_pcie_metric_(Structure):
pass
@@ -876,21 +891,6 @@ struct_pcie_metric_._fields_ = [
('reserved', ctypes.c_uint64 * 12),
]
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),
('max_pcie_interface_version', ctypes.c_uint32),
('PADDING_1', ctypes.c_ubyte * 4),
('reserved', ctypes.c_uint64 * 9),
]
struct_amdsmi_pcie_info_t._pack_ = 1 # source:False
struct_amdsmi_pcie_info_t._fields_ = [
('pcie_static', struct_pcie_static_),
@@ -1127,6 +1127,19 @@ AMDSMI_LINK_TYPE_PCIE = 2
AMDSMI_LINK_TYPE_NOT_APPLICABLE = 3
AMDSMI_LINK_TYPE_UNKNOWN = 4
amdsmi_link_type_t = ctypes.c_uint32 # enum
class struct_amdsmi_cpu_util_t(Structure):
pass
struct_amdsmi_cpu_util_t._pack_ = 1 # source:False
struct_amdsmi_cpu_util_t._fields_ = [
('cpu_util_total', ctypes.c_uint32),
('cpu_util_user', ctypes.c_uint32),
('cpu_util_nice', ctypes.c_uint32),
('cpu_util_sys', ctypes.c_uint32),
('cpu_util_irq', ctypes.c_uint32),
]
amdsmi_cpu_util_t = struct_amdsmi_cpu_util_t
class struct_amdsmi_link_metrics_t(Structure):
pass
@@ -2216,6 +2229,35 @@ struct_amdsmi_hsmp_metrics_table_t._fields_ = [
amdsmi_hsmp_metrics_table_t = struct_amdsmi_hsmp_metrics_table_t
amdsmi_hsmp_freqlimit_src_names = ['cHTC-Active', 'PROCHOT', 'TDC limit', 'PPT Limit', 'OPN Max', 'Reliability Limit', 'APML Agent', 'HSMP Agent'] # Variable ctypes.POINTER(ctypes.c_char) * 8
class struct_amdsmi_cpu_info_t(Structure):
pass
struct_amdsmi_cpu_info_t._pack_ = 1 # source:False
struct_amdsmi_cpu_info_t._fields_ = [
('model_name', ctypes.c_char * 256),
('cpu_family_id', ctypes.c_uint32),
('model_id', ctypes.c_uint32),
('threads_per_core', ctypes.c_uint32),
('cores_per_socket', ctypes.c_uint32),
('frequency_boost', ctypes.c_bool),
('PADDING_0', ctypes.c_ubyte * 3),
('vendor_id', ctypes.c_uint32),
('vendor_name', ctypes.c_char * 256),
('subvendor_id', ctypes.c_uint32),
('PADDING_1', ctypes.c_ubyte * 4),
('device_id', ctypes.c_uint64),
('rev_id', ctypes.c_uint32),
('asic_serial', ctypes.c_char * 256),
('socket_id', ctypes.c_uint32),
('core_id', ctypes.c_uint32),
('num_of_cpu_cores', ctypes.c_uint32),
('socket_count', ctypes.c_uint32),
('core_count', ctypes.c_uint32),
('reserved', ctypes.c_uint32 * 17),
('PADDING_2', ctypes.c_ubyte * 4),
]
amdsmi_cpu_info_t = struct_amdsmi_cpu_info_t
uint64_t = ctypes.c_uint64
amdsmi_init = _libraries['libamd_smi.so'].amdsmi_init
amdsmi_init.restype = amdsmi_status_t
@@ -2748,6 +2790,9 @@ amdsmi_get_cpu_family.argtypes = [ctypes.POINTER(ctypes.c_uint32)]
amdsmi_get_cpu_model = _libraries['libamd_smi.so'].amdsmi_get_cpu_model
amdsmi_get_cpu_model.restype = amdsmi_status_t
amdsmi_get_cpu_model.argtypes = [ctypes.POINTER(ctypes.c_uint32)]
amdsmi_get_cpu_model_name = _libraries['libamd_smi.so'].amdsmi_get_cpu_model_name
amdsmi_get_cpu_model_name.restype = amdsmi_status_t
amdsmi_get_cpu_model_name.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_cpu_info_t)]
amdsmi_get_esmi_err_msg = _libraries['libamd_smi.so'].amdsmi_get_esmi_err_msg
amdsmi_get_esmi_err_msg.restype = amdsmi_status_t
amdsmi_get_esmi_err_msg.argtypes = [amdsmi_status_t, ctypes.POINTER(ctypes.POINTER(ctypes.c_char))]
@@ -2978,6 +3023,7 @@ __all__ = \
'amdsmi_compute_partition_type_t', 'amdsmi_container_types_t',
'amdsmi_counter_command_t', 'amdsmi_counter_value_t',
'amdsmi_cpu_apb_disable', 'amdsmi_cpu_apb_enable',
'amdsmi_cpu_info_t', 'amdsmi_cpu_util_t',
'amdsmi_cpusocket_handle', 'amdsmi_ddr_bw_metrics_t',
'amdsmi_dev_perf_level_t', 'amdsmi_dimm_power_t',
'amdsmi_dimm_thermal_t', 'amdsmi_dpm_level_t',
@@ -3004,7 +3050,7 @@ __all__ = \
'amdsmi_get_cpu_fclk_mclk', 'amdsmi_get_cpu_handles',
'amdsmi_get_cpu_hsmp_driver_version',
'amdsmi_get_cpu_hsmp_proto_ver', 'amdsmi_get_cpu_model',
'amdsmi_get_cpu_prochot_status',
'amdsmi_get_cpu_model_name', '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',
@@ -3146,6 +3192,7 @@ __all__ = \
'struct_amdsmi_accelerator_partition_resource_profile_t',
'struct_amdsmi_asic_info_t', 'struct_amdsmi_board_info_t',
'struct_amdsmi_clk_info_t', 'struct_amdsmi_counter_value_t',
'struct_amdsmi_cpu_info_t', 'struct_amdsmi_cpu_util_t',
'struct_amdsmi_ddr_bw_metrics_t', 'struct_amdsmi_dimm_power_t',
'struct_amdsmi_dimm_thermal_t', 'struct_amdsmi_dpm_level_t',
'struct_amdsmi_dpm_policy_entry_t', 'struct_amdsmi_dpm_policy_t',
+26
View File
@@ -1520,6 +1520,7 @@ amdsmi_status_t amdsmi_get_gpu_vendor_name(
name, len);
}
amdsmi_status_t amdsmi_get_gpu_vram_vendor(amdsmi_processor_handle processor_handle,
char *brand, uint32_t len) {
return rsmi_wrapper(rsmi_dev_vram_vendor_get, processor_handle, 0,
@@ -5224,6 +5225,30 @@ amdsmi_status_t amdsmi_get_cpu_model(uint32_t *cpu_model)
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_model_name(amdsmi_processor_handle processor_handle, amdsmi_cpu_info_t *cpu_info)
{
amdsmi_status_t status;
uint32_t sock_ind;
std::string model_name;
if (processor_handle == nullptr)
return AMDSMI_STATUS_INVAL;
amdsmi_status_t r = amdsmi_get_processor_info(processor_handle, SIZE, proc_id);
if (r != AMDSMI_STATUS_SUCCESS)
return r;
sock_ind = (uint8_t)std::stoi(proc_id, NULL, 0);
status = amd::smi::AMDSmiSystem::getInstance().get_cpu_model_name(sock_ind, &model_name);
if (status != AMDSMI_STATUS_SUCCESS)
return amdsmi_errno_to_esmi_status(status);
strncpy(cpu_info->model_name, model_name.c_str(), AMDSMI_MAX_STRING_LENGTH -1);
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count,
amdsmi_processor_handle *processor_handles)
{
@@ -5349,4 +5374,5 @@ amdsmi_status_t amdsmi_get_esmi_err_msg(amdsmi_status_t status, const char **sta
}
return AMDSMI_STATUS_SUCCESS;
}
#endif
+39 -1
View File
@@ -29,6 +29,9 @@
#include "amd_smi/impl/amd_smi_utils.h"
#include "rocm_smi/rocm_smi.h"
#include "rocm_smi/rocm_smi_main.h"
#include <fstream>
#include <cerrno>
#include <cstring>
namespace amd {
namespace smi {
@@ -92,24 +95,59 @@ static amdsmi_status_t get_nr_cpu_sockets(uint32_t *num_socks) {
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::get_cpu_model_name(uint32_t socket_id, std::string *model_name) {
std::ifstream cpu_info("/proc/cpuinfo");
std::string info;
std::map<uint32_t, std::string> socket_model_map;
if (!cpu_info.is_open()) {
std::cerr << "Failed to open /proc/cpuinfo:" << strerror(errno) << std::endl;
return AMDSMI_STATUS_FILE_ERROR;
} else {
uint32_t current_socket_id = -1;
while (std::getline(cpu_info, info)) {
if (info.find("processor") != std::string::npos) {
current_socket_id = std::stoi(info.substr(info.find(':') + 1));
}
if (info.find("model name") != std::string::npos) {
*model_name = info.substr(info.find(':') + 2);
if (current_socket_id != -1) {
socket_model_map[current_socket_id] = *model_name;
}
}
}
cpu_info.close();
}
if (socket_model_map.find(socket_id) != socket_model_map.end()) {
*model_name = socket_model_map[socket_id];
} else {
return AMDSMI_STATUS_NO_DATA;
}
return AMDSMI_STATUS_SUCCESS;
}
#endif
amdsmi_status_t AMDSmiSystem::init(uint64_t flags) {
init_flag_ = flags;
amdsmi_status_t amd_smi_status;
// populate sockets and processors
// populate GPU sockets and processors
if (flags & AMDSMI_INIT_AMD_GPUS) {
amd_smi_status = populate_amd_gpu_devices();
if (amd_smi_status != AMDSMI_STATUS_SUCCESS)
return amd_smi_status;
}
#ifdef ENABLE_ESMI_LIB
// populate CPU sockets and processors
if (flags & AMDSMI_INIT_AMD_CPUS) {
amd_smi_status = populate_amd_cpus();
if (amd_smi_status != AMDSMI_STATUS_SUCCESS)
return amd_smi_status;
}
#endif
return AMDSMI_STATUS_SUCCESS;
}