[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>
此提交包含在:
+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`
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
新增問題並參考
封鎖使用者