[SWDEV-512393] Added amdsmi_get_cpu_affinity_with_scope (#198)

Signed-off-by: Maisam Arif <Maisam.Arif@amd.com>
Signed-off-by: Deepak Mewar <deepak.mewar@amd.com>
This commit is contained in:
Mewar, Deepak
2025-05-20 11:36:09 +05:30
committed by GitHub
parent 51e99965b3
commit b999f86611
15 changed files with 524 additions and 39 deletions
+110 -2
View File
@@ -3941,8 +3941,8 @@ amdsmi_get_gpu_cper_entries(
std::string path = std::string("/sys/kernel/debug/dri/") +
std::to_string(gpu_device->get_card_id()) +
"/amdgpu_ring_cper";
return amdsmi_get_gpu_cper_entries_by_path(
path.c_str(),
severity_mask,
@@ -4795,6 +4795,85 @@ amdsmi_get_gpu_virtualization_mode(amdsmi_processor_handle processor_handle,
return status;
}
amdsmi_status_t amdsmi_get_cpu_affinity_with_scope(amdsmi_processor_handle processor_handle,
uint32_t cpu_set_size, uint64_t *cpu_set, amdsmi_affinity_scope_t scope)
{
AMDSMI_CHECK_INIT();
if (processor_handle == nullptr || cpu_set == nullptr || cpu_set_size == 0) {
return AMDSMI_STATUS_INVAL;
}
// Retrieve GPU device from the processor handle
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
amdsmi_status_t status = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
uint32_t numa_node;
status = amdsmi_topo_get_numa_node_number(processor_handle, &numa_node);
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
int32_t node_id = static_cast<int32_t>(numa_node);
status = amdsmi_get_gpu_topo_numa_affinity(processor_handle, &node_id);
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
if(node_id < 0) {
return AMDSMI_STATUS_NOT_FOUND;
}
std::memset(cpu_set, 0, cpu_set_size * sizeof(uint64_t));
switch(scope) {
case AMDSMI_AFFINITY_SCOPE_NODE:
{
std::vector<uint64_t> bitmask = gpu_device->get_bitmask_from_numa_node(node_id, cpu_set_size);
if(bitmask[0] == std::numeric_limits<int32_t>::max()){
return AMDSMI_STATUS_REFCOUNT_OVERFLOW;
} else {
std::memcpy(cpu_set, bitmask.data(), cpu_set_size * sizeof(uint64_t));
}
break;
}
case AMDSMI_AFFINITY_SCOPE_SOCKET:
{
std::vector<uint32_t> sockets = amd::smi::AMDSmiSystem::getInstance().get_cpu_sockets_from_numa_node(node_id);
if(sockets[0] == std::numeric_limits<int32_t>::max()){
return AMDSMI_STATUS_REFCOUNT_OVERFLOW;
} else {
for (uint32_t idx : sockets) {
cpu_set[idx] = idx;
}
std::sort(cpu_set, cpu_set + cpu_set_size);
// Discard duplicates
uint32_t temp_size = 0;
for (uint32_t i = 0; i < cpu_set_size; ++i) {
if (i == 0 || cpu_set[i] != cpu_set[i - 1]) {
cpu_set[temp_size++] = cpu_set[i];
}
}
// Update the size to the temp size after discarding duplicates
cpu_set_size = temp_size;
}
break;
}
default:
return AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS;
}
return AMDSMI_STATUS_SUCCESS;
}
#ifdef ENABLE_ESMI_LIB
static amdsmi_status_t amdsmi_errno_to_esmi_status(amdsmi_status_t status)
@@ -5905,6 +5984,35 @@ amdsmi_status_t amdsmi_get_cpu_model_name(amdsmi_processor_handle processor_hand
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_cores_per_socket(uint32_t sock_count, amdsmi_sock_info_t *sock_info)
{
std::map<uint32_t, uint32_t> socket_core_count = amd::smi::AMDSmiSystem::getInstance().get_sys_cpu_cores_per_socket();
for (uint32_t i = 0; i < sock_count; ++i) {
auto it = socket_core_count.find(sock_info[i].socket_id);
if (it != socket_core_count.end()) {
sock_info[i].cores_per_socket = it->second;
} else {
sock_info[i].cores_per_socket = 0;
}
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_socket_count(uint32_t *sock_count)
{
amdsmi_status_t status;
uint32_t sock_num;
status = amd::smi::AMDSmiSystem::getInstance().get_sys_num_of_cpu_sockets(&sock_num);
if (status != AMDSMI_STATUS_SUCCESS)
return status;
*sock_count = sock_num;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t amdsmi_get_cpu_handles(uint32_t *cpu_count,
amdsmi_processor_handle *processor_handles)
{
+33 -1
View File
@@ -323,7 +323,39 @@ std::string AMDSmiGPUDevice::bdf_to_string() const {
return oss.str();
}
std::vector<uint64_t> AMDSmiGPUDevice::get_bitmask_from_numa_node(int32_t node_id, uint32_t size) const {
std::vector<uint64_t> bitmask(size, 0);
if (node_id < 0) {
bitmask[0] = std::numeric_limits<int32_t>::max();
return bitmask;
}
std::string path = "/sys/devices/system/node/node" + std::to_string(node_id) + "/cpulist";
std::ifstream file(path);
if (file.is_open()) {
std::string info;
while (std::getline(file, info)) {
std::istringstream sstr(info);
std::string node_cpus;
while (std::getline(sstr, node_cpus, ',')) {
size_t hyphen = node_cpus.find('-');
if (hyphen != std::string::npos) {
int start = std::stoi(node_cpus.substr(0, hyphen));
int end = std::stoi(node_cpus.substr(hyphen + 1));
for (int i = start; i <= end; ++i) {
bitmask[i / 64] |= (1ULL << (i % 64));
}
} else {
int core = std::stoi(node_cpus);
bitmask[core / 64] |= (1ULL << (core % 64));
}
}
}
}
return bitmask;
}
} // namespace smi
} // namespace amd
+80 -1
View File
@@ -31,6 +31,7 @@
#include "amd_smi/impl/amd_smi_utils.h"
#include "rocm_smi/rocm_smi.h"
#include "rocm_smi/rocm_smi_main.h"
#include <map>
namespace amd {
namespace smi {
@@ -103,7 +104,7 @@ amdsmi_status_t AMDSmiSystem::get_cpu_model_name(uint32_t socket_id, std::string
if (!cpu_info.is_open()) {
std::cerr << "Failed to open /proc/cpuinfo:" << strerror(errno) << std::endl;
return AMDSMI_STATUS_FILE_ERROR;
} else {
} else {
uint32_t current_socket_id = -1;
while (std::getline(cpu_info, info)) {
if (info.find("processor") != std::string::npos) {
@@ -126,7 +127,85 @@ amdsmi_status_t AMDSmiSystem::get_cpu_model_name(uint32_t socket_id, std::string
}
return AMDSMI_STATUS_SUCCESS;
}
#endif
std::map<uint32_t, uint32_t> AMDSmiSystem::get_sys_cpu_cores_per_socket() {
std::map<uint32_t, uint32_t> socket_core_count;
std::string base_path = "/sys/devices/system/cpu/";
iterate_directory(base_path, [&socket_core_count](const std::string &path) {
std::string filename(basename(path.c_str()));
if (filename.find("cpu") != std::string::npos) {
std::string cpuPath = path;
std::ifstream package_id_file(cpuPath + "/topology/physical_package_id");
std::ifstream core_id_file(cpuPath + "/topology/core_id");
if (package_id_file.is_open() && core_id_file.is_open()) {
uint32_t physical_id, core_id;
package_id_file >> physical_id;
core_id_file >> core_id;
socket_core_count[physical_id]++;
}
}
});
return socket_core_count;
}
amdsmi_status_t AMDSmiSystem::get_sys_num_of_cpu_sockets(uint32_t *sock_num) {
std::map<uint32_t, uint32_t> socket_count_map;
std::string base_path = "/sys/devices/system/cpu/";
iterate_directory(base_path, [&socket_count_map](std::string path) {
std::string filename(basename(path.c_str()));
if (filename.find("cpu") != std::string::npos) {
std::string cpu_path = path;
std::ifstream package_id_file(cpu_path + "/topology/physical_package_id");
if (package_id_file.is_open()) {
uint32_t physical_id;
package_id_file >> physical_id;
socket_count_map[physical_id]++;
}
}
});
*sock_num = static_cast<uint32_t>(socket_count_map.size());
return AMDSMI_STATUS_SUCCESS;
}
std::vector<uint32_t> AMDSmiSystem::get_cpu_sockets_from_numa_node(int32_t numa_node) {
std::vector<uint32_t> sockets;
if (numa_node < 0) {
sockets[0] = std::numeric_limits<int32_t>::max();
return sockets;
}
std::ifstream node_info("/sys/devices/system/node/node" + std::to_string(numa_node) + "/cpulist");
std::string info;
if (node_info.is_open()) {
std::getline(node_info, info);
std::istringstream iss(info);
uint32_t index;
while (iss >> index) {
std::ifstream cpu_info("/sys/devices/system/cpu/cpu" + std::to_string(index) + "/topology/physical_package_id");
if (cpu_info.is_open()) {
uint32_t socket;
cpu_info >> socket;
sockets.push_back(socket);
}
}
}
// Discarding duplicate socket entries
std::sort(sockets.begin(), sockets.end());
sockets.erase(std::unique(sockets.begin(), sockets.end()), sockets.end());
return sockets;
}
amdsmi_status_t AMDSmiSystem::init(uint64_t flags) {
init_flag_ = flags;
+28 -6
View File
@@ -36,15 +36,15 @@
#include <dirent.h>
#include <sys/types.h>
#include <memory>
#include <random>
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <regex>
#include <cstdio>
#include <sstream>
#include <iterator>
#include <algorithm>
#include <memory>
#include <random>
#include <regex>
#include <sstream>
#include "amd_smi/impl/amd_smi_utils.h"
#include "amd_smi/impl/amd_smi_system.h"
@@ -1046,3 +1046,25 @@ void amdsmi_wait_for_user_input(void) {
}
}
}
bool iterate_directory(const std::string &base_path,
std::function<void(const std::string &)> entry_callback) {
DIR *dir = opendir(base_path.c_str());
if (!dir) {
return false;
}
struct dirent *entry = nullptr;
while ((entry = readdir(dir)) != NULL) {
entry_callback(entry->d_name);
}
if (errno != 0) {
closedir(dir);
return false;
}
closedir(dir);
return true;
}