diff --git a/projects/amdsmi/example/CMakeLists.txt b/projects/amdsmi/example/CMakeLists.txt index 34d61e50c1..fbcd61a283 100644 --- a/projects/amdsmi/example/CMakeLists.txt +++ b/projects/amdsmi/example/CMakeLists.txt @@ -27,3 +27,10 @@ set(SMI_NODRM_EXAMPLE_EXE "amd_smi_nodrm_ex") add_executable(${SMI_NODRM_EXAMPLE_EXE} "amd_smi_nodrm_example.cc") target_link_libraries(${SMI_NODRM_EXAMPLE_EXE} ${AMD_SMI_TARGET}) add_dependencies(${SMI_NODRM_EXAMPLE_EXE} ${AMD_SMI_TARGET}) + +if(ENABLE_ESMI_LIB) +set(ESMI_SAMPLE_EXE "amd_smi_esmi_ex") +add_executable(${ESMI_SAMPLE_EXE} "amdsmi_esmi_intg_example.cc") +target_link_libraries(${ESMI_SAMPLE_EXE} ${AMD_SMI_TARGET}) +add_dependencies(${ESMI_SAMPLE_EXE} ${AMD_SMI_TARGET}) +endif() diff --git a/projects/amdsmi/example/CMakeLists.txt.in b/projects/amdsmi/example/CMakeLists.txt.in index 4cf30ee0b2..c4c4c6a854 100644 --- a/projects/amdsmi/example/CMakeLists.txt.in +++ b/projects/amdsmi/example/CMakeLists.txt.in @@ -21,3 +21,6 @@ link_libraries(amd_smi) # compile example files but do not install add_executable(amd_smi_drm_ex "amd_smi_drm_example.cc") add_executable(amd_smi_nodrm_ex "amd_smi_nodrm_example.cc") +if(ENABLE_ESMI_LIB) +add_executable(amd_smi_esmi_ex "amdsmi_esmi_intg_example.cc") +endif() diff --git a/projects/amdsmi/example/amdsmi_esmi_intg_example.cc b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc new file mode 100644 index 0000000000..78de1f1566 --- /dev/null +++ b/projects/amdsmi/example/amdsmi_esmi_intg_example.cc @@ -0,0 +1,313 @@ +/* + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2022, 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 , + * 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 +#include +#include + +#include +#include +#include +#include +#include "amd_smi/amdsmi.h" +#include + +using namespace std; + +#define SHOWLINESZ 256 + +#define CHK_AMDSMI_RET(RET) \ + { \ + if (RET != AMDSMI_STATUS_SUCCESS) { \ + const char *err_str; \ + std::cout << "AMDSMI call returned " << RET << " at line " \ + << __LINE__ << std::endl; \ + amdsmi_status_code_to_string(RET, &err_str); \ + std::cout << err_str << std::endl; \ + return RET; \ + } \ + } + +int main(int argc, char **argv) { + amdsmi_status_t ret; + uint32_t proto_ver; + amdsmi_smu_fw_version_t smu_fw = {}; + amdsmi_cpusocket_handle socket_handle; + + // Initialize esmi for AMD CPUs + ret = amdsmi_init(AMDSMI_INIT_AMD_CPUS); + CHK_AMDSMI_RET(ret) + + // Get all sockets + uint32_t socket_count = 0; + + ret = amdsmi_get_cpusocket_handles(&socket_count, nullptr); + CHK_AMDSMI_RET(ret) + + // Allocate the memory for the sockets + std::vector sockets(socket_count); + + // Get the sockets of the system + ret = amdsmi_get_cpusocket_handles(&socket_count, &sockets[0]); + CHK_AMDSMI_RET(ret) + + std::cout << "Total Socket: " << socket_count << std::endl; + + // For each socket, get identifier and cores + for (uint32_t i = 0; i < socket_count; i++) { + // Get Socket info + uint32_t socket_info; + ret = amdsmi_get_cpusocket_info(sockets[i], socket_info); + CHK_AMDSMI_RET(ret) + std::cout << "Socket " << socket_info << std::endl; + + // Get the core count available for the socket. + uint32_t core_count = 0; + ret = amdsmi_get_cpucore_handles(sockets[i], &core_count, nullptr); + CHK_AMDSMI_RET(ret) + + // Allocate the memory for the cpu core handles on the socket + std::vector processor_handles(core_count); + // Get all cores of the socket + ret = amdsmi_get_cpucore_handles(sockets[i], + &core_count, &processor_handles[0]); + CHK_AMDSMI_RET(ret) + std::cout << "core_count=" << core_count << std::endl; + + ret = amdsmi_get_hsmp_proto_ver(&proto_ver); + CHK_AMDSMI_RET(ret) + + cout<<"\n------------------------------------------"; + cout<<"\n| HSMP Proto Version | "<< proto_ver <<"\t\t |"<< endl; + cout<<"------------------------------------------\n"; + + ret = amdsmi_get_smu_fw_version(&smu_fw); + CHK_AMDSMI_RET(ret) + + cout<<"\n------------------------------------------"; + cout<<"\n| SMU FW Version | " + <<(unsigned)smu_fw.major<<"." + <<(unsigned)smu_fw.minor<<"." + <<(unsigned)smu_fw.debug + <<"\t\t |"<(pkg_input)/1000000000<<"\t|"; + } else { + err_bits |= 1 << ret; + cout<<" NA (Err:" < 0 && retVal < SHOWLINESZ) + cout << str; + else + cout <<"error writing to buffer" << endl; + + cout<<"\n-------------------------------------------------\n"; + cout<<"-----------------------------------------------------------------"; + ret = amdsmi_get_cpu_cclk_limit(sockets[i], i, &cclk); + CHK_AMDSMI_RET(ret) + cout<<"\n| SOCKET["<(core_input)/1000000<<" Joules\t\t|\n"; + cout<<"-------------------------------------------------\n"; + + core_input = 0; + cout<<"\n| CPU energies in Joules:\t\t\t\t\t\t\t\t\t|"; + for (uint32_t j = 0; j < core_count; j++) { + ret = amdsmi_get_cpu_core_energy(processor_handles[j], j, &core_input); + CHK_AMDSMI_RET(ret) + if(!(j % 8)) { + if(j < 10) + cout<<"\n| cpu [0"<(core_input)/1000000<<" "; + if (j % 8 == 7) + cout<<"\t|"; + } + cout<<"\n-------------------------------------------------\n"; + +#if 0 + uint32_t c_clk = 0; + ret = amdsmi_get_cpu_core_current_freq_limit(processor_handles[i], i, &c_clk); + CHK_AMDSMI_RET(ret) + + cout<<"--------------------------------------------------------------"; + cout<<"\n| CPU["<(power)/1000<<"\t|"; + } else { + err_bits |= 1 << ret; + cout<<" NA (Err:" <(powerlimit)/1000<<"\t|"; + } else { + err_bits |= 1 << ret; + cout<<" NA (Err:" <(powermax)/1000<<"\t|"; + } else { + err_bits |= 1 << ret; + cout<<" NA (Err:" <(svi_power)/1000<<"\t|"; + } else { + err_bits |= 1 << ret; + cout<<" NA (Err:" < rsmi_status_map = { amdsmi_status_t rsmi_to_amdsmi_status(rsmi_status_t status); +#ifdef ENABLE_ESMI_LIB +// Define a map of esmi status codes to amdsmi status codes +const std::map esmi_status_map = { + {ESMI_SUCCESS, AMDSMI_STATUS_SUCCESS}, + {ESMI_INITIALIZED, AMDSMI_STATUS_SUCCESS}, + {ESMI_INVALID_INPUT, AMDSMI_STATUS_INVAL}, + {ESMI_NOT_SUPPORTED, AMDSMI_STATUS_NOT_SUPPORTED}, + {ESMI_PERMISSION, AMDSMI_STATUS_NO_PERM}, + {ESMI_INTERRUPTED, AMDSMI_STATUS_INTERRUPT}, + {ESMI_IO_ERROR, AMDSMI_STATUS_IO}, + {ESMI_FILE_ERROR, AMDSMI_STATUS_FILE_ERROR}, + {ESMI_NO_MEMORY, AMDSMI_STATUS_OUT_OF_RESOURCES}, + {ESMI_DEV_BUSY, AMDSMI_STATUS_BUSY}, + {ESMI_NOT_INITIALIZED, AMDSMI_STATUS_NOT_INIT}, + {ESMI_UNEXPECTED_SIZE, AMDSMI_STATUS_UNEXPECTED_SIZE}, + {ESMI_UNKNOWN_ERROR, AMDSMI_STATUS_UNKNOWN_ERROR}, + {ESMI_NO_ENERGY_DRV, AMDSMI_NO_ENERGY_DRV}, + {ESMI_NO_MSR_DRV, AMDSMI_NO_MSR_DRV}, + {ESMI_NO_HSMP_DRV, AMDSMI_NO_HSMP_DRV}, + {ESMI_NO_HSMP_SUP, AMDSMI_NO_HSMP_SUP}, + {ESMI_NO_DRV, AMDSMI_NO_DRV}, + {ESMI_FILE_NOT_FOUND, AMDSMI_FILE_NOT_FOUND}, + {ESMI_ARG_PTR_NULL, AMDSMI_ARG_PTR_NULL}, + {ESMI_HSMP_TIMEOUT, AMDSMI_HSMP_TIMEOUT}, + {ESMI_NO_HSMP_MSG_SUP, AMDSMI_NO_HSMP_MSG_SUP}, +}; + +amdsmi_status_t esmi_to_amdsmi_status(esmi_status_t status); +#endif } // namespace smi } // namespace amd diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_cpu_core.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_cpu_core.h new file mode 100644 index 0000000000..ffcca3a6c9 --- /dev/null +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_cpu_core.h @@ -0,0 +1,77 @@ +/* + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2022, 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 , + * 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. + * + */ + +#ifndef AMD_SMI_INCLUDE_AMD_SMI_CPU_CORE_H_ +#define AMD_SMI_INCLUDE_AMD_SMI_CPU_CORE_H_ + +#include +#include +#include +#include "amd_smi/amdsmi.h" +#include "amd_smi/impl/amd_smi_processor.h" + +namespace amd { +namespace smi { + +/*Subclass CPU Core*/ +class AMDSmiCpuCore : public AMDSmiProcessor { +public: + explicit AMDSmiCpuCore(const uint32_t& core_idx):AMDSmiProcessor(AMD_CPU_CORE),core_idx_(core_idx) {} + + virtual ~AMDSmiCpuCore() {} + + void add_processor(AMDSmiProcessor* processor) { processors_.push_back(processor); } + std::vector& get_processors() { return processors_;} + amdsmi_status_t get_processor_count(uint32_t* processor_count) const; + +private: + uint32_t core_idx_; + //uint64_t input; + //uint32_t idx; + std::vector processors_; +}; + +} // namespace smi +} // namespace amd + +#endif // AMD_SMI_INCLUDE_AMD_SMI_CPU_CORE_H_ diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_cpu_socket.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_cpu_socket.h new file mode 100644 index 0000000000..8e41422cec --- /dev/null +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_cpu_socket.h @@ -0,0 +1,81 @@ +/* + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2022, 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 , + * 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. + * + */ + +#ifndef AMD_SMI_INCLUDE_AMD_SMI_CPU_SOCKET_H_ +#define AMD_SMI_INCLUDE_AMD_SMI_CPU_SOCKET_H_ + +#include +#include +#include +#include "amd_smi/amdsmi.h" +#include "amd_smi/impl/amd_smi_processor.h" +#include "amd_smi/impl/amd_smi_cpu_core.h" + +namespace amd { +namespace smi { + +/*Subclass CPU Socket*/ +class AMDSmiCpuSocket : public AMDSmiProcessor { + public: + explicit AMDSmiCpuSocket(const uint32_t& id):AMDSmiProcessor(AMD_CPU),socket_identifier_(id) {} + + virtual ~AMDSmiCpuSocket() {} + + amdsmi_status_t get_cpu_vendor() { return AMDSMI_STATUS_SUCCESS; } + uint32_t get_cpu_id() const { return cpu_id_; } + const uint32_t& get_socket_id() const { return socket_identifier_; } + + void add_processor(AMDSmiProcessor* processor) { processors_.push_back(processor); } + std::vector& get_processors() { return processors_;} + amdsmi_status_t get_processor_count(uint32_t* processor_count) const; + + private: + uint32_t cpu_id_; + uint32_t socket_identifier_; + std::vector processors_; +}; + +} // namespace smi +} // namespace amd + +#endif // AMD_SMI_INCLUDE_AMD_SMI_CPU_SOCKET_H_ diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_system.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_system.h index 531a7b9499..f20b2ed0b7 100644 --- a/projects/amdsmi/include/amd_smi/impl/amd_smi_system.h +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_system.h @@ -50,6 +50,9 @@ #include "amd_smi/impl/amd_smi_socket.h" #include "amd_smi/impl/amd_smi_processor.h" #include "amd_smi/impl/amd_smi_drm.h" +#ifdef ENABLE_ESMI_LIB +#include "amd_smi/impl/amd_smi_cpu_socket.h" +#endif namespace amd { namespace smi { @@ -75,6 +78,25 @@ class AMDSmiSystem { amdsmi_status_t gpu_index_to_handle(uint32_t gpu_index, amdsmi_processor_handle* processor_handle); +#ifdef ENABLE_ESMI_LIB + std::vector& get_cpu_sockets() {return cpu_sockets_;} + + amdsmi_status_t handle_to_cpusocket(amdsmi_cpusocket_handle cpusock_handle, + AMDSmiCpuSocket** cpu_socket); + + amdsmi_status_t cpu_index_to_handle(uint32_t cpu_index, + amdsmi_cpusocket_handle* cpusock_handle); + + amdsmi_status_t get_cpu_sockets(uint32_t socks); + + amdsmi_status_t get_cpu_cores(uint32_t cpus); + + amdsmi_status_t get_threads_per_core(uint32_t threads); + + amdsmi_status_t get_cpu_family(uint32_t family); + + amdsmi_status_t get_cpu_model(uint32_t model); +#endif private: AMDSmiSystem() : init_flag_(AMDSMI_INIT_AMD_GPUS) {} amdsmi_status_t get_gpu_bdf_by_index(uint32_t index, std::string& bdf); @@ -83,6 +105,15 @@ class AMDSmiSystem { AMDSmiDrm drm_; std::vector sockets_; std::set processors_; // Track valid processors +#ifdef ENABLE_ESMI_LIB + amdsmi_status_t populate_amd_cpus(); + std::vector cpu_sockets_; + static uint32_t sockets; + static uint32_t cpus; + static uint32_t threads; + static uint32_t family; + static uint32_t model; +#endif }; diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index cecd4ad53e..b534b106b7 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -67,6 +67,11 @@ #include "rocm_smi/rocm_smi_common.h" #include "amd_smi/impl/amdgpu_drm.h" #include "amd_smi/impl/amd_smi_utils.h" +#include "amd_smi/impl/amd_smi_processor.h" +#ifdef ENABLE_ESMI_LIB + #include "amd_smi/impl/amd_smi_cpu_socket.h" + #include "amd_smi/impl/amd_smi_cpu_core.h" +#endif static bool initialized_lib = false; @@ -97,6 +102,49 @@ static amdsmi_status_t get_gpu_device_from_handle(amdsmi_processor_handle proces return AMDSMI_STATUS_NOT_SUPPORTED; } +#ifdef ENABLE_ESMI_LIB +static amdsmi_status_t get_cpu_socket_from_handle(amdsmi_cpusocket_handle socket_handle, + amd::smi::AMDSmiCpuSocket** cpusocket) { + + AMDSMI_CHECK_INIT(); + + if (socket_handle == nullptr || cpusocket == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance() + .handle_to_cpusocket(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) return r; + + if (socket->get_processor_type() == AMD_CPU) { + *cpusocket = static_cast(socket_handle); + return AMDSMI_STATUS_SUCCESS; + } + + return AMDSMI_STATUS_NOT_SUPPORTED; +} + +static amdsmi_status_t get_cpu_core_from_handle(amdsmi_processor_handle processor_handle, + amd::smi::AMDSmiCpuCore** cpucore) { + + AMDSMI_CHECK_INIT(); + if (processor_handle == nullptr || cpucore == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiProcessor* core = nullptr; + amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance() + .handle_to_processor(processor_handle, &core); + if (r != AMDSMI_STATUS_SUCCESS) return r; + + if (core->get_processor_type() == AMD_CPU_CORE) { + *cpucore = static_cast(processor_handle); + return AMDSMI_STATUS_SUCCESS; + } + + return AMDSMI_STATUS_NOT_SUPPORTED; +} +#endif + template amdsmi_status_t rsmi_wrapper(F && f, amdsmi_processor_handle processor_handle, Args &&... args) { @@ -114,6 +162,24 @@ amdsmi_status_t rsmi_wrapper(F && f, return amd::smi::rsmi_to_amdsmi_status(rstatus); } +#ifdef ENABLE_ESMI_LIB +template +amdsmi_status_t esmi_wrapper(F && f, + amdsmi_processor_handle processor_handle, Args &&... args) { + + AMDSMI_CHECK_INIT(); + + amd::smi::AMDSmiCpuSocket* cpu_socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(processor_handle, &cpu_socket); + if (r != AMDSMI_STATUS_SUCCESS) return r; + + uint32_t cpu_index = cpu_socket->get_cpu_id(); + auto estatus = std::forward(f)(cpu_index, + std::forward(args)...); + return amd::smi::esmi_to_amdsmi_status(estatus); +} +#endif + amdsmi_status_t amdsmi_init(uint64_t flags) { if (initialized_lib) @@ -165,6 +231,37 @@ amdsmi_status_code_to_string(amdsmi_status_t status, const char **status_string) return AMDSMI_STATUS_SUCCESS; } +#ifdef ENABLE_ESMI_LIB +amdsmi_status_t amdsmi_get_cpusocket_handles(uint32_t *socket_count, + amdsmi_cpusocket_handle* socket_handles) { + + AMDSMI_CHECK_INIT(); + if (socket_count == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + std::vector& sockets + = amd::smi::AMDSmiSystem::getInstance().get_cpu_sockets(); + uint32_t socket_size = static_cast(sockets.size()); + + // Get the socket size + if (socket_handles == nullptr) { + *socket_count = socket_size; + return AMDSMI_STATUS_SUCCESS; + } + + // If the socket_handles can hold all sockets, return all of them. + *socket_count = *socket_count >= socket_size ? socket_size : *socket_count; + + // Copy the cpu socket handles + for (uint32_t i = 0; i < *socket_count; i++) { + socket_handles[i] = reinterpret_cast(sockets[i]); + } + + return AMDSMI_STATUS_SUCCESS; +} +#endif + amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count, amdsmi_socket_handle* socket_handles) { @@ -214,6 +311,27 @@ amdsmi_status_t amdsmi_get_socket_info( return AMDSMI_STATUS_SUCCESS; } +#ifdef ENABLE_ESMI_LIB +amdsmi_status_t amdsmi_get_cpusocket_info( + amdsmi_cpusocket_handle socket_handle, + uint32_t sock_id) { + AMDSMI_CHECK_INIT(); + + if (socket_handle == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance() + .handle_to_cpusocket(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) return r; + + sock_id = socket->get_socket_id(); + + return AMDSMI_STATUS_SUCCESS; +} +#endif + amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle, uint32_t* processor_count, amdsmi_processor_handle* processor_handles) { @@ -249,6 +367,44 @@ amdsmi_status_t amdsmi_get_processor_handles(amdsmi_socket_handle socket_handle, return AMDSMI_STATUS_SUCCESS; } +#ifdef ENABLE_ESMI_LIB +amdsmi_status_t amdsmi_get_cpucore_handles(amdsmi_cpusocket_handle socket_handle, + uint32_t* processor_count, + amdsmi_processor_handle* processor_handles) { + AMDSMI_CHECK_INIT(); + + if (processor_count == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + // Get the socket object via socket handle. + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = amd::smi::AMDSmiSystem::getInstance() + .handle_to_cpusocket(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) return r; + + + std::vector& processors = socket->get_processors(); + uint32_t processor_size = static_cast(processors.size()); + + // Get the processor count only + if (processor_handles == nullptr) { + *processor_count = processor_size; + return AMDSMI_STATUS_SUCCESS; + } + + // If the processor_handles can hold all processors, return all of them. + *processor_count = *processor_count >= processor_size ? processor_size : *processor_count; + + // Copy the processor handles + for (uint32_t i = 0; i < *processor_count; i++) { + processor_handles[i] = reinterpret_cast(processors[i]); + } + + return AMDSMI_STATUS_SUCCESS; +} +#endif + amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_handle , processor_type_t* processor_type) { @@ -1646,3 +1802,368 @@ amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf, return AMDSMI_STATUS_API_FAILED; } + +#ifdef ENABLE_ESMI_LIB +amdsmi_status_t amdsmi_get_hsmp_proto_ver(uint32_t *proto_ver) +{ + amdsmi_status_t status; + uint32_t hsmp_proto_ver; + + if (proto_ver == nullptr) + return AMDSMI_STATUS_INVAL; + + status = static_cast(esmi_hsmp_proto_ver_get(&hsmp_proto_ver)); + *proto_ver = hsmp_proto_ver; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_smu_fw_version(amdsmi_smu_fw_version_t *amdsmi_smu_fw) +{ + amdsmi_status_t status; + struct smu_fw_version smu_fw; + + if (amdsmi_smu_fw == nullptr) + return AMDSMI_STATUS_INVAL; + + status = static_cast(esmi_smu_fw_version_get(&smu_fw)); + + amdsmi_smu_fw->major = smu_fw.major; + amdsmi_smu_fw->minor = smu_fw.minor; + amdsmi_smu_fw->debug = smu_fw.debug; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_core_energy(amdsmi_processor_handle processor_handle, + uint32_t core_ind, uint64_t *penergy) +{ + amdsmi_status_t status; + uint64_t core_input; + + if (processor_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuCore* core = nullptr; + amdsmi_status_t r = get_cpu_core_from_handle(processor_handle, &core); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_core_energy_get(core_ind, &core_input)); + *penergy = core_input; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; + +} + +amdsmi_status_t amdsmi_get_cpu_socket_energy(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint64_t *penergy) +{ + amdsmi_status_t status; + uint64_t pkg_input; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_socket_energy_get(sock_ind, &pkg_input)); + *penergy = pkg_input; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_prochot_status(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *prochot) +{ + amdsmi_status_t status; + uint32_t phot; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_prochot_status_get(sock_ind, &phot)); + *prochot = phot; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_fclk_mclk(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *fclk, uint32_t *mclk) +{ + amdsmi_status_t status; + uint32_t f_clk, m_clk; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_fclk_mclk_get(sock_ind, &f_clk, &m_clk)); + *fclk = f_clk; + *mclk = m_clk; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_cclk_limit(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *cclk) +{ + amdsmi_status_t status; + uint32_t c_clk; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_cclk_limit_get(sock_ind, &c_clk)); + *cclk = c_clk; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_socket_current_active_freq_limit(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint16_t *freq, char **src_type) +{ + amdsmi_status_t status; + uint16_t limit; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_socket_current_active_freq_limit_get(sock_ind, &limit, src_type)); + *freq = limit; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_socket_freq_range(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint16_t *fmax, uint16_t *fmin) +{ + amdsmi_status_t status; + uint16_t f_max; + uint16_t f_min; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_socket_freq_range_get(sock_ind, &f_max, &f_min)); + *fmax = f_max; + *fmin = f_min; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_core_current_freq_limit(amdsmi_processor_handle processor_handle, + uint32_t core_ind, uint32_t *freq) +{ + amdsmi_status_t status; + uint32_t c_clk; + + if (processor_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuCore* core = nullptr; + amdsmi_status_t r = get_cpu_core_from_handle(processor_handle, &core); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_current_freq_limit_core_get(core_ind, &c_clk)); + *freq = c_clk; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; + +} + +amdsmi_status_t amdsmi_get_cpu_socket_power(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *ppower) +{ + amdsmi_status_t status; + uint32_t avg_power; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_socket_power_get(sock_ind, &avg_power)); + *ppower = avg_power; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_socket_power_cap(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *pcap) +{ + amdsmi_status_t status; + uint32_t p_cap; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_socket_power_cap_get(sock_ind, &p_cap)); + *pcap = p_cap; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_socket_power_cap_max(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *pmax) +{ + amdsmi_status_t status; + uint32_t p_max; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_socket_power_cap_max_get(sock_ind, &p_max)); + *pmax = p_max; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_pwr_svi_telemetry_all_rails(amdsmi_cpusocket_handle socket_handle, + uint32_t sock_ind, uint32_t *power) +{ + amdsmi_status_t status; + uint32_t pow; + + if (socket_handle == nullptr) + return AMDSMI_STATUS_INVAL; + + amd::smi::AMDSmiCpuSocket* socket = nullptr; + amdsmi_status_t r = get_cpu_socket_from_handle(socket_handle, &socket); + if (r != AMDSMI_STATUS_SUCCESS) + return r; + + status = static_cast(esmi_pwr_svi_telemetry_all_rails_get(sock_ind, &pow)); + *power = pow; + + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_number_of_cpu_sockets(uint32_t sockets) +{ + amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_sockets(sockets); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_number_of_cpu_cores(uint32_t cpus) +{ + amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_cores(cpus); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_threads_per_core(uint32_t threads) +{ + amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_threads_per_core(threads); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_family(uint32_t family) +{ + amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_family(family); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} + +amdsmi_status_t amdsmi_get_cpu_model(uint32_t model) +{ + amdsmi_status_t status = amd::smi::AMDSmiSystem::getInstance().get_cpu_model(model); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + return AMDSMI_STATUS_SUCCESS; +} +#endif diff --git a/projects/amdsmi/src/amd_smi/amd_smi_common.cc b/projects/amdsmi/src/amd_smi/amd_smi_common.cc index b6b153a513..21dff9bca4 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_common.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_common.cc @@ -63,5 +63,21 @@ amdsmi_status_t rsmi_to_amdsmi_status(rsmi_status_t status) { return amdsmi_status; } +#ifdef ENABLE_ESMI_LIB +amdsmi_status_t esmi_to_amdsmi_status(esmi_status_t status) { + amdsmi_status_t amdsmi_status = AMDSMI_STATUS_MAP_ERROR; + + // Look for it in the map + // If found: use the mapped value + // If not found: return the map error established above + auto search = amd::smi::esmi_status_map.find(status); + if (search != amd::smi::esmi_status_map.end()) { + amdsmi_status = search->second; + } + + return amdsmi_status; +} +#endif + } // namespace smi } // namespace amd diff --git a/projects/amdsmi/src/amd_smi/amd_smi_cpu_core.cc b/projects/amdsmi/src/amd_smi/amd_smi_cpu_core.cc new file mode 100644 index 0000000000..deb1206f72 --- /dev/null +++ b/projects/amdsmi/src/amd_smi/amd_smi_cpu_core.cc @@ -0,0 +1,62 @@ +/* + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2022, 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 , + * 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 +#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(processors_.size()); + return AMDSMI_STATUS_SUCCESS; +} + +} // namespace smi +} // namespace amd diff --git a/projects/amdsmi/src/amd_smi/amd_smi_cpu_socket.cc b/projects/amdsmi/src/amd_smi/amd_smi_cpu_socket.cc new file mode 100644 index 0000000000..64117e21bb --- /dev/null +++ b/projects/amdsmi/src/amd_smi/amd_smi_cpu_socket.cc @@ -0,0 +1,72 @@ +/* + * ============================================================================= + * The University of Illinois/NCSA + * Open Source License (NCSA) + * + * Copyright (c) 2022, 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 , + * 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 +#include "amd_smi/impl/amd_smi_cpu_socket.h" +#include + +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 diff --git a/projects/amdsmi/src/amd_smi/amd_smi_system.cc b/projects/amdsmi/src/amd_smi/amd_smi_system.cc index 6c78dbd8bc..ff73d6b559 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_system.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_system.cc @@ -47,11 +47,20 @@ #include "amd_smi/impl/amd_smi_common.h" #include "rocm_smi/rocm_smi.h" #include "rocm_smi/rocm_smi_main.h" +#include 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 amdsmi_status_t AMDSmiSystem::init(uint64_t flags) { @@ -62,12 +71,141 @@ amdsmi_status_t AMDSmiSystem::init(uint64_t flags) { amd_smi_status = populate_amd_gpu_devices(); if (amd_smi_status != AMDSMI_STATUS_SUCCESS) return amd_smi_status; - } else { // Currently only support AMD GPU +#ifdef ENABLE_ESMI_LIB + } + else 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; } return AMDSMI_STATUS_SUCCESS; } +#ifdef ENABLE_ESMI_LIB +amdsmi_status_t AMDSmiSystem::populate_amd_cpus() { + 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(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 | "< 1) { + std::cout <<"| THREADS PER CORE | "<get_socket_id() == cpu_socket_id) { + socket = cpu_sockets_[j]; + break; + } + } + if (socket == nullptr) { + socket = new AMDSmiCpuSocket(cpu_socket_id); + cpu_sockets_.push_back(socket); + } + + for (uint32_t k = 0; k < cpus/threads; k++) { + AMDSmiCpuCore* core = new AMDSmiCpuCore(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(esmi_number_of_sockets_get(&num_socks)); + sockets = num_socks; + + if (ret != AMDSMI_STATUS_SUCCESS) { + std::cout << "Failed to get number of sockets, Err["<(esmi_number_of_cpus_get(&num_cpus)); + cpus = num_cpus; + + if (ret != AMDSMI_STATUS_SUCCESS) { + std::cout << "Failed to get number of cpus, Err["<(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["<(esmi_cpu_family_get(&cpu_family)); + family = cpu_family; + + if (ret != AMDSMI_STATUS_SUCCESS) { + std::cout << "Failed to get cpu family, Err["<(esmi_cpu_model_get(&cpu_model)); + model = cpu_model; + + if (ret != AMDSMI_STATUS_SUCCESS) { + std::cout << "Failed to get cpu model, Err["<(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) { @@ -203,7 +371,28 @@ 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(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 -