amd-smi: fix cpu specific apis and header

1. provide prototype and documentation for esmi specific api.
   define structures and update classes as required
2. update cmake files as required and add esmi api to the
   amdsmi esmi integration example.

Change-Id: I753ec176f9b381e74c9646525dfd9075237bf8d9
Este commit está contenido en:
Naveen Krishna Chatradhi
2023-12-07 06:46:48 -08:00
cometido por khashaik
padre 8f3861e1d9
commit 65eed73f4d
Se han modificado 12 ficheros con 752 adiciones y 1470 borrados
+292 -335
Ver fichero
La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff
-62
Ver fichero
@@ -1,62 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <functional>
#include "amd_smi/impl/amd_smi_cpu_core.h"
namespace amd {
namespace smi {
AMDSmiCpuCore::~AMDSmiCpuCore() {
for (uint32_t i = 0; i < processors_.size(); i++) {
delete processors_[i];
}
processors_.clear();
}
amdsmi_status_t AMDSmiCpuCore::get_processor_count(uint32_t* processor_count) const {
*processor_count = static_cast<uint32_t>(processors_.size());
return AMDSMI_STATUS_SUCCESS;
}
} // namespace smi
} // namespace amd
-72
Ver fichero
@@ -1,72 +0,0 @@
/*
* =============================================================================
* The University of Illinois/NCSA
* Open Source License (NCSA)
*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All rights reserved.
*
* Developed by:
*
* AMD Research and AMD ROC Software Development
*
* Advanced Micro Devices, Inc.
*
* www.amd.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal with the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimers.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimers in
* the documentation and/or other materials provided with the distribution.
* - Neither the names of <Name of Development Group, Name of Institution>,
* nor the names of its contributors may be used to endorse or promote
* products derived from this Software without specific prior written
* permission.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS WITH THE SOFTWARE.
*
*/
#include <functional>
#include "amd_smi/impl/amd_smi_cpu_socket.h"
#include <cpuid.h>
namespace amd {
namespace smi {
AMDSmiCpuSocket::~AMDSmiCpuSocket() {}
amdsmi_status_t AMDSmiCpuSocket::set_socket_id(uint32_t idx, uint32_t socket_id) {
socket_id = idx;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiCpuSocket::get_cpu_vendor() {
uint32_t eax, ebx, ecx, edx;
if (!__get_cpuid(0, &eax, &ebx, &ecx, &edx))
return AMDSMI_STATUS_IO;
/* check if the value in ebx, ecx, edx matches "AuthenticAMD" string */
if (ebx != 0x68747541 || ecx != 0x444d4163 || edx != 0x69746e65)
return AMDSMI_STATUS_NON_AMD_CPU;
return AMDSMI_STATUS_SUCCESS;
}
} // namespace smi
} // namespace amd
+28
Ver fichero
@@ -53,6 +53,14 @@ AMDSmiSocket::~AMDSmiSocket() {
delete processors_[i];
}
processors_.clear();
for (uint32_t i = 0; i < cpu_processors_.size(); i++) {
delete cpu_processors_[i];
}
cpu_processors_.clear();
for (uint32_t i = 0; i < cpu_core_processors_.size(); i++) {
delete cpu_core_processors_[i];
}
cpu_core_processors_.clear();
}
amdsmi_status_t AMDSmiSocket::get_processor_count(uint32_t* processor_count) const {
@@ -60,6 +68,26 @@ amdsmi_status_t AMDSmiSocket::get_processor_count(uint32_t* processor_count) con
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSocket::get_processor_count(processor_type_t type, uint32_t* processor_count) const {
amdsmi_status_t ret = AMDSMI_STATUS_SUCCESS;
switch (type) {
case AMD_GPU:
*processor_count = static_cast<uint32_t>(processors_.size());
break;
case AMD_CPU:
*processor_count = static_cast<uint32_t>(cpu_processors_.size());
break;
case AMD_CPU_CORE:
*processor_count = static_cast<uint32_t>(cpu_core_processors_.size());
break;
default:
*processor_count = 0;
ret = AMDSMI_STATUS_INVAL;
break;
}
return ret;
}
} // namespace smi
} // namespace amd
+96 -161
Ver fichero
@@ -53,16 +53,65 @@
namespace amd {
namespace smi {
#ifdef ENABLE_ESMI_LIB
uint32_t AMDSmiSystem::sockets = 0;
uint32_t AMDSmiSystem::cpus = 0;
uint32_t AMDSmiSystem::threads = 0;
uint32_t AMDSmiSystem::family = 0;
uint32_t AMDSmiSystem::model = 0;
#endif
#define AMD_SMI_INIT_FLAG_RESRV_TEST1 0x800000000000000 //!< Reserved for test
static amdsmi_status_t get_cpu_family(uint32_t *cpu_family) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_cpu_family_get(cpu_family));
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get cpu family, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
static amdsmi_status_t get_cpu_model(uint32_t *cpu_model) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_cpu_model_get(cpu_model));
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get cpu model, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
static amdsmi_status_t get_nr_cpu_cores(uint32_t *num_cpus) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_number_of_cpus_get(num_cpus));
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get number of cpus, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
static amdsmi_status_t get_nr_threads_per_core(uint32_t *threads_per_core) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_threads_per_core_get(threads_per_core));
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get threads per core, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
static amdsmi_status_t get_nr_cpu_sockets(uint32_t *num_socks) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_number_of_sockets_get(num_socks));
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get number of sockets, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::init(uint64_t flags) {
init_flag_ = flags;
amdsmi_status_t amd_smi_status;
@@ -73,137 +122,61 @@ amdsmi_status_t AMDSmiSystem::init(uint64_t flags) {
return amd_smi_status;
#ifdef ENABLE_ESMI_LIB
}
else if(flags & AMDSMI_INIT_AMD_CPUS) {
if (flags & AMDSMI_INIT_AMD_CPUS) {
amd_smi_status = populate_amd_cpus();
if (amd_smi_status != AMDSMI_STATUS_SUCCESS)
return amd_smi_status;
#endif
} else {
return AMDSMI_STATUS_NOT_SUPPORTED;
}
#endif
return AMDSMI_STATUS_SUCCESS;
}
#ifdef ENABLE_ESMI_LIB
amdsmi_status_t AMDSmiSystem::populate_amd_cpus() {
uint32_t sockets, cpus, threads;
amdsmi_status_t amd_smi_status;
amd::smi::AMDSmiCpuSocket *cpu_instance = nullptr;
/* detect if its an AMD cpu */
amd_smi_status = cpu_instance->get_cpu_vendor();
/* esmi is for AMD cpus, if its not AMD CPU, we are not going to initialise esmi */
if (!amd_smi_status) {
amd_smi_status = static_cast<amdsmi_status_t>(esmi_init());
if (amd_smi_status != AMDSMI_STATUS_SUCCESS){
std::cout<<"\tESMI Not initialized, drivers not found " << std::endl;
return amd_smi_status;
}
amd_smi_status = static_cast<amdsmi_status_t>(esmi_init());
if (amd_smi_status != AMDSMI_STATUS_SUCCESS){
std::cout<<"\tESMI Not initialized, drivers not found " << std::endl;
return amd_smi_status;
}
amd_smi_status = get_cpu_sockets(&sockets);
amd_smi_status = get_cpu_cores(&cpus);
amd_smi_status = get_threads_per_core(&threads);
amd_smi_status = get_cpu_family(&family);
amd_smi_status = get_cpu_model(&model);
std::cout << "\n***********************EPYC METRICS***********************" << std::endl;
std::cout <<"| NR_SOCKETS | "<<sockets<<"\t\t|" << std::endl;
std::cout <<"| NR_CPUS | "<<cpus<<"\t\t|" << std::endl;
if (threads > 1) {
std::cout <<"| THREADS PER CORE | "<<threads<<" (SMT ON)\t|" << std::endl;
} else {
std::cout <<"| THREADS PER CORE | "<<threads<<" (SMT OFF)\t|" << std::endl;
}
std::cout <<"| CPU Family | 0x"<<std::hex<<family<<"("<<std::dec<<family<<")\t|" << std::endl;
std::cout <<"| CPU Model | 0x"<<std::hex<<model<<"("<<std::dec<<model<<")\t|" << std::endl;
std::cout << std::endl;
amd_smi_status = get_nr_cpu_sockets(&sockets);
amd_smi_status = get_nr_cpu_cores(&cpus);
amd_smi_status = get_nr_threads_per_core(&threads);
for(uint32_t i = 0; i < sockets; i++) {
uint32_t cpu_socket_id = i;
std::string cpu_socket_id = std::to_string(i);
// Multiple cores may share the same socket
AMDSmiCpuSocket* socket = nullptr;
for (uint32_t j = 0; j < cpu_sockets_.size(); j++) {
if (cpu_sockets_[j]->get_socket_id() == cpu_socket_id) {
socket = cpu_sockets_[j];
AMDSmiSocket* socket = nullptr;
for (uint32_t j = 0; j < sockets_.size(); j++) {
if (sockets_[j]->get_socket_id() == cpu_socket_id) {
socket = sockets_[j];
break;
}
}
if (socket == nullptr) {
socket = new AMDSmiCpuSocket(cpu_socket_id);
cpu_sockets_.push_back(socket);
socket = new AMDSmiSocket(cpu_socket_id);
sockets_.push_back(socket);
}
AMDSmiProcessor* cpusocket = new AMDSmiProcessor(AMD_CPU, i);
socket->add_processor(cpusocket);
processors_.insert(cpusocket);
for (uint32_t k = 0; k < cpus/threads; k++) {
AMDSmiCpuCore* core = new AMDSmiCpuCore(k);
for (uint32_t k = 0; k < (cpus/threads)/sockets; k++) {
AMDSmiProcessor* core = new AMDSmiProcessor(AMD_CPU_CORE, k);
socket->add_processor(core);
processors_.insert(core);
}
}
std::cout << std::endl;
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::get_cpu_sockets(uint32_t *num_socks) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_number_of_sockets_get(num_socks));
sockets = *num_socks;
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get number of sockets, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::get_cpu_cores(uint32_t *num_cpus) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_number_of_cpus_get(num_cpus));
cpus = *num_cpus;
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get number of cpus, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::get_threads_per_core(uint32_t *threads_per_core) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_threads_per_core_get(threads_per_core));
threads = *threads_per_core;
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get threads per core, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::get_cpu_family(uint32_t *cpu_family) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_cpu_family_get(cpu_family));
family = *cpu_family;
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get cpu family, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t AMDSmiSystem::get_cpu_model(uint32_t *cpu_model) {
amdsmi_status_t ret;
ret = static_cast<amdsmi_status_t>(esmi_cpu_model_get(cpu_model));
model = *cpu_model;
if (ret != AMDSMI_STATUS_SUCCESS) {
std::cout << "Failed to get cpu model, Err["<<ret<<"]" << std::endl;
return ret;
}
return AMDSMI_STATUS_SUCCESS;
}
#endif
amdsmi_status_t AMDSmiSystem::populate_amd_gpu_devices() {
@@ -281,29 +254,31 @@ amdsmi_status_t AMDSmiSystem::get_gpu_socket_id(uint32_t index,
amdsmi_status_t AMDSmiSystem::cleanup() {
#ifdef ENABLE_ESMI_LIB
if(init_flag_ == AMDSMI_INIT_AMD_CPUS){
for (uint32_t i = 0; i < cpu_sockets_.size(); i++) {
delete cpu_sockets_[i];
if (init_flag_ & AMDSMI_INIT_AMD_CPUS) {
for (uint32_t i = 0; i < sockets_.size(); i++) {
delete sockets_[i];
}
cpu_sockets_.clear();
processors_.clear();
sockets_.clear();
esmi_exit();
init_flag_ = AMDSMI_INIT_ALL_PROCESSORS;
return AMDSMI_STATUS_SUCCESS;
}
#endif
for (uint32_t i = 0; i < sockets_.size(); i++) {
delete sockets_[i];
}
processors_.clear();
sockets_.clear();
init_flag_ = AMDSMI_INIT_ALL_PROCESSORS;
rsmi_status_t ret = rsmi_shut_down();
if (ret != RSMI_STATUS_SUCCESS) {
return amd::smi::rsmi_to_amdsmi_status(ret);
if (init_flag_ & AMDSMI_INIT_AMD_GPUS) {
for (uint32_t i = 0; i < sockets_.size(); i++) {
delete sockets_[i];
}
processors_.clear();
sockets_.clear();
init_flag_ = AMDSMI_INIT_ALL_PROCESSORS;
rsmi_status_t ret = rsmi_shut_down();
if (ret != RSMI_STATUS_SUCCESS) {
return amd::smi::rsmi_to_amdsmi_status(ret);
}
drm_.cleanup();
}
drm_.cleanup();
return AMDSMI_STATUS_SUCCESS;
}
@@ -323,24 +298,6 @@ amdsmi_status_t AMDSmiSystem::handle_to_socket(
return AMDSMI_STATUS_INVAL;
}
#ifdef ENABLE_ESMI_LIB
amdsmi_status_t AMDSmiSystem::handle_to_cpusocket(
amdsmi_cpusocket_handle socket_handle,
AMDSmiCpuSocket** socket) {
if (socket_handle == nullptr || socket == nullptr) {
return AMDSMI_STATUS_INVAL;
}
*socket = static_cast<AMDSmiCpuSocket*>(socket_handle);
// double check handlers is here
if (std::find(cpu_sockets_.begin(), cpu_sockets_.end(), *socket)
!= cpu_sockets_.end()) {
return AMDSMI_STATUS_SUCCESS;
}
return AMDSMI_STATUS_INVAL;
}
#endif
amdsmi_status_t AMDSmiSystem::handle_to_processor(
amdsmi_processor_handle processor_handle,
AMDSmiProcessor** processor) {
@@ -378,28 +335,6 @@ amdsmi_status_t AMDSmiSystem::gpu_index_to_handle(uint32_t gpu_index,
return AMDSMI_STATUS_INVAL;
}
#ifdef ENABLE_ESMI_LIB
amdsmi_status_t AMDSmiSystem::cpu_index_to_handle(uint32_t cpu_index,
amdsmi_cpusocket_handle* cpu_handle) {
if (cpu_handle == nullptr)
return AMDSMI_STATUS_INVAL;
auto iter = cpu_sockets_.begin();
for (; iter != cpu_sockets_.end(); iter++) {
auto cur_socket = (*iter);
if (cur_socket->get_processor_type() != AMD_CPU)
continue;
amd::smi::AMDSmiCpuSocket* cpu_socket =
static_cast<amd::smi::AMDSmiCpuSocket*>(cur_socket);
uint32_t cur_cpu_index = cpu_socket->get_cpu_id();
if (cpu_index == cur_cpu_index) {
*cpu_handle = cur_socket;
return AMDSMI_STATUS_SUCCESS;
}
}
return AMDSMI_STATUS_INVAL;
}
#endif
} // namespace smi
} // namespace amd