[SWDEV-453922] AMD SMI to provide mapping feature of other enumeration methods (#51)

Added enumeration mapping for 
- drm render
- drm card
- hsa id 
- hip id
- hip uuid (rocminfo uuid)

Signed-off-by: AL Musaffar, Yazen <Yazen.ALMusaffar@amd.com>
Signed-off-by: Maisam Arif <Maisam.Arif@amd.com>
Co-authored-by: Maisam Arif <Maisam.Arif@amd.com>
此提交包含在:
AL Musaffar, Yazen
2025-03-07 09:09:12 -06:00
提交者 GitHub
父節點 d5b2763aba
當前提交 2936e00fed
共有 11 個檔案被更改,包括 417 行新增88 行删除
+30
查看文件
@@ -8,6 +8,36 @@ Full documentation for amd_smi_lib is available at [https://rocm.docs.amd.com/pr
### Added
- **Added enumeration mapping `amdsmi_get_gpu_enumeration_info()` to Python & C APIs.**
- Enumeration mapping consists of `amdsmi_enumeration_info_t`
```shell
typedef struct {
uint32_t drm_render; // the render node under /sys/class/drm/renderD*
uint32_t drm_card; // the graphic card device under /sys/class/drm/card*
uint32_t hsa_id; // the HSA enumeration ID
uint32_t hip_id; // the HIP enumeration ID
char hip_uuid[AMDSMI_MAX_STRING_LENGTH]; // the HIP unique identifer
} amdsmi_enumeration_info_t;
```
- The mapping is also enabled in the CLI interface via `amd-smi list -e`
```shell
$ amd-smi list -e
GPU: 0
BDF: 0000:23:00.0
UUID: XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
KFD_ID: 45412
NODE_ID: 1
PARTITION_ID: 0
RENDER: renderD128
CARD: card0
HSA_ID: 1
HIP_ID: 0
HIP_UUID: GPU-XXXXXXXXXXXXXXXX
```
- **Added dynamic virtualization mode detection**.
- Added new C and Python API `amdsmi_get_gpu_virtualization_mode_info`
- Added new C and Python enum `amdsmi_virtualization_mode_t`
+26 -8
查看文件
@@ -175,7 +175,6 @@ class AMDSMICommands():
elif self.logger.is_json_format() or self.logger.is_csv_format():
self.logger.print_output()
def list(self, args, multiple_devices=False, gpu=None):
"""List information for target gpu
@@ -214,12 +213,20 @@ class AMDSMICommands():
bdf = amdsmi_interface.amdsmi_get_gpu_device_bdf(args.gpu)
except amdsmi_exception.AmdSmiLibraryException as e:
bdf = e.get_error_info()
try:
uuid = amdsmi_interface.amdsmi_get_gpu_device_uuid(args.gpu)
except amdsmi_exception.AmdSmiLibraryException as e:
uuid = e.get_error_info()
try:
enumeration_info = amdsmi_interface.amdsmi_get_gpu_enumeration_info(args.gpu)
except:
enumeration_info = {"drm_render": "N/A",
"drm_card": "N/A",
"hip_id": "N/A",
"hip_uuid": "N/A",
"hsa_id": "N/A"}
try:
kfd_info = amdsmi_interface.amdsmi_get_gpu_kfd_info(args.gpu)
kfd_id = kfd_info['kfd_id']
@@ -233,15 +240,26 @@ class AMDSMICommands():
if self.logger.is_csv_format():
self.logger.store_output(args.gpu, 'gpu_bdf', bdf)
self.logger.store_output(args.gpu, 'gpu_uuid', uuid)
self.logger.store_output(args.gpu, 'kfd_id', kfd_id)
self.logger.store_output(args.gpu, 'node_id', node_id)
self.logger.store_output(args.gpu, 'partition_id', partition_id)
else:
self.logger.store_output(args.gpu, 'bdf', bdf)
self.logger.store_output(args.gpu, 'uuid', uuid)
self.logger.store_output(args.gpu, 'kfd_id', kfd_id)
self.logger.store_output(args.gpu, 'node_id', node_id)
self.logger.store_output(args.gpu, 'partition_id', partition_id)
self.logger.store_output(args.gpu, 'kfd_id', kfd_id)
self.logger.store_output(args.gpu, 'node_id', node_id)
self.logger.store_output(args.gpu, 'partition_id', partition_id)
if args.e:
if enumeration_info['drm_render'] == "N/A":
self.logger.store_output(args.gpu, 'render', enumeration_info['drm_render'])
else:
self.logger.store_output(args.gpu, 'render', f"renderD{enumeration_info['drm_render']}")
if enumeration_info['drm_card'] == "N/A":
self.logger.store_output(args.gpu, 'card', enumeration_info['drm_card'])
else:
self.logger.store_output(args.gpu, 'card', f"card{enumeration_info['drm_card']}")
self.logger.store_output(args.gpu, 'hsa_id', enumeration_info['hsa_id'])
self.logger.store_output(args.gpu, 'hip_id', enumeration_info['hip_id'])
self.logger.store_output(args.gpu, 'hip_uuid', enumeration_info['hip_uuid'])
if multiple_devices:
self.logger.store_multiple_device_output()
+2
查看文件
@@ -626,6 +626,8 @@ class AMDSMIParser(argparse.ArgumentParser):
# Create list subparser
list_parser = subparsers.add_parser('list', help=list_help, description=list_subcommand_help)
# Create -e subparser
list_parser.add_argument("-e", action="store_true", help="Enumeration mapping to other features.\n Lists the BDF, UUID, KFD_ID, CARD, RENDER, HIP_ID, HIP_UUID and HSA_ID for each GPU.")
list_parser.formatter_class=lambda prog: AMDSMISubparserHelpFormatter(prog)
list_parser.set_defaults(func=func)
+40
查看文件
@@ -274,6 +274,46 @@ except AmdSmiException as e:
print(e)
```
### amdsmi_get_gpu_enumeration_info
Description: Returns enumeration information for the given GPU
Input parameters:
* `processor_handle` device which to query
Output: Dictionary with fields
Field | Content
---|---
`drm_render` | DRM render ID
`drm_card` | DRM card ID
`hsa_id` | HSA ID
`hip_id` | HIP ID
`hip_uuid` | HIP UUID
Exceptions that can be thrown by `amdsmi_get_gpu_enumeration_info` function:
* `AmdSmiLibraryException`
* `AmdSmiRetryException`
* `AmdSmiParameterException`
Example:
```python
try:
devices = amdsmi_get_processor_handles()
for device in devices:
info = amdsmi_get_gpu_enumeration_info(device)
print("DRM Render ID:", info['drm_render'])
print("DRM Card ID:", info['drm_card'])
print("HSA ID:", info['hsa_id'])
print("HIP ID:", info['hip_id'])
print("HIP UUID:", info['hip_uuid'])
except AmdSmiException as e:
print(e)
```
### amdsmi_get_gpu_driver_info
Description: Returns the info of the driver
+44 -6
查看文件
@@ -174,7 +174,7 @@ typedef enum {
*
* Refer to amd.com documentation for more detail:
* https://www.amd.com/content/dam/amd/en/documents/instinct-tech-docs/white-papers/amd-cdna-3-white-paper.pdf
*
*
* @cond @tag{gpu_bm_linux} @tag{host} @tag{guest_windows} @endcond
*/
#define AMDSMI_MAX_NUM_XCP 8
@@ -680,6 +680,19 @@ typedef union {
uint64_t as_uint;
} amdsmi_bdf_t;
/**
* @brief Structure holds enumeration information
*
* @cond @tag{gpu_bm_linux} @tag{host} @endcond
*/
typedef struct {
uint32_t drm_render; // the render node under /sys/class/drm/renderD*
uint32_t drm_card; // the graphic card device under /sys/class/drm/card*
uint32_t hsa_id; // the HSA enumeration ID
uint32_t hip_id; // the HIP enumeration ID
char hip_uuid[AMDSMI_MAX_STRING_LENGTH]; // the HIP unique identifer
} amdsmi_enumeration_info_t;
/**
* @brief Card Form Factor
*
@@ -813,6 +826,7 @@ typedef struct {
uint32_t reserved[22];
} amdsmi_asic_info_t;
/**
* @brief Structure holds kfd information
*
@@ -2448,6 +2462,7 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle,
uint32_t *processor_count,
amdsmi_processor_handle* processor_handles);
#ifdef ENABLE_ESMI_LIB
/**
* @brief Get the list of the cpu core handles in a system.
@@ -2541,13 +2556,13 @@ amdsmi_get_gpu_device_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t
*
* @ingroup tagProcDiscovery
*
* @platform{gpu_bm_linux} @platform{host} @platform{guest_1vf} @platform{guest_mvf}
* @platform{gpu_bm_linux} @platform{host} @platform{guest_1vf} @platform{guest_mvf}
* @platform{guest_windows}
*
* @param[in] processor_handle Device which to query
*
* @param[in,out] uuid_length Length of the uuid string. As input, must be
* equal or greater than SMI_GPU_UUID_SIZE and be allocated by
* equal or greater than AMDSMI_GPU_UUID_SIZE and be allocated by
* user. As output it is the length of the uuid string.
*
* @param[out] uuid Pointer to string to store the UUID. Must be
@@ -2558,6 +2573,28 @@ amdsmi_get_gpu_device_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t
amdsmi_status_t
amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned int *uuid_length, char *uuid);
/**
* @brief Returns the Enumeration information for the device
*
* @ingroup tagProcDiscovery
*
* @platform{gpu_bm_linux} @platform{host} @platform{guest_1vf} @platform{guest_mvf}
* @platform{guest_windows}
*
* @details This function returns Enumeration information of the corresponding
* processor_handle. It will return the render number, card number,
* HSA ID, HIP ID, and the HIP UUID.
*
* @param[in] processor_handle Device which to query
*
* @param[out] info Reference to Enumeration information structure.
* Must be allocated by user.
*
* @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail
*/
amdsmi_status_t
amdsmi_get_gpu_enumeration_info(amdsmi_processor_handle processor_handle, amdsmi_enumeration_info_t *info);
/** @} End tagProcDiscovery */
/*****************************************************************************/
@@ -2746,7 +2783,7 @@ amdsmi_get_gpu_subsystem_name(amdsmi_processor_handle processor_handle, char *na
* @brief Returns the virtualization mode for the target device.
*
* @ingroup tagIdentQuery
*
*
* @platform{gpu_bm_linux} @platform{host}
*
* @details The virtualization mode is detected and returned as an enum.
@@ -3194,7 +3231,7 @@ amdsmi_get_gpu_memory_total(amdsmi_processor_handle processor_handle, amdsmi_mem
/**
* @brief Get the current memory usage
*
*
* @ingroup tagMemoryQuery
*
* @platform{gpu_bm_linux}
@@ -3279,7 +3316,7 @@ amdsmi_get_gpu_bad_page_threshold(amdsmi_processor_handle processor_handle, uint
*
* @details This call will verify the device @p processor_handle for the
* checksum of RAS EEPROM.
*
*
* @param[in] processor_handle a processor handle
*
* @note This function requires root access
@@ -5718,6 +5755,7 @@ amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_handle, amdsmi_driv
amdsmi_status_t
amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_info_t *info);
/**
* @brief Returns the KFD (Kernel Fusion Driver) information for the device
*
+5
查看文件
@@ -80,6 +80,11 @@ class AMDSmiGPUDevice: public AMDSmiProcessor {
amdsmi_status_t amdgpu_query_driver_name(std::string& name) const;
amdsmi_status_t amdgpu_query_driver_date(std::string& date) const;
// New methods for -e feature
std::string bdf_to_string() const;
uint32_t get_card_from_bdf() const;
uint32_t get_render_id() const;
private:
uint32_t gpu_id_;
uint32_t fd_;
+2 -1
查看文件
@@ -80,9 +80,10 @@ try:
except AttributeError:
pass
from .amdsmi_interface import amdsmi_get_processor_handle_from_bdf
from .amdsmi_interface import amdsmi_get_gpu_device_bdf
from .amdsmi_interface import amdsmi_get_gpu_device_uuid
from .amdsmi_interface import amdsmi_get_processor_handle_from_bdf
from .amdsmi_interface import amdsmi_get_gpu_enumeration_info
# # SW Version Information
from .amdsmi_interface import amdsmi_get_gpu_driver_info
+59 -20
查看文件
@@ -1690,6 +1690,65 @@ def amdsmi_get_gpu_device_bdf(processor_handle: amdsmi_wrapper.amdsmi_processor_
return _format_bdf(bdf_info)
def amdsmi_get_gpu_device_uuid(processor_handle: amdsmi_wrapper.amdsmi_processor_handle) -> str:
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
raise AmdSmiParameterException(
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
)
uuid = ctypes.create_string_buffer(AMDSMI_GPU_UUID_SIZE)
uuid_length = ctypes.c_uint32()
uuid_length.value = AMDSMI_GPU_UUID_SIZE
_check_res(
amdsmi_wrapper.amdsmi_get_gpu_device_uuid(
processor_handle, ctypes.byref(uuid_length), uuid
)
)
return uuid.value.decode("utf-8")
def amdsmi_get_gpu_enumeration_info(processor_handle: amdsmi_wrapper.amdsmi_processor_handle) -> Dict[str, Any]:
"""
Retrieves GPU enumeration information including DRM card ID, DRM render ID, HIP ID, and HIP UUID.
Parameters:
processor_handle (amdsmi_processor_handle): The processor handle.
Returns:
Dict[str, Any]: A dictionary containing the retrieved enumeration information.
Raises:
AmdSmiParameterException: If the input parameters are invalid.
"""
# Validate the processor handle
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
raise AmdSmiParameterException(
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
)
# Create an instance of the enumeration info struct
enumeration_info = amdsmi_wrapper.amdsmi_enumeration_info_t()
# Call the C function to populate the struct
status = amdsmi_wrapper.amdsmi_get_gpu_enumeration_info(processor_handle, ctypes.byref(enumeration_info))
# Validate the status result
_check_res(status)
# Convert the struct fields into a dictionary and return
enumeration_info = {
"drm_render": _validate_if_max_uint(enumeration_info.drm_render, MaxUIntegerTypes.UINT32_T),
"drm_card": _validate_if_max_uint(enumeration_info.drm_render, MaxUIntegerTypes.UINT32_T),
"hsa_id": _validate_if_max_uint(enumeration_info.hsa_id, MaxUIntegerTypes.UINT32_T),
"hip_id": _validate_if_max_uint(enumeration_info.hip_id, MaxUIntegerTypes.UINT32_T),
"hip_uuid": enumeration_info.hip_uuid.decode('utf-8')
}
return enumeration_info
def amdsmi_get_gpu_asic_info(
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
) -> Dict[str, Any]:
@@ -2258,26 +2317,6 @@ def amdsmi_get_gpu_process_list(
return result
def amdsmi_get_gpu_device_uuid(processor_handle: amdsmi_wrapper.amdsmi_processor_handle) -> str:
if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle):
raise AmdSmiParameterException(
processor_handle, amdsmi_wrapper.amdsmi_processor_handle
)
uuid = ctypes.create_string_buffer(AMDSMI_GPU_UUID_SIZE)
uuid_length = ctypes.c_uint32()
uuid_length.value = AMDSMI_GPU_UUID_SIZE
_check_res(
amdsmi_wrapper.amdsmi_get_gpu_device_uuid(
processor_handle, ctypes.byref(uuid_length), uuid
)
)
return uuid.value.decode("utf-8")
def amdsmi_get_gpu_driver_info(
processor_handle: amdsmi_wrapper.amdsmi_processor_handle,
) -> Dict[str, Any]:
+36 -19
查看文件
@@ -827,6 +827,19 @@ union_amdsmi_bdf_t._fields_ = [
]
amdsmi_bdf_t = union_amdsmi_bdf_t
class struct_amdsmi_enumeration_info_t(Structure):
pass
struct_amdsmi_enumeration_info_t._pack_ = 1 # source:False
struct_amdsmi_enumeration_info_t._fields_ = [
('drm_render', ctypes.c_uint32),
('drm_card', ctypes.c_uint32),
('hsa_id', ctypes.c_uint32),
('hip_id', ctypes.c_uint32),
('hip_uuid', ctypes.c_char * 256),
]
amdsmi_enumeration_info_t = struct_amdsmi_enumeration_info_t
# values for enumeration 'amdsmi_card_form_factor_t'
amdsmi_card_form_factor_t__enumvalues = {
@@ -843,21 +856,6 @@ 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
@@ -878,6 +876,21 @@ 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_),
@@ -2243,6 +2256,9 @@ amdsmi_get_gpu_device_bdf.argtypes = [amdsmi_processor_handle, ctypes.POINTER(un
amdsmi_get_gpu_device_uuid = _libraries['libamd_smi.so'].amdsmi_get_gpu_device_uuid
amdsmi_get_gpu_device_uuid.restype = amdsmi_status_t
amdsmi_get_gpu_device_uuid.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_char)]
amdsmi_get_gpu_enumeration_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_enumeration_info
amdsmi_get_gpu_enumeration_info.restype = amdsmi_status_t
amdsmi_get_gpu_enumeration_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_amdsmi_enumeration_info_t)]
amdsmi_get_gpu_id = _libraries['libamd_smi.so'].amdsmi_get_gpu_id
amdsmi_get_gpu_id.restype = amdsmi_status_t
amdsmi_get_gpu_id.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint16)]
@@ -2957,9 +2973,9 @@ __all__ = \
'amdsmi_dimm_thermal_t', 'amdsmi_dpm_level_t',
'amdsmi_dpm_policy_entry_t', 'amdsmi_dpm_policy_t',
'amdsmi_driver_info_t', 'amdsmi_engine_usage_t',
'amdsmi_error_count_t', 'amdsmi_event_group_t',
'amdsmi_event_handle_t', 'amdsmi_event_type_t',
'amdsmi_evt_notification_data_t',
'amdsmi_enumeration_info_t', 'amdsmi_error_count_t',
'amdsmi_event_group_t', 'amdsmi_event_handle_t',
'amdsmi_event_type_t', 'amdsmi_evt_notification_data_t',
'amdsmi_evt_notification_type_t',
'amdsmi_first_online_core_on_cpu_socket',
'amdsmi_free_name_value_pairs', 'amdsmi_freq_ind_t',
@@ -3005,6 +3021,7 @@ __all__ = \
'amdsmi_get_gpu_device_bdf', 'amdsmi_get_gpu_device_uuid',
'amdsmi_get_gpu_driver_info', 'amdsmi_get_gpu_ecc_count',
'amdsmi_get_gpu_ecc_enabled', 'amdsmi_get_gpu_ecc_status',
'amdsmi_get_gpu_enumeration_info',
'amdsmi_get_gpu_event_notification', 'amdsmi_get_gpu_fan_rpms',
'amdsmi_get_gpu_fan_speed', 'amdsmi_get_gpu_fan_speed_max',
'amdsmi_get_gpu_id', 'amdsmi_get_gpu_kfd_info',
@@ -3123,7 +3140,7 @@ __all__ = \
'struct_amdsmi_dimm_thermal_t', 'struct_amdsmi_dpm_level_t',
'struct_amdsmi_dpm_policy_entry_t', 'struct_amdsmi_dpm_policy_t',
'struct_amdsmi_driver_info_t', 'struct_amdsmi_engine_usage_t',
'struct_amdsmi_error_count_t',
'struct_amdsmi_enumeration_info_t', 'struct_amdsmi_error_count_t',
'struct_amdsmi_evt_notification_data_t',
'struct_amdsmi_freq_volt_region_t', 'struct_amdsmi_frequencies_t',
'struct_amdsmi_frequency_range_t', 'struct_amdsmi_fw_info_t',
+101 -34
查看文件
@@ -54,6 +54,7 @@
#include "rocm_smi/rocm_smi_logger.h"
#include "rocm_smi/rocm_smi_utils.h"
#include "rocm_smi/rocm_smi.h"
#include "rocm_smi/rocm_smi_kfd.h"
// a global instance of std::mutex to protect data passed during threads
std::mutex myMutex;
@@ -124,6 +125,7 @@ static amdsmi_status_t get_gpu_device_from_handle(amdsmi_processor_handle proces
return AMDSMI_STATUS_NOT_SUPPORTED;
}
template <typename F, typename ...Args>
amdsmi_status_t rsmi_wrapper(F && f,
amdsmi_processor_handle processor_handle, uint32_t increment_gpu_id = 0, Args &&... args) {
@@ -510,8 +512,8 @@ amdsmi_status_t amdsmi_get_processor_handles_by_type(amdsmi_socket_handle socket
return AMDSMI_STATUS_SUCCESS;
}
#endif
amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_handle ,
processor_type_t* processor_type) {
@@ -549,7 +551,103 @@ amdsmi_get_gpu_device_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_gpu_board_info(amdsmi_processor_handle processor_handle, amdsmi_board_info_t *board_info) {
amdsmi_status_t
amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle,
unsigned int *uuid_length,
char *uuid) {
AMDSMI_CHECK_INIT();
if (uuid_length == nullptr || uuid == nullptr || uuid_length == nullptr || *uuid_length < AMDSMI_GPU_UUID_SIZE) {
return AMDSMI_STATUS_INVAL;
}
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (r != AMDSMI_STATUS_SUCCESS)
return r;
amdsmi_status_t status = AMDSMI_STATUS_SUCCESS;
SMIGPUDEVICE_MUTEX(gpu_device->get_mutex())
amdsmi_asic_info_t asic_info = {};
const uint8_t fcn = 0xff;
status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info);
if (status != AMDSMI_STATUS_SUCCESS) {
printf("Getting asic info failed. Return code: %d", status);
return status;
}
/* generate random UUID */
status = amdsmi_uuid_gen(uuid,
strtoull(asic_info.asic_serial, nullptr, 16),
(uint16_t)asic_info.device_id, fcn);
return status;
}
amdsmi_status_t
amdsmi_get_gpu_enumeration_info(amdsmi_processor_handle processor_handle,
amdsmi_enumeration_info_t *info){
// Ensure library initialization
AMDSMI_CHECK_INIT();
if (info == nullptr) {
return AMDSMI_STATUS_INVAL;
}
amdsmi_status_t status;
// Retrieve GPU device from the processor handle
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
status = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
// Retrieve DRM Card ID
info->drm_card = gpu_device->get_card_from_bdf();
// Retrieve DRM Render ID
info->drm_render = gpu_device->get_render_id();
// Retrieve HIP ID (difference from the smallest node ID) and HSA ID
std::map<uint64_t, std::shared_ptr<amd::smi::KFDNode>> nodes;
if (amd::smi::DiscoverKFDNodes(&nodes) == 0) {
uint32_t smallest_node_id = std::numeric_limits<uint32_t>::max();
for (const auto& node_pair : nodes) {
uint32_t node_id = 0;
if (node_pair.second->get_node_id(&node_id) == 0) {
smallest_node_id = std::min(smallest_node_id, node_id);
}
}
// Default to 0xffffffff as not supported
info->hsa_id = std::numeric_limits<uint32_t>::max();
info->hip_id = std::numeric_limits<uint32_t>::max();
amdsmi_kfd_info_t kfd_info;
status = amdsmi_get_gpu_kfd_info(processor_handle, &kfd_info);
if (status == AMDSMI_STATUS_SUCCESS) {
info->hsa_id = kfd_info.node_id;
info->hip_id = kfd_info.node_id - smallest_node_id;
}
}
// Retrieve HIP UUID
std::string hip_uuid_str = "GPU-";
amdsmi_asic_info_t asic_info = {};
status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info);
if (status == AMDSMI_STATUS_SUCCESS) {
hip_uuid_str += std::string(asic_info.asic_serial).substr(0, sizeof(info->hip_uuid) - hip_uuid_str.size() - 1);
std::strncpy(info->hip_uuid, hip_uuid_str.c_str(), sizeof(info->hip_uuid) - 1);
info->hip_uuid[sizeof(info->hip_uuid) - 1] = '\0'; // Ensure null termination
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t
amdsmi_get_gpu_board_info(amdsmi_processor_handle processor_handle, amdsmi_board_info_t *board_info) {
AMDSMI_CHECK_INIT();
if (board_info == nullptr) {
@@ -1277,6 +1375,7 @@ amdsmi_get_gpu_asic_info(amdsmi_processor_handle processor_handle, amdsmi_asic_i
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t
amdsmi_get_gpu_xgmi_link_status(amdsmi_processor_handle processor_handle,
amdsmi_xgmi_link_status_t *link_status) {
@@ -3399,38 +3498,6 @@ amdsmi_status_t amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_han
}
amdsmi_status_t
amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned int *uuid_length, char *uuid) {
AMDSMI_CHECK_INIT();
if (uuid_length == nullptr || uuid == nullptr || uuid_length == nullptr || *uuid_length < AMDSMI_GPU_UUID_SIZE) {
return AMDSMI_STATUS_INVAL;
}
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (r != AMDSMI_STATUS_SUCCESS)
return r;
amdsmi_status_t status = AMDSMI_STATUS_SUCCESS;
SMIGPUDEVICE_MUTEX(gpu_device->get_mutex())
amdsmi_asic_info_t asic_info = {};
const uint8_t fcn = 0xff;
status = amdsmi_get_gpu_asic_info(processor_handle, &asic_info);
if (status != AMDSMI_STATUS_SUCCESS) {
printf("Getting asic info failed. Return code: %d", status);
return status;
}
/* generate random UUID */
status = amdsmi_uuid_gen(uuid,
strtoull(asic_info.asic_serial, nullptr, 16),
(uint16_t)asic_info.device_id, fcn);
return status;
}
amdsmi_status_t amdsmi_get_pcie_info(amdsmi_processor_handle processor_handle, amdsmi_pcie_info_t *info) {
AMDSMI_CHECK_INIT();
+72
查看文件
@@ -30,6 +30,7 @@
#include <map>
#include <memory>
#include <unordered_set>
#include <filesystem>
namespace amd {
namespace smi {
@@ -285,6 +286,77 @@ const GPUComputeProcessList_t& AMDSmiGPUDevice::amdgpu_get_compute_process_list(
return compute_process_list_;
}
// Convert `amdsmi_bdf_t` to a PCI BDF string
std::string AMDSmiGPUDevice::bdf_to_string() const {
std::ostringstream oss;
oss << std::setfill('0') << std::hex // Use hexadecimal formatting
<< std::setw(4) << bdf_.domain_number << ":" // Domain (4 digits)
<< std::setw(2) << static_cast<int>(bdf_.bus_number) << ":" // Bus (2 digits)
<< std::setw(2) << static_cast<int>(bdf_.device_number) << "." // Device (2 digits)
<< static_cast<int>(bdf_.function_number); // Function (1 digit)
return oss.str();
}
uint32_t AMDSmiGPUDevice::get_card_from_bdf() const {
const std::string drm_path = "/sys/class/drm/";
// Iterate over the contents of /sys/class/drm/
for (const auto& entry : std::filesystem::directory_iterator(drm_path)) {
const std::string device_name = entry.path().filename();
// Check if the entry starts with "card"
if (device_name.find("card") == 0) {
const std::string card_path = drm_path + device_name + "/device";
// Open the uevent file for the device
std::ifstream uevent_file(card_path + "/uevent");
if (!uevent_file) {
continue; // Skip if the file is not found
}
std::string line;
while (std::getline(uevent_file, line)) {
// Check for the PCI_SLOT_NAME and if it contains the BDF
if (line.rfind("PCI_SLOT_NAME", 0) == 0 && line.find(bdf_to_string()) != std::string::npos) {
return std::stoi(device_name.substr(4)); // Convert extracted number to int
}
}
}
}
return std::numeric_limits<uint32_t>::max(); // Return -1 if no matching card is found
}
uint32_t AMDSmiGPUDevice::get_render_id() const {
const std::string drm_path = "/sys/class/drm/";
// Iterate over the contents of /sys/class/drm/
for (const auto& entry : std::filesystem::directory_iterator(drm_path)) {
const std::string device_name = entry.path().filename();
// Check if the entry starts with "renderD"
if (device_name.find("renderD") == 0) {
const std::string render_path = drm_path + device_name + "/device";
// Open the uevent file for the device
std::ifstream uevent_file(render_path + "/uevent");
if (!uevent_file) {
continue; // Skip if the file is not found
}
std::string line;
while (std::getline(uevent_file, line)) {
// Check for the PCI_SLOT_NAME and if it contains the BDF
if (line.rfind("PCI_SLOT_NAME", 0) == 0 && line.find(bdf_to_string()) != std::string::npos) {
return std::stoi(device_name.substr(7)); // Extract only the number after "renderD"
}
}
}
}
return std::numeric_limits<uint32_t>::max(); // Return -1 if no matching render ID is found
}
} // namespace smi
} // namespace amd