2
0

[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>
Este cometimento está contido em:
AL Musaffar, Yazen
2025-03-07 09:09:12 -06:00
cometido por GitHub
ascendente d5b2763aba
cometimento 2936e00fed
11 ficheiros modificados com 417 adições e 88 eliminações
+101 -34
Ver ficheiro
@@ -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
Ver ficheiro
@@ -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