From 14d9160565077bc3c8dc398c26ef9287fd87b993 Mon Sep 17 00:00:00 2001 From: Dejan Andjelkovic Date: Tue, 11 Oct 2022 16:06:32 +0200 Subject: [PATCH] SWDEV-361376 - Add python wrapper - Add generator for python wrapper - Add interface, exception and init files - Add CMake custom targets Change-Id: I63c1d94fbb587387c22f559a3db79987eb214a2e Signed-off-by: Dejan Andjelkovic [ROCm/amdsmi commit: 6064f160a345928236f8cd90dcab6a31207335e3] --- projects/amdsmi/CMakeLists.txt | 40 + projects/amdsmi/LICENSE | 20 + .../amdsmi/example/amd_smi_drm_example.cc | 65 +- projects/amdsmi/include/amd_smi/amd_smi.h | 114 +- .../include/amd_smi/impl/amd_smi_utils.h | 1 + .../include/amd_smi/impl/amd_smi_uuid.h | 41 + projects/amdsmi/py-interface/README.md | 1134 +++++++++ projects/amdsmi/py-interface/__init__.py | 114 + .../amdsmi/py-interface/amdsmi_exception.py | 172 ++ .../amdsmi/py-interface/amdsmi_interface.py | 1028 ++++++++ .../amdsmi/py-interface/amdsmi_wrapper.py | 2174 +++++++++++++++++ projects/amdsmi/py-interface/setup.py | 16 + projects/amdsmi/src/amd_smi/amd_smi.cc | 253 +- projects/amdsmi/src/amd_smi/amd_smi_utils.cc | 94 +- projects/amdsmi/src/amd_smi/amd_smi_uuid.cc | 107 + projects/amdsmi/tools/generator.py | 504 ++++ 16 files changed, 5805 insertions(+), 72 deletions(-) create mode 100644 projects/amdsmi/LICENSE create mode 100644 projects/amdsmi/include/amd_smi/impl/amd_smi_uuid.h create mode 100644 projects/amdsmi/py-interface/README.md create mode 100644 projects/amdsmi/py-interface/__init__.py create mode 100644 projects/amdsmi/py-interface/amdsmi_exception.py create mode 100644 projects/amdsmi/py-interface/amdsmi_interface.py create mode 100644 projects/amdsmi/py-interface/amdsmi_wrapper.py create mode 100644 projects/amdsmi/py-interface/setup.py create mode 100644 projects/amdsmi/src/amd_smi/amd_smi_uuid.cc create mode 100644 projects/amdsmi/tools/generator.py diff --git a/projects/amdsmi/CMakeLists.txt b/projects/amdsmi/CMakeLists.txt index e12c35ebbc..d4e61143a5 100755 --- a/projects/amdsmi/CMakeLists.txt +++ b/projects/amdsmi/CMakeLists.txt @@ -142,6 +142,7 @@ set(CMN_SRC_LIST ${CMN_SRC_LIST} "${AMDSMI_SRC_DIR}/amd_smi_system.cc") set(CMN_SRC_LIST ${CMN_SRC_LIST} "${AMDSMI_SRC_DIR}/amd_smi_drm.cc") set(CMN_SRC_LIST ${CMN_SRC_LIST} "${AMDSMI_SRC_DIR}/amd_smi_lib_loader.cc") set(CMN_SRC_LIST ${CMN_SRC_LIST} "${AMDSMI_SRC_DIR}/amd_smi_utils.cc") +set(CMN_SRC_LIST ${CMN_SRC_LIST} "${AMDSMI_SRC_DIR}/amd_smi_uuid.cc") set(CMN_SRC_LIST ${CMN_SRC_LIST} "${AMDSMI_SRC_DIR}/fdinfo.cc") set(CMN_INC_LIST "${ROCM_INC_DIR}/rocm_smi_device.h") @@ -210,6 +211,45 @@ else() message("Doxygen or Latex is not found. Will not generate documents.") endif(DOXYGEN_FOUND AND LATEX_FOUND) +# Generate python_wrapper and package targets +find_program(PYTHON3 "python3") +find_program(PIP3 "pip3") + +if (PYTHON3 AND PIP3) + add_custom_command(OUTPUT clang_tools_extract + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper + COMMAND pip3 download ctypeslib2==2.3.2 -d ${CMAKE_CURRENT_BINARY_DIR}/dl + COMMAND pip3 download clang==10.0.1 -d ${CMAKE_CURRENT_BINARY_DIR}/dl + COMMAND unzip -o ${CMAKE_CURRENT_BINARY_DIR}/dl/ctypeslib2-2.3.2-py3-none-any.whl -d ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper + COMMAND unzip -o ${CMAKE_CURRENT_BINARY_DIR}/dl/clang-10.0.1-py3-none-any.whl -d ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + add_custom_target(python_wrapper DEPENDS clang_tools_extract + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper + COMMAND cp -r ${CMAKE_CURRENT_SOURCE_DIR}/include/amd_smi/amd_smi.h ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper + COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/rocm_smi + COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/rocm_smi/include/rocm_smi/kfd_ioctl.h ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/rocm_smi/ + COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/tools/generator.py ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amd_smi.h ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/ ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/ + COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi_wrapper.py ${CMAKE_CURRENT_SOURCE_DIR}/py-interface/ + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper) + + set (PY_INTERFACE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/py-interface") + set (PACKAGE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/python_package/amdsmi") + + add_custom_target(python_package DEPENDS python_wrapper + COMMAND mkdir -p ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${PY_INTERFACE_DIR}/__init__.py ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${PY_INTERFACE_DIR}/amdsmi_exception.py ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${PY_INTERFACE_DIR}/amdsmi_interface.py ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${PY_INTERFACE_DIR}/amdsmi_wrapper.py ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${PY_INTERFACE_DIR}/README.md ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/rocm_smi/libamd_smi64.so ${PACKAGE_OUTPUT_DIR} + COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE ${PACKAGE_OUTPUT_DIR} + COMMAND echo ${PACKAGE_OUTPUT_DIR}) + +else() + message("Python3 or Pip3 not found.") +endif(PYTHON3 AND PIP3) #TODO: Should use GNUInstallDirs to match distro standards #This need fix in subdirectory CMakefile as well diff --git a/projects/amdsmi/LICENSE b/projects/amdsmi/LICENSE new file mode 100644 index 0000000000..49bfb6bb25 --- /dev/null +++ b/projects/amdsmi/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2019-2022 Advanced Micro Devices, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in 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: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +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 +AUTHORS 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 IN +THE SOFTWARE. + diff --git a/projects/amdsmi/example/amd_smi_drm_example.cc b/projects/amdsmi/example/amd_smi_drm_example.cc index c8fe25c80e..72c4f87200 100644 --- a/projects/amdsmi/example/amd_smi_drm_example.cc +++ b/projects/amdsmi/example/amd_smi_drm_example.cc @@ -118,6 +118,7 @@ int main() { return AMDSMI_STATUS_NOT_SUPPORTED; } + // Get BDF info amdsmi_bdf_t bdf = {}; ret = amdsmi_get_device_bdf(device_handles[j], &bdf); CHK_AMDSMI_RET(ret) @@ -126,6 +127,12 @@ int main() { bdf.domain_number, bdf.bus_number, bdf.device_number, bdf.function_number); + // Get handle from BDF + amdsmi_device_handle dev_handle; + ret = amdsmi_get_device_handle_from_bdf(bdf, &device_handles[0], device_count, &dev_handle); + CHK_AMDSMI_RET(ret) + + // Get ASIC info amdsmi_asic_info_t asic_info = {}; ret = amdsmi_get_asic_info(device_handles[j], &asic_info); CHK_AMDSMI_RET(ret) @@ -149,6 +156,34 @@ int main() { printf("\tVBios Version String: %s\n\n", vbios_info.vbios_version_string); + // Get power measure + amdsmi_power_measure_t power_measure = {}; + ret = amdsmi_get_power_measure(device_handles[j], &power_measure); + CHK_AMDSMI_RET(ret) + printf(" Output of amdsmi_get_power_measure:\n"); + printf("\tCurrent GFX Voltage: %d\n", + power_measure.voltage_gfx); + printf("\tAverage socket power: %d\n", + power_measure.average_socket_power); + printf("\tEnergy accumulator: %d\n\n", + power_measure.energy_accumulator); + + // Get driver version + char version[AMDSMI_MAX_DRIVER_VERSION_LENGTH]; + int version_length = AMDSMI_MAX_DRIVER_VERSION_LENGTH; + ret = amdsmi_get_driver_version(device_handles[j], &version_length, version); + CHK_AMDSMI_RET(ret) + printf(" Output of amdsmi_get_driver_version:\n"); + printf("\tDriver version: %s\n\n", version); + + // Get device uuid + unsigned int uuid_length = AMDSMI_GPU_UUID_SIZE; + char uuid[AMDSMI_GPU_UUID_SIZE]; + ret = amdsmi_get_device_uuid(device_handles[j], &uuid_length, uuid); + CHK_AMDSMI_RET(ret) + printf(" Output of amdsmi_get_device_uuid:\n"); + printf("\tDevice uuid: %s\n\n", uuid); + // Get engine usage info amdsmi_engine_usage_t engine_usage = {}; ret = amdsmi_get_gpu_activity(device_handles[j], &engine_usage); @@ -228,8 +263,8 @@ int main() { printf("\tGPU Power limit: %d\n\n", power_limit.limit); // Get GFX clock measurements - amdsmi_clock_measure_t gfx_clk_values = {}; - ret = amdsmi_get_clock_measure(device_handles[j], CLOCK_TYPE_GFX, + amdsmi_clk_measure_t gfx_clk_values = {}; + ret = amdsmi_get_clock_measure(device_handles[j], CLK_TYPE_GFX, &gfx_clk_values); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_clock_measure:\n"); @@ -238,14 +273,30 @@ int main() { printf("\tGPU GFX Current Clock: %d\n", gfx_clk_values.cur_clk); // Get MEM clock measurements - amdsmi_clock_measure_t mem_clk_values = {}; - ret = amdsmi_get_clock_measure(device_handles[j], CLOCK_TYPE_MEM, + amdsmi_clk_measure_t mem_clk_values = {}; + ret = amdsmi_get_clock_measure(device_handles[j], CLK_TYPE_MEM, &mem_clk_values); CHK_AMDSMI_RET(ret) printf("\tGPU MEM Max Clock: %d\n", mem_clk_values.max_clk); printf("\tGPU MEM Average Clock: %d\n", mem_clk_values.avg_clk); printf("\tGPU MEM Current Clock: %d\n\n", mem_clk_values.cur_clk); + // Get PCIe status + amdsmi_pcie_info_t pcie_info = {}; + ret = amdsmi_get_pcie_link_status(device_handles[j], &pcie_info); + CHK_AMDSMI_RET(ret) + printf(" Output of amdsmi_get_pcie_link_status:\n"); + printf("\tPCIe lanes: %d\n", pcie_info.pcie_lanes); + printf("\tPCIe speed: %d\n\n", pcie_info.pcie_speed); + + // Get PCIe caps + amdsmi_pcie_info_t pcie_caps_info = {}; + ret = amdsmi_get_pcie_link_caps(device_handles[j], &pcie_caps_info); + CHK_AMDSMI_RET(ret) + printf(" Output of amdsmi_get_pcie_link_caps:\n"); + printf("\tPCIe max lanes: %d\n", pcie_caps_info.pcie_lanes); + printf("\tPCIe max speed: %d\n\n", pcie_caps_info.pcie_speed); + // Get VRAM temperature limit amdsmi_temperature_limit_t mem_temp_limit = {}; ret = amdsmi_get_temperature_limit( @@ -294,11 +345,11 @@ int main() { "ENABLED"}; amdsmi_ras_err_state_t state = {}; int index = 0; - printf(" Output of amdsmi_get_ras_features_enabled:\n"); + printf(" Output of amdsmi_get_ras_block_features_enabled:\n"); for (auto block = AMDSMI_GPU_BLOCK_FIRST; block <= AMDSMI_GPU_BLOCK_LAST; block = (amdsmi_gpu_block_t)(block * 2)) { - ret = amdsmi_get_ras_features_enabled(device_handles[j], block, + ret = amdsmi_get_ras_block_features_enabled(device_handles[j], block, &state); CHK_AMDSMI_RET(ret) printf("\tBlock: %s\n", block_names[index]); @@ -362,7 +413,7 @@ int main() { // Get frequency ranges amdsmi_frequency_range_t freq_ranges = {}; ret = amdsmi_get_target_frequency_range( - device_handles[j], CLOCK_TYPE_GFX, &freq_ranges); + device_handles[j], CLK_TYPE_GFX, &freq_ranges); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_target_frequency_range:\n"); printf("\tSupported min freq: %lu\n", diff --git a/projects/amdsmi/include/amd_smi/amd_smi.h b/projects/amdsmi/include/amd_smi/amd_smi.h index fd3f7541eb..5147199d37 100644 --- a/projects/amdsmi/include/amd_smi/amd_smi.h +++ b/projects/amdsmi/include/amd_smi/amd_smi.h @@ -45,13 +45,14 @@ #define INCLUDE_AMD_SMI_H_ #include +#include #ifdef __cplusplus extern "C" { #include #else #include #endif // __cplusplus - + /** * @brief Initialization flags * @@ -141,20 +142,20 @@ typedef enum amdsmi_status_t { * Clock types */ typedef enum amdsmi_clk_type { - CLOCK_TYPE_SYS = 0x0, //!< System clock - CLOCK_TYPE_FIRST = CLOCK_TYPE_SYS, - CLOCK_TYPE_GFX = CLOCK_TYPE_SYS, - CLOCK_TYPE_DF, //!< Data Fabric clock (for ASICs + CLK_TYPE_SYS = 0x0, //!< System clock + CLK_TYPE_FIRST = CLK_TYPE_SYS, + CLK_TYPE_GFX = CLK_TYPE_SYS, + CLK_TYPE_DF, //!< Data Fabric clock (for ASICs //!< running on a separate clock) - CLOCK_TYPE_DCEF, //!< Display Controller Engine clock - CLOCK_TYPE_SOC, - CLOCK_TYPE_MEM, - CLOCK_TYPE_PCIE, - CLOCK_TYPE_VCLK0, - CLOCK_TYPE_VCLK1, - CLOCK_TYPE_DCLK0, - CLOCK_TYPE_DCLK1, - CLOCK_TYPE__MAX = CLOCK_TYPE_DCLK1 + CLK_TYPE_DCEF, //!< Display Controller Engine clock + CLK_TYPE_SOC, + CLK_TYPE_MEM, + CLK_TYPE_PCIE, + CLK_TYPE_VCLK0, + CLK_TYPE_VCLK1, + CLK_TYPE_DCLK0, + CLK_TYPE_DCLK1, + CLK_TYPE__MAX = CLK_TYPE_DCLK1 } amdsmi_clk_type_t; /// \cond Ignore in docs. typedef amdsmi_clk_type_t amdsmi_clk_type; @@ -346,19 +347,19 @@ typedef struct amdsmi_power_limit { } amdsmi_power_limit_t; typedef struct amdsmi_power_measure { - uint16_t average_socket_power; + uint32_t average_socket_power; uint64_t energy_accumulator; // v1 mod. (32->64) uint32_t voltage_gfx; // GFX voltage measurement in mV uint32_t voltage_soc; // SOC voltage measurement in mV uint32_t voltage_mem; // MEM voltage measurement in mV } amdsmi_power_measure_t; -typedef struct amdsmi_clock_measure { +typedef struct amdsmi_clk_measure { uint32_t cur_clk; uint32_t avg_clk; uint32_t min_clk; uint32_t max_clk; -} amdsmi_clock_measure_t; +} amdsmi_clk_measure_t; typedef struct amdsmi_engine_usage { uint32_t average_gfx_activity; @@ -1080,6 +1081,13 @@ typedef struct { uint64_t uncorrectable_count; //!< Accumulated uncorrectable errors } amdsmi_error_count_t; +/** + * @brief This structure holds pcie info. + */ +typedef struct amdsmi_pcie_info { + uint16_t pcie_lanes; + uint16_t pcie_speed; +} amdsmi_pcie_info_t; /** * @brief This structure contains information specific to a process. */ @@ -1134,8 +1142,8 @@ typedef union amd_id { * @{ */ /** - * @brief Initialize AMD SMI. - * + * @brief Initialize AMD SMI. + * * @details When called, this initializes internal data structures, * including those corresponding to sources of information that SMI provides. * @@ -1164,7 +1172,7 @@ amdsmi_status_t amdsmi_shut_down(void); /*****************************************************************************/ /** @defgroup Discovery Queries - * These functions provide discovery of the sockets. + * These functions provide discovery of the sockets. * @{ */ @@ -1208,7 +1216,7 @@ amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count, * @param[in] socket_handle a socket handle * * @param[out] name The id of the socket. - * + * * @param[in] len the length of the caller provided buffer @p name. * * @retval ::AMDSMI_STATUS_SUCCESS call was successful @@ -1275,6 +1283,28 @@ amdsmi_status_t amdsmi_get_device_handles(amdsmi_socket_handle socket_handle, amdsmi_status_t amdsmi_get_device_type(amdsmi_device_handle device_handle, device_type_t* device_type); +/** + * @brief Get device handle with the matching bdf. + * + * @details Given bdf info @p bdf, this function will get + * the device handle with the matching bdf. + * + * @param[in] bdf The bdf to match with corresponding device handle. + * + * @param[in] device_handles a list of devices handles on the socket. + * + * @param[in] device_count a count of handles in device_handles. + * + * @param[out] device_handle device handle with the matching bdf. + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_INVAL the provided arguments are not valid + */ +amdsmi_status_t amdsmi_get_device_handle_from_bdf(amdsmi_bdf_t bdf, + amdsmi_device_handle* device_handles, + uint32_t device_count, + amdsmi_device_handle* device_handle); + /** @} */ // end of Discovery @@ -1868,7 +1898,7 @@ amdsmi_get_bad_page_info(amdsmi_device_handle device_handle, uint32_t *num_pages * */ amdsmi_status_t -amdsmi_get_ras_features_enabled(amdsmi_device_handle device_handle, amdsmi_gpu_block block, +amdsmi_get_ras_block_features_enabled(amdsmi_device_handle device_handle, amdsmi_gpu_block block, amdsmi_ras_err_state_t *state); /** * @brief Get percentage of time any device memory is being used @@ -2211,6 +2241,42 @@ amdsmi_utilization_count_get(amdsmi_device_handle device_handle, uint32_t count, uint64_t *timestamp); +/** + * @brief Get current PCIE info of the device with provided device handle. + * + * @details Given a device handle @p dev, this function returns PCIE info of the + * given device. + * + * @param[in] dev a device handle + * + * @param[out] info amdsmi_pcie_info_t struct which will hold all the extracted PCIE info data. + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function with the given arguments + * @retval ::AMDSMI_STATUS_INVAL the provided arguments are not valid + * + */ +amdsmi_status_t amdsmi_get_pcie_link_status(amdsmi_device_handle dev, amdsmi_pcie_info_t *info); + +/** + * @brief Get max PCIe capabilities of the device with provided device handle. + * + * @details Given a device handle @p dev, this function returns PCIe caps info of the + * given device. + * + * @param[in] dev a device handle + * + * @param[out] info amdsmi_pcie_info_t struct which will hold all the extracted PCIe caps data. + * + * @retval ::AMDSMI_STATUS_SUCCESS call was successful + * @retval ::AMDSMI_STATUS_NOT_SUPPORTED installed software or hardware does not + * support this function with the given arguments + * @retval ::AMDSMI_STATUS_INVAL the provided arguments are not valid + * + */ +amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_device_handle dev, amdsmi_pcie_info_t *info); + /** * @brief Get the performance level of the device with provided * device handle. @@ -3447,7 +3513,7 @@ amdsmi_is_P2P_accessible(amdsmi_device_handle device_handle_src, amdsmi_device_h * * // Get the device handle via amdsmi_get_device_handles() * // ... ... - * + * * std::cout << "Supported AMDSMI Functions:" << std::endl; * * err = amdsmi_dev_supported_func_iterator_open(device, &iter_handle); * @@ -4033,7 +4099,7 @@ amdsmi_get_power_measure(amdsmi_device_handle dev, amdsmi_power_measure_t *info) * * -::AMDSMI_STATUS_API_FAILED - Other errors */ amdsmi_status_t -amdsmi_get_clock_measure(amdsmi_device_handle dev, amdsmi_clk_type_t clk_type, amdsmi_clock_measure_t *info); +amdsmi_get_clock_measure(amdsmi_device_handle dev, amdsmi_clk_type_t clk_type, amdsmi_clk_measure_t *info); /** * \brief Returns temperature measurements of the GPU. diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_utils.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_utils.h index 47977b17d3..177d042a0d 100644 --- a/projects/amdsmi/include/amd_smi/impl/amd_smi_utils.h +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_utils.h @@ -40,5 +40,6 @@ amdsmi_status_t smi_amdgpu_get_ranges(amd::smi::AMDSmiGPUDevice* device, amdsmi_ amdsmi_status_t smi_amdgpu_get_enabled_blocks(amd::smi::AMDSmiGPUDevice* device, uint64_t *enabled_blocks); amdsmi_status_t smi_amdgpu_get_bad_page_info(amd::smi::AMDSmiGPUDevice* device, uint32_t *num_pages, amdsmi_retired_page_record_t *info); amdsmi_status_t smi_amdgpu_get_ecc_error_count(amd::smi::AMDSmiGPUDevice* device, amdsmi_error_count_t *err_cnt); +amdsmi_status_t smi_amdgpu_get_driver_version(amd::smi::AMDSmiGPUDevice* device, int *length, char *version); #endif // diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_uuid.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_uuid.h new file mode 100644 index 0000000000..2b9bbe9494 --- /dev/null +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_uuid.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in 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: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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 + * AUTHORS 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 IN + * THE SOFTWARE. + */ + +#ifndef GPUVSMI_UUID_H_ +#define GPUVSMI_UUID_H_ + +/** + * \brief Generates uuid for device with specified parameters + * + * \param [out] str String buffer where to output generated uuid + * + * \param [in] serial Asic serial + * + * \param [in] did Device ID + * + * \param [in] idx PF/VF index + * + * \return SMI_RET_CODE indicating result. + */ +amdsmi_status_t amdsmi_uuid_gen(char *str, uint64_t serial, uint16_t did, uint8_t idx); + +#endif diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md new file mode 100644 index 0000000000..86b37ea9d6 --- /dev/null +++ b/projects/amdsmi/py-interface/README.md @@ -0,0 +1,1134 @@ +# Requirements +* python 3.6 64-bit +* driver must be loaded for gpuvsmi_init() to pass + +# Overview +## Folder structure: +File Name | Note +---|--- +`__init__.py` | Python package initialization file +`smi_interface.py` | Smi library python interface +`smi_wrapper.py` | Python wrapper around smi binary +`smi_exception.py` | Smi exceptions python file +`README.md` | Documentation + +## Usage: + +`amdsmi` folder should be copied and placed next to importing script. It should be imported as: +```python +from amdsmi import * + +try: + gpuvsmi_init() + + # amdsmi calls ... + +except SmiException as e: + print(e) +finally: + try: + gpuvsmi_fini() + except SmiException as e: + print(e) +``` + +To initialize smi lib, gpuvsmi_init() must be called before all other calls to smi lib. + +To close connection to driver, gpuvsmi_fini() must be the last call. + +# Exceptions + +All exceptions are in `smi_exception.py` file. +Exceptions that can be thrown are: +* `SmiException`: base smi exception class +* `SmiLibraryException`: derives base `SmiException` class and represents errors that can occur in smi-lib. +When this exception is thrown, `err_code` and `err_info` are set. `err_code` is an integer that corresponds to errors that can occur +in smi-lib and `err_info` is a string that explains the error that occurred. +Example: +```python +try: + num_of_GPUs = gpuvsmi_get_device_count() + if num_of_GPUs == 0: + print("No GPUs on machine") +except SmiException as e: + print("Error code: {}".format(e.err_code)) + if e.err_code == SmiRetCode.ERR_RETRY: + print("Error info: {}".format(e.err_info)) +``` +* `SmiRetryException` : Derives `SmiLibraryException` class and signals device is busy and call should be retried. +* `SmiTimeoutException` : Derives `SmiLibraryException` class and represents that call had timed out. +* `SmiParameterException`: Derives base `SmiException` class and represents errors related to invaild parameters passed to functions. When this exception is thrown, err_msg is set and it explains what is the actual and expected type of the parameters. +* `SmiBdfFormatException`: Derives base `SmiException` class and represents invalid bdf format. + +# API + +## gpuvsmi_init +Description: Initialize smi lib and connect to driver + +Input parameters: `None` + +Output: `None` + +Exceptions that can be thrown by `gpuvsmi_init` function: +* `SmiLibraryException` + +Example: +```python +try: + gpuvsmi_init() + # continue with amdsmi +except SmiException as e: + print("Init failed") + print(e) +``` + +## gpuvsmi_fini +Description: Finalize and close connection to driver + +Input parameters: `None` + +Output: `None` + +Exceptions that can be thrown by `gpuvsmi_fini` function: +* `SmiLibraryException` + +Example: +```python +try: + gpuvsmi_fini() +except SmiException as e: + print("Fini failed") + print(e) +``` + +## gpuvsmi_get_device_count +Description: Returns number of GPUs on current machine + +Input parameters: `None` + +Output: Integer, number of GPUs + +Exceptions that can be thrown by `gpuvsmi_get_device_count` function: +* `SmiLibraryException` + +Example: +```python +try: + num_of_GPUs = gpuvsmi_get_device_count() + if num_of_GPUs == 0: + print("No GPUs on machine") +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_devices +Description: Returns list of GPU device handle objects on current machine + +Input parameters: `None` + +Output: List of GPU device handle objects + +Exceptions that can be thrown by `gpuvsmi_get_devices` function: +* `SmiLibraryException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + print(gpuvsmi_get_device_uuid(device)) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_device_handle +Description: Returns device handle from the given BDF + +Input parameters: bdf string in form of either `::.` or `:.` in hexcode format. +Where: +* `` is 4 hex digits long from 0000-FFFF interval +* `` is 2 hex digits long from 00-FF interval +* `` is 2 hex digits long from 00-1F interval +* `` is 1 hex digit long from 0-7 interval + +Output: device handle object + +Exceptions that can be thrown by `gpuvsmi_get_device_handle` function: +* `SmiLibraryException` +* `SmiBdfFormatException` + +Example: +```python +try: + device = gpuvsmi_get_device_handle("0000:23:00.0") + print(gpuvsmi_get_device_uuid(device)) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_device_bdf +Description: Returns BDF of the given device + +Input parameters: +* `device_handle` dev for which to query + +Output: BDF string in form of `::.` in hexcode format. +Where: +* `` is 4 hex digits long from 0000-FFFF interval +* `` is 2 hex digits long from 00-FF interval +* `` is 2 hex digits long from 00-1F interval +* `` is 1 hex digit long from 0-7 interval + +Exceptions that can be thrown by `gpuvsmi_get_device_bdf` function: +* `SmiParameterException` +* `SmiLibraryException` + +Example: +```python +try: + device = gpuvsmi_get_device_handle("0000:23:00.0") + print("Device's bdf:", gpuvsmi_get_device_bdf(device)) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_device_uuid +Description: Returns the UUID of the device + +Input parameters: +* `device_handle` dev for which to query + +Output: UUID string unique to the device + +Exceptions that can be thrown by `gpuvsmi_get_device_uuid` function: +* `SmiParameterException` +* `SmiLibraryException` + +Example: +```python +try: + device = gpuvsmi_get_device_handle("0000:23:00.0") + print("Device UUID: ", gpuvsmi_get_device_uuid(device)) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_driver_version +Description: Returns the version string of the driver + +Input parameters: +* `device_handle` dev for which to query + +Output: Driver version string that is handling the device + +Exceptions that can be thrown by `gpuvsmi_get_driver_version` function: +* `SmiParameterException` +* `SmiLibraryException` + +Example: +```python +try: + device = gpuvsmi_get_device_handle("0000:23:00.0") + print("Driver version: ", gpuvsmi_get_driver_version(device)) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_asic_info +Description: Returns asic information for the given GPU + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Content +---|--- +`market_name` | market name +`family` | family +`vendor_id` | vendor id +`device_id` | device id +`rev_id` | revision id + +Exceptions that can be thrown by `gpuvsmi_get_asic_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + asic_info = gpuvsmi_get_asic_info(device) + print(asic_info['market_name']) + print(hex(asic_info['family'])) + print(hex(asic_info['vendor_id'])) + print(hex(asic_info['device_id'])) + print(hex(asic_info['rev_id'])) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_bus_info +Description: Returns bus information for the given GPU + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with `pcie` and `xgmi` fields and its subfields + +Field | Content +---|--- +`pcie` |
Subfield Description
`bdf`bdf string
`pcie_link_speed`pcie speed in MT/s
`pcie_link_width`pcie_lanes
+`xgmi` |
Subfield Description
`xgmi_lanes`xgmi lanes
`xgmi_hive_id`xgmi hive id
`xgmi_node_id`xgmi node id
`index`xgmi index
+ +Exceptions that can be thrown by `gpuvsmi_get_bus_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + bus_info = gpuvsmi_get_bus_info(device) + print(bus_info['pcie']['bdf']) + print(bus_info['pcie']['pcie_link_speed']) + print(bus_info['pcie']['pcie_link_width']) + print(bus_info['xgmi']['xgmi_lanes']) + print(bus_info['xgmi']['xgmi_hive_id']) + print(bus_info['xgmi']['xgmi_node_id']) + print(bus_info['xgmi']['index']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_power_info +Description: Returns dictionary of power capabilities as currently configured +on the given GPU + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`dpm_cap` | dynamic power management capability +`power_cap` | power capability + +Exceptions that can be thrown by `gpuvsmi_get_power_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + power_info = gpuvsmi_get_power_info(device) + print(power_info['dpm_cap']) + print(power_info['power_cap']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_caps_info +Description: Returns capabilities as currently configured for the given GPU + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- + `ras_supported` | `True` if ecc is supported, `False` if not + `mm_list` | List of MM engines on the device, of SmiMmIp type + `gfx_ip_count` | Number of GFX engines on the device + `dma_ip_count` | Number of DMA engines on the device + `gfx` |
Subfield Description
`gfxip_major` major revision of GFX IP
`gfxip_minor`minor revision of GFX IP
`gfxip_cu_count`number of GFX compute units
+`supported_flags` |
Subfield Description
`xgmi` `True` if xgmi is supported, `False` if not
`mm_metrics``True` if mm metrics is supported, `False` if not
`power_gfx_voltage``True` if gfx voltage is supported, `False` if not
`power_dpm``True` if dpm is supported, `False` if not
`mem_usage``True` if mem usage is supported, `False` if not
`max_freq_target_range``True` if target frequency setting is supported, `False` if not
+ +Exceptions that can be thrown by `gpuvsmi_get_caps_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + caps_info = gpuvsmi_get_caps_info(device) + print(caps_info['ras_supported']) + print(caps_info['gfx']['gfxip_major']) + print(caps_info['gfx']['gfxip_minor']) + print(caps_info['gfx']['gfxip_cu_count']) + print(caps_info['mm_list']) + print(caps_info['gfx_ip_count']) + print(caps_info['dma_ip_count']) + print(caps_info['supported_flags']['xgmi']) + print(caps_info['supported_flags']['mm_metrics']) + print(caps_info['supported_flags']['power_gfx_voltage']) + print(caps_info['supported_flags']['power_dpm']) + print(caps_info['supported_flags']['mem_usage']) + print(caps_info['supported_flags']['max_freq_target_range']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_vbios_info +Description: Returns the static information for the VBIOS on the device. + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`vbios_part_number` | vbios part number +`vbios_build_date` | vbios build date +`vbios_version` | vbios current version +`vbios_name` | vbios name +`vbios_version_string` | vbios version string + +Exceptions that can be thrown by `gpuvsmi_get_vbios_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + vbios_info = gpuvsmi_get_vbios_info(device) + print(vbios_info['vbios_part_number']) + print(vbios_info['vbios_build_date']) + print(vbios_info['vbios_version']) + print(vbios_info['vbios_name']) + print(vbios_info['vbios_version_string']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_ucode_info +Description: Returns GPU microcode related information. + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with field `ucode_list`, which is a list of dictionary elements: + +Field | Description +---|--- +`ucode_list` |
Subfield Description
`ucode_name``SmiUcodeName` enum
`ucode_version_integer`ucode version which is integer
+ +If microcode of certain type is not loaded, version will be 0. + +Exceptions that can be thrown by `gpuvsmi_get_ucode_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + ucode_info = gpuvsmi_get_ucode_info(device) + ucode_num = len(ucode_info['ucode_list']) + for j in range(0, ucode_num): + ucode = ucode_info['ucode_list'][j] + print(ucode['ucode_name'].name) + print(ucode['ucode_version_integer']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_gpu_activity +Description: Returns the engine usage for the given GPU + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`gfx_usage`| graphics engine usage percentage (0 - 100) +`mem_usage` | memory engine usage percentage (0 - 100) +`mm_usage_list` | list of multimedia engine usages in percentage (0 - 100) + +Exceptions that can be thrown by `gpuvsmi_get_gpu_activity` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + engine_usage = gpuvsmi_get_gpu_activity(device) + print(engine_usage['gfx_usage']) + print(engine_usage['mem_usage']) + print(engine_usage['mm_usage_list']) +except SmiException as e: + print(e) +``` +## gpuvsmi_get_power_measure +Description: Returns the current power and voltage for the given GPU + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`current_power_usage`| current power +`current_voltage` | current voltage gfx +`current_voltage_soc` | current voltage soc +`current_voltage_mem` | current voltage mem +`current_fan_rpm` | current fan speed + +Exceptions that can be thrown by `gpuvsmi_get_power_measure` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + power_measure = gpuvsmi_get_power_measure(device) + print(power_measure['current_power_usage']) + print(power_measure['current_voltage']) + print(power_measure['current_voltage_soc']) + print(power_measure['current_voltage_mem']) + print(power_measure['current_fan_rpm']) +except SmiException as e: + print(e) +``` +## gpuvsmi_get_thermal_measure +Description: Returns the measurements of thermals for the given GPU + +Input parameters: + +* `device_handle` device which to query +* `thermal_domain` one of `SmiThermalDomain` enum values: + +Field | Description +---|--- +`EDGE` | edge thermal domain +`HOTSPOT` | hotspot thermal domain +`MEM` | memory thermal domain +`PLX` | plx thermal domain + +Output: Dictionary with fields + +Field | Description +---|--- +`temperature`| temperature value for the given thermal domain + +Exceptions that can be thrown by `gpuvsmi_get_thermal_measure` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + thermal_measure = gpuvsmi_get_thermal_measure(device, SmiThermalDomain.EDGE) + print(thermal_measure['temperature']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_power_limit +Description: Returns the power limit for the given GPU + +Input parameters: +* `device handle object` PF or child VF of a device for which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`power_limit`| power limit + +Exceptions that can be thrown by `gpuvsmi_get_power_limit` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + power_limit = gpuvsmi_get_power_limit(device) + print(power_limit['power_limit']) + +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_thermal_limit +Description: Returns the temperature limits of thermals for the given GPU + +Input parameters: + +* `device handle object` PF or child VF of a device for which to query +* `SmiThermalDomain enum object with values` + +Field | Description +---|--- +`EDGE` | edge thermal domain +`HOTSPOT` | hotspot thermal domain +`MEM` | memory thermal domain + +Output: Dictionary with fields + +Field | Description +---|--- +`temperature`| temperature limit for the given thermal domain + +Exceptions that can be thrown by `gpuvsmi_get_thermal_limit` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + thermal_limit = gpuvsmi_get_thermal_limit(device, SmiThermalDomain.EDGE) + print(thermal_limit['temperature']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_clock_measure +Description: Returns the clock measurements for the given GPU + +Input parameters: + +* `device_handle` device which to query +* `clock_domain` one of `SmiClockDomain` enum values: + +Field | Description +---|--- +`GFX` | gfx clock domain +`MEM` | memory clock domain +`MM1` | first multimedia engine clock domain +`MM2` | second multimedia engine clock domain + +Output: Dictionary with fields + +Field | Description +---|--- +`cur_clk`| current clock value for the given domain + +Exceptions that can be thrown by `gpuvsmi_get_clock_measure` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + print("=============== GFX DOMAIN ================") + clock_measure = gpuvsmi_get_clock_measure(device, SmiClockDomain.GFX) + print(clock_measure['cur_clk']) + print("=============== MEM DOMAIN ================") + clock_measure = gpuvsmi_get_clock_measure(device, SmiClockDomain.MEM) + print(clock_measure['cur_clk']) + print("=============== MM1 engine DOMAIN ================") + clock_measure = gpuvsmi_get_clock_measure(device, SmiClockDomain.MM1) + print(clock_measure['cur_clk']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_pcie_link_status +Description: Returns current PCIe configuration + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`lanes` | Number of PCIe lanes +`speed` | PCIe speed in MT/s + +Exceptions that can be thrown by `gpuvsmi_get_pcie_link_status` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + pcie_status = gpuvsmi_get_pcie_link_status(device) + print(pcie_status['lanes']) + print(pcie_status['speed']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_fb_usage +Description: Returns current framebuffer usage + +Input parameters: +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`total` | Total FB size in MBs +`used` | Used FB size in MBs + +Exceptions that can be thrown by `gpuvsmi_get_fb_usage` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + fb_usage = gpuvsmi_get_fb_usage(device) + print(fb_usage['total']) + print(fb_usage['used']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_target_frequency_supported_range +Description: Returns the supported frequency target range + +`Note: Not Supported` + +Input parameters: + +* `device_handle` device which to query +* `clock_domain` one of `SmiClockDomain` enum values: + +Field | Description +---|--- +`GFX` | gfx clock domain +`MEM` | memory clock domain +`MM1` | first multimedia engine clock domain +`MM2` | second multimedia engine clock domain + +Output: Dictionary with fields + +Field | Description +---|--- +`soft_min`| Minimal value of target frequency in MHz +`soft_max`| Maximal value of target frequency in MHz + +Exceptions that can be thrown by `gpuvsmi_get_target_frequency_supported_range` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + print("=============== GFX DOMAIN ================") + freq_range = gpuvsmi_get_target_frequency_supported_range(device, + SmiClockDomain.GFX) + print(freq_range['soft_min']) + print(freq_range['soft_max']) + print("=============== MEM DOMAIN ================") + freq_range = gpuvsmi_get_target_frequency_supported_range(device, + SmiClockDomain.MEM) + print(freq_range['soft_min']) + print(freq_range['soft_max']) + print("=============== MM1 engine DOMAIN ================") + freq_range = gpuvsmi_get_target_frequency_supported_range(device, + SmiClockDomain.MM1) + print(freq_range['soft_min']) + print(freq_range['soft_max']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_target_frequency_current_range +Description: Returns the current frequency target range + +`Note: Not Supported` + +Input parameters: + +* `device_handle` device which to query +* `clock_domain` one of `SmiClockDomain` enum values: + +Field | Description +---|--- +`GFX` | gfx clock domain +`MEM` | memory clock domain +`MM1` | first multimedia engine clock domain +`MM2` | second multimedia engine clock domain + +Output: Dictionary with fields + +Field | Description +---|--- +`soft_min`| Minimal value of target frequency in MHz +`soft_max`| Maximal value of target frequency in MHz + +Exceptions that can be thrown by `gpuvsmi_get_target_frequency_current_range` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + print("=============== GFX DOMAIN ================") + freq_range = gpuvsmi_get_target_frequency_current_range(device, + SmiClockDomain.GFX) + print(freq_range['soft_min']) + print(freq_range['soft_max']) + print("=============== MEM DOMAIN ================") + freq_range = gpuvsmi_get_target_frequency_current_range(device, + SmiClockDomain.MEM) + print(freq_range['soft_min']) + print(freq_range['soft_max']) + print("=============== MM1 engine DOMAIN ================") + freq_range = gpuvsmi_get_target_frequency_current_range(device, + SmiClockDomain.MM1) + print(freq_range['soft_min']) + print(freq_range['soft_max']) +except SmiException as e: + print(e) +``` + + +## gpuvsmi_get_process_list +Description: Returns the list of processes running on a device + +Input parameters: + +* `device_handle` device which to query + +Output: List of process handles + +Exceptions that can be thrown by `gpuvsmi_get_process_list` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + proc_list = gpuvsmi_get_process_list(device) + print(proc_list) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_process_info +Description: Returns the process information of a given process + +Input parameters: + +* `device_handle` device which to query +* `procces_handle` handle of process to query + +Output: Dictionary with fields + +Field | Description +---|--- +`name`| Process name +`pid`| Process ID +`mem`| Process memory usage +`flags`|
Subfield Description
`has_usage_metrics`True if engine usage metrics are available
`has_compute_metrics`True if compute metrics are available
+`usage`|
Subfield Description
`gfx`GFX engine usage
`compute`Compute engine usage
`sdma`DMA engine usage
`enc`Encode engine usage
`dec`Decode engine usage
+`memory_usage`|
Subfield Description
`gtt_mem`GTT memory usage
`cpu_mem`CPU memory usage
`vram_mem`VRAM memory usage
+ + +Exceptions that can be thrown by `gpuvsmi_get_process_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + proc_list = gpuvsmi_get_process_list(device) + for proc in proc_list: + proc_info = gpuvsmi_get_process_info(device, proc) + print(proc_info['name']) + print(proc_info['pid']) + print(proc_info['mem']) + print(proc_info['flags']['has_usage_metrics']) + print(proc_info['flags']['has_compute_metrics']) + print(proc_info['usage']['gfx']) + print(proc_info['usage']['compute']) + print(proc_info['usage']['sdma']) + print(proc_info['usage']['enc']) + print(proc_info['usage']['dec']) + print(proc_info['memory_usage']['gtt_mem']) + print(proc_info['memory_usage']['cpu_mem']) + print(proc_info['memory_usage']['vram_mem']) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_ecc_error_count +Description: Returns dictionary of ecc error counts + +Input parameters: + +* `device_handle` device which to query + +Output: Dictionary with fields correctable and uncorrectable + +Field | Description +---|--- +`correctable`| Count of ecc correctable errors since last time driver was loaded +`uncorrectable`| Count of ecc uncorrectable errors since last time driver was loaded + +Exceptions that can be thrown by `gpuvsmi_get_ecc_error_count` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + device = gpuvsmi_get_device_handle("0000:23.00.0") + ecc_count_dict = gpuvsmi_get_ecc_error_count(device) + if ecc_count_dict["correctable"] == 0 and ecc_count_dict["uncorrectable"] == 0: + print("no errors") +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_ras_features_enabled +Description: Returns status of each block + +Input parameters: + +* `device_handle` device which to query +* `block` block which to query + +Output: Status of block + +Exceptions that can be thrown by `gpuvsmi_get_ras_features_enabled` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + block = SmiGpuBlocks.DF + status = gpuvsmi_get_ras_features_enabled(device, block) + print(status) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_bad_page_info +Description: Returns the bad page information + +Input parameters: + +* `device_handle` device which to query + +Output: Number of pages and list of bad page records + +Field | Description +---|--- +`count` | number of pages +`table_records` |
Subfield Description
`page_address`Address of page
`page_size`Size of page
`status`Status
+ +Exceptions that can be thrown by `gpuvsmi_get_bad_page_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + bad_page = gpuvsmi_get_bad_page_info(device) + print(bad_page) +except SmiException as e: + print(e) +``` + +## gpuvsmi_get_board_info +Description: Returns board related information for the given GPU + +Input parameters: + +* `device_handle` device which to query + +Output: Dictionary with fields + +Field | Description +---|--- +`serial_number`| board serial number +`product_number`| board product serial number +`product_name`| board product name + +Exceptions that can be thrown by `gpuvsmi_get_board_info` function: +* `SmiLibraryException` +* `SmiRetryException` +* `SmiParameterException` + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + for device in devices: + board_info = gpuvsmi_get_board_info(device) + print(board_info) +except SmiException as e: + print(e) +``` + +## EventListen class + +Description: Providing methods for event monitoring + +Methods: + +## Constructor + +Description: Allocates a new event reader notifier to monitor different types of events with the multiple GPUs + +Input parameters: + +* `event_types` types of events to monitor and react on + +## read + +Description: Reads events on GPUs. When event is caught, device handle, event id, message, event type and + time are returned. Reading events stops when timestamp passes without event reading. + +Input parameters: + +* `timestamp` Amount of miliseconds to wait for event. If event does not happen monitoring is finished +* `i` GPU index to which we need to listen to events. For example 0,1,2... + +Example: +```python +try: + devices = gpuvsmi_get_devices() + if len(devices) == 0: + print("No GPUs on machine") + else: + device = devices[0] + listener = EventListen(SmiEventType.GPU_PRE_RESET) + listener.read(10000) +except SmiException as e: + print(e) +``` + +## Destructor + +Description: Detroys event listener object, closes all open files and directories + +Input parameters: `None` diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py new file mode 100644 index 0000000000..81ed597e7e --- /dev/null +++ b/projects/amdsmi/py-interface/__init__.py @@ -0,0 +1,114 @@ +# +# Copyright (C) 2022 Advanced Micro Devices. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# 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: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# 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 AUTHORS 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 IN THE SOFTWARE. +# + +# Library Initialization +from .amdsmi_interface import amdsmi_init +from .amdsmi_interface import amdsmi_fini + +# Device Descovery +from .amdsmi_interface import amdsmi_get_device_type +from .amdsmi_interface import amdsmi_get_device_handles +from .amdsmi_interface import amdsmi_get_device_bdf +from .amdsmi_interface import amdsmi_get_device_uuid +from .amdsmi_interface import amdsmi_get_device_handle_from_bdf + +# # SW Version Information +from .amdsmi_interface import amdsmi_get_driver_version + +# # ASIC and Bus Static Information +from .amdsmi_interface import amdsmi_get_asic_info +from .amdsmi_interface import amdsmi_get_power_info +from .amdsmi_interface import amdsmi_get_caps_info + +# # Microcode and VBIOS Information +from .amdsmi_interface import amdsmi_get_vbios_info +from .amdsmi_interface import amdsmi_get_fw_info + +# # GPU Monitoring +from .amdsmi_interface import amdsmi_get_gpu_activity +from .amdsmi_interface import amdsmi_get_vram_usage +from .amdsmi_interface import amdsmi_get_power_measure +from .amdsmi_interface import amdsmi_get_clock_measure +from .amdsmi_interface import amdsmi_get_temperature_measure + +from .amdsmi_interface import amdsmi_get_pcie_link_status +from .amdsmi_interface import amdsmi_get_pcie_link_caps +from .amdsmi_interface import amdsmi_get_power_limit +from .amdsmi_interface import amdsmi_get_temperature_limit +from .amdsmi_interface import amdsmi_get_bad_page_info + +# # Power Management +from .amdsmi_interface import amdsmi_get_target_frequency_range + +# # Process Information +from .amdsmi_interface import amdsmi_get_process_list +from .amdsmi_interface import amdsmi_get_process_info + +# # ECC Error Information +from .amdsmi_interface import amdsmi_get_ecc_error_count + +# # Board Information +from .amdsmi_interface import amdsmi_get_board_info + +# # Ras Information +from .amdsmi_interface import amdsmi_get_ras_block_features_enabled + +# # Events +# from .smi_interface import EventListen + +# # Enums + +from .amdsmi_interface import AmdSmiInitFlags +from .amdsmi_interface import AmdSmiContainerTypes +from .amdsmi_interface import AmdSmiDeviceType +from .amdsmi_interface import AmdSmiMmIp +from .amdsmi_interface import AmdSmiFWBlock +from .amdsmi_interface import AmdSmiClockType +from .amdsmi_interface import AmdSmiTemperatureType +from .amdsmi_interface import AmdSmiDevPerfLevel +from .amdsmi_interface import AmdSmiSwComponent +from .amdsmi_interface import AmdSmiEventGroup +from .amdsmi_interface import AmdSmiEventType +from .amdsmi_interface import AmdSmiCounterCommand +from .amdsmi_interface import AmdSmiEvtNotificationType +from .amdsmi_interface import AmdSmiTemperatureMetric +from .amdsmi_interface import AmdSmiVoltageMetric +from .amdsmi_interface import AmdSmiVoltageType +from .amdsmi_interface import AmdSmiPowerProfilePresetMasks +from .amdsmi_interface import AmdSmiGpuBlock +from .amdsmi_interface import AmdSmiRasErrState +from .amdsmi_interface import AmdSmiMemoryType +from .amdsmi_interface import AmdSmiFreqInd +from .amdsmi_interface import AmdSmiXgmiStatus +from .amdsmi_interface import AmdSmiMemoryPageStatus +from .amdsmi_interface import AmdSmiIoLinkType +from .amdsmi_interface import AmdSmiUtilizationCounterType + +# Exceptions + +from .amdsmi_exception import AmdSmiLibraryException +from .amdsmi_exception import AmdSmiRetryException +from .amdsmi_exception import AmdSmiParameterException +from .amdsmi_exception import AmdSmiKeyException +from .amdsmi_exception import AmdSmiBdfFormatException +from .amdsmi_exception import AmdSmiTimeoutException +from .amdsmi_exception import AmdSmiException +from .amdsmi_exception import AmdSmiRetCode diff --git a/projects/amdsmi/py-interface/amdsmi_exception.py b/projects/amdsmi/py-interface/amdsmi_exception.py new file mode 100644 index 0000000000..8702f64194 --- /dev/null +++ b/projects/amdsmi/py-interface/amdsmi_exception.py @@ -0,0 +1,172 @@ +# +# Copyright (C) 2022 Advanced Micro Devices. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# 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: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# 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 AUTHORS 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 IN THE SOFTWARE. +# + +from enum import IntEnum +from . import amdsmi_wrapper + + +class AmdSmiRetCode(IntEnum): + SUCCESS = amdsmi_wrapper.AMDSMI_STATUS_SUCCESS + ERR_INVAL = amdsmi_wrapper.AMDSMI_STATUS_INVAL + ERR_NOT_SUPPORTED = amdsmi_wrapper.AMDSMI_STATUS_NOT_SUPPORTED + FILE_ERROR = amdsmi_wrapper.AMDSMI_STATUS_FILE_ERROR + ERR_NO_PERM = amdsmi_wrapper.AMDSMI_STATUS_NO_PERM + ERR_OUT_OF_RESOURCES = amdsmi_wrapper.AMDSMI_STATUS_OUT_OF_RESOURCES + INTERNAL_EXCEPTION = amdsmi_wrapper.AMDSMI_STATUS_INTERNAL_EXCEPTION + INPUT_OUT_OF_BOUNDS = amdsmi_wrapper.AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS + INIT_ERROR = amdsmi_wrapper.AMDSMI_STATUS_INIT_ERROR + NOT_IMPLEMENTED = amdsmi_wrapper.AMDSMI_STATUS_NOT_YET_IMPLEMENTED + ERR_NOT_FOUND = amdsmi_wrapper.AMDSMI_STATUS_NOT_FOUND + INSUFFICIENT_SIZE = amdsmi_wrapper.AMDSMI_STATUS_INSUFFICIENT_SIZE + INTERRUPT = amdsmi_wrapper.AMDSMI_STATUS_INTERRUPT + UNEXPECTED_SIZE = amdsmi_wrapper.AMDSMI_STATUS_UNEXPECTED_SIZE + NO_DATA = amdsmi_wrapper.AMDSMI_STATUS_NO_DATA + UNEXPECTED_DATA = amdsmi_wrapper.AMDSMI_STATUS_UNEXPECTED_DATA + ERR_BUSY = amdsmi_wrapper.AMDSMI_STATUS_BUSY + REFCOUNT_OVERFLOW = amdsmi_wrapper.AMDSMI_STATUS_REFCOUNT_OVERFLOW + LIB_START = amdsmi_wrapper.AMDSMI_LIB_START + FAIL_LOAD_MODULE = amdsmi_wrapper.AMDSMI_STATUS_FAIL_LOAD_MODULE + FAIL_LOAD_SYMBOL = amdsmi_wrapper.AMDSMI_STATUS_FAIL_LOAD_SYMBOL + DRM_ERROR = amdsmi_wrapper.AMDSMI_STATUS_DRM_ERROR + ERR_IO = amdsmi_wrapper.AMDSMI_STATUS_IO + FAULT = amdsmi_wrapper.AMDSMI_STATUS_FAULT + API_FAILED = amdsmi_wrapper.AMDSMI_STATUS_API_FAILED + TIMEOUT = amdsmi_wrapper.AMDSMI_STATUS_TIMEOUT + NO_SLOT = amdsmi_wrapper.AMDSMI_STATUS_NO_SLOT + RETRY = amdsmi_wrapper.AMDSMI_STATUS_RETRY + NOT_INIT = amdsmi_wrapper.AMDSMI_STATUS_NOT_INIT + UNKNOWN_ERROR = amdsmi_wrapper.AMDSMI_STATUS_UNKNOWN_ERROR + + +class AmdSmiException(Exception): + """Base smi exception class""" + + pass + + +class AmdSmiLibraryException(AmdSmiException): + def __init__(self, err_code): + err_code = abs(err_code) + super().__init__(err_code) + self.err_code = err_code + self.set_err_info() + + def __str__(self): + return "An error occured with code: {err_code}({err_info})".format( + err_code=self.err_code, err_info=self.err_info + ) + + def get_error_code(self): + return self.err_code + + def set_err_info(self): + switch = { + AmdSmiRetCode.ERR_INVAL: "AMDSMI_STATUS_INVAL - Invalid parameters", + AmdSmiRetCode.ERR_NOT_SUPPORTED: "AMDSMI_STATUS_NOT_SUPPORTED - Feature not supported", + AmdSmiRetCode.FILE_ERROR: "AMDSMI_STATUS_FILE_ERROR - Error opening file", + AmdSmiRetCode.ERR_OUT_OF_RESOURCES: "AMDSMI_STATUS_OUT_OF_RESOURCES - Not enough memory", + AmdSmiRetCode.INTERNAL_EXCEPTION: "AMDSMI_STATUS_INTERNAL_EXCEPTION - Internal error", + AmdSmiRetCode.ERR_NO_PERM: "AMDSMI_STATUS_NO_PERM - Permission Denied", + AmdSmiRetCode.INPUT_OUT_OF_BOUNDS: "AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS - Out of bounds", + AmdSmiRetCode.INIT_ERROR: "AMDSMI_STATUS_INIT_ERROR - Initialization error", + AmdSmiRetCode.ERR_BUSY: "AMDSMI_STATUS_BUSY - Device busy", + AmdSmiRetCode.ERR_NOT_FOUND: "AMDSMI_STATUS_NOT_FOUND - Device Not found", + AmdSmiRetCode.ERR_IO: "AMDSMI_STATUS_IO - I/O Error", + AmdSmiRetCode.NOT_IMPLEMENTED: "AMDSMI_STATUS_NOT_YET_IMPLEMENTED - Feature not yet implemented", + AmdSmiRetCode.INSUFFICIENT_SIZE: "AMDSMI_STATUS_INSUFFICIENT_SIZE - Insufficient size for operation", + AmdSmiRetCode.INTERRUPT: "AMDSMI_STATUS_INTERRUPT - Interrupt ocurred during execution", + AmdSmiRetCode.UNEXPECTED_SIZE: "AMDSMI_STATUS_UNEXPECTED_SIZE - unexpected size of data was read", + AmdSmiRetCode.NO_DATA: "AMDSMI_STATUS_NO_DATA - No data was found for given input", + AmdSmiRetCode.UNEXPECTED_DATA: "AMDSMI_STATUS_UNEXPECTED_DATA - The data read or provided was unexpected", + AmdSmiRetCode.REFCOUNT_OVERFLOW: "AMDSMI_STATUS_REFCOUNT_OVERFLOW - Internal reference counter exceeded INT32_MAX", + AmdSmiRetCode.LIB_START: "AMDSMI_LIB_START - Lib start status", + AmdSmiRetCode.FAIL_LOAD_MODULE: "AMDSMI_STATUS_FAIL_LOAD_MODULE - Fail to load lib", + AmdSmiRetCode.FAIL_LOAD_SYMBOL: "AMDSMI_STATUS_FAIL_LOAD_SYMBOL - Fail to load symbol", + AmdSmiRetCode.DRM_ERROR: "AMDSMI_STATUS_DRM_ERROR - Error when called libdrm", + AmdSmiRetCode.FAULT: "AMDSMI_STATUS_FAULT - Bad address", + AmdSmiRetCode.API_FAILED: "AMDSMI_STATUS_API_FAILED - API call failed", + AmdSmiRetCode.TIMEOUT: "AMDSMI_STATUS_TIMEOUT - Timeout in API call", + AmdSmiRetCode.NO_SLOT: "AMDSMI_STATUS_NO_SLOT - No more free slot", + AmdSmiRetCode.RETRY: "AMDSMI_STATUS_RETRY - Retry operation", + AmdSmiRetCode.NOT_INIT: "AMDSMI_STATUS_NOT_INIT - Device not initialized", + } + + self.err_info = switch.get(self.err_code, "AMDSMI_STATUS_UNKNOWN_ERROR - An unknown error occurred") + + +class AmdSmiRetryException(AmdSmiLibraryException): + def __init__(self): + super().__init__(AmdSmiRetCode.RETRY) + + +class AmdSmiTimeoutException(AmdSmiLibraryException): + def __init__(self): + super().__init__(AmdSmiRetCode.TIMEOUT) + + +class AmdSmiParameterException(AmdSmiException): + def __init__(self, receivedValue, expectedType, msg=None): + super().__init__(msg) + self.actualType = type(receivedValue) + self.expectedType = expectedType + self.set_err_msg() + if msg is not None: + self.err_msg = msg + + def set_err_msg(self): + self.err_msg = ( + "Invalid parameter:\n" + + "Actual type: {actualType}\n".format(actualType=self.actualType) + + "Expected type: {expectedType}".format(expectedType=self.expectedType) + ) + + def __str__(self): + return self.err_msg + + +class AmdSmiKeyException(AmdSmiException): + def __init__(self, key): + super().__init__() + self.key = key + self.set_err_msg() + + def set_err_msg(self): + self.err_msg = "Key " + self.key + " is missing from dictionary" + + def __str__(self): + return self.err_msg + + +class AmdSmiBdfFormatException(AmdSmiException): + def __init__(self, bdf): + super().__init__() + self.bdf = bdf + + def __str__(self): + return ( + "Wrong BDF format: {}. \n" + + "BDF string should be: ::.\n" + + " or :. in hexcode format.\n" + + "Where:\n\t is 4 hex digits long from 0000-FFFF interval\n" + + "\t is 2 hex digits long from 00-FF interval\n" + + "\t is 2 hex digits long from 00-1F interval\n" + + "\t is 1 hex digit long from 0-7 interval" + ).format(self.bdf) diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py new file mode 100644 index 0000000000..ab09fb8ce3 --- /dev/null +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -0,0 +1,1028 @@ +# +# Copyright (C) 2022 Advanced Micro Devices. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# 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: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# 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 AUTHORS 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 IN THE SOFTWARE. +# + +import ctypes +from typing import Union, Any, Dict, List, Tuple +from enum import IntEnum + + +from . import amdsmi_wrapper +from .amdsmi_exception import * + + +class AmdSmiInitFlags(IntEnum): + ALL_DEVICES = amdsmi_wrapper.AMDSMI_INIT_ALL_DEVICES + AMD_CPUS = amdsmi_wrapper.AMDSMI_INIT_AMD_CPUS + AMD_GPUS = amdsmi_wrapper.AMDSMI_INIT_AMD_GPUS + NON_AMD_CPUS = amdsmi_wrapper.AMDSMI_INIT_NON_AMD_CPUS + NON_AMD_GPUS = amdsmi_wrapper.AMDSMI_INIT_NON_AMD_GPUS + + +class AmdSmiContainerTypes(IntEnum): + LXC = amdsmi_wrapper.CONTAINER_LXC + DOCKER = amdsmi_wrapper.CONTAINER_DOCKER + + +class AmdSmiDeviceType(IntEnum): + UNKNOWN_DEVICE = amdsmi_wrapper.UNKNOWN + AMD_GPU_DEVICE = amdsmi_wrapper.AMD_GPU + AMD_CPU_DEVICE = amdsmi_wrapper.AMD_CPU + NON_AMD_GPU_DEVICE = amdsmi_wrapper.NON_AMD_GPU + NON_AMD_CPU_DEVICE = amdsmi_wrapper.NON_AMD_CPU + + +class AmdSmiMmIp(IntEnum): + UVD = amdsmi_wrapper.MM_UVD + VCE = amdsmi_wrapper.MM_VCE + VCN = amdsmi_wrapper.MM_VCN + + +class AmdSmiFWBlock(IntEnum): + FW_ID_SMU = amdsmi_wrapper.FW_ID_SMU + FW_ID_CP_CE = amdsmi_wrapper.FW_ID_CP_CE + FW_ID_CP_PFP = amdsmi_wrapper.FW_ID_CP_PFP + FW_ID_CP_ME = amdsmi_wrapper.FW_ID_CP_ME + FW_ID_CP_MEC_JT1 = amdsmi_wrapper.FW_ID_CP_MEC_JT1 + FW_ID_CP_MEC_JT2 = amdsmi_wrapper.FW_ID_CP_MEC_JT2 + FW_ID_CP_MEC1 = amdsmi_wrapper.FW_ID_CP_MEC1 + FW_ID_CP_MEC2 = amdsmi_wrapper.FW_ID_CP_MEC2 + FW_ID_RLC = amdsmi_wrapper.FW_ID_RLC + FW_ID_SDMA0 = amdsmi_wrapper.FW_ID_SDMA0 + FW_ID_SDMA1 = amdsmi_wrapper.FW_ID_SDMA1 + FW_ID_SDMA2 = amdsmi_wrapper.FW_ID_SDMA2 + FW_ID_SDMA3 = amdsmi_wrapper.FW_ID_SDMA3 + FW_ID_SDMA4 = amdsmi_wrapper.FW_ID_SDMA4 + FW_ID_SDMA5 = amdsmi_wrapper.FW_ID_SDMA5 + FW_ID_SDMA6 = amdsmi_wrapper.FW_ID_SDMA6 + FW_ID_SDMA7 = amdsmi_wrapper.FW_ID_SDMA7 + FW_ID_VCN = amdsmi_wrapper.FW_ID_VCN + FW_ID_UVD = amdsmi_wrapper.FW_ID_UVD + FW_ID_VCE = amdsmi_wrapper.FW_ID_VCE + FW_ID_ISP = amdsmi_wrapper.FW_ID_ISP + FW_ID_DMCU_ERAM = amdsmi_wrapper.FW_ID_DMCU_ERAM + FW_ID_DMCU_ISR = amdsmi_wrapper.FW_ID_DMCU_ISR + FW_ID_RLC_RESTORE_LIST_GPM_MEM = amdsmi_wrapper.FW_ID_RLC_RESTORE_LIST_GPM_MEM + FW_ID_RLC_RESTORE_LIST_SRM_MEM = amdsmi_wrapper.FW_ID_RLC_RESTORE_LIST_SRM_MEM + FW_ID_RLC_RESTORE_LIST_CNTL = amdsmi_wrapper.FW_ID_RLC_RESTORE_LIST_CNTL + FW_ID_RLC_V = amdsmi_wrapper.FW_ID_RLC_V + FW_ID_MMSCH = amdsmi_wrapper.FW_ID_MMSCH + FW_ID_PSP_SYSDRV = amdsmi_wrapper.FW_ID_PSP_SYSDRV + FW_ID_PSP_SOSDRV = amdsmi_wrapper.FW_ID_PSP_SOSDRV + FW_ID_PSP_TOC = amdsmi_wrapper.FW_ID_PSP_TOC + FW_ID_PSP_KEYDB = amdsmi_wrapper.FW_ID_PSP_KEYDB + FW_ID_DFC = amdsmi_wrapper.FW_ID_DFC + FW_ID_PSP_SPL = amdsmi_wrapper.FW_ID_PSP_SPL + FW_ID_DRV_CAP = amdsmi_wrapper.FW_ID_DRV_CAP + FW_ID_MC = amdsmi_wrapper.FW_ID_MC + FW_ID_PSP_BL = amdsmi_wrapper.FW_ID_PSP_BL + FW_ID_CP_PM4 = amdsmi_wrapper.FW_ID_CP_PM4 + FW_ID_ASD = amdsmi_wrapper.FW_ID_ASD + FW_ID_TA_RAS = amdsmi_wrapper.FW_ID_TA_RAS + FW_ID_XGMI = amdsmi_wrapper.FW_ID_XGMI + FW_ID_RLC_SRLG = amdsmi_wrapper.FW_ID_RLC_SRLG + FW_ID_RLC_SRLS = amdsmi_wrapper.FW_ID_RLC_SRLS + FW_ID_SMC = amdsmi_wrapper.FW_ID_SMC + FW_ID_DMCU = amdsmi_wrapper.FW_ID_DMCU + + +class AmdSmiClockType(IntEnum): + SYS = amdsmi_wrapper.CLK_TYPE_SYS + GFX = amdsmi_wrapper.CLK_TYPE_GFX + DF = amdsmi_wrapper.CLK_TYPE_DF + DCEF = amdsmi_wrapper.CLK_TYPE_DCEF + SOC = amdsmi_wrapper.CLK_TYPE_SOC + MEM = amdsmi_wrapper.CLK_TYPE_MEM + PCIE = amdsmi_wrapper.CLK_TYPE_PCIE + VCLK0 = amdsmi_wrapper.CLK_TYPE_VCLK0 + VCLK1 = amdsmi_wrapper.CLK_TYPE_VCLK1 + DCLK0 = amdsmi_wrapper.CLK_TYPE_DCLK0 + DCLK1 = amdsmi_wrapper.CLK_TYPE_DCLK1 + + +class AmdSmiTemperatureType(IntEnum): + EDGE = amdsmi_wrapper.TEMPERATURE_TYPE_EDGE + JUNCTION = amdsmi_wrapper.TEMPERATURE_TYPE_JUNCTION + VRAM = amdsmi_wrapper.TEMPERATURE_TYPE_VRAM + HBM_0 = amdsmi_wrapper.TEMPERATURE_TYPE_HBM_0 + HBM_1 = amdsmi_wrapper.TEMPERATURE_TYPE_HBM_1 + HBM_2 = amdsmi_wrapper.TEMPERATURE_TYPE_HBM_2 + HBM_3 = amdsmi_wrapper.TEMPERATURE_TYPE_HBM_3 + PLX = amdsmi_wrapper.TEMPERATURE_TYPE_PLX + + +class AmdSmiDevPerfLevel(IntEnum): + AUTO = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_AUTO + LOW = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_LOW + HIGH = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_HIGH + MANUAL = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_MANUAL + STABLE_STD = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_STABLE_STD + STABLE_PEAK = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_STABLE_PEAK + STABLE_MIN_MCLK = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK + STABLE_MIN_SCLK = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK + DETERMINISM = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_DETERMINISM + UNKNOWN = amdsmi_wrapper.AMDSMI_DEV_PERF_LEVEL_UNKNOWN + + +class AmdSmiSwComponent(IntEnum): + DRIVER = amdsmi_wrapper.AMDSMI_SW_COMP_DRIVER + + +class AmdSmiEventGroup(IntEnum): + XGMI = amdsmi_wrapper.AMDSMI_EVNT_GRP_XGMI + XGMI_DATA_OUT = amdsmi_wrapper.AMDSMI_EVNT_GRP_XGMI_DATA_OUT + GRP_INVALID = amdsmi_wrapper.AMDSMI_EVNT_GRP_INVALID + + +class AmdSmiEventType(IntEnum): + XGMI_0_NOP_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_0_NOP_TX + XGMI_0_REQUEST_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_0_REQUEST_TX + XGMI_0_RESPONSE_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_0_RESPONSE_TX + XGMI_0_BEATS_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_0_BEATS_TX + XGMI_1_NOP_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_1_NOP_TX + XGMI_1_REQUEST_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_1_REQUEST_TX + XGMI_1_RESPONSE_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_1_RESPONSE_TX + XGMI_1_BEATS_TX = amdsmi_wrapper.AMDSMI_EVNT_XGMI_1_BEATS_TX + XGMI_DATA_OUT_0 = amdsmi_wrapper.AMDSMI_EVNT_XGMI_DATA_OUT_0 + XGMI_DATA_OUT_1 = amdsmi_wrapper.AMDSMI_EVNT_XGMI_DATA_OUT_1 + XGMI_DATA_OUT_2 = amdsmi_wrapper.AMDSMI_EVNT_XGMI_DATA_OUT_2 + XGMI_DATA_OUT_3 = amdsmi_wrapper.AMDSMI_EVNT_XGMI_DATA_OUT_3 + XGMI_DATA_OUT_4 = amdsmi_wrapper.AMDSMI_EVNT_XGMI_DATA_OUT_4 + XGMI_DATA_OUT_5 = amdsmi_wrapper.AMDSMI_EVNT_XGMI_DATA_OUT_5 + + +class AmdSmiCounterCommand(IntEnum): + CMD_START = amdsmi_wrapper.AMDSMI_CNTR_CMD_START + CMD_STOP = amdsmi_wrapper.AMDSMI_CNTR_CMD_STOP + + +class AmdSmiEvtNotificationType(IntEnum): + VMFAULT = amdsmi_wrapper.AMDSMI_EVT_NOTIF_VMFAULT + THERMAL_THROTTLE = amdsmi_wrapper.AMDSMI_EVT_NOTIF_THERMAL_THROTTLE + GPU_PRE_RESET = amdsmi_wrapper.AMDSMI_EVT_NOTIF_GPU_PRE_RESET + GPU_POST_RESET = amdsmi_wrapper.AMDSMI_EVT_NOTIF_GPU_POST_RESET + + +class AmdSmiTemperatureMetric(IntEnum): + CURRENT = amdsmi_wrapper.AMDSMI_TEMP_CURRENT + MAX = amdsmi_wrapper.AMDSMI_TEMP_MAX + MIN = amdsmi_wrapper.AMDSMI_TEMP_MIN + MAX_HYST = amdsmi_wrapper.AMDSMI_TEMP_MAX_HYST + MIN_HYST = amdsmi_wrapper.AMDSMI_TEMP_MIN_HYST + CRITICAL = amdsmi_wrapper.AMDSMI_TEMP_CRITICAL + CRITICAL_HYST = amdsmi_wrapper.AMDSMI_TEMP_CRITICAL_HYST + EMERGENCY = amdsmi_wrapper.AMDSMI_TEMP_EMERGENCY + EMERGENCY_HYST = amdsmi_wrapper.AMDSMI_TEMP_EMERGENCY_HYST + CRIT_MIN = amdsmi_wrapper.AMDSMI_TEMP_CRIT_MIN + CRIT_MIN_HYST = amdsmi_wrapper.AMDSMI_TEMP_CRIT_MIN_HYST + OFFSET = amdsmi_wrapper.AMDSMI_TEMP_OFFSET + LOWEST = amdsmi_wrapper.AMDSMI_TEMP_LOWEST + HIGHEST = amdsmi_wrapper.AMDSMI_TEMP_HIGHEST + + +class AmdSmiVoltageMetric(IntEnum): + CURRENT = amdsmi_wrapper.AMDSMI_VOLT_CURRENT + MAX = amdsmi_wrapper.AMDSMI_VOLT_MAX + MIN_CRIT = amdsmi_wrapper.AMDSMI_VOLT_MIN_CRIT + MIN = amdsmi_wrapper.AMDSMI_VOLT_MIN + MAX_CRIT = amdsmi_wrapper.AMDSMI_VOLT_MAX_CRIT + AVERAGE = amdsmi_wrapper.AMDSMI_VOLT_AVERAGE + LOWEST = amdsmi_wrapper.AMDSMI_VOLT_LOWEST + HIGHEST = amdsmi_wrapper.AMDSMI_VOLT_HIGHEST + + +class AmdSmiVoltageType(IntEnum): + VDDGFX = amdsmi_wrapper.AMDSMI_VOLT_TYPE_VDDGFX + INVALID = amdsmi_wrapper.AMDSMI_VOLT_TYPE_INVALID + + +class AmdSmiPowerProfilePresetMasks(IntEnum): + CUSTOM_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_CUSTOM_MASK + VIDEO_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_VIDEO_MASK + POWER_SAVING_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_POWER_SAVING_MASK + COMPUTE_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_COMPUTE_MASK + VR_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_VR_MASK + THREE_D_FULL_SCR_MASK = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK + BOOTUP_DEFAULT = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT + INVALID = amdsmi_wrapper.AMDSMI_PWR_PROF_PRST_INVALID + + +class AmdSmiGpuBlock(IntEnum): + INVALID = amdsmi_wrapper.AMDSMI_GPU_BLOCK_INVALID + UMC = amdsmi_wrapper.AMDSMI_GPU_BLOCK_UMC + SDMA = amdsmi_wrapper.AMDSMI_GPU_BLOCK_SDMA + GFX = amdsmi_wrapper.AMDSMI_GPU_BLOCK_GFX + MMHUB = amdsmi_wrapper.AMDSMI_GPU_BLOCK_MMHUB + ATHUB = amdsmi_wrapper.AMDSMI_GPU_BLOCK_ATHUB + PCIE_BIF = amdsmi_wrapper.AMDSMI_GPU_BLOCK_PCIE_BIF + HDP = amdsmi_wrapper.AMDSMI_GPU_BLOCK_HDP + XGMI_WAFL = amdsmi_wrapper.AMDSMI_GPU_BLOCK_XGMI_WAFL + DF = amdsmi_wrapper.AMDSMI_GPU_BLOCK_DF + SMN = amdsmi_wrapper.AMDSMI_GPU_BLOCK_SMN + SEM = amdsmi_wrapper.AMDSMI_GPU_BLOCK_SEM + MP0 = amdsmi_wrapper.AMDSMI_GPU_BLOCK_MP0 + MP1 = amdsmi_wrapper.AMDSMI_GPU_BLOCK_MP1 + FUSE = amdsmi_wrapper.AMDSMI_GPU_BLOCK_FUSE + RESERVED = amdsmi_wrapper.AMDSMI_GPU_BLOCK_RESERVED + + +class AmdSmiRasErrState(IntEnum): + NONE = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_NONE + DISABLED = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_DISABLED + PARITY = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_PARITY + SING_C = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_SING_C + MULT_UC = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_MULT_UC + POISON = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_POISON + ENABLED = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_ENABLED + INVALID = amdsmi_wrapper.AMDSMI_RAS_ERR_STATE_INVALID + + +class AmdSmiMemoryType(IntEnum): + VRAM = amdsmi_wrapper.AMDSMI_MEM_TYPE_VRAM + VIS_VRAM = amdsmi_wrapper.AMDSMI_MEM_TYPE_VIS_VRAM + GTT = amdsmi_wrapper.AMDSMI_MEM_TYPE_GTT + + +class AmdSmiFreqInd(IntEnum): + MIN = amdsmi_wrapper.AMDSMI_FREQ_IND_MIN + MAX = amdsmi_wrapper.AMDSMI_FREQ_IND_MAX + INVALID = amdsmi_wrapper.AMDSMI_FREQ_IND_INVALID + + +class AmdSmiXgmiStatus(IntEnum): + NO_ERRORS = amdsmi_wrapper.AMDSMI_XGMI_STATUS_NO_ERRORS + ERROR = amdsmi_wrapper.AMDSMI_XGMI_STATUS_ERROR + MULTIPLE_ERRORS = amdsmi_wrapper.AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS + + +class AmdSmiMemoryPageStatus(IntEnum): + RESERVED = amdsmi_wrapper.AMDSMI_MEM_PAGE_STATUS_RESERVED + PENDING = amdsmi_wrapper.AMDSMI_MEM_PAGE_STATUS_PENDING + UNRESERVABLE = amdsmi_wrapper.AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE + + +class AmdSmiIoLinkType(IntEnum): + UNDEFINED = amdsmi_wrapper.AMDSMI_IOLINK_TYPE_UNDEFINED + PCIEXPRESS = amdsmi_wrapper.AMDSMI_IOLINK_TYPE_PCIEXPRESS + XGMI = amdsmi_wrapper.AMDSMI_IOLINK_TYPE_XGMI + NUMIOLINKTYPES = amdsmi_wrapper.AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES + SIZE = amdsmi_wrapper.AMDSMI_IOLINK_TYPE_SIZE + + +class AmdSmiUtilizationCounterType(IntEnum): + COARSE_GRAIN_GFX_ACTIVITY = amdsmi_wrapper.AMDSMI_COARSE_GRAIN_GFX_ACTIVITY + COARSE_GRAIN_MEM_ACTIVITY = amdsmi_wrapper.AMDSMI_COARSE_GRAIN_MEM_ACTIVITY + + +_AMDSMI_MAX_DRIVER_VERSION_LENGTH = 80 +_AMDSMI_GPU_UUID_SIZE = 38 + + +def _parse_fw_info(fw_info: amdsmi_wrapper.amdsmi_fw_info_t) -> Dict[str, Any]: + """ + Format firmware info extracted. + + Parameters: + fw_info(`amdsmi_fw_info_t`): Struct containing the extracted info to be + formatted. + + Returns: + `dict`: All of the firmware info formatted into a dictionary. + """ + if not isinstance(fw_info, amdsmi_wrapper.amdsmi_fw_info_t): + raise AmdSmiParameterException(fw_info, amdsmi_wrapper.amdsmi_fw_info_t) + formatted_fw_info = {"num_fw_info": fw_info.num_fw_info} + for index, value in amdsmi_wrapper.amdsmi_fw_block__enumvalues.items(): + if value == "FW_ID_FIRST": + value = "FW_ID_SMU" + if value == "FW_ID__MAX": + continue + formatted_fw_info.update({value: fw_info.fw_info_list[index - 1].fw_version}) + + return formatted_fw_info + + +def _format_bad_page_info(bad_page_info, bad_page_count: ctypes.c_uint32) -> List[Dict]: + """ + Format bad page info data retrieved. + + Parameters: + bad_page_info(`POINTER(amdsmi_retired_page_record_t)`): Pointer to bad page info + retrieved. + bad_page_count(`c_uint32`): Bad page count. + + Returns: + `list`: List containing formatted bad pages. + """ + if not isinstance( + bad_page_info, ctypes.POINTER(amdsmi_wrapper.amdsmi_retired_page_record_t) + ): + raise AmdSmiParameterException( + bad_page_info, ctypes.POINTER(amdsmi_wrapper.amdsmi_retired_page_record_t) + ) + + table_records = list() + for i in range(bad_page_count.value): + table_records.append( + { + "value": i, + "page_address": bad_page_info[i].page_address, + "page_size": bad_page_info[i].page_size, + "status": bad_page_info[i].status, + } + ) + return table_records + + +def _format_bdf(amdsmi_bdf: amdsmi_wrapper.amdsmi_bdf_t) -> str: + """ + Format BDF struct to readable data. + + Parameters: + amdsmi_bdf(`amdsmi_bdf_t`): Struct containing BDF data that + will be formatted. + + Returns: + `str`: String containing BDF data in a readable format. + """ + domain = hex(amdsmi_bdf.amdsmi_bdf_0.domain_number)[2:].zfill(4) + bus = hex(amdsmi_bdf.amdsmi_bdf_0.bus_number)[2:].zfill(2) + device = hex(amdsmi_bdf.amdsmi_bdf_0.device_number)[2:].zfill(2) + function = hex(amdsmi_bdf.amdsmi_bdf_0.function_number)[2:] + + return domain + ":" + bus + ":" + device + "." + function + + +def _check_res(ret_code) -> None: + """ + Wrapper for amdsmi function calls. Checks the status returned + by the call. Raises exceptions if the status was inappropriate. + + Parameters: + ret_code(`amdsmi_status_t`): Status code returned by function + call. + + Returns: + `None`. + """ + if ret_code == amdsmi_wrapper.AMDSMI_STATUS_RETRY: + raise AmdSmiRetryException() + + if ret_code == amdsmi_wrapper.AMDSMI_STATUS_TIMEOUT: + raise AmdSmiTimeoutException() + + if ret_code != amdsmi_wrapper.AMDSMI_STATUS_SUCCESS: + raise AmdSmiLibraryException(ret_code) + + +def _amdsmi_get_socket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: + """ + Function that gets socket handles. Wraps the same named function call. + + Parameters: + `None`. + + Returns: + `List`: List containing all of the found socket handles. + """ + socket_count = ctypes.c_uint32(0) + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_socket_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_socket_handles( + ctypes.byref(socket_count), null_ptr + ) + ) + socket_handles = (amdsmi_wrapper.amdsmi_socket_handle * socket_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_socket_handles( + ctypes.byref(socket_count), socket_handles + ) + ) + sockets = [ + amdsmi_wrapper.amdsmi_socket_handle(socket_handles[sock_idx]) + for sock_idx in range(socket_count.value) + ] + + return sockets + + +def amdsmi_get_device_handles() -> List[amdsmi_wrapper.amdsmi_device_handle]: + socket_handles = _amdsmi_get_socket_handles() + devices = [] + for socket in socket_handles: + device_count = ctypes.c_uint32() + null_ptr = ctypes.POINTER(amdsmi_wrapper.amdsmi_device_handle)() + _check_res( + amdsmi_wrapper.amdsmi_get_device_handles( + socket, + ctypes.byref(device_count), + null_ptr, + ) + ) + device_handles = (amdsmi_wrapper.amdsmi_device_handle * device_count.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_device_handles( + socket, + ctypes.byref(device_count), + device_handles, + ) + ) + devices.extend( + [ + amdsmi_wrapper.amdsmi_device_handle(device_handles[dev_idx]) + for dev_idx in range(device_count.value) + ] + ) + + return devices + + +def amdsmi_init(): + _check_res(amdsmi_wrapper.amdsmi_init(AmdSmiInitFlags.AMD_GPUS)) + + +def amdsmi_fini(): + _check_res(amdsmi_wrapper.amdsmi_shut_down()) + + +def amdsmi_get_device_type( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> ctypes.c_uint32: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + dev_type = amdsmi_wrapper.device_type_t() + _check_res( + amdsmi_wrapper.amdsmi_get_device_type(device_handle, ctypes.byref(dev_type)) + ) + return dev_type + + +def amdsmi_get_device_bdf(device_handle: amdsmi_wrapper.amdsmi_device_handle) -> str: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + bdf_info = amdsmi_wrapper.amdsmi_bdf_t() + _check_res( + amdsmi_wrapper.amdsmi_get_device_bdf(device_handle, ctypes.byref(bdf_info)) + ) + + return _format_bdf(bdf_info) + + +def amdsmi_get_asic_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + asic_info = amdsmi_wrapper.amdsmi_asic_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_asic_info(device_handle, ctypes.byref(asic_info)) + ) + + return { + "market_name": asic_info.market_name.decode("utf-8"), + "family": asic_info.family, + "vendor_id": asic_info.vendor_id, + "device_id": asic_info.device_id, + "rev_id": asic_info.rev_id, + "asic_serial": asic_info.asic_serial.decode("utf-8"), + } + + +def amdsmi_get_power_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + power_info = amdsmi_wrapper.amdsmi_power_cap_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_power_cap_info( + device_handle, ctypes.c_uint32(0), ctypes.byref(power_info) + ) + ) + + return {"dpm_cap": power_info.dpm_cap, "power_cap": power_info.power_cap} + + +def amdsmi_get_caps_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + gpu_caps = amdsmi_wrapper.amdsmi_gpu_caps_t() + _check_res( + amdsmi_wrapper.amdsmi_get_caps_info(device_handle, ctypes.byref(gpu_caps)) + ) + + return { + "gfx": { + "gfxip_major": gpu_caps.gfx.gfxip_major, + "gfxip_minor": gpu_caps.gfx.gfxip_minor, + "gfxip_cu_count": gpu_caps.gfx.gfxip_cu_count, + }, + "mm_ip_list": list(gpu_caps.mm.mm_ip_list), + "ras_supported": gpu_caps.ras_supported, + "gfx_ip_count": gpu_caps.gfx_ip_count, + "dma_ip_count": gpu_caps.dma_ip_count, + } + + +def amdsmi_get_vbios_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + vbios_info = amdsmi_wrapper.amdsmi_vbios_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_vbios_info(device_handle, ctypes.byref(vbios_info)) + ) + + return { + "name": vbios_info.name.decode("utf-8"), + "vbios_version": vbios_info.vbios_version, + "build_date": vbios_info.build_date.decode("utf-8"), + "part_number": vbios_info.part_number.decode("utf-8"), + "vbios_version_string": vbios_info.vbios_version_string.decode("utf-8"), + } + + +def amdsmi_get_gpu_activity( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + engine_usage = amdsmi_wrapper.amdsmi_engine_usage_t() + _check_res( + amdsmi_wrapper.amdsmi_get_gpu_activity( + device_handle, ctypes.byref(engine_usage) + ) + ) + + return { + "average_gfx_activity": engine_usage.average_gfx_activity, + "average_umc_activity": engine_usage.average_umc_activity, + "average_mm_activity": list(engine_usage.average_mm_activity), + } + + +def amdsmi_get_clock_measure( + device_handle: amdsmi_wrapper.amdsmi_device_handle, + clock_type: amdsmi_wrapper.amdsmi_clk_type_t, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + clock_measure = amdsmi_wrapper.amdsmi_clk_measure_t() + _check_res( + amdsmi_wrapper.amdsmi_get_clock_measure( + device_handle, + amdsmi_wrapper.amdsmi_clk_type_t(clock_type), + ctypes.byref(clock_measure), + ) + ) + + return { + "cur_clk": clock_measure.cur_clk, + "avg_clk": clock_measure.avg_clk, + "min_clk": clock_measure.min_clk, + "max_clk": clock_measure.max_clk, + } + + +def amdsmi_get_temperature_measure( + device_handle: amdsmi_wrapper.amdsmi_device_handle, + temperature_type: amdsmi_wrapper.amdsmi_temperature_type_t, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + temperature_measure = amdsmi_wrapper.amdsmi_temperature_t() + _check_res( + amdsmi_wrapper.amdsmi_get_temperature_measure( + device_handle, + amdsmi_wrapper.amdsmi_temperature_type_t(temperature_type), + ctypes.byref(temperature_measure), + ) + ) + + return {"cur_temp": temperature_measure.cur_temp} + + +def amdsmi_get_power_limit( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + power_limit = amdsmi_wrapper.amdsmi_power_limit_t() + _check_res( + amdsmi_wrapper.amdsmi_get_power_limit(device_handle, ctypes.byref(power_limit)) + ) + + return {"limit": power_limit.limit} + + +def amdsmi_get_temperature_limit( + device_handle: amdsmi_wrapper.amdsmi_device_handle, + temperature_type: amdsmi_wrapper.amdsmi_temperature_type_t, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + temperature_limit = amdsmi_wrapper.amdsmi_temperature_limit_t() + _check_res( + amdsmi_wrapper.amdsmi_get_temperature_limit( + device_handle, + amdsmi_wrapper.amdsmi_temperature_type_t(temperature_type), + ctypes.byref(temperature_limit), + ) + ) + + return {"limit": temperature_limit.limit} + + +def amdsmi_get_bad_page_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Union[list, str]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + num_pages = ctypes.c_uint32() + retired_page_record = ctypes.POINTER(amdsmi_wrapper.amdsmi_retired_page_record_t)() + _check_res( + amdsmi_wrapper.amdsmi_get_bad_page_info( + device_handle, ctypes.byref(num_pages), retired_page_record + ) + ) + table_records = _format_bad_page_info(retired_page_record, num_pages) + if num_pages.value == 0: + return "No bad pages found." + else: + table_records = _format_bad_page_info(retired_page_record, num_pages) + + return table_records + + +def amdsmi_get_target_frequency_range( + device_handle: amdsmi_wrapper.amdsmi_device_handle, + clock_type: amdsmi_wrapper.amdsmi_clk_type_t, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + freq_range = amdsmi_wrapper.amdsmi_frequency_range_t() + _check_res( + amdsmi_wrapper.amdsmi_get_target_frequency_range( + device_handle, + amdsmi_wrapper.amdsmi_clk_type_t(clock_type), + ctypes.byref(freq_range), + ) + ) + + return { + "supported_upper_bound": freq_range.supported_freq_range.upper_bound, + "supported_lower_bound": freq_range.supported_freq_range.lower_bound, + "current_upper_bound": freq_range.current_freq_range.upper_bound, + "current_lower_bound": freq_range.current_freq_range.lower_bound, + } + + +def amdsmi_get_ecc_error_count( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + error_count = amdsmi_wrapper.amdsmi_error_count_t() + _check_res( + amdsmi_wrapper.amdsmi_get_ecc_error_count( + device_handle, ctypes.byref(error_count) + ) + ) + + return { + "correctable_count": error_count.correctable_count, + "uncorrectable_count": error_count.uncorrectable_count, + } + + +def amdsmi_get_board_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + board_info = amdsmi_wrapper.amdsmi_board_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_board_info(device_handle, ctypes.byref(board_info)) + ) + + return { + "serial_number": board_info.serial_number, + "product_serial": board_info.product_serial.decode("utf-8"), + "product_name": board_info.product_name.decode("utf-8"), + } + + +def amdsmi_get_ras_block_features_enabled( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + ras_state = amdsmi_wrapper.amdsmi_ras_err_state_t() + ras_states = [] + for key, gpu_block in amdsmi_wrapper.amdsmi_gpu_block__enumvalues.items(): + if gpu_block == "AMDSMI_GPU_BLOCK_RESERVED": + continue + if gpu_block == "AMDSMI_GPU_BLOCK_LAST": + gpu_block = "AMDSMI_GPU_BLOCK_FUSE" + _check_res( + amdsmi_wrapper.amdsmi_get_ras_block_features_enabled( + device_handle, + amdsmi_wrapper.amdsmi_gpu_block_t(key), + ctypes.byref(ras_state), + ) + ) + ras_states.append( + { + "block": gpu_block, + "status": amdsmi_wrapper.amdsmi_ras_err_state_t__enumvalues[ + ras_state.value + ], + } + ) + + return ras_states + + +def amdsmi_get_process_list( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> List[amdsmi_wrapper.amdsmi_process_handle]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + max_processes = amdsmi_wrapper.c_uint32(0) + process_list = (amdsmi_wrapper.amdsmi_process_handle * max_processes.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_process_list( + device_handle, process_list, ctypes.byref(max_processes) + ) + ) + + process_list = (amdsmi_wrapper.amdsmi_process_handle * max_processes.value)() + _check_res( + amdsmi_wrapper.amdsmi_get_process_list( + device_handle, process_list, ctypes.byref(max_processes) + ) + ) + + return [amdsmi_wrapper.amdsmi_process_handle(x) for x in list(process_list)] + + +def amdsmi_get_process_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, + procces_handle: amdsmi_wrapper.amdsmi_process_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + if not isinstance(procces_handle, amdsmi_wrapper.amdsmi_process_handle): + raise AmdSmiParameterException( + procces_handle, amdsmi_wrapper.amdsmi_process_handle + ) + + info = amdsmi_wrapper.amdsmi_process_info() + _check_res( + amdsmi_wrapper.amdsmi_get_process_info( + device_handle, procces_handle, ctypes.byref(info) + ) + ) + + return { + "name": info.name.decode("utf-8"), + "pid": info.pid, + "mem": info.mem, + "usage": { + "gfx": list(info.engine_usage.gfx), + "compute": list(info.engine_usage.compute), + "sdma": list(info.engine_usage.sdma), + "enc": list(info.engine_usage.enc), + "dec": list(info.engine_usage.dec), + }, + "memory_usage": { + "gtt_mem": info.memory_usage.gtt_mem, + "cpu_mem": info.memory_usage.cpu_mem, + "vram_mem": info.memory_usage.vram_mem, + }, + } + + +def amdsmi_get_device_uuid(device_handle: amdsmi_wrapper.amdsmi_device_handle) -> str: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_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_device_uuid( + device_handle, ctypes.byref(uuid_length), uuid + ) + ) + + return uuid.value.decode("utf-8") + + +def amdsmi_get_driver_version( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> str: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + length = ctypes.c_int() + length.value = _AMDSMI_MAX_DRIVER_VERSION_LENGTH + + version = ctypes.create_string_buffer(_AMDSMI_MAX_DRIVER_VERSION_LENGTH) + + _check_res( + amdsmi_wrapper.amdsmi_get_driver_version( + device_handle, ctypes.byref(length), version + ) + ) + + return version.value.decode("utf-8") + + +def amdsmi_get_power_measure( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + power_measure = amdsmi_wrapper.amdsmi_power_measure_t() + _check_res( + amdsmi_wrapper.amdsmi_get_power_measure( + device_handle, ctypes.byref(power_measure) + ) + ) + + return { + "average_socket_power": power_measure.average_socket_power, + "voltage_gfx": power_measure.voltage_gfx, + "energy_accumulator": power_measure.energy_accumulator, + } + + +def amdsmi_get_fw_info( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + fw_info = amdsmi_wrapper.amdsmi_fw_info_t() + _check_res(amdsmi_wrapper.amdsmi_get_fw_info(device_handle, ctypes.byref(fw_info))) + + return _parse_fw_info(fw_info) + + +def amdsmi_get_vram_usage( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + vram_info = amdsmi_wrapper.amdsmi_vram_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_vram_usage(device_handle, ctypes.byref(vram_info)) + ) + + return {"vram_used": vram_info.vram_used, "vram_total": vram_info.vram_total} + + +def amdsmi_get_pcie_link_status( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + pcie_info = amdsmi_wrapper.amdsmi_pcie_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_pcie_link_status( + device_handle, ctypes.byref(pcie_info) + ) + ) + + return {"pcie_lanes": pcie_info.pcie_lanes, "pcie_speed": pcie_info.pcie_speed} + + +def amdsmi_get_pcie_link_caps( + device_handle: amdsmi_wrapper.amdsmi_device_handle, +) -> Dict[str, Any]: + if not isinstance(device_handle, amdsmi_wrapper.amdsmi_device_handle): + raise AmdSmiParameterException( + device_handle, amdsmi_wrapper.amdsmi_device_handle + ) + + pcie_info = amdsmi_wrapper.amdsmi_pcie_info_t() + _check_res( + amdsmi_wrapper.amdsmi_get_pcie_link_caps(device_handle, ctypes.byref(pcie_info)) + ) + + return {"pcie_lanes": pcie_info.pcie_lanes, "pcie_speed": pcie_info.pcie_speed} + + +def amdsmi_get_device_handle_from_bdf( + bdf_info: amdsmi_wrapper.amdsmi_bdf_t, +) -> amdsmi_wrapper.amdsmi_device_handle: + if not isinstance(bdf_info, amdsmi_wrapper.amdsmi_bdf_t): + raise AmdSmiParameterException(bdf_info, amdsmi_wrapper.amdsmi_bdf_t) + + device_handles_pylist = amdsmi_get_device_handles() + device_handles = (amdsmi_wrapper.amdsmi_device_handle * len(device_handles_pylist))( + *device_handles_pylist + ) + device_handle = amdsmi_wrapper.amdsmi_device_handle() + _check_res( + amdsmi_wrapper.amdsmi_get_device_handle_from_bdf( + bdf_info, + device_handles, + ctypes.c_uint32(len(device_handles_pylist)), + ctypes.byref(device_handle), + ) + ) + + return device_handle diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py new file mode 100644 index 0000000000..7ab2249c72 --- /dev/null +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -0,0 +1,2174 @@ + +# +# Copyright (C) 2022 Advanced Micro Devices. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# 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: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# 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 AUTHORS 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 IN THE SOFTWARE. +# + +from ctypes import * +from ctypes import POINTER +from subprocess import run +from subprocess import PIPE +import os + +# -*- coding: utf-8 -*- +# +# TARGET arch is: ['-I/usr/lib/llvm-14/lib/clang/14.0.0/include/'] +# WORD_SIZE is: 8 +# POINTER_SIZE is: 8 +# LONGDOUBLE_SIZE is: 16 +# +import ctypes + + +c_int128 = ctypes.c_ubyte*16 +c_uint128 = c_int128 +void = None +if ctypes.sizeof(ctypes.c_longdouble) == 16: + c_long_double_t = ctypes.c_longdouble +else: + c_long_double_t = ctypes.c_ubyte*16 + +class AsDictMixin: + @classmethod + def as_dict(cls, self): + result = {} + if not isinstance(self, AsDictMixin): + # not a structure, assume it's already a python object + return self + if not hasattr(cls, "_fields_"): + return result + # sys.version_info >= (3, 5) + # for (field, *_) in cls._fields_: # noqa + for field_tuple in cls._fields_: # noqa + field = field_tuple[0] + if field.startswith('PADDING_'): + continue + value = getattr(self, field) + type_ = type(value) + if hasattr(value, "_length_") and hasattr(value, "_type_"): + # array + if not hasattr(type_, "as_dict"): + value = [v for v in value] + else: + type_ = type_._type_ + value = [type_.as_dict(v) for v in value] + elif hasattr(value, "contents") and hasattr(value, "_type_"): + # pointer + try: + if not hasattr(type_, "as_dict"): + value = value.contents + else: + type_ = type_._type_ + value = type_.as_dict(value.contents) + except ValueError: + # nullptr + value = None + elif isinstance(value, AsDictMixin): + # other structure + value = type_.as_dict(value) + result[field] = value + return result + + +class Structure(ctypes.Structure, AsDictMixin): + + def __init__(self, *args, **kwds): + # We don't want to use positional arguments fill PADDING_* fields + + args = dict(zip(self.__class__._field_names_(), args)) + args.update(kwds) + super(Structure, self).__init__(**args) + + @classmethod + def _field_names_(cls): + if hasattr(cls, '_fields_'): + return (f[0] for f in cls._fields_ if not f[0].startswith('PADDING')) + else: + return () + + @classmethod + def get_type(cls, field): + for f in cls._fields_: + if f[0] == field: + return f[1] + return None + + @classmethod + def bind(cls, bound_fields): + fields = {} + for name, type_ in cls._fields_: + if hasattr(type_, "restype"): + if name in bound_fields: + if bound_fields[name] is None: + fields[name] = type_() + else: + # use a closure to capture the callback from the loop scope + fields[name] = ( + type_((lambda callback: lambda *args: callback(*args))( + bound_fields[name])) + ) + del bound_fields[name] + else: + # default callback implementation (does nothing) + try: + default_ = type_(0).restype().value + except TypeError: + default_ = None + fields[name] = type_(( + lambda default_: lambda *args: default_)(default_)) + else: + # not a callback function, use default initialization + if name in bound_fields: + fields[name] = bound_fields[name] + del bound_fields[name] + else: + fields[name] = type_() + if len(bound_fields) != 0: + raise ValueError( + "Cannot bind the following unknown callback(s) {}.{}".format( + cls.__name__, bound_fields.keys() + )) + return cls(**fields) + + +class Union(ctypes.Union, AsDictMixin): + pass + + + +def string_cast(char_pointer, encoding='utf-8', errors='strict'): + value = ctypes.cast(char_pointer, ctypes.c_char_p).value + if value is not None and encoding is not None: + value = value.decode(encoding, errors=errors) + return value + + +def char_pointer_cast(string, encoding='utf-8'): + if encoding is not None: + try: + string = string.encode(encoding) + except AttributeError: + # In Python3, bytes has no encode attribute + pass + string = ctypes.c_char_p(string) + return ctypes.cast(string, ctypes.POINTER(ctypes.c_char)) + + + + + + +# values for enumeration 'amdsmi_init_flags' +amdsmi_init_flags__enumvalues = { + 0: 'AMDSMI_INIT_ALL_DEVICES', + 1: 'AMDSMI_INIT_AMD_CPUS', + 2: 'AMDSMI_INIT_AMD_GPUS', + 4: 'AMDSMI_INIT_NON_AMD_CPUS', + 8: 'AMDSMI_INIT_NON_AMD_GPUS', +} +AMDSMI_INIT_ALL_DEVICES = 0 +AMDSMI_INIT_AMD_CPUS = 1 +AMDSMI_INIT_AMD_GPUS = 2 +AMDSMI_INIT_NON_AMD_CPUS = 4 +AMDSMI_INIT_NON_AMD_GPUS = 8 +amdsmi_init_flags = ctypes.c_uint32 # enum +amdsmi_init_flags_t = amdsmi_init_flags +amdsmi_init_flags_t__enumvalues = amdsmi_init_flags__enumvalues + +# values for enumeration 'amdsmi_mm_ip' +amdsmi_mm_ip__enumvalues = { + 0: 'MM_UVD', + 1: 'MM_VCE', + 2: 'MM_VCN', + 3: 'MM__MAX', +} +MM_UVD = 0 +MM_VCE = 1 +MM_VCN = 2 +MM__MAX = 3 +amdsmi_mm_ip = ctypes.c_uint32 # enum +amdsmi_mm_ip_t = amdsmi_mm_ip +amdsmi_mm_ip_t__enumvalues = amdsmi_mm_ip__enumvalues + +# values for enumeration 'amdsmi_container_types' +amdsmi_container_types__enumvalues = { + 0: 'CONTAINER_LXC', + 1: 'CONTAINER_DOCKER', +} +CONTAINER_LXC = 0 +CONTAINER_DOCKER = 1 +amdsmi_container_types = ctypes.c_uint32 # enum +amdsmi_container_types_t = amdsmi_container_types +amdsmi_container_types_t__enumvalues = amdsmi_container_types__enumvalues +amdsmi_device_handle = ctypes.c_void_p +amdsmi_socket_handle = ctypes.c_void_p + +# values for enumeration 'device_type' +device_type__enumvalues = { + 0: 'UNKNOWN', + 1: 'AMD_GPU', + 2: 'AMD_CPU', + 3: 'NON_AMD_GPU', + 4: 'NON_AMD_CPU', +} +UNKNOWN = 0 +AMD_GPU = 1 +AMD_CPU = 2 +NON_AMD_GPU = 3 +NON_AMD_CPU = 4 +device_type = ctypes.c_uint32 # enum +device_type_t = device_type +device_type_t__enumvalues = device_type__enumvalues + +# values for enumeration 'amdsmi_clk_type' +amdsmi_clk_type__enumvalues = { + 0: 'CLK_TYPE_SYS', + 0: 'CLK_TYPE_FIRST', + 0: 'CLK_TYPE_GFX', + 1: 'CLK_TYPE_DF', + 2: 'CLK_TYPE_DCEF', + 3: 'CLK_TYPE_SOC', + 4: 'CLK_TYPE_MEM', + 5: 'CLK_TYPE_PCIE', + 6: 'CLK_TYPE_VCLK0', + 7: 'CLK_TYPE_VCLK1', + 8: 'CLK_TYPE_DCLK0', + 9: 'CLK_TYPE_DCLK1', + 9: 'CLK_TYPE__MAX', +} +CLK_TYPE_SYS = 0 +CLK_TYPE_FIRST = 0 +CLK_TYPE_GFX = 0 +CLK_TYPE_DF = 1 +CLK_TYPE_DCEF = 2 +CLK_TYPE_SOC = 3 +CLK_TYPE_MEM = 4 +CLK_TYPE_PCIE = 5 +CLK_TYPE_VCLK0 = 6 +CLK_TYPE_VCLK1 = 7 +CLK_TYPE_DCLK0 = 8 +CLK_TYPE_DCLK1 = 9 +CLK_TYPE__MAX = 9 +amdsmi_clk_type = ctypes.c_uint32 # enum +amdsmi_clk_type_t = amdsmi_clk_type +amdsmi_clk_type_t__enumvalues = amdsmi_clk_type__enumvalues + +# values for enumeration 'amdsmi_temperature_type' +amdsmi_temperature_type__enumvalues = { + 0: 'TEMPERATURE_TYPE_EDGE', + 0: 'TEMPERATURE_TYPE_FIRST', + 1: 'TEMPERATURE_TYPE_JUNCTION', + 2: 'TEMPERATURE_TYPE_VRAM', + 3: 'TEMPERATURE_TYPE_HBM_0', + 4: 'TEMPERATURE_TYPE_HBM_1', + 5: 'TEMPERATURE_TYPE_HBM_2', + 6: 'TEMPERATURE_TYPE_HBM_3', + 7: 'TEMPERATURE_TYPE_PLX', + 7: 'TEMPERATURE_TYPE__MAX', +} +TEMPERATURE_TYPE_EDGE = 0 +TEMPERATURE_TYPE_FIRST = 0 +TEMPERATURE_TYPE_JUNCTION = 1 +TEMPERATURE_TYPE_VRAM = 2 +TEMPERATURE_TYPE_HBM_0 = 3 +TEMPERATURE_TYPE_HBM_1 = 4 +TEMPERATURE_TYPE_HBM_2 = 5 +TEMPERATURE_TYPE_HBM_3 = 6 +TEMPERATURE_TYPE_PLX = 7 +TEMPERATURE_TYPE__MAX = 7 +amdsmi_temperature_type = ctypes.c_uint32 # enum +amdsmi_temperature_type_t = amdsmi_temperature_type +amdsmi_temperature_type_t__enumvalues = amdsmi_temperature_type__enumvalues + +# values for enumeration 'amdsmi_fw_block' +amdsmi_fw_block__enumvalues = { + 1: 'FW_ID_SMU', + 1: 'FW_ID_FIRST', + 2: 'FW_ID_CP_CE', + 3: 'FW_ID_CP_PFP', + 4: 'FW_ID_CP_ME', + 5: 'FW_ID_CP_MEC_JT1', + 6: 'FW_ID_CP_MEC_JT2', + 7: 'FW_ID_CP_MEC1', + 8: 'FW_ID_CP_MEC2', + 9: 'FW_ID_RLC', + 10: 'FW_ID_SDMA0', + 11: 'FW_ID_SDMA1', + 12: 'FW_ID_SDMA2', + 13: 'FW_ID_SDMA3', + 14: 'FW_ID_SDMA4', + 15: 'FW_ID_SDMA5', + 16: 'FW_ID_SDMA6', + 17: 'FW_ID_SDMA7', + 18: 'FW_ID_VCN', + 19: 'FW_ID_UVD', + 20: 'FW_ID_VCE', + 21: 'FW_ID_ISP', + 22: 'FW_ID_DMCU_ERAM', + 23: 'FW_ID_DMCU_ISR', + 24: 'FW_ID_RLC_RESTORE_LIST_GPM_MEM', + 25: 'FW_ID_RLC_RESTORE_LIST_SRM_MEM', + 26: 'FW_ID_RLC_RESTORE_LIST_CNTL', + 27: 'FW_ID_RLC_V', + 28: 'FW_ID_MMSCH', + 29: 'FW_ID_PSP_SYSDRV', + 30: 'FW_ID_PSP_SOSDRV', + 31: 'FW_ID_PSP_TOC', + 32: 'FW_ID_PSP_KEYDB', + 33: 'FW_ID_DFC', + 34: 'FW_ID_PSP_SPL', + 35: 'FW_ID_DRV_CAP', + 36: 'FW_ID_MC', + 37: 'FW_ID_PSP_BL', + 38: 'FW_ID_CP_PM4', + 39: 'FW_ID_ASD', + 40: 'FW_ID_TA_RAS', + 41: 'FW_ID_XGMI', + 42: 'FW_ID_RLC_SRLG', + 43: 'FW_ID_RLC_SRLS', + 44: 'FW_ID_SMC', + 45: 'FW_ID_DMCU', + 46: 'FW_ID__MAX', +} +FW_ID_SMU = 1 +FW_ID_FIRST = 1 +FW_ID_CP_CE = 2 +FW_ID_CP_PFP = 3 +FW_ID_CP_ME = 4 +FW_ID_CP_MEC_JT1 = 5 +FW_ID_CP_MEC_JT2 = 6 +FW_ID_CP_MEC1 = 7 +FW_ID_CP_MEC2 = 8 +FW_ID_RLC = 9 +FW_ID_SDMA0 = 10 +FW_ID_SDMA1 = 11 +FW_ID_SDMA2 = 12 +FW_ID_SDMA3 = 13 +FW_ID_SDMA4 = 14 +FW_ID_SDMA5 = 15 +FW_ID_SDMA6 = 16 +FW_ID_SDMA7 = 17 +FW_ID_VCN = 18 +FW_ID_UVD = 19 +FW_ID_VCE = 20 +FW_ID_ISP = 21 +FW_ID_DMCU_ERAM = 22 +FW_ID_DMCU_ISR = 23 +FW_ID_RLC_RESTORE_LIST_GPM_MEM = 24 +FW_ID_RLC_RESTORE_LIST_SRM_MEM = 25 +FW_ID_RLC_RESTORE_LIST_CNTL = 26 +FW_ID_RLC_V = 27 +FW_ID_MMSCH = 28 +FW_ID_PSP_SYSDRV = 29 +FW_ID_PSP_SOSDRV = 30 +FW_ID_PSP_TOC = 31 +FW_ID_PSP_KEYDB = 32 +FW_ID_DFC = 33 +FW_ID_PSP_SPL = 34 +FW_ID_DRV_CAP = 35 +FW_ID_MC = 36 +FW_ID_PSP_BL = 37 +FW_ID_CP_PM4 = 38 +FW_ID_ASD = 39 +FW_ID_TA_RAS = 40 +FW_ID_XGMI = 41 +FW_ID_RLC_SRLG = 42 +FW_ID_RLC_SRLS = 43 +FW_ID_SMC = 44 +FW_ID_DMCU = 45 +FW_ID__MAX = 46 +amdsmi_fw_block = ctypes.c_uint32 # enum +amdsmi_fw_block_t = amdsmi_fw_block +amdsmi_fw_block_t__enumvalues = amdsmi_fw_block__enumvalues +class c__SA_amdsmi_range_t(Structure): + pass + +c__SA_amdsmi_range_t._pack_ = 1 # source:False +c__SA_amdsmi_range_t._fields_ = [ + ('lower_bound', ctypes.c_uint64), + ('upper_bound', ctypes.c_uint64), +] + +amdsmi_range_t = c__SA_amdsmi_range_t +amdsmi_range = c__SA_amdsmi_range_t +class amdsmi_xgmi_info(Structure): + pass + +amdsmi_xgmi_info._pack_ = 1 # source:False +amdsmi_xgmi_info._fields_ = [ + ('xgmi_lanes', ctypes.c_ubyte), + ('PADDING_0', ctypes.c_ubyte * 7), + ('xgmi_hive_id', ctypes.c_uint64), + ('xgmi_node_id', ctypes.c_uint64), + ('index', ctypes.c_uint32), + ('PADDING_1', ctypes.c_ubyte * 4), +] + +amdsmi_xgmi_info_t = amdsmi_xgmi_info +class amdsmi_gpu_caps(Structure): + pass + +class amdsmi_gpu_caps_1(Structure): + pass + +amdsmi_gpu_caps_1._pack_ = 1 # source:False +amdsmi_gpu_caps_1._fields_ = [ + ('mm_ip_count', ctypes.c_ubyte), + ('mm_ip_list', ctypes.c_ubyte * 8), +] + +class amdsmi_gpu_caps_0(Structure): + pass + +amdsmi_gpu_caps_0._pack_ = 1 # source:False +amdsmi_gpu_caps_0._fields_ = [ + ('gfxip_major', ctypes.c_uint32), + ('gfxip_minor', ctypes.c_uint32), + ('gfxip_cu_count', ctypes.c_uint16), + ('PADDING_0', ctypes.c_ubyte * 2), +] + +amdsmi_gpu_caps._pack_ = 1 # source:False +amdsmi_gpu_caps._fields_ = [ + ('gfx', amdsmi_gpu_caps_0), + ('mm', amdsmi_gpu_caps_1), + ('ras_supported', ctypes.c_bool), + ('max_vf_num', ctypes.c_ubyte), + ('PADDING_0', ctypes.c_ubyte), + ('gfx_ip_count', ctypes.c_uint32), + ('dma_ip_count', ctypes.c_uint32), +] + +amdsmi_gpu_caps_t = amdsmi_gpu_caps +class amdsmi_vram_info(Structure): + pass + +amdsmi_vram_info._pack_ = 1 # source:False +amdsmi_vram_info._fields_ = [ + ('vram_total', ctypes.c_uint32), + ('vram_used', ctypes.c_uint32), +] + +amdsmi_vram_info_t = amdsmi_vram_info +class amdsmi_frequency_range(Structure): + _pack_ = 1 # source:False + _fields_ = [ + ('supported_freq_range', amdsmi_range_t), + ('current_freq_range', amdsmi_range_t), + ] + +amdsmi_frequency_range_t = amdsmi_frequency_range +class amdsmi_bdf(Union): + pass + +class amdsmi_bdf_0(Structure): + pass + +amdsmi_bdf_0._pack_ = 1 # source:False +amdsmi_bdf_0._fields_ = [ + ('function_number', ctypes.c_uint64, 3), + ('device_number', ctypes.c_uint64, 5), + ('bus_number', ctypes.c_uint64, 8), + ('domain_number', ctypes.c_uint64, 48), +] + +amdsmi_bdf._pack_ = 1 # source:False +amdsmi_bdf._fields_ = [ + ('amdsmi_bdf_0', amdsmi_bdf_0), + ('as_uint', ctypes.c_uint64), +] + +amdsmi_bdf_t = amdsmi_bdf +class amdsmi_power_cap_info(Structure): + pass + +amdsmi_power_cap_info._pack_ = 1 # source:False +amdsmi_power_cap_info._fields_ = [ + ('power_cap', ctypes.c_uint64), + ('default_power_cap', ctypes.c_uint64), + ('dpm_cap', ctypes.c_uint64), + ('min_power_cap', ctypes.c_uint64), + ('max_power_cap', ctypes.c_uint64), +] + +amdsmi_power_cap_info_t = amdsmi_power_cap_info +class amdsmi_vbios_info(Structure): + pass + +amdsmi_vbios_info._pack_ = 1 # source:False +amdsmi_vbios_info._fields_ = [ + ('name', ctypes.c_char * 64), + ('vbios_version', ctypes.c_uint32), + ('build_date', ctypes.c_char * 32), + ('part_number', ctypes.c_char * 64), + ('vbios_version_string', ctypes.c_char * 32), +] + +amdsmi_vbios_info_t = amdsmi_vbios_info +class amdsmi_fw_info(Structure): + pass + +class amdsmi_fw_info_0(Structure): + pass + +amdsmi_fw_info_0._pack_ = 1 # source:False +amdsmi_fw_info_0._fields_ = [ + ('fw_id', amdsmi_fw_block_t), + ('PADDING_0', ctypes.c_ubyte * 4), + ('fw_version', ctypes.c_uint64), +] + +amdsmi_fw_info._pack_ = 1 # source:False +amdsmi_fw_info._fields_ = [ + ('num_fw_info', ctypes.c_ubyte), + ('PADDING_0', ctypes.c_ubyte * 7), + ('fw_info_list', amdsmi_fw_info_0 * 46), +] + +amdsmi_fw_info_t = amdsmi_fw_info +class amdsmi_asic_info(Structure): + pass + +amdsmi_asic_info._pack_ = 1 # source:False +amdsmi_asic_info._fields_ = [ + ('market_name', ctypes.c_char * 64), + ('family', ctypes.c_uint32), + ('vendor_id', ctypes.c_uint32), + ('subvendor_id', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ('device_id', ctypes.c_uint64), + ('rev_id', ctypes.c_uint32), + ('asic_serial', ctypes.c_char * 32), + ('PADDING_1', ctypes.c_ubyte * 4), +] + +amdsmi_asic_info_t = amdsmi_asic_info +class amdsmi_board_info(Structure): + pass + +amdsmi_board_info._pack_ = 1 # source:False +amdsmi_board_info._fields_ = [ + ('serial_number', ctypes.c_uint64), + ('is_master', ctypes.c_bool), + ('model_number', ctypes.c_char * 32), + ('product_serial', ctypes.c_char * 32), + ('fru_id', ctypes.c_char * 32), + ('product_name', ctypes.c_char * 128), + ('manufacturer_name', ctypes.c_char * 32), + ('PADDING_0', ctypes.c_ubyte * 7), +] + +amdsmi_board_info_t = amdsmi_board_info +class amdsmi_temperature(Structure): + pass + +amdsmi_temperature._pack_ = 1 # source:False +amdsmi_temperature._fields_ = [ + ('cur_temp', ctypes.c_uint32), +] + +amdsmi_temperature_t = amdsmi_temperature +class amdsmi_temperature_limit(Structure): + pass + +amdsmi_temperature_limit._pack_ = 1 # source:False +amdsmi_temperature_limit._fields_ = [ + ('limit', ctypes.c_uint32), +] + +amdsmi_temperature_limit_t = amdsmi_temperature_limit +class amdsmi_power_limit(Structure): + pass + +amdsmi_power_limit._pack_ = 1 # source:False +amdsmi_power_limit._fields_ = [ + ('limit', ctypes.c_uint32), +] + +amdsmi_power_limit_t = amdsmi_power_limit +class amdsmi_power_measure(Structure): + pass + +amdsmi_power_measure._pack_ = 1 # source:False +amdsmi_power_measure._fields_ = [ + ('average_socket_power', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ('energy_accumulator', ctypes.c_uint64), + ('voltage_gfx', ctypes.c_uint32), + ('voltage_soc', ctypes.c_uint32), + ('voltage_mem', ctypes.c_uint32), + ('PADDING_1', ctypes.c_ubyte * 4), +] + +amdsmi_power_measure_t = amdsmi_power_measure +class amdsmi_clk_measure(Structure): + pass + +amdsmi_clk_measure._pack_ = 1 # source:False +amdsmi_clk_measure._fields_ = [ + ('cur_clk', ctypes.c_uint32), + ('avg_clk', ctypes.c_uint32), + ('min_clk', ctypes.c_uint32), + ('max_clk', ctypes.c_uint32), +] + +amdsmi_clk_measure_t = amdsmi_clk_measure +class amdsmi_engine_usage(Structure): + pass + +amdsmi_engine_usage._pack_ = 1 # source:False +amdsmi_engine_usage._fields_ = [ + ('average_gfx_activity', ctypes.c_uint32), + ('average_umc_activity', ctypes.c_uint32), + ('average_mm_activity', ctypes.c_uint32 * 8), +] + +amdsmi_engine_usage_t = amdsmi_engine_usage +amdsmi_process_handle = ctypes.c_uint32 +class amdsmi_process_info(Structure): + pass + +class amdsmi_process_info_1(Structure): + pass + +amdsmi_process_info_1._pack_ = 1 # source:False +amdsmi_process_info_1._fields_ = [ + ('gtt_mem', ctypes.c_uint64), + ('cpu_mem', ctypes.c_uint64), + ('vram_mem', ctypes.c_uint64), +] + +class amdsmi_process_info_0(Structure): + pass + +amdsmi_process_info_0._pack_ = 1 # source:False +amdsmi_process_info_0._fields_ = [ + ('gfx', ctypes.c_uint16 * 8), + ('compute', ctypes.c_uint16 * 8), + ('sdma', ctypes.c_uint16 * 8), + ('enc', ctypes.c_uint16 * 8), + ('dec', ctypes.c_uint16 * 8), +] + +amdsmi_process_info._pack_ = 1 # source:False +amdsmi_process_info._fields_ = [ + ('name', ctypes.c_char * 32), + ('pid', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ('mem', ctypes.c_uint64), + ('engine_usage', amdsmi_process_info_0), + ('memory_usage', amdsmi_process_info_1), + ('container_name', ctypes.c_char * 32), +] + +amdsmi_proc_info_t = amdsmi_process_info + +# values for enumeration 'c__EA_amdsmi_dev_perf_level_t' +c__EA_amdsmi_dev_perf_level_t__enumvalues = { + 0: 'AMDSMI_DEV_PERF_LEVEL_AUTO', + 0: 'AMDSMI_DEV_PERF_LEVEL_FIRST', + 1: 'AMDSMI_DEV_PERF_LEVEL_LOW', + 2: 'AMDSMI_DEV_PERF_LEVEL_HIGH', + 3: 'AMDSMI_DEV_PERF_LEVEL_MANUAL', + 4: 'AMDSMI_DEV_PERF_LEVEL_STABLE_STD', + 5: 'AMDSMI_DEV_PERF_LEVEL_STABLE_PEAK', + 6: 'AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK', + 7: 'AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK', + 8: 'AMDSMI_DEV_PERF_LEVEL_DETERMINISM', + 8: 'AMDSMI_DEV_PERF_LEVEL_LAST', + 256: 'AMDSMI_DEV_PERF_LEVEL_UNKNOWN', +} +AMDSMI_DEV_PERF_LEVEL_AUTO = 0 +AMDSMI_DEV_PERF_LEVEL_FIRST = 0 +AMDSMI_DEV_PERF_LEVEL_LOW = 1 +AMDSMI_DEV_PERF_LEVEL_HIGH = 2 +AMDSMI_DEV_PERF_LEVEL_MANUAL = 3 +AMDSMI_DEV_PERF_LEVEL_STABLE_STD = 4 +AMDSMI_DEV_PERF_LEVEL_STABLE_PEAK = 5 +AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK = 6 +AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK = 7 +AMDSMI_DEV_PERF_LEVEL_DETERMINISM = 8 +AMDSMI_DEV_PERF_LEVEL_LAST = 8 +AMDSMI_DEV_PERF_LEVEL_UNKNOWN = 256 +c__EA_amdsmi_dev_perf_level_t = ctypes.c_uint32 # enum +amdsmi_dev_perf_level_t = c__EA_amdsmi_dev_perf_level_t +amdsmi_dev_perf_level_t__enumvalues = c__EA_amdsmi_dev_perf_level_t__enumvalues +amdsmi_dev_perf_level = c__EA_amdsmi_dev_perf_level_t +amdsmi_dev_perf_level__enumvalues = c__EA_amdsmi_dev_perf_level_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_sw_component_t' +c__EA_amdsmi_sw_component_t__enumvalues = { + 0: 'AMDSMI_SW_COMP_FIRST', + 0: 'AMDSMI_SW_COMP_DRIVER', + 0: 'AMDSMI_SW_COMP_LAST', +} +AMDSMI_SW_COMP_FIRST = 0 +AMDSMI_SW_COMP_DRIVER = 0 +AMDSMI_SW_COMP_LAST = 0 +c__EA_amdsmi_sw_component_t = ctypes.c_uint32 # enum +amdsmi_sw_component_t = c__EA_amdsmi_sw_component_t +amdsmi_sw_component_t__enumvalues = c__EA_amdsmi_sw_component_t__enumvalues +amdsmi_event_handle_t = ctypes.c_uint64 + +# values for enumeration 'c__EA_amdsmi_event_group_t' +c__EA_amdsmi_event_group_t__enumvalues = { + 0: 'AMDSMI_EVNT_GRP_XGMI', + 10: 'AMDSMI_EVNT_GRP_XGMI_DATA_OUT', + 4294967295: 'AMDSMI_EVNT_GRP_INVALID', +} +AMDSMI_EVNT_GRP_XGMI = 0 +AMDSMI_EVNT_GRP_XGMI_DATA_OUT = 10 +AMDSMI_EVNT_GRP_INVALID = 4294967295 +c__EA_amdsmi_event_group_t = ctypes.c_uint32 # enum +amdsmi_event_group_t = c__EA_amdsmi_event_group_t +amdsmi_event_group_t__enumvalues = c__EA_amdsmi_event_group_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_event_type_t' +c__EA_amdsmi_event_type_t__enumvalues = { + 0: 'AMDSMI_EVNT_FIRST', + 0: 'AMDSMI_EVNT_XGMI_FIRST', + 0: 'AMDSMI_EVNT_XGMI_0_NOP_TX', + 1: 'AMDSMI_EVNT_XGMI_0_REQUEST_TX', + 2: 'AMDSMI_EVNT_XGMI_0_RESPONSE_TX', + 3: 'AMDSMI_EVNT_XGMI_0_BEATS_TX', + 4: 'AMDSMI_EVNT_XGMI_1_NOP_TX', + 5: 'AMDSMI_EVNT_XGMI_1_REQUEST_TX', + 6: 'AMDSMI_EVNT_XGMI_1_RESPONSE_TX', + 7: 'AMDSMI_EVNT_XGMI_1_BEATS_TX', + 7: 'AMDSMI_EVNT_XGMI_LAST', + 10: 'AMDSMI_EVNT_XGMI_DATA_OUT_FIRST', + 10: 'AMDSMI_EVNT_XGMI_DATA_OUT_0', + 11: 'AMDSMI_EVNT_XGMI_DATA_OUT_1', + 12: 'AMDSMI_EVNT_XGMI_DATA_OUT_2', + 13: 'AMDSMI_EVNT_XGMI_DATA_OUT_3', + 14: 'AMDSMI_EVNT_XGMI_DATA_OUT_4', + 15: 'AMDSMI_EVNT_XGMI_DATA_OUT_5', + 15: 'AMDSMI_EVNT_XGMI_DATA_OUT_LAST', + 15: 'AMDSMI_EVNT_LAST', +} +AMDSMI_EVNT_FIRST = 0 +AMDSMI_EVNT_XGMI_FIRST = 0 +AMDSMI_EVNT_XGMI_0_NOP_TX = 0 +AMDSMI_EVNT_XGMI_0_REQUEST_TX = 1 +AMDSMI_EVNT_XGMI_0_RESPONSE_TX = 2 +AMDSMI_EVNT_XGMI_0_BEATS_TX = 3 +AMDSMI_EVNT_XGMI_1_NOP_TX = 4 +AMDSMI_EVNT_XGMI_1_REQUEST_TX = 5 +AMDSMI_EVNT_XGMI_1_RESPONSE_TX = 6 +AMDSMI_EVNT_XGMI_1_BEATS_TX = 7 +AMDSMI_EVNT_XGMI_LAST = 7 +AMDSMI_EVNT_XGMI_DATA_OUT_FIRST = 10 +AMDSMI_EVNT_XGMI_DATA_OUT_0 = 10 +AMDSMI_EVNT_XGMI_DATA_OUT_1 = 11 +AMDSMI_EVNT_XGMI_DATA_OUT_2 = 12 +AMDSMI_EVNT_XGMI_DATA_OUT_3 = 13 +AMDSMI_EVNT_XGMI_DATA_OUT_4 = 14 +AMDSMI_EVNT_XGMI_DATA_OUT_5 = 15 +AMDSMI_EVNT_XGMI_DATA_OUT_LAST = 15 +AMDSMI_EVNT_LAST = 15 +c__EA_amdsmi_event_type_t = ctypes.c_uint32 # enum +amdsmi_event_type_t = c__EA_amdsmi_event_type_t +amdsmi_event_type_t__enumvalues = c__EA_amdsmi_event_type_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_counter_command_t' +c__EA_amdsmi_counter_command_t__enumvalues = { + 0: 'AMDSMI_CNTR_CMD_START', + 1: 'AMDSMI_CNTR_CMD_STOP', +} +AMDSMI_CNTR_CMD_START = 0 +AMDSMI_CNTR_CMD_STOP = 1 +c__EA_amdsmi_counter_command_t = ctypes.c_uint32 # enum +amdsmi_counter_command_t = c__EA_amdsmi_counter_command_t +amdsmi_counter_command_t__enumvalues = c__EA_amdsmi_counter_command_t__enumvalues +class c__SA_amdsmi_counter_value_t(Structure): + pass + +c__SA_amdsmi_counter_value_t._pack_ = 1 # source:False +c__SA_amdsmi_counter_value_t._fields_ = [ + ('value', ctypes.c_uint64), + ('time_enabled', ctypes.c_uint64), + ('time_running', ctypes.c_uint64), +] + +amdsmi_counter_value_t = c__SA_amdsmi_counter_value_t + +# values for enumeration 'c__EA_amdsmi_evt_notification_type_t' +c__EA_amdsmi_evt_notification_type_t__enumvalues = { + 1: 'AMDSMI_EVT_NOTIF_VMFAULT', + 1: 'AMDSMI_EVT_NOTIF_FIRST', + 2: 'AMDSMI_EVT_NOTIF_THERMAL_THROTTLE', + 3: 'AMDSMI_EVT_NOTIF_GPU_PRE_RESET', + 4: 'AMDSMI_EVT_NOTIF_GPU_POST_RESET', + 4: 'AMDSMI_EVT_NOTIF_LAST', +} +AMDSMI_EVT_NOTIF_VMFAULT = 1 +AMDSMI_EVT_NOTIF_FIRST = 1 +AMDSMI_EVT_NOTIF_THERMAL_THROTTLE = 2 +AMDSMI_EVT_NOTIF_GPU_PRE_RESET = 3 +AMDSMI_EVT_NOTIF_GPU_POST_RESET = 4 +AMDSMI_EVT_NOTIF_LAST = 4 +c__EA_amdsmi_evt_notification_type_t = ctypes.c_uint32 # enum +amdsmi_evt_notification_type_t = c__EA_amdsmi_evt_notification_type_t +amdsmi_evt_notification_type_t__enumvalues = c__EA_amdsmi_evt_notification_type_t__enumvalues +class c__SA_amdsmi_evt_notification_data_t(Structure): + pass + +c__SA_amdsmi_evt_notification_data_t._pack_ = 1 # source:False +c__SA_amdsmi_evt_notification_data_t._fields_ = [ + ('device_handle', ctypes.c_void_p), + ('event', amdsmi_evt_notification_type_t), + ('message', ctypes.c_char * 64), + ('PADDING_0', ctypes.c_ubyte * 4), +] + +amdsmi_evt_notification_data_t = c__SA_amdsmi_evt_notification_data_t + +# values for enumeration 'c__EA_amdsmi_temperature_metric_t' +c__EA_amdsmi_temperature_metric_t__enumvalues = { + 0: 'AMDSMI_TEMP_CURRENT', + 0: 'AMDSMI_TEMP_FIRST', + 1: 'AMDSMI_TEMP_MAX', + 2: 'AMDSMI_TEMP_MIN', + 3: 'AMDSMI_TEMP_MAX_HYST', + 4: 'AMDSMI_TEMP_MIN_HYST', + 5: 'AMDSMI_TEMP_CRITICAL', + 6: 'AMDSMI_TEMP_CRITICAL_HYST', + 7: 'AMDSMI_TEMP_EMERGENCY', + 8: 'AMDSMI_TEMP_EMERGENCY_HYST', + 9: 'AMDSMI_TEMP_CRIT_MIN', + 10: 'AMDSMI_TEMP_CRIT_MIN_HYST', + 11: 'AMDSMI_TEMP_OFFSET', + 12: 'AMDSMI_TEMP_LOWEST', + 13: 'AMDSMI_TEMP_HIGHEST', + 13: 'AMDSMI_TEMP_LAST', +} +AMDSMI_TEMP_CURRENT = 0 +AMDSMI_TEMP_FIRST = 0 +AMDSMI_TEMP_MAX = 1 +AMDSMI_TEMP_MIN = 2 +AMDSMI_TEMP_MAX_HYST = 3 +AMDSMI_TEMP_MIN_HYST = 4 +AMDSMI_TEMP_CRITICAL = 5 +AMDSMI_TEMP_CRITICAL_HYST = 6 +AMDSMI_TEMP_EMERGENCY = 7 +AMDSMI_TEMP_EMERGENCY_HYST = 8 +AMDSMI_TEMP_CRIT_MIN = 9 +AMDSMI_TEMP_CRIT_MIN_HYST = 10 +AMDSMI_TEMP_OFFSET = 11 +AMDSMI_TEMP_LOWEST = 12 +AMDSMI_TEMP_HIGHEST = 13 +AMDSMI_TEMP_LAST = 13 +c__EA_amdsmi_temperature_metric_t = ctypes.c_uint32 # enum +amdsmi_temperature_metric_t = c__EA_amdsmi_temperature_metric_t +amdsmi_temperature_metric_t__enumvalues = c__EA_amdsmi_temperature_metric_t__enumvalues +amdsmi_temperature_metric = c__EA_amdsmi_temperature_metric_t +amdsmi_temperature_metric__enumvalues = c__EA_amdsmi_temperature_metric_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_voltage_metric_t' +c__EA_amdsmi_voltage_metric_t__enumvalues = { + 0: 'AMDSMI_VOLT_CURRENT', + 0: 'AMDSMI_VOLT_FIRST', + 1: 'AMDSMI_VOLT_MAX', + 2: 'AMDSMI_VOLT_MIN_CRIT', + 3: 'AMDSMI_VOLT_MIN', + 4: 'AMDSMI_VOLT_MAX_CRIT', + 5: 'AMDSMI_VOLT_AVERAGE', + 6: 'AMDSMI_VOLT_LOWEST', + 7: 'AMDSMI_VOLT_HIGHEST', + 7: 'AMDSMI_VOLT_LAST', +} +AMDSMI_VOLT_CURRENT = 0 +AMDSMI_VOLT_FIRST = 0 +AMDSMI_VOLT_MAX = 1 +AMDSMI_VOLT_MIN_CRIT = 2 +AMDSMI_VOLT_MIN = 3 +AMDSMI_VOLT_MAX_CRIT = 4 +AMDSMI_VOLT_AVERAGE = 5 +AMDSMI_VOLT_LOWEST = 6 +AMDSMI_VOLT_HIGHEST = 7 +AMDSMI_VOLT_LAST = 7 +c__EA_amdsmi_voltage_metric_t = ctypes.c_uint32 # enum +amdsmi_voltage_metric_t = c__EA_amdsmi_voltage_metric_t +amdsmi_voltage_metric_t__enumvalues = c__EA_amdsmi_voltage_metric_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_voltage_type_t' +c__EA_amdsmi_voltage_type_t__enumvalues = { + 0: 'AMDSMI_VOLT_TYPE_FIRST', + 0: 'AMDSMI_VOLT_TYPE_VDDGFX', + 0: 'AMDSMI_VOLT_TYPE_LAST', + 4294967295: 'AMDSMI_VOLT_TYPE_INVALID', +} +AMDSMI_VOLT_TYPE_FIRST = 0 +AMDSMI_VOLT_TYPE_VDDGFX = 0 +AMDSMI_VOLT_TYPE_LAST = 0 +AMDSMI_VOLT_TYPE_INVALID = 4294967295 +c__EA_amdsmi_voltage_type_t = ctypes.c_uint32 # enum +amdsmi_voltage_type_t = c__EA_amdsmi_voltage_type_t +amdsmi_voltage_type_t__enumvalues = c__EA_amdsmi_voltage_type_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_power_profile_preset_masks_t' +c__EA_amdsmi_power_profile_preset_masks_t__enumvalues = { + 1: 'AMDSMI_PWR_PROF_PRST_CUSTOM_MASK', + 2: 'AMDSMI_PWR_PROF_PRST_VIDEO_MASK', + 4: 'AMDSMI_PWR_PROF_PRST_POWER_SAVING_MASK', + 8: 'AMDSMI_PWR_PROF_PRST_COMPUTE_MASK', + 16: 'AMDSMI_PWR_PROF_PRST_VR_MASK', + 32: 'AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK', + 64: 'AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT', + 64: 'AMDSMI_PWR_PROF_PRST_LAST', + 18446744073709551615: 'AMDSMI_PWR_PROF_PRST_INVALID', +} +AMDSMI_PWR_PROF_PRST_CUSTOM_MASK = 1 +AMDSMI_PWR_PROF_PRST_VIDEO_MASK = 2 +AMDSMI_PWR_PROF_PRST_POWER_SAVING_MASK = 4 +AMDSMI_PWR_PROF_PRST_COMPUTE_MASK = 8 +AMDSMI_PWR_PROF_PRST_VR_MASK = 16 +AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK = 32 +AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT = 64 +AMDSMI_PWR_PROF_PRST_LAST = 64 +AMDSMI_PWR_PROF_PRST_INVALID = 18446744073709551615 +c__EA_amdsmi_power_profile_preset_masks_t = ctypes.c_uint64 # enum +amdsmi_power_profile_preset_masks_t = c__EA_amdsmi_power_profile_preset_masks_t +amdsmi_power_profile_preset_masks_t__enumvalues = c__EA_amdsmi_power_profile_preset_masks_t__enumvalues +amdsmi_power_profile_preset_masks = c__EA_amdsmi_power_profile_preset_masks_t +amdsmi_power_profile_preset_masks__enumvalues = c__EA_amdsmi_power_profile_preset_masks_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_gpu_block_t' +c__EA_amdsmi_gpu_block_t__enumvalues = { + 0: 'AMDSMI_GPU_BLOCK_INVALID', + 1: 'AMDSMI_GPU_BLOCK_FIRST', + 1: 'AMDSMI_GPU_BLOCK_UMC', + 2: 'AMDSMI_GPU_BLOCK_SDMA', + 4: 'AMDSMI_GPU_BLOCK_GFX', + 8: 'AMDSMI_GPU_BLOCK_MMHUB', + 16: 'AMDSMI_GPU_BLOCK_ATHUB', + 32: 'AMDSMI_GPU_BLOCK_PCIE_BIF', + 64: 'AMDSMI_GPU_BLOCK_HDP', + 128: 'AMDSMI_GPU_BLOCK_XGMI_WAFL', + 256: 'AMDSMI_GPU_BLOCK_DF', + 512: 'AMDSMI_GPU_BLOCK_SMN', + 1024: 'AMDSMI_GPU_BLOCK_SEM', + 2048: 'AMDSMI_GPU_BLOCK_MP0', + 4096: 'AMDSMI_GPU_BLOCK_MP1', + 8192: 'AMDSMI_GPU_BLOCK_FUSE', + 8192: 'AMDSMI_GPU_BLOCK_LAST', + 9223372036854775808: 'AMDSMI_GPU_BLOCK_RESERVED', +} +AMDSMI_GPU_BLOCK_INVALID = 0 +AMDSMI_GPU_BLOCK_FIRST = 1 +AMDSMI_GPU_BLOCK_UMC = 1 +AMDSMI_GPU_BLOCK_SDMA = 2 +AMDSMI_GPU_BLOCK_GFX = 4 +AMDSMI_GPU_BLOCK_MMHUB = 8 +AMDSMI_GPU_BLOCK_ATHUB = 16 +AMDSMI_GPU_BLOCK_PCIE_BIF = 32 +AMDSMI_GPU_BLOCK_HDP = 64 +AMDSMI_GPU_BLOCK_XGMI_WAFL = 128 +AMDSMI_GPU_BLOCK_DF = 256 +AMDSMI_GPU_BLOCK_SMN = 512 +AMDSMI_GPU_BLOCK_SEM = 1024 +AMDSMI_GPU_BLOCK_MP0 = 2048 +AMDSMI_GPU_BLOCK_MP1 = 4096 +AMDSMI_GPU_BLOCK_FUSE = 8192 +AMDSMI_GPU_BLOCK_LAST = 8192 +AMDSMI_GPU_BLOCK_RESERVED = 9223372036854775808 +c__EA_amdsmi_gpu_block_t = ctypes.c_uint64 # enum +amdsmi_gpu_block_t = c__EA_amdsmi_gpu_block_t +amdsmi_gpu_block_t__enumvalues = c__EA_amdsmi_gpu_block_t__enumvalues +amdsmi_gpu_block = c__EA_amdsmi_gpu_block_t +amdsmi_gpu_block__enumvalues = c__EA_amdsmi_gpu_block_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_ras_err_state_t' +c__EA_amdsmi_ras_err_state_t__enumvalues = { + 0: 'AMDSMI_RAS_ERR_STATE_NONE', + 1: 'AMDSMI_RAS_ERR_STATE_DISABLED', + 2: 'AMDSMI_RAS_ERR_STATE_PARITY', + 3: 'AMDSMI_RAS_ERR_STATE_SING_C', + 4: 'AMDSMI_RAS_ERR_STATE_MULT_UC', + 5: 'AMDSMI_RAS_ERR_STATE_POISON', + 6: 'AMDSMI_RAS_ERR_STATE_ENABLED', + 6: 'AMDSMI_RAS_ERR_STATE_LAST', + 4294967295: 'AMDSMI_RAS_ERR_STATE_INVALID', +} +AMDSMI_RAS_ERR_STATE_NONE = 0 +AMDSMI_RAS_ERR_STATE_DISABLED = 1 +AMDSMI_RAS_ERR_STATE_PARITY = 2 +AMDSMI_RAS_ERR_STATE_SING_C = 3 +AMDSMI_RAS_ERR_STATE_MULT_UC = 4 +AMDSMI_RAS_ERR_STATE_POISON = 5 +AMDSMI_RAS_ERR_STATE_ENABLED = 6 +AMDSMI_RAS_ERR_STATE_LAST = 6 +AMDSMI_RAS_ERR_STATE_INVALID = 4294967295 +c__EA_amdsmi_ras_err_state_t = ctypes.c_uint32 # enum +amdsmi_ras_err_state_t = c__EA_amdsmi_ras_err_state_t +amdsmi_ras_err_state_t__enumvalues = c__EA_amdsmi_ras_err_state_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_memory_type_t' +c__EA_amdsmi_memory_type_t__enumvalues = { + 0: 'AMDSMI_MEM_TYPE_FIRST', + 0: 'AMDSMI_MEM_TYPE_VRAM', + 1: 'AMDSMI_MEM_TYPE_VIS_VRAM', + 2: 'AMDSMI_MEM_TYPE_GTT', + 2: 'AMDSMI_MEM_TYPE_LAST', +} +AMDSMI_MEM_TYPE_FIRST = 0 +AMDSMI_MEM_TYPE_VRAM = 0 +AMDSMI_MEM_TYPE_VIS_VRAM = 1 +AMDSMI_MEM_TYPE_GTT = 2 +AMDSMI_MEM_TYPE_LAST = 2 +c__EA_amdsmi_memory_type_t = ctypes.c_uint32 # enum +amdsmi_memory_type_t = c__EA_amdsmi_memory_type_t +amdsmi_memory_type_t__enumvalues = c__EA_amdsmi_memory_type_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_freq_ind_t' +c__EA_amdsmi_freq_ind_t__enumvalues = { + 0: 'AMDSMI_FREQ_IND_MIN', + 1: 'AMDSMI_FREQ_IND_MAX', + 4294967295: 'AMDSMI_FREQ_IND_INVALID', +} +AMDSMI_FREQ_IND_MIN = 0 +AMDSMI_FREQ_IND_MAX = 1 +AMDSMI_FREQ_IND_INVALID = 4294967295 +c__EA_amdsmi_freq_ind_t = ctypes.c_uint32 # enum +amdsmi_freq_ind_t = c__EA_amdsmi_freq_ind_t +amdsmi_freq_ind_t__enumvalues = c__EA_amdsmi_freq_ind_t__enumvalues +amdsmi_freq_ind = c__EA_amdsmi_freq_ind_t +amdsmi_freq_ind__enumvalues = c__EA_amdsmi_freq_ind_t__enumvalues + +# values for enumeration 'c__EA_amdsmi_xgmi_status_t' +c__EA_amdsmi_xgmi_status_t__enumvalues = { + 0: 'AMDSMI_XGMI_STATUS_NO_ERRORS', + 1: 'AMDSMI_XGMI_STATUS_ERROR', + 2: 'AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS', +} +AMDSMI_XGMI_STATUS_NO_ERRORS = 0 +AMDSMI_XGMI_STATUS_ERROR = 1 +AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS = 2 +c__EA_amdsmi_xgmi_status_t = ctypes.c_uint32 # enum +amdsmi_xgmi_status_t = c__EA_amdsmi_xgmi_status_t +amdsmi_xgmi_status_t__enumvalues = c__EA_amdsmi_xgmi_status_t__enumvalues +amdsmi_bit_field_t = ctypes.c_uint64 +amdsmi_bit_field = ctypes.c_uint64 + +# values for enumeration 'c__EA_amdsmi_memory_page_status_t' +c__EA_amdsmi_memory_page_status_t__enumvalues = { + 0: 'AMDSMI_MEM_PAGE_STATUS_RESERVED', + 1: 'AMDSMI_MEM_PAGE_STATUS_PENDING', + 2: 'AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE', +} +AMDSMI_MEM_PAGE_STATUS_RESERVED = 0 +AMDSMI_MEM_PAGE_STATUS_PENDING = 1 +AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE = 2 +c__EA_amdsmi_memory_page_status_t = ctypes.c_uint32 # enum +amdsmi_memory_page_status_t = c__EA_amdsmi_memory_page_status_t +amdsmi_memory_page_status_t__enumvalues = c__EA_amdsmi_memory_page_status_t__enumvalues + +# values for enumeration '_AMDSMI_IO_LINK_TYPE' +_AMDSMI_IO_LINK_TYPE__enumvalues = { + 0: 'AMDSMI_IOLINK_TYPE_UNDEFINED', + 1: 'AMDSMI_IOLINK_TYPE_PCIEXPRESS', + 2: 'AMDSMI_IOLINK_TYPE_XGMI', + 3: 'AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES', + 4294967295: 'AMDSMI_IOLINK_TYPE_SIZE', +} +AMDSMI_IOLINK_TYPE_UNDEFINED = 0 +AMDSMI_IOLINK_TYPE_PCIEXPRESS = 1 +AMDSMI_IOLINK_TYPE_XGMI = 2 +AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES = 3 +AMDSMI_IOLINK_TYPE_SIZE = 4294967295 +_AMDSMI_IO_LINK_TYPE = ctypes.c_uint32 # enum +AMDSMI_IO_LINK_TYPE = _AMDSMI_IO_LINK_TYPE +AMDSMI_IO_LINK_TYPE__enumvalues = _AMDSMI_IO_LINK_TYPE__enumvalues + +# values for enumeration 'c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE' +c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE__enumvalues = { + 0: 'AMDSMI_UTILIZATION_COUNTER_FIRST', + 0: 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', + 1: 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', + 1: 'AMDSMI_UTILIZATION_COUNTER_LAST', +} +AMDSMI_UTILIZATION_COUNTER_FIRST = 0 +AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = 0 +AMDSMI_COARSE_GRAIN_MEM_ACTIVITY = 1 +AMDSMI_UTILIZATION_COUNTER_LAST = 1 +c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE = ctypes.c_uint32 # enum +AMDSMI_UTILIZATION_COUNTER_TYPE = c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE +AMDSMI_UTILIZATION_COUNTER_TYPE__enumvalues = c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE__enumvalues +class c__SA_amdsmi_utilization_counter_t(Structure): + pass + +c__SA_amdsmi_utilization_counter_t._pack_ = 1 # source:False +c__SA_amdsmi_utilization_counter_t._fields_ = [ + ('type', AMDSMI_UTILIZATION_COUNTER_TYPE), + ('PADDING_0', ctypes.c_ubyte * 4), + ('value', ctypes.c_uint64), +] + +amdsmi_utilization_counter_t = c__SA_amdsmi_utilization_counter_t +class c__SA_amdsmi_retired_page_record_t(Structure): + pass + +c__SA_amdsmi_retired_page_record_t._pack_ = 1 # source:False +c__SA_amdsmi_retired_page_record_t._fields_ = [ + ('page_address', ctypes.c_uint64), + ('page_size', ctypes.c_uint64), + ('status', amdsmi_memory_page_status_t), + ('PADDING_0', ctypes.c_ubyte * 4), +] + +amdsmi_retired_page_record_t = c__SA_amdsmi_retired_page_record_t +class c__SA_amdsmi_power_profile_status_t(Structure): + pass + +c__SA_amdsmi_power_profile_status_t._pack_ = 1 # source:False +c__SA_amdsmi_power_profile_status_t._fields_ = [ + ('available_profiles', ctypes.c_uint64), + ('current', amdsmi_power_profile_preset_masks_t), + ('num_profiles', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), +] + +amdsmi_power_profile_status_t = c__SA_amdsmi_power_profile_status_t +amdsmi_power_profile_status = c__SA_amdsmi_power_profile_status_t +class c__SA_amdsmi_frequencies_t(Structure): + pass + +c__SA_amdsmi_frequencies_t._pack_ = 1 # source:False +c__SA_amdsmi_frequencies_t._fields_ = [ + ('num_supported', ctypes.c_uint32), + ('current', ctypes.c_uint32), + ('frequency', ctypes.c_uint64 * 32), +] + +amdsmi_frequencies_t = c__SA_amdsmi_frequencies_t +amdsmi_frequencies = c__SA_amdsmi_frequencies_t +class c__SA_amdsmi_pcie_bandwidth_t(Structure): + pass + +c__SA_amdsmi_pcie_bandwidth_t._pack_ = 1 # source:False +c__SA_amdsmi_pcie_bandwidth_t._fields_ = [ + ('transfer_rate', amdsmi_frequencies_t), + ('lanes', ctypes.c_uint32 * 32), +] + +amdsmi_pcie_bandwidth_t = c__SA_amdsmi_pcie_bandwidth_t +amdsmi_pcie_bandwidth = c__SA_amdsmi_pcie_bandwidth_t +class c__SA_amdsmi_version_t(Structure): + pass + +c__SA_amdsmi_version_t._pack_ = 1 # source:False +c__SA_amdsmi_version_t._fields_ = [ + ('major', ctypes.c_uint32), + ('minor', ctypes.c_uint32), + ('patch', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), + ('build', ctypes.POINTER(ctypes.c_char)), +] + +amdsmi_version_t = c__SA_amdsmi_version_t +amdsmi_version = c__SA_amdsmi_version_t +class c__SA_amdsmi_od_vddc_point_t(Structure): + pass + +c__SA_amdsmi_od_vddc_point_t._pack_ = 1 # source:False +c__SA_amdsmi_od_vddc_point_t._fields_ = [ + ('frequency', ctypes.c_uint64), + ('voltage', ctypes.c_uint64), +] + +amdsmi_od_vddc_point_t = c__SA_amdsmi_od_vddc_point_t +amdsmi_od_vddc_point = c__SA_amdsmi_od_vddc_point_t +class c__SA_amdsmi_freq_volt_region_t(Structure): + _pack_ = 1 # source:False + _fields_ = [ + ('freq_range', amdsmi_range_t), + ('volt_range', amdsmi_range_t), + ] + +amdsmi_freq_volt_region_t = c__SA_amdsmi_freq_volt_region_t +amdsmi_freq_volt_region = c__SA_amdsmi_freq_volt_region_t +class c__SA_amdsmi_od_volt_curve_t(Structure): + _pack_ = 1 # source:False + _fields_ = [ + ('vc_points', c__SA_amdsmi_od_vddc_point_t * 3), + ] + +amdsmi_od_volt_curve_t = c__SA_amdsmi_od_volt_curve_t +amdsmi_od_volt_curve = c__SA_amdsmi_od_volt_curve_t +class c__SA_amdsmi_od_volt_freq_data_t(Structure): + pass + +c__SA_amdsmi_od_volt_freq_data_t._pack_ = 1 # source:False +c__SA_amdsmi_od_volt_freq_data_t._fields_ = [ + ('curr_sclk_range', amdsmi_range_t), + ('curr_mclk_range', amdsmi_range_t), + ('sclk_freq_limits', amdsmi_range_t), + ('mclk_freq_limits', amdsmi_range_t), + ('curve', amdsmi_od_volt_curve_t), + ('num_regions', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), +] + +amdsmi_od_volt_freq_data_t = c__SA_amdsmi_od_volt_freq_data_t +amdsmi_od_volt_freq_data = c__SA_amdsmi_od_volt_freq_data_t +class amd_metrics_table_header_t(Structure): + pass + +amd_metrics_table_header_t._pack_ = 1 # source:False +amd_metrics_table_header_t._fields_ = [ + ('structure_size', ctypes.c_uint16), + ('format_revision', ctypes.c_ubyte), + ('content_revision', ctypes.c_ubyte), +] + +class c__SA_amdsmi_gpu_metrics_t(Structure): + pass + +c__SA_amdsmi_gpu_metrics_t._pack_ = 1 # source:False +c__SA_amdsmi_gpu_metrics_t._fields_ = [ + ('common_header', amd_metrics_table_header_t), + ('temperature_edge', ctypes.c_uint16), + ('temperature_hotspot', ctypes.c_uint16), + ('temperature_mem', ctypes.c_uint16), + ('temperature_vrgfx', ctypes.c_uint16), + ('temperature_vrsoc', ctypes.c_uint16), + ('temperature_vrmem', ctypes.c_uint16), + ('average_gfx_activity', ctypes.c_uint16), + ('average_umc_activity', ctypes.c_uint16), + ('average_mm_activity', ctypes.c_uint16), + ('average_socket_power', ctypes.c_uint16), + ('energy_accumulator', ctypes.c_uint64), + ('system_clock_counter', ctypes.c_uint64), + ('average_gfxclk_frequency', ctypes.c_uint16), + ('average_socclk_frequency', ctypes.c_uint16), + ('average_uclk_frequency', ctypes.c_uint16), + ('average_vclk0_frequency', ctypes.c_uint16), + ('average_dclk0_frequency', ctypes.c_uint16), + ('average_vclk1_frequency', ctypes.c_uint16), + ('average_dclk1_frequency', ctypes.c_uint16), + ('current_gfxclk', ctypes.c_uint16), + ('current_socclk', ctypes.c_uint16), + ('current_uclk', ctypes.c_uint16), + ('current_vclk0', ctypes.c_uint16), + ('current_dclk0', ctypes.c_uint16), + ('current_vclk1', ctypes.c_uint16), + ('current_dclk1', ctypes.c_uint16), + ('throttle_status', ctypes.c_uint32), + ('current_fan_speed', ctypes.c_uint16), + ('pcie_link_width', ctypes.c_uint16), + ('pcie_link_speed', ctypes.c_uint16), + ('padding', ctypes.c_uint16), + ('gfx_activity_acc', ctypes.c_uint32), + ('mem_actvity_acc', ctypes.c_uint32), + ('temperature_hbm', ctypes.c_uint16 * 4), +] + +amdsmi_gpu_metrics_t = c__SA_amdsmi_gpu_metrics_t +class c__SA_amdsmi_error_count_t(Structure): + pass + +c__SA_amdsmi_error_count_t._pack_ = 1 # source:False +c__SA_amdsmi_error_count_t._fields_ = [ + ('correctable_count', ctypes.c_uint64), + ('uncorrectable_count', ctypes.c_uint64), +] + +amdsmi_error_count_t = c__SA_amdsmi_error_count_t +class amdsmi_pcie_info(Structure): + pass + +amdsmi_pcie_info._pack_ = 1 # source:False +amdsmi_pcie_info._fields_ = [ + ('pcie_lanes', ctypes.c_uint16), + ('pcie_speed', ctypes.c_uint16), +] + +amdsmi_pcie_info_t = amdsmi_pcie_info +class c__SA_amdsmi_process_info_t(Structure): + pass + +c__SA_amdsmi_process_info_t._pack_ = 1 # source:False +c__SA_amdsmi_process_info_t._fields_ = [ + ('process_id', ctypes.c_uint32), + ('pasid', ctypes.c_uint32), + ('vram_usage', ctypes.c_uint64), + ('sdma_usage', ctypes.c_uint64), + ('cu_occupancy', ctypes.c_uint32), + ('PADDING_0', ctypes.c_ubyte * 4), +] + +amdsmi_process_info_t = c__SA_amdsmi_process_info_t +class amdsmi_func_id_iter_handle(Structure): + pass + +amdsmi_func_id_iter_handle_t = ctypes.POINTER(amdsmi_func_id_iter_handle) +class amd_id(Union): + pass + +class amd_id_0(Union): + _pack_ = 1 # source:False + _fields_ = [ + ('memory_type', amdsmi_memory_type_t), + ('temp_metric', amdsmi_temperature_metric_t), + ('evnt_type', amdsmi_event_type_t), + ('evnt_group', amdsmi_event_group_t), + ('clk_type', amdsmi_clk_type_t), + ('fw_block', amdsmi_fw_block_t), + ('gpu_block_type', amdsmi_gpu_block_t), + ] + +amd_id._pack_ = 1 # source:False +amd_id._fields_ = [ + ('id', ctypes.c_uint64), + ('name', ctypes.POINTER(ctypes.c_char)), + ('amd_id_0', amd_id_0), +] + +amdsmi_func_id_value_t = amd_id +__all__ = \ + ['AMDSMI_CNTR_CMD_START', 'AMDSMI_CNTR_CMD_STOP', + 'AMDSMI_COARSE_GRAIN_GFX_ACTIVITY', + 'AMDSMI_COARSE_GRAIN_MEM_ACTIVITY', 'AMDSMI_DEV_PERF_LEVEL_AUTO', + 'AMDSMI_DEV_PERF_LEVEL_DETERMINISM', + 'AMDSMI_DEV_PERF_LEVEL_FIRST', 'AMDSMI_DEV_PERF_LEVEL_HIGH', + 'AMDSMI_DEV_PERF_LEVEL_LAST', 'AMDSMI_DEV_PERF_LEVEL_LOW', + 'AMDSMI_DEV_PERF_LEVEL_MANUAL', + 'AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK', + 'AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK', + 'AMDSMI_DEV_PERF_LEVEL_STABLE_PEAK', + 'AMDSMI_DEV_PERF_LEVEL_STABLE_STD', + 'AMDSMI_DEV_PERF_LEVEL_UNKNOWN', 'AMDSMI_EVNT_FIRST', + 'AMDSMI_EVNT_GRP_INVALID', 'AMDSMI_EVNT_GRP_XGMI', + 'AMDSMI_EVNT_GRP_XGMI_DATA_OUT', 'AMDSMI_EVNT_LAST', + 'AMDSMI_EVNT_XGMI_0_BEATS_TX', 'AMDSMI_EVNT_XGMI_0_NOP_TX', + 'AMDSMI_EVNT_XGMI_0_REQUEST_TX', 'AMDSMI_EVNT_XGMI_0_RESPONSE_TX', + 'AMDSMI_EVNT_XGMI_1_BEATS_TX', 'AMDSMI_EVNT_XGMI_1_NOP_TX', + 'AMDSMI_EVNT_XGMI_1_REQUEST_TX', 'AMDSMI_EVNT_XGMI_1_RESPONSE_TX', + 'AMDSMI_EVNT_XGMI_DATA_OUT_0', 'AMDSMI_EVNT_XGMI_DATA_OUT_1', + 'AMDSMI_EVNT_XGMI_DATA_OUT_2', 'AMDSMI_EVNT_XGMI_DATA_OUT_3', + 'AMDSMI_EVNT_XGMI_DATA_OUT_4', 'AMDSMI_EVNT_XGMI_DATA_OUT_5', + 'AMDSMI_EVNT_XGMI_DATA_OUT_FIRST', + 'AMDSMI_EVNT_XGMI_DATA_OUT_LAST', 'AMDSMI_EVNT_XGMI_FIRST', + 'AMDSMI_EVNT_XGMI_LAST', 'AMDSMI_EVT_NOTIF_FIRST', + 'AMDSMI_EVT_NOTIF_GPU_POST_RESET', + 'AMDSMI_EVT_NOTIF_GPU_PRE_RESET', 'AMDSMI_EVT_NOTIF_LAST', + 'AMDSMI_EVT_NOTIF_THERMAL_THROTTLE', 'AMDSMI_EVT_NOTIF_VMFAULT', + 'AMDSMI_FREQ_IND_INVALID', 'AMDSMI_FREQ_IND_MAX', + 'AMDSMI_FREQ_IND_MIN', 'AMDSMI_GPU_BLOCK_ATHUB', + 'AMDSMI_GPU_BLOCK_DF', 'AMDSMI_GPU_BLOCK_FIRST', + 'AMDSMI_GPU_BLOCK_FUSE', 'AMDSMI_GPU_BLOCK_GFX', + 'AMDSMI_GPU_BLOCK_HDP', 'AMDSMI_GPU_BLOCK_INVALID', + 'AMDSMI_GPU_BLOCK_LAST', 'AMDSMI_GPU_BLOCK_MMHUB', + 'AMDSMI_GPU_BLOCK_MP0', 'AMDSMI_GPU_BLOCK_MP1', + 'AMDSMI_GPU_BLOCK_PCIE_BIF', 'AMDSMI_GPU_BLOCK_RESERVED', + 'AMDSMI_GPU_BLOCK_SDMA', 'AMDSMI_GPU_BLOCK_SEM', + 'AMDSMI_GPU_BLOCK_SMN', 'AMDSMI_GPU_BLOCK_UMC', + 'AMDSMI_GPU_BLOCK_XGMI_WAFL', 'AMDSMI_INIT_ALL_DEVICES', + 'AMDSMI_INIT_AMD_CPUS', 'AMDSMI_INIT_AMD_GPUS', + 'AMDSMI_INIT_NON_AMD_CPUS', 'AMDSMI_INIT_NON_AMD_GPUS', + 'AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES', + 'AMDSMI_IOLINK_TYPE_PCIEXPRESS', 'AMDSMI_IOLINK_TYPE_SIZE', + 'AMDSMI_IOLINK_TYPE_UNDEFINED', 'AMDSMI_IOLINK_TYPE_XGMI', + 'AMDSMI_IO_LINK_TYPE', 'AMDSMI_IO_LINK_TYPE__enumvalues', + 'AMDSMI_MEM_PAGE_STATUS_PENDING', + 'AMDSMI_MEM_PAGE_STATUS_RESERVED', + 'AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE', 'AMDSMI_MEM_TYPE_FIRST', + 'AMDSMI_MEM_TYPE_GTT', 'AMDSMI_MEM_TYPE_LAST', + 'AMDSMI_MEM_TYPE_VIS_VRAM', 'AMDSMI_MEM_TYPE_VRAM', + 'AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK', + 'AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT', + 'AMDSMI_PWR_PROF_PRST_COMPUTE_MASK', + 'AMDSMI_PWR_PROF_PRST_CUSTOM_MASK', + 'AMDSMI_PWR_PROF_PRST_INVALID', 'AMDSMI_PWR_PROF_PRST_LAST', + 'AMDSMI_PWR_PROF_PRST_POWER_SAVING_MASK', + 'AMDSMI_PWR_PROF_PRST_VIDEO_MASK', 'AMDSMI_PWR_PROF_PRST_VR_MASK', + 'AMDSMI_RAS_ERR_STATE_DISABLED', 'AMDSMI_RAS_ERR_STATE_ENABLED', + 'AMDSMI_RAS_ERR_STATE_INVALID', 'AMDSMI_RAS_ERR_STATE_LAST', + 'AMDSMI_RAS_ERR_STATE_MULT_UC', 'AMDSMI_RAS_ERR_STATE_NONE', + 'AMDSMI_RAS_ERR_STATE_PARITY', 'AMDSMI_RAS_ERR_STATE_POISON', + 'AMDSMI_RAS_ERR_STATE_SING_C', 'AMDSMI_SW_COMP_DRIVER', + 'AMDSMI_SW_COMP_FIRST', 'AMDSMI_SW_COMP_LAST', + 'AMDSMI_TEMP_CRITICAL', 'AMDSMI_TEMP_CRITICAL_HYST', + 'AMDSMI_TEMP_CRIT_MIN', 'AMDSMI_TEMP_CRIT_MIN_HYST', + 'AMDSMI_TEMP_CURRENT', 'AMDSMI_TEMP_EMERGENCY', + 'AMDSMI_TEMP_EMERGENCY_HYST', 'AMDSMI_TEMP_FIRST', + 'AMDSMI_TEMP_HIGHEST', 'AMDSMI_TEMP_LAST', 'AMDSMI_TEMP_LOWEST', + 'AMDSMI_TEMP_MAX', 'AMDSMI_TEMP_MAX_HYST', 'AMDSMI_TEMP_MIN', + 'AMDSMI_TEMP_MIN_HYST', 'AMDSMI_TEMP_OFFSET', + 'AMDSMI_UTILIZATION_COUNTER_FIRST', + 'AMDSMI_UTILIZATION_COUNTER_LAST', + 'AMDSMI_UTILIZATION_COUNTER_TYPE', + 'AMDSMI_UTILIZATION_COUNTER_TYPE__enumvalues', + 'AMDSMI_VOLT_AVERAGE', 'AMDSMI_VOLT_CURRENT', 'AMDSMI_VOLT_FIRST', + 'AMDSMI_VOLT_HIGHEST', 'AMDSMI_VOLT_LAST', 'AMDSMI_VOLT_LOWEST', + 'AMDSMI_VOLT_MAX', 'AMDSMI_VOLT_MAX_CRIT', 'AMDSMI_VOLT_MIN', + 'AMDSMI_VOLT_MIN_CRIT', 'AMDSMI_VOLT_TYPE_FIRST', + 'AMDSMI_VOLT_TYPE_INVALID', 'AMDSMI_VOLT_TYPE_LAST', + 'AMDSMI_VOLT_TYPE_VDDGFX', 'AMDSMI_XGMI_STATUS_ERROR', + 'AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS', + 'AMDSMI_XGMI_STATUS_NO_ERRORS', 'AMD_CPU', 'AMD_GPU', + 'CLK_TYPE_DCEF', 'CLK_TYPE_DCLK0', 'CLK_TYPE_DCLK1', + 'CLK_TYPE_DF', 'CLK_TYPE_FIRST', 'CLK_TYPE_GFX', 'CLK_TYPE_MEM', + 'CLK_TYPE_PCIE', 'CLK_TYPE_SOC', 'CLK_TYPE_SYS', 'CLK_TYPE_VCLK0', + 'CLK_TYPE_VCLK1', 'CLK_TYPE__MAX', 'CONTAINER_DOCKER', + 'CONTAINER_LXC', 'FW_ID_ASD', 'FW_ID_CP_CE', 'FW_ID_CP_ME', + 'FW_ID_CP_MEC1', 'FW_ID_CP_MEC2', 'FW_ID_CP_MEC_JT1', + 'FW_ID_CP_MEC_JT2', 'FW_ID_CP_PFP', 'FW_ID_CP_PM4', 'FW_ID_DFC', + 'FW_ID_DMCU', 'FW_ID_DMCU_ERAM', 'FW_ID_DMCU_ISR', + 'FW_ID_DRV_CAP', 'FW_ID_FIRST', 'FW_ID_ISP', 'FW_ID_MC', + 'FW_ID_MMSCH', 'FW_ID_PSP_BL', 'FW_ID_PSP_KEYDB', + 'FW_ID_PSP_SOSDRV', 'FW_ID_PSP_SPL', 'FW_ID_PSP_SYSDRV', + 'FW_ID_PSP_TOC', 'FW_ID_RLC', 'FW_ID_RLC_RESTORE_LIST_CNTL', + 'FW_ID_RLC_RESTORE_LIST_GPM_MEM', + 'FW_ID_RLC_RESTORE_LIST_SRM_MEM', 'FW_ID_RLC_SRLG', + 'FW_ID_RLC_SRLS', 'FW_ID_RLC_V', 'FW_ID_SDMA0', 'FW_ID_SDMA1', + 'FW_ID_SDMA2', 'FW_ID_SDMA3', 'FW_ID_SDMA4', 'FW_ID_SDMA5', + 'FW_ID_SDMA6', 'FW_ID_SDMA7', 'FW_ID_SMC', 'FW_ID_SMU', + 'FW_ID_TA_RAS', 'FW_ID_UVD', 'FW_ID_VCE', 'FW_ID_VCN', + 'FW_ID_XGMI', 'FW_ID__MAX', 'MM_UVD', 'MM_VCE', 'MM_VCN', + 'MM__MAX', 'NON_AMD_CPU', 'NON_AMD_GPU', 'TEMPERATURE_TYPE_EDGE', + 'TEMPERATURE_TYPE_FIRST', 'TEMPERATURE_TYPE_HBM_0', + 'TEMPERATURE_TYPE_HBM_1', 'TEMPERATURE_TYPE_HBM_2', + 'TEMPERATURE_TYPE_HBM_3', 'TEMPERATURE_TYPE_JUNCTION', + 'TEMPERATURE_TYPE_PLX', 'TEMPERATURE_TYPE_VRAM', + 'TEMPERATURE_TYPE__MAX', 'UNKNOWN', '_AMDSMI_IO_LINK_TYPE', + 'amdsmi_asic_info_t', 'amdsmi_bdf_t', 'amdsmi_bit_field', + 'amdsmi_bit_field_t', 'amdsmi_board_info_t', + 'amdsmi_clk_measure_t', 'amdsmi_clk_type', 'amdsmi_clk_type_t', + 'amdsmi_clk_type_t__enumvalues', 'amdsmi_container_types', + 'amdsmi_container_types_t', + 'amdsmi_container_types_t__enumvalues', + 'amdsmi_counter_command_t', + 'amdsmi_counter_command_t__enumvalues', 'amdsmi_counter_value_t', + 'amdsmi_dev_perf_level', 'amdsmi_dev_perf_level__enumvalues', + 'amdsmi_dev_perf_level_t', 'amdsmi_dev_perf_level_t__enumvalues', + 'amdsmi_device_handle', 'amdsmi_engine_usage_t', + 'amdsmi_error_count_t', 'amdsmi_event_group_t', + 'amdsmi_event_group_t__enumvalues', 'amdsmi_event_handle_t', + 'amdsmi_event_type_t', 'amdsmi_event_type_t__enumvalues', + 'amdsmi_evt_notification_data_t', + 'amdsmi_evt_notification_type_t', + 'amdsmi_evt_notification_type_t__enumvalues', 'amdsmi_freq_ind', + 'amdsmi_freq_ind__enumvalues', 'amdsmi_freq_ind_t', + 'amdsmi_freq_ind_t__enumvalues', 'amdsmi_freq_volt_region', + 'amdsmi_freq_volt_region_t', 'amdsmi_frequencies', + 'amdsmi_frequencies_t', 'amdsmi_frequency_range_t', + 'amdsmi_func_id_iter_handle_t', 'amdsmi_func_id_value_t', + 'amdsmi_fw_block', 'amdsmi_fw_block_t', + 'amdsmi_fw_block_t__enumvalues', 'amdsmi_fw_info_t', + 'amdsmi_gpu_block', 'amdsmi_gpu_block__enumvalues', + 'amdsmi_gpu_block_t', 'amdsmi_gpu_block_t__enumvalues', + 'amdsmi_gpu_caps_t', 'amdsmi_gpu_metrics_t', 'amdsmi_init_flags', + 'amdsmi_init_flags_t', 'amdsmi_init_flags_t__enumvalues', + 'amdsmi_memory_page_status_t', + 'amdsmi_memory_page_status_t__enumvalues', 'amdsmi_memory_type_t', + 'amdsmi_memory_type_t__enumvalues', 'amdsmi_mm_ip', + 'amdsmi_mm_ip_t', 'amdsmi_mm_ip_t__enumvalues', + 'amdsmi_od_vddc_point', 'amdsmi_od_vddc_point_t', + 'amdsmi_od_volt_curve', 'amdsmi_od_volt_curve_t', + 'amdsmi_od_volt_freq_data', 'amdsmi_od_volt_freq_data_t', + 'amdsmi_pcie_bandwidth', 'amdsmi_pcie_bandwidth_t', + 'amdsmi_pcie_info_t', 'amdsmi_power_cap_info_t', + 'amdsmi_power_limit_t', 'amdsmi_power_measure_t', + 'amdsmi_power_profile_preset_masks', + 'amdsmi_power_profile_preset_masks__enumvalues', + 'amdsmi_power_profile_preset_masks_t', + 'amdsmi_power_profile_preset_masks_t__enumvalues', + 'amdsmi_power_profile_status', 'amdsmi_power_profile_status_t', + 'amdsmi_proc_info_t', 'amdsmi_process_handle', + 'amdsmi_process_info_t', 'amdsmi_range', 'amdsmi_range_t', + 'amdsmi_ras_err_state_t', 'amdsmi_ras_err_state_t__enumvalues', + 'amdsmi_retired_page_record_t', 'amdsmi_socket_handle', + 'amdsmi_sw_component_t', 'amdsmi_sw_component_t__enumvalues', + 'amdsmi_temperature_limit_t', 'amdsmi_temperature_metric', + 'amdsmi_temperature_metric__enumvalues', + 'amdsmi_temperature_metric_t', + 'amdsmi_temperature_metric_t__enumvalues', 'amdsmi_temperature_t', + 'amdsmi_temperature_type', 'amdsmi_temperature_type_t', + 'amdsmi_temperature_type_t__enumvalues', + 'amdsmi_utilization_counter_t', 'amdsmi_vbios_info_t', + 'amdsmi_version', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', + 'amdsmi_voltage_metric_t__enumvalues', 'amdsmi_voltage_type_t', + 'amdsmi_voltage_type_t__enumvalues', 'amdsmi_vram_info_t', + 'amdsmi_xgmi_info_t', 'amdsmi_xgmi_status_t', + 'amdsmi_xgmi_status_t__enumvalues', + 'c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE', + 'c__EA_amdsmi_counter_command_t', 'c__EA_amdsmi_dev_perf_level_t', + 'c__EA_amdsmi_event_group_t', 'c__EA_amdsmi_event_type_t', + 'c__EA_amdsmi_evt_notification_type_t', 'c__EA_amdsmi_freq_ind_t', + 'c__EA_amdsmi_gpu_block_t', 'c__EA_amdsmi_memory_page_status_t', + 'c__EA_amdsmi_memory_type_t', + 'c__EA_amdsmi_power_profile_preset_masks_t', + 'c__EA_amdsmi_ras_err_state_t', 'c__EA_amdsmi_sw_component_t', + 'c__EA_amdsmi_temperature_metric_t', + 'c__EA_amdsmi_voltage_metric_t', 'c__EA_amdsmi_voltage_type_t', + 'c__EA_amdsmi_xgmi_status_t', 'device_type', 'device_type_t', + 'device_type_t__enumvalues', 'amd_metrics_table_header_t', + 'amdsmi_asic_info', 'amdsmi_bdf_0', + 'amdsmi_board_info', 'amdsmi_clk_measure', + 'amdsmi_engine_usage', 'amdsmi_frequency_range', + 'amdsmi_func_id_iter_handle', 'amdsmi_fw_info', + 'amdsmi_fw_info_0', 'amdsmi_gpu_caps', + 'amdsmi_gpu_caps_0', 'amdsmi_gpu_caps_1', + 'amdsmi_pcie_info', 'amdsmi_power_cap_info', + 'amdsmi_power_limit', 'amdsmi_power_measure', + 'amdsmi_process_info', 'amdsmi_process_info_0', + 'amdsmi_process_info_1', 'amdsmi_temperature', + 'amdsmi_temperature_limit', 'amdsmi_vbios_info', + 'amdsmi_vram_info', 'amdsmi_xgmi_info', + 'c__SA_amdsmi_counter_value_t', + 'c__SA_amdsmi_error_count_t', + 'c__SA_amdsmi_evt_notification_data_t', + 'c__SA_amdsmi_freq_volt_region_t', + 'c__SA_amdsmi_frequencies_t', + 'c__SA_amdsmi_gpu_metrics_t', + 'c__SA_amdsmi_od_vddc_point_t', + 'c__SA_amdsmi_od_volt_curve_t', + 'c__SA_amdsmi_od_volt_freq_data_t', + 'c__SA_amdsmi_pcie_bandwidth_t', + 'c__SA_amdsmi_power_profile_status_t', + 'c__SA_amdsmi_process_info_t', + 'c__SA_amdsmi_range_t', + 'c__SA_amdsmi_retired_page_record_t', + 'c__SA_amdsmi_utilization_counter_t', + 'c__SA_amdsmi_version_t', 'amd_id', 'amd_id_0', + 'amdsmi_bdf'] + +# -*- coding: utf-8 -*- +# +# TARGET arch is: [] +# WORD_SIZE is: 8 +# POINTER_SIZE is: 8 +# LONGDOUBLE_SIZE is: 16 +# +import ctypes + + +c_int128 = ctypes.c_ubyte*16 +c_uint128 = c_int128 +void = None +if ctypes.sizeof(ctypes.c_longdouble) == 16: + c_long_double_t = ctypes.c_longdouble +else: + c_long_double_t = ctypes.c_ubyte*16 + + + + +# values for enumeration 'amdsmi_init_flags' +amdsmi_init_flags__enumvalues = { + 0: 'AMDSMI_INIT_ALL_DEVICES', + 1: 'AMDSMI_INIT_AMD_CPUS', + 2: 'AMDSMI_INIT_AMD_GPUS', + 4: 'AMDSMI_INIT_NON_AMD_CPUS', + 8: 'AMDSMI_INIT_NON_AMD_GPUS', +} +AMDSMI_INIT_ALL_DEVICES = 0 +AMDSMI_INIT_AMD_CPUS = 1 +AMDSMI_INIT_AMD_GPUS = 2 +AMDSMI_INIT_NON_AMD_CPUS = 4 +AMDSMI_INIT_NON_AMD_GPUS = 8 +amdsmi_init_flags = ctypes.c_uint32 # enum +amdsmi_init_flags_t = amdsmi_init_flags +amdsmi_init_flags_t__enumvalues = amdsmi_init_flags__enumvalues + +# values for enumeration 'amdsmi_mm_ip' +amdsmi_mm_ip__enumvalues = { + 0: 'MM_UVD', + 1: 'MM_VCE', + 2: 'MM_VCN', + 3: 'MM__MAX', +} +MM_UVD = 0 +MM_VCE = 1 +MM_VCN = 2 +MM__MAX = 3 +amdsmi_mm_ip = ctypes.c_uint32 # enum +amdsmi_mm_ip_t = amdsmi_mm_ip +amdsmi_mm_ip_t__enumvalues = amdsmi_mm_ip__enumvalues + +# values for enumeration 'amdsmi_container_types' +amdsmi_container_types__enumvalues = { + 0: 'CONTAINER_LXC', + 1: 'CONTAINER_DOCKER', +} +CONTAINER_LXC = 0 +CONTAINER_DOCKER = 1 +amdsmi_container_types = ctypes.c_uint32 # enum +amdsmi_container_types_t = amdsmi_container_types +amdsmi_container_types_t__enumvalues = amdsmi_container_types__enumvalues +amdsmi_device_handle = ctypes.POINTER(None) +amdsmi_socket_handle = ctypes.POINTER(None) + +# values for enumeration 'device_type' +device_type__enumvalues = { + 0: 'UNKNOWN', + 1: 'AMD_GPU', + 2: 'AMD_CPU', + 3: 'NON_AMD_GPU', + 4: 'NON_AMD_CPU', +} +UNKNOWN = 0 +AMD_GPU = 1 +AMD_CPU = 2 +NON_AMD_GPU = 3 +NON_AMD_CPU = 4 +device_type = ctypes.c_uint32 # enum +device_type_t = device_type +device_type_t__enumvalues = device_type__enumvalues + +# values for enumeration 'amdsmi_status_t' +amdsmi_status_t__enumvalues = { + 0: 'AMDSMI_STATUS_SUCCESS', + 1: 'AMDSMI_STATUS_INVAL', + 2: 'AMDSMI_STATUS_NOT_SUPPORTED', + 3: 'AMDSMI_STATUS_FILE_ERROR', + 4: 'AMDSMI_STATUS_NO_PERM', + 5: 'AMDSMI_STATUS_OUT_OF_RESOURCES', + 6: 'AMDSMI_STATUS_INTERNAL_EXCEPTION', + 7: 'AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS', + 8: 'AMDSMI_STATUS_INIT_ERROR', + 9: 'AMDSMI_STATUS_NOT_YET_IMPLEMENTED', + 10: 'AMDSMI_STATUS_NOT_FOUND', + 11: 'AMDSMI_STATUS_INSUFFICIENT_SIZE', + 12: 'AMDSMI_STATUS_INTERRUPT', + 13: 'AMDSMI_STATUS_UNEXPECTED_SIZE', + 14: 'AMDSMI_STATUS_NO_DATA', + 15: 'AMDSMI_STATUS_UNEXPECTED_DATA', + 16: 'AMDSMI_STATUS_BUSY', + 17: 'AMDSMI_STATUS_REFCOUNT_OVERFLOW', + 1000: 'AMDSMI_LIB_START', + 1000: 'AMDSMI_STATUS_FAIL_LOAD_MODULE', + 1001: 'AMDSMI_STATUS_FAIL_LOAD_SYMBOL', + 1002: 'AMDSMI_STATUS_DRM_ERROR', + 1003: 'AMDSMI_STATUS_IO', + 1004: 'AMDSMI_STATUS_FAULT', + 1005: 'AMDSMI_STATUS_API_FAILED', + 1006: 'AMDSMI_STATUS_TIMEOUT', + 1007: 'AMDSMI_STATUS_NO_SLOT', + 1008: 'AMDSMI_STATUS_RETRY', + 1009: 'AMDSMI_STATUS_NOT_INIT', + 4294967295: 'AMDSMI_STATUS_UNKNOWN_ERROR', +} +AMDSMI_STATUS_SUCCESS = 0 +AMDSMI_STATUS_INVAL = 1 +AMDSMI_STATUS_NOT_SUPPORTED = 2 +AMDSMI_STATUS_FILE_ERROR = 3 +AMDSMI_STATUS_NO_PERM = 4 +AMDSMI_STATUS_OUT_OF_RESOURCES = 5 +AMDSMI_STATUS_INTERNAL_EXCEPTION = 6 +AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS = 7 +AMDSMI_STATUS_INIT_ERROR = 8 +AMDSMI_STATUS_NOT_YET_IMPLEMENTED = 9 +AMDSMI_STATUS_NOT_FOUND = 10 +AMDSMI_STATUS_INSUFFICIENT_SIZE = 11 +AMDSMI_STATUS_INTERRUPT = 12 +AMDSMI_STATUS_UNEXPECTED_SIZE = 13 +AMDSMI_STATUS_NO_DATA = 14 +AMDSMI_STATUS_UNEXPECTED_DATA = 15 +AMDSMI_STATUS_BUSY = 16 +AMDSMI_STATUS_REFCOUNT_OVERFLOW = 17 +AMDSMI_LIB_START = 1000 +AMDSMI_STATUS_FAIL_LOAD_MODULE = 1000 +AMDSMI_STATUS_FAIL_LOAD_SYMBOL = 1001 +AMDSMI_STATUS_DRM_ERROR = 1002 +AMDSMI_STATUS_IO = 1003 +AMDSMI_STATUS_FAULT = 1004 +AMDSMI_STATUS_API_FAILED = 1005 +AMDSMI_STATUS_TIMEOUT = 1006 +AMDSMI_STATUS_NO_SLOT = 1007 +AMDSMI_STATUS_RETRY = 1008 +AMDSMI_STATUS_NOT_INIT = 1009 +AMDSMI_STATUS_UNKNOWN_ERROR = 4294967295 +amdsmi_status_t = ctypes.c_uint32 # enum +__all__ += \ + ['AMDSMI_INIT_ALL_DEVICES', 'AMDSMI_INIT_AMD_CPUS', + 'AMDSMI_INIT_AMD_GPUS', 'AMDSMI_INIT_NON_AMD_CPUS', + 'AMDSMI_INIT_NON_AMD_GPUS', 'AMDSMI_LIB_START', + 'AMDSMI_STATUS_API_FAILED', 'AMDSMI_STATUS_BUSY', + 'AMDSMI_STATUS_DRM_ERROR', 'AMDSMI_STATUS_FAIL_LOAD_MODULE', + 'AMDSMI_STATUS_FAIL_LOAD_SYMBOL', 'AMDSMI_STATUS_FAULT', + 'AMDSMI_STATUS_FILE_ERROR', 'AMDSMI_STATUS_INIT_ERROR', + 'AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS', + 'AMDSMI_STATUS_INSUFFICIENT_SIZE', + 'AMDSMI_STATUS_INTERNAL_EXCEPTION', 'AMDSMI_STATUS_INTERRUPT', + 'AMDSMI_STATUS_INVAL', 'AMDSMI_STATUS_IO', + 'AMDSMI_STATUS_NOT_FOUND', 'AMDSMI_STATUS_NOT_INIT', + 'AMDSMI_STATUS_NOT_SUPPORTED', + 'AMDSMI_STATUS_NOT_YET_IMPLEMENTED', 'AMDSMI_STATUS_NO_DATA', + 'AMDSMI_STATUS_NO_PERM', 'AMDSMI_STATUS_NO_SLOT', + 'AMDSMI_STATUS_OUT_OF_RESOURCES', + 'AMDSMI_STATUS_REFCOUNT_OVERFLOW', 'AMDSMI_STATUS_RETRY', + 'AMDSMI_STATUS_SUCCESS', 'AMDSMI_STATUS_TIMEOUT', + 'AMDSMI_STATUS_UNEXPECTED_DATA', 'AMDSMI_STATUS_UNEXPECTED_SIZE', + 'AMDSMI_STATUS_UNKNOWN_ERROR', 'AMD_CPU', 'AMD_GPU', + 'CONTAINER_DOCKER', 'CONTAINER_LXC', 'MM_UVD', 'MM_VCE', 'MM_VCN', + 'MM__MAX', 'NON_AMD_CPU', 'NON_AMD_GPU', 'UNKNOWN', + 'amdsmi_container_types', 'amdsmi_container_types_t', + 'amdsmi_container_types_t__enumvalues', 'amdsmi_device_handle', + 'amdsmi_init_flags', 'amdsmi_init_flags_t', + 'amdsmi_init_flags_t__enumvalues', 'amdsmi_mm_ip', + 'amdsmi_mm_ip_t', 'amdsmi_mm_ip_t__enumvalues', + 'amdsmi_socket_handle', 'amdsmi_status_t', 'device_type', + 'device_type_t', 'device_type_t__enumvalues'] + + + +__all__ += ['amdsmi_init', 'amdsmi_shut_down', 'amdsmi_get_socket_handles', 'amdsmi_get_socket_info', 'amdsmi_get_device_handles', 'amdsmi_get_device_type', 'amdsmi_get_device_handle_from_bdf', 'amdsmi_dev_id_get', 'amdsmi_dev_vendor_name_get', 'amdsmi_dev_vram_vendor_get', 'amdsmi_dev_subsystem_id_get', 'amdsmi_dev_subsystem_name_get', 'amdsmi_dev_drm_render_minor_get', 'amdsmi_dev_pci_bandwidth_get', 'amdsmi_dev_pci_id_get', 'amdsmi_topo_numa_affinity_get', 'amdsmi_dev_pci_throughput_get', 'amdsmi_dev_pci_replay_counter_get', 'amdsmi_dev_pci_bandwidth_set', 'amdsmi_dev_power_ave_get', 'amdsmi_dev_energy_count_get', 'amdsmi_dev_power_cap_set', 'amdsmi_dev_power_profile_set', 'amdsmi_dev_memory_total_get', 'amdsmi_dev_memory_usage_get', 'amdsmi_get_bad_page_info', 'amdsmi_get_ras_block_features_enabled', 'amdsmi_dev_memory_busy_percent_get', 'amdsmi_dev_memory_reserved_pages_get', 'amdsmi_dev_fan_rpms_get', 'amdsmi_dev_fan_speed_get', 'amdsmi_dev_fan_speed_max_get', 'amdsmi_dev_temp_metric_get', 'amdsmi_dev_volt_metric_get', 'amdsmi_dev_fan_reset', 'amdsmi_dev_fan_speed_set', 'amdsmi_dev_busy_percent_get', 'amdsmi_utilization_count_get', 'amdsmi_get_pcie_link_status', 'amdsmi_get_pcie_link_caps', 'amdsmi_dev_perf_level_get', 'amdsmi_perf_determinism_mode_set', 'amdsmi_dev_overdrive_level_get', 'amdsmi_dev_gpu_clk_freq_get', 'amdsmi_dev_gpu_reset', 'amdsmi_dev_od_volt_info_get', 'amdsmi_dev_gpu_metrics_info_get', 'amdsmi_dev_clk_range_set', 'amdsmi_dev_od_clk_info_set', 'amdsmi_dev_od_volt_info_set', 'amdsmi_dev_od_volt_curve_regions_get', 'amdsmi_dev_power_profile_presets_get', 'amdsmi_dev_perf_level_set', 'amdsmi_dev_perf_level_set_v1', 'amdsmi_dev_overdrive_level_set', 'amdsmi_dev_overdrive_level_set_v1', 'amdsmi_dev_gpu_clk_freq_set', 'amdsmi_version_get', 'amdsmi_version_str_get', 'amdsmi_dev_ecc_count_get', 'amdsmi_dev_ecc_enabled_get', 'amdsmi_dev_ecc_status_get', 'amdsmi_status_string', 'amdsmi_dev_counter_group_supported', 'amdsmi_dev_counter_create', 'amdsmi_dev_counter_destroy', 'amdsmi_counter_control', 'amdsmi_counter_read', 'amdsmi_counter_available_counters_get', 'amdsmi_compute_process_info_get', 'amdsmi_compute_process_info_by_pid_get', 'amdsmi_compute_process_gpus_get', 'amdsmi_dev_xgmi_error_status', 'amdsmi_dev_xgmi_error_reset', 'amdsmi_topo_get_numa_node_number', 'amdsmi_topo_get_link_weight', 'amdsmi_minmax_bandwidth_get', 'amdsmi_topo_get_link_type', 'amdsmi_is_P2P_accessible', 'amdsmi_dev_supported_func_iterator_open', 'amdsmi_dev_supported_variant_iterator_open', 'amdsmi_func_iter_next', 'amdsmi_dev_supported_func_iterator_close', 'amdsmi_func_iter_value_get', 'amdsmi_event_notification_init', 'amdsmi_event_notification_mask_set', 'amdsmi_event_notification_get', 'amdsmi_event_notification_stop', 'amdsmi_get_device_bdf', 'amdsmi_get_device_uuid', 'amdsmi_get_driver_version', 'amdsmi_get_asic_info', 'amdsmi_get_board_info', 'amdsmi_get_power_cap_info', 'amdsmi_get_xgmi_info', 'amdsmi_get_caps_info', 'amdsmi_get_fw_info', 'amdsmi_get_vbios_info', 'amdsmi_get_gpu_activity', 'amdsmi_get_power_measure', 'amdsmi_get_clock_measure', 'amdsmi_get_temperature_measure', 'amdsmi_get_temperature_limit', 'amdsmi_get_power_limit', 'amdsmi_get_vram_usage', 'amdsmi_get_target_frequency_range', 'amdsmi_get_process_list', 'amdsmi_get_process_info', 'amdsmi_get_ecc_error_count'] +__all__ += [] + +_lib = CDLL(os.path.join(os.path.dirname(__file__), "libamd_smi64.so")) + + +_lib.amdsmi_init.argtypes = [c_uint64] +_lib.amdsmi_init.restype = amdsmi_status_t +amdsmi_init = _lib.amdsmi_init + +_lib.amdsmi_shut_down.argtypes = [] +_lib.amdsmi_shut_down.restype = amdsmi_status_t +amdsmi_shut_down = _lib.amdsmi_shut_down + +_lib.amdsmi_get_socket_handles.argtypes = [POINTER(c_uint32),POINTER(amdsmi_socket_handle)] +_lib.amdsmi_get_socket_handles.restype = amdsmi_status_t +amdsmi_get_socket_handles = _lib.amdsmi_get_socket_handles + +_lib.amdsmi_get_socket_info.argtypes = [amdsmi_socket_handle,c_char_p,c_uint64] +_lib.amdsmi_get_socket_info.restype = amdsmi_status_t +amdsmi_get_socket_info = _lib.amdsmi_get_socket_info + +_lib.amdsmi_get_device_handles.argtypes = [amdsmi_socket_handle,POINTER(c_uint32),POINTER(amdsmi_device_handle)] +_lib.amdsmi_get_device_handles.restype = amdsmi_status_t +amdsmi_get_device_handles = _lib.amdsmi_get_device_handles + +_lib.amdsmi_get_device_type.argtypes = [amdsmi_device_handle,POINTER(device_type_t)] +_lib.amdsmi_get_device_type.restype = amdsmi_status_t +amdsmi_get_device_type = _lib.amdsmi_get_device_type + +_lib.amdsmi_get_device_handle_from_bdf.argtypes = [amdsmi_bdf_t,POINTER(amdsmi_device_handle),c_uint32,POINTER(amdsmi_device_handle)] +_lib.amdsmi_get_device_handle_from_bdf.restype = amdsmi_status_t +amdsmi_get_device_handle_from_bdf = _lib.amdsmi_get_device_handle_from_bdf + +_lib.amdsmi_dev_id_get.argtypes = [amdsmi_device_handle,POINTER(c_uint16)] +_lib.amdsmi_dev_id_get.restype = amdsmi_status_t +amdsmi_dev_id_get = _lib.amdsmi_dev_id_get + +_lib.amdsmi_dev_vendor_name_get.argtypes = [amdsmi_device_handle,c_char_p,c_uint64] +_lib.amdsmi_dev_vendor_name_get.restype = amdsmi_status_t +amdsmi_dev_vendor_name_get = _lib.amdsmi_dev_vendor_name_get + +_lib.amdsmi_dev_vram_vendor_get.argtypes = [amdsmi_device_handle,c_char_p,c_uint32] +_lib.amdsmi_dev_vram_vendor_get.restype = amdsmi_status_t +amdsmi_dev_vram_vendor_get = _lib.amdsmi_dev_vram_vendor_get + +_lib.amdsmi_dev_subsystem_id_get.argtypes = [amdsmi_device_handle,POINTER(c_uint16)] +_lib.amdsmi_dev_subsystem_id_get.restype = amdsmi_status_t +amdsmi_dev_subsystem_id_get = _lib.amdsmi_dev_subsystem_id_get + +_lib.amdsmi_dev_subsystem_name_get.argtypes = [amdsmi_device_handle,c_char_p,c_uint64] +_lib.amdsmi_dev_subsystem_name_get.restype = amdsmi_status_t +amdsmi_dev_subsystem_name_get = _lib.amdsmi_dev_subsystem_name_get + +_lib.amdsmi_dev_drm_render_minor_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32)] +_lib.amdsmi_dev_drm_render_minor_get.restype = amdsmi_status_t +amdsmi_dev_drm_render_minor_get = _lib.amdsmi_dev_drm_render_minor_get + +_lib.amdsmi_dev_pci_bandwidth_get.argtypes = [amdsmi_device_handle,POINTER(amdsmi_pcie_bandwidth_t)] +_lib.amdsmi_dev_pci_bandwidth_get.restype = amdsmi_status_t +amdsmi_dev_pci_bandwidth_get = _lib.amdsmi_dev_pci_bandwidth_get + +_lib.amdsmi_dev_pci_id_get.argtypes = [amdsmi_device_handle,POINTER(c_uint64)] +_lib.amdsmi_dev_pci_id_get.restype = amdsmi_status_t +amdsmi_dev_pci_id_get = _lib.amdsmi_dev_pci_id_get + +_lib.amdsmi_topo_numa_affinity_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32)] +_lib.amdsmi_topo_numa_affinity_get.restype = amdsmi_status_t +amdsmi_topo_numa_affinity_get = _lib.amdsmi_topo_numa_affinity_get + +_lib.amdsmi_dev_pci_throughput_get.argtypes = [amdsmi_device_handle,POINTER(c_uint64),POINTER(c_uint64),POINTER(c_uint64)] +_lib.amdsmi_dev_pci_throughput_get.restype = amdsmi_status_t +amdsmi_dev_pci_throughput_get = _lib.amdsmi_dev_pci_throughput_get + +_lib.amdsmi_dev_pci_replay_counter_get.argtypes = [amdsmi_device_handle,POINTER(c_uint64)] +_lib.amdsmi_dev_pci_replay_counter_get.restype = amdsmi_status_t +amdsmi_dev_pci_replay_counter_get = _lib.amdsmi_dev_pci_replay_counter_get + +_lib.amdsmi_dev_pci_bandwidth_set.argtypes = [amdsmi_device_handle,c_uint64] +_lib.amdsmi_dev_pci_bandwidth_set.restype = amdsmi_status_t +amdsmi_dev_pci_bandwidth_set = _lib.amdsmi_dev_pci_bandwidth_set + +_lib.amdsmi_dev_power_ave_get.argtypes = [amdsmi_device_handle,c_uint32,POINTER(c_uint64)] +_lib.amdsmi_dev_power_ave_get.restype = amdsmi_status_t +amdsmi_dev_power_ave_get = _lib.amdsmi_dev_power_ave_get + +_lib.amdsmi_dev_energy_count_get.argtypes = [amdsmi_device_handle,POINTER(c_uint64),POINTER(c_float),POINTER(c_uint64)] +_lib.amdsmi_dev_energy_count_get.restype = amdsmi_status_t +amdsmi_dev_energy_count_get = _lib.amdsmi_dev_energy_count_get + +_lib.amdsmi_dev_power_cap_set.argtypes = [amdsmi_device_handle,c_uint32,c_uint64] +_lib.amdsmi_dev_power_cap_set.restype = amdsmi_status_t +amdsmi_dev_power_cap_set = _lib.amdsmi_dev_power_cap_set + +_lib.amdsmi_dev_power_profile_set.argtypes = [amdsmi_device_handle,c_uint32,amdsmi_power_profile_preset_masks_t] +_lib.amdsmi_dev_power_profile_set.restype = amdsmi_status_t +amdsmi_dev_power_profile_set = _lib.amdsmi_dev_power_profile_set + +_lib.amdsmi_dev_memory_total_get.argtypes = [amdsmi_device_handle,amdsmi_memory_type_t,POINTER(c_uint64)] +_lib.amdsmi_dev_memory_total_get.restype = amdsmi_status_t +amdsmi_dev_memory_total_get = _lib.amdsmi_dev_memory_total_get + +_lib.amdsmi_dev_memory_usage_get.argtypes = [amdsmi_device_handle,amdsmi_memory_type_t,POINTER(c_uint64)] +_lib.amdsmi_dev_memory_usage_get.restype = amdsmi_status_t +amdsmi_dev_memory_usage_get = _lib.amdsmi_dev_memory_usage_get + +_lib.amdsmi_get_bad_page_info.argtypes = [amdsmi_device_handle,POINTER(c_uint32),POINTER(amdsmi_retired_page_record_t)] +_lib.amdsmi_get_bad_page_info.restype = amdsmi_status_t +amdsmi_get_bad_page_info = _lib.amdsmi_get_bad_page_info + +_lib.amdsmi_get_ras_block_features_enabled.argtypes = [amdsmi_device_handle,amdsmi_gpu_block,POINTER(amdsmi_ras_err_state_t)] +_lib.amdsmi_get_ras_block_features_enabled.restype = amdsmi_status_t +amdsmi_get_ras_block_features_enabled = _lib.amdsmi_get_ras_block_features_enabled + +_lib.amdsmi_dev_memory_busy_percent_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32)] +_lib.amdsmi_dev_memory_busy_percent_get.restype = amdsmi_status_t +amdsmi_dev_memory_busy_percent_get = _lib.amdsmi_dev_memory_busy_percent_get + +_lib.amdsmi_dev_memory_reserved_pages_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32),POINTER(amdsmi_retired_page_record_t)] +_lib.amdsmi_dev_memory_reserved_pages_get.restype = amdsmi_status_t +amdsmi_dev_memory_reserved_pages_get = _lib.amdsmi_dev_memory_reserved_pages_get + +_lib.amdsmi_dev_fan_rpms_get.argtypes = [amdsmi_device_handle,c_uint32,POINTER(c_int64)] +_lib.amdsmi_dev_fan_rpms_get.restype = amdsmi_status_t +amdsmi_dev_fan_rpms_get = _lib.amdsmi_dev_fan_rpms_get + +_lib.amdsmi_dev_fan_speed_get.argtypes = [amdsmi_device_handle,c_uint32,POINTER(c_int64)] +_lib.amdsmi_dev_fan_speed_get.restype = amdsmi_status_t +amdsmi_dev_fan_speed_get = _lib.amdsmi_dev_fan_speed_get + +_lib.amdsmi_dev_fan_speed_max_get.argtypes = [amdsmi_device_handle,c_uint32,POINTER(c_uint64)] +_lib.amdsmi_dev_fan_speed_max_get.restype = amdsmi_status_t +amdsmi_dev_fan_speed_max_get = _lib.amdsmi_dev_fan_speed_max_get + +_lib.amdsmi_dev_temp_metric_get.argtypes = [amdsmi_device_handle,c_uint32,amdsmi_temperature_metric_t,POINTER(c_int64)] +_lib.amdsmi_dev_temp_metric_get.restype = amdsmi_status_t +amdsmi_dev_temp_metric_get = _lib.amdsmi_dev_temp_metric_get + +_lib.amdsmi_dev_volt_metric_get.argtypes = [amdsmi_device_handle,amdsmi_voltage_type_t,amdsmi_voltage_metric_t,POINTER(c_int64)] +_lib.amdsmi_dev_volt_metric_get.restype = amdsmi_status_t +amdsmi_dev_volt_metric_get = _lib.amdsmi_dev_volt_metric_get + +_lib.amdsmi_dev_fan_reset.argtypes = [amdsmi_device_handle,c_uint32] +_lib.amdsmi_dev_fan_reset.restype = amdsmi_status_t +amdsmi_dev_fan_reset = _lib.amdsmi_dev_fan_reset + +_lib.amdsmi_dev_fan_speed_set.argtypes = [amdsmi_device_handle,c_uint32,c_uint64] +_lib.amdsmi_dev_fan_speed_set.restype = amdsmi_status_t +amdsmi_dev_fan_speed_set = _lib.amdsmi_dev_fan_speed_set + +_lib.amdsmi_dev_busy_percent_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32)] +_lib.amdsmi_dev_busy_percent_get.restype = amdsmi_status_t +amdsmi_dev_busy_percent_get = _lib.amdsmi_dev_busy_percent_get + +_lib.amdsmi_utilization_count_get.argtypes = [amdsmi_device_handle,POINTER(amdsmi_utilization_counter_t),c_uint32,POINTER(c_uint64)] +_lib.amdsmi_utilization_count_get.restype = amdsmi_status_t +amdsmi_utilization_count_get = _lib.amdsmi_utilization_count_get + +_lib.amdsmi_get_pcie_link_status.argtypes = [amdsmi_device_handle,POINTER(amdsmi_pcie_info_t)] +_lib.amdsmi_get_pcie_link_status.restype = amdsmi_status_t +amdsmi_get_pcie_link_status = _lib.amdsmi_get_pcie_link_status + +_lib.amdsmi_get_pcie_link_caps.argtypes = [amdsmi_device_handle,POINTER(amdsmi_pcie_info_t)] +_lib.amdsmi_get_pcie_link_caps.restype = amdsmi_status_t +amdsmi_get_pcie_link_caps = _lib.amdsmi_get_pcie_link_caps + +_lib.amdsmi_dev_perf_level_get.argtypes = [amdsmi_device_handle,POINTER(amdsmi_dev_perf_level_t)] +_lib.amdsmi_dev_perf_level_get.restype = amdsmi_status_t +amdsmi_dev_perf_level_get = _lib.amdsmi_dev_perf_level_get + +_lib.amdsmi_perf_determinism_mode_set.argtypes = [amdsmi_device_handle,c_uint64] +_lib.amdsmi_perf_determinism_mode_set.restype = amdsmi_status_t +amdsmi_perf_determinism_mode_set = _lib.amdsmi_perf_determinism_mode_set + +_lib.amdsmi_dev_overdrive_level_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32)] +_lib.amdsmi_dev_overdrive_level_get.restype = amdsmi_status_t +amdsmi_dev_overdrive_level_get = _lib.amdsmi_dev_overdrive_level_get + +_lib.amdsmi_dev_gpu_clk_freq_get.argtypes = [amdsmi_device_handle,amdsmi_clk_type_t,POINTER(amdsmi_frequencies_t)] +_lib.amdsmi_dev_gpu_clk_freq_get.restype = amdsmi_status_t +amdsmi_dev_gpu_clk_freq_get = _lib.amdsmi_dev_gpu_clk_freq_get + +_lib.amdsmi_dev_gpu_reset.argtypes = [amdsmi_device_handle] +_lib.amdsmi_dev_gpu_reset.restype = amdsmi_status_t +amdsmi_dev_gpu_reset = _lib.amdsmi_dev_gpu_reset + +_lib.amdsmi_dev_od_volt_info_get.argtypes = [amdsmi_device_handle,POINTER(amdsmi_od_volt_freq_data_t)] +_lib.amdsmi_dev_od_volt_info_get.restype = amdsmi_status_t +amdsmi_dev_od_volt_info_get = _lib.amdsmi_dev_od_volt_info_get + +_lib.amdsmi_dev_gpu_metrics_info_get.argtypes = [amdsmi_device_handle,POINTER(amdsmi_gpu_metrics_t)] +_lib.amdsmi_dev_gpu_metrics_info_get.restype = amdsmi_status_t +amdsmi_dev_gpu_metrics_info_get = _lib.amdsmi_dev_gpu_metrics_info_get + +_lib.amdsmi_dev_clk_range_set.argtypes = [amdsmi_device_handle,c_uint64,c_uint64,amdsmi_clk_type_t] +_lib.amdsmi_dev_clk_range_set.restype = amdsmi_status_t +amdsmi_dev_clk_range_set = _lib.amdsmi_dev_clk_range_set + +_lib.amdsmi_dev_od_clk_info_set.argtypes = [amdsmi_device_handle,amdsmi_freq_ind_t,c_uint64,amdsmi_clk_type_t] +_lib.amdsmi_dev_od_clk_info_set.restype = amdsmi_status_t +amdsmi_dev_od_clk_info_set = _lib.amdsmi_dev_od_clk_info_set + +_lib.amdsmi_dev_od_volt_info_set.argtypes = [amdsmi_device_handle,c_uint32,c_uint64,c_uint64] +_lib.amdsmi_dev_od_volt_info_set.restype = amdsmi_status_t +amdsmi_dev_od_volt_info_set = _lib.amdsmi_dev_od_volt_info_set + +_lib.amdsmi_dev_od_volt_curve_regions_get.argtypes = [amdsmi_device_handle,POINTER(c_uint32),POINTER(amdsmi_freq_volt_region_t)] +_lib.amdsmi_dev_od_volt_curve_regions_get.restype = amdsmi_status_t +amdsmi_dev_od_volt_curve_regions_get = _lib.amdsmi_dev_od_volt_curve_regions_get + +_lib.amdsmi_dev_power_profile_presets_get.argtypes = [amdsmi_device_handle,c_uint32,POINTER(amdsmi_power_profile_status_t)] +_lib.amdsmi_dev_power_profile_presets_get.restype = amdsmi_status_t +amdsmi_dev_power_profile_presets_get = _lib.amdsmi_dev_power_profile_presets_get + +_lib.amdsmi_dev_perf_level_set.argtypes = [amdsmi_device_handle,amdsmi_dev_perf_level_t] +_lib.amdsmi_dev_perf_level_set.restype = amdsmi_status_t +amdsmi_dev_perf_level_set = _lib.amdsmi_dev_perf_level_set + +_lib.amdsmi_dev_perf_level_set_v1.argtypes = [amdsmi_device_handle,amdsmi_dev_perf_level_t] +_lib.amdsmi_dev_perf_level_set_v1.restype = amdsmi_status_t +amdsmi_dev_perf_level_set_v1 = _lib.amdsmi_dev_perf_level_set_v1 + +_lib.amdsmi_dev_overdrive_level_set.argtypes = [amdsmi_device_handle,c_uint32] +_lib.amdsmi_dev_overdrive_level_set.restype = amdsmi_status_t +amdsmi_dev_overdrive_level_set = _lib.amdsmi_dev_overdrive_level_set + +_lib.amdsmi_dev_overdrive_level_set_v1.argtypes = [amdsmi_device_handle,c_uint32] +_lib.amdsmi_dev_overdrive_level_set_v1.restype = amdsmi_status_t +amdsmi_dev_overdrive_level_set_v1 = _lib.amdsmi_dev_overdrive_level_set_v1 + +_lib.amdsmi_dev_gpu_clk_freq_set.argtypes = [amdsmi_device_handle,amdsmi_clk_type_t,c_uint64] +_lib.amdsmi_dev_gpu_clk_freq_set.restype = amdsmi_status_t +amdsmi_dev_gpu_clk_freq_set = _lib.amdsmi_dev_gpu_clk_freq_set + +_lib.amdsmi_version_get.argtypes = [POINTER(amdsmi_version_t)] +_lib.amdsmi_version_get.restype = amdsmi_status_t +amdsmi_version_get = _lib.amdsmi_version_get + +_lib.amdsmi_version_str_get.argtypes = [amdsmi_sw_component_t,c_char_p,c_uint32] +_lib.amdsmi_version_str_get.restype = amdsmi_status_t +amdsmi_version_str_get = _lib.amdsmi_version_str_get + +_lib.amdsmi_dev_ecc_count_get.argtypes = [amdsmi_device_handle,amdsmi_gpu_block_t,POINTER(amdsmi_error_count_t)] +_lib.amdsmi_dev_ecc_count_get.restype = amdsmi_status_t +amdsmi_dev_ecc_count_get = _lib.amdsmi_dev_ecc_count_get + +_lib.amdsmi_dev_ecc_enabled_get.argtypes = [amdsmi_device_handle,POINTER(c_uint64)] +_lib.amdsmi_dev_ecc_enabled_get.restype = amdsmi_status_t +amdsmi_dev_ecc_enabled_get = _lib.amdsmi_dev_ecc_enabled_get + +_lib.amdsmi_dev_ecc_status_get.argtypes = [amdsmi_device_handle,amdsmi_gpu_block_t,POINTER(amdsmi_ras_err_state_t)] +_lib.amdsmi_dev_ecc_status_get.restype = amdsmi_status_t +amdsmi_dev_ecc_status_get = _lib.amdsmi_dev_ecc_status_get + +_lib.amdsmi_status_string.argtypes = [amdsmi_status_t,POINTER(c_char_p)] +_lib.amdsmi_status_string.restype = amdsmi_status_t +amdsmi_status_string = _lib.amdsmi_status_string + +_lib.amdsmi_dev_counter_group_supported.argtypes = [amdsmi_device_handle,amdsmi_event_group_t] +_lib.amdsmi_dev_counter_group_supported.restype = amdsmi_status_t +amdsmi_dev_counter_group_supported = _lib.amdsmi_dev_counter_group_supported + +_lib.amdsmi_dev_counter_create.argtypes = [amdsmi_device_handle,amdsmi_event_type_t,POINTER(amdsmi_event_handle_t)] +_lib.amdsmi_dev_counter_create.restype = amdsmi_status_t +amdsmi_dev_counter_create = _lib.amdsmi_dev_counter_create + +_lib.amdsmi_dev_counter_destroy.argtypes = [amdsmi_event_handle_t] +_lib.amdsmi_dev_counter_destroy.restype = amdsmi_status_t +amdsmi_dev_counter_destroy = _lib.amdsmi_dev_counter_destroy + +_lib.amdsmi_counter_control.argtypes = [amdsmi_event_handle_t,amdsmi_counter_command_t,c_void_p] +_lib.amdsmi_counter_control.restype = amdsmi_status_t +amdsmi_counter_control = _lib.amdsmi_counter_control + +_lib.amdsmi_counter_read.argtypes = [amdsmi_event_handle_t,POINTER(amdsmi_counter_value_t)] +_lib.amdsmi_counter_read.restype = amdsmi_status_t +amdsmi_counter_read = _lib.amdsmi_counter_read + +_lib.amdsmi_counter_available_counters_get.argtypes = [amdsmi_device_handle,amdsmi_event_group_t,POINTER(c_uint32)] +_lib.amdsmi_counter_available_counters_get.restype = amdsmi_status_t +amdsmi_counter_available_counters_get = _lib.amdsmi_counter_available_counters_get + +_lib.amdsmi_compute_process_info_get.argtypes = [POINTER(amdsmi_process_info_t),POINTER(c_uint32)] +_lib.amdsmi_compute_process_info_get.restype = amdsmi_status_t +amdsmi_compute_process_info_get = _lib.amdsmi_compute_process_info_get + +_lib.amdsmi_compute_process_info_by_pid_get.argtypes = [c_uint32,POINTER(amdsmi_process_info_t)] +_lib.amdsmi_compute_process_info_by_pid_get.restype = amdsmi_status_t +amdsmi_compute_process_info_by_pid_get = _lib.amdsmi_compute_process_info_by_pid_get + +_lib.amdsmi_compute_process_gpus_get.argtypes = [c_uint32,POINTER(c_uint32),POINTER(c_uint32)] +_lib.amdsmi_compute_process_gpus_get.restype = amdsmi_status_t +amdsmi_compute_process_gpus_get = _lib.amdsmi_compute_process_gpus_get + +_lib.amdsmi_dev_xgmi_error_status.argtypes = [amdsmi_device_handle,POINTER(amdsmi_xgmi_status_t)] +_lib.amdsmi_dev_xgmi_error_status.restype = amdsmi_status_t +amdsmi_dev_xgmi_error_status = _lib.amdsmi_dev_xgmi_error_status + +_lib.amdsmi_dev_xgmi_error_reset.argtypes = [amdsmi_device_handle] +_lib.amdsmi_dev_xgmi_error_reset.restype = amdsmi_status_t +amdsmi_dev_xgmi_error_reset = _lib.amdsmi_dev_xgmi_error_reset + +_lib.amdsmi_topo_get_numa_node_number.argtypes = [amdsmi_device_handle,POINTER(c_uint32)] +_lib.amdsmi_topo_get_numa_node_number.restype = amdsmi_status_t +amdsmi_topo_get_numa_node_number = _lib.amdsmi_topo_get_numa_node_number + +_lib.amdsmi_topo_get_link_weight.argtypes = [amdsmi_device_handle,amdsmi_device_handle,POINTER(c_uint64)] +_lib.amdsmi_topo_get_link_weight.restype = amdsmi_status_t +amdsmi_topo_get_link_weight = _lib.amdsmi_topo_get_link_weight + +_lib.amdsmi_minmax_bandwidth_get.argtypes = [amdsmi_device_handle,amdsmi_device_handle,POINTER(c_uint64),POINTER(c_uint64)] +_lib.amdsmi_minmax_bandwidth_get.restype = amdsmi_status_t +amdsmi_minmax_bandwidth_get = _lib.amdsmi_minmax_bandwidth_get + +_lib.amdsmi_topo_get_link_type.argtypes = [amdsmi_device_handle,amdsmi_device_handle,POINTER(c_uint64),POINTER(AMDSMI_IO_LINK_TYPE)] +_lib.amdsmi_topo_get_link_type.restype = amdsmi_status_t +amdsmi_topo_get_link_type = _lib.amdsmi_topo_get_link_type + +_lib.amdsmi_is_P2P_accessible.argtypes = [amdsmi_device_handle,amdsmi_device_handle,POINTER(c_bool)] +_lib.amdsmi_is_P2P_accessible.restype = amdsmi_status_t +amdsmi_is_P2P_accessible = _lib.amdsmi_is_P2P_accessible + +_lib.amdsmi_dev_supported_func_iterator_open.argtypes = [amdsmi_device_handle,POINTER(amdsmi_func_id_iter_handle_t)] +_lib.amdsmi_dev_supported_func_iterator_open.restype = amdsmi_status_t +amdsmi_dev_supported_func_iterator_open = _lib.amdsmi_dev_supported_func_iterator_open + +_lib.amdsmi_dev_supported_variant_iterator_open.argtypes = [amdsmi_func_id_iter_handle_t,POINTER(amdsmi_func_id_iter_handle_t)] +_lib.amdsmi_dev_supported_variant_iterator_open.restype = amdsmi_status_t +amdsmi_dev_supported_variant_iterator_open = _lib.amdsmi_dev_supported_variant_iterator_open + +_lib.amdsmi_func_iter_next.argtypes = [amdsmi_func_id_iter_handle_t] +_lib.amdsmi_func_iter_next.restype = amdsmi_status_t +amdsmi_func_iter_next = _lib.amdsmi_func_iter_next + +_lib.amdsmi_dev_supported_func_iterator_close.argtypes = [POINTER(amdsmi_func_id_iter_handle_t)] +_lib.amdsmi_dev_supported_func_iterator_close.restype = amdsmi_status_t +amdsmi_dev_supported_func_iterator_close = _lib.amdsmi_dev_supported_func_iterator_close + +_lib.amdsmi_func_iter_value_get.argtypes = [amdsmi_func_id_iter_handle_t,POINTER(amdsmi_func_id_value_t)] +_lib.amdsmi_func_iter_value_get.restype = amdsmi_status_t +amdsmi_func_iter_value_get = _lib.amdsmi_func_iter_value_get + +_lib.amdsmi_event_notification_init.argtypes = [amdsmi_device_handle] +_lib.amdsmi_event_notification_init.restype = amdsmi_status_t +amdsmi_event_notification_init = _lib.amdsmi_event_notification_init + +_lib.amdsmi_event_notification_mask_set.argtypes = [amdsmi_device_handle,c_uint64] +_lib.amdsmi_event_notification_mask_set.restype = amdsmi_status_t +amdsmi_event_notification_mask_set = _lib.amdsmi_event_notification_mask_set + +_lib.amdsmi_event_notification_get.argtypes = [c_int,POINTER(c_uint32),POINTER(amdsmi_evt_notification_data_t)] +_lib.amdsmi_event_notification_get.restype = amdsmi_status_t +amdsmi_event_notification_get = _lib.amdsmi_event_notification_get + +_lib.amdsmi_event_notification_stop.argtypes = [amdsmi_device_handle] +_lib.amdsmi_event_notification_stop.restype = amdsmi_status_t +amdsmi_event_notification_stop = _lib.amdsmi_event_notification_stop + +_lib.amdsmi_get_device_bdf.argtypes = [amdsmi_device_handle,POINTER(amdsmi_bdf_t)] +_lib.amdsmi_get_device_bdf.restype = amdsmi_status_t +amdsmi_get_device_bdf = _lib.amdsmi_get_device_bdf + +_lib.amdsmi_get_device_uuid.argtypes = [amdsmi_device_handle,POINTER(c_uint),c_char_p] +_lib.amdsmi_get_device_uuid.restype = amdsmi_status_t +amdsmi_get_device_uuid = _lib.amdsmi_get_device_uuid + +_lib.amdsmi_get_driver_version.argtypes = [amdsmi_device_handle,POINTER(c_int),c_char_p] +_lib.amdsmi_get_driver_version.restype = amdsmi_status_t +amdsmi_get_driver_version = _lib.amdsmi_get_driver_version + +_lib.amdsmi_get_asic_info.argtypes = [amdsmi_device_handle,POINTER(amdsmi_asic_info_t)] +_lib.amdsmi_get_asic_info.restype = amdsmi_status_t +amdsmi_get_asic_info = _lib.amdsmi_get_asic_info + +_lib.amdsmi_get_board_info.argtypes = [amdsmi_device_handle,POINTER(amdsmi_board_info_t)] +_lib.amdsmi_get_board_info.restype = amdsmi_status_t +amdsmi_get_board_info = _lib.amdsmi_get_board_info + +_lib.amdsmi_get_power_cap_info.argtypes = [amdsmi_device_handle,c_uint32,POINTER(amdsmi_power_cap_info_t)] +_lib.amdsmi_get_power_cap_info.restype = amdsmi_status_t +amdsmi_get_power_cap_info = _lib.amdsmi_get_power_cap_info + +_lib.amdsmi_get_xgmi_info.argtypes = [amdsmi_device_handle,POINTER(amdsmi_xgmi_info_t)] +_lib.amdsmi_get_xgmi_info.restype = amdsmi_status_t +amdsmi_get_xgmi_info = _lib.amdsmi_get_xgmi_info + +_lib.amdsmi_get_caps_info.argtypes = [amdsmi_device_handle,POINTER(amdsmi_gpu_caps_t)] +_lib.amdsmi_get_caps_info.restype = amdsmi_status_t +amdsmi_get_caps_info = _lib.amdsmi_get_caps_info + +_lib.amdsmi_get_fw_info.argtypes = [amdsmi_device_handle,POINTER(amdsmi_fw_info_t)] +_lib.amdsmi_get_fw_info.restype = amdsmi_status_t +amdsmi_get_fw_info = _lib.amdsmi_get_fw_info + +_lib.amdsmi_get_vbios_info.argtypes = [amdsmi_device_handle,POINTER(amdsmi_vbios_info_t)] +_lib.amdsmi_get_vbios_info.restype = amdsmi_status_t +amdsmi_get_vbios_info = _lib.amdsmi_get_vbios_info + +_lib.amdsmi_get_gpu_activity.argtypes = [amdsmi_device_handle,POINTER(amdsmi_engine_usage_t)] +_lib.amdsmi_get_gpu_activity.restype = amdsmi_status_t +amdsmi_get_gpu_activity = _lib.amdsmi_get_gpu_activity + +_lib.amdsmi_get_power_measure.argtypes = [amdsmi_device_handle,POINTER(amdsmi_power_measure_t)] +_lib.amdsmi_get_power_measure.restype = amdsmi_status_t +amdsmi_get_power_measure = _lib.amdsmi_get_power_measure + +_lib.amdsmi_get_clock_measure.argtypes = [amdsmi_device_handle,amdsmi_clk_type_t,POINTER(amdsmi_clk_measure_t)] +_lib.amdsmi_get_clock_measure.restype = amdsmi_status_t +amdsmi_get_clock_measure = _lib.amdsmi_get_clock_measure + +_lib.amdsmi_get_temperature_measure.argtypes = [amdsmi_device_handle,amdsmi_temperature_type_t,POINTER(amdsmi_temperature_t)] +_lib.amdsmi_get_temperature_measure.restype = amdsmi_status_t +amdsmi_get_temperature_measure = _lib.amdsmi_get_temperature_measure + +_lib.amdsmi_get_temperature_limit.argtypes = [amdsmi_device_handle,amdsmi_temperature_type_t,POINTER(amdsmi_temperature_limit_t)] +_lib.amdsmi_get_temperature_limit.restype = amdsmi_status_t +amdsmi_get_temperature_limit = _lib.amdsmi_get_temperature_limit + +_lib.amdsmi_get_power_limit.argtypes = [amdsmi_device_handle,POINTER(amdsmi_power_limit_t)] +_lib.amdsmi_get_power_limit.restype = amdsmi_status_t +amdsmi_get_power_limit = _lib.amdsmi_get_power_limit + +_lib.amdsmi_get_vram_usage.argtypes = [amdsmi_device_handle,POINTER(amdsmi_vram_info_t)] +_lib.amdsmi_get_vram_usage.restype = amdsmi_status_t +amdsmi_get_vram_usage = _lib.amdsmi_get_vram_usage + +_lib.amdsmi_get_target_frequency_range.argtypes = [amdsmi_device_handle,amdsmi_clk_type_t,POINTER(amdsmi_frequency_range_t)] +_lib.amdsmi_get_target_frequency_range.restype = amdsmi_status_t +amdsmi_get_target_frequency_range = _lib.amdsmi_get_target_frequency_range + +_lib.amdsmi_get_process_list.argtypes = [amdsmi_device_handle,POINTER(amdsmi_process_handle),POINTER(c_uint32)] +_lib.amdsmi_get_process_list.restype = amdsmi_status_t +amdsmi_get_process_list = _lib.amdsmi_get_process_list + +_lib.amdsmi_get_process_info.argtypes = [amdsmi_device_handle,amdsmi_process_handle,POINTER(amdsmi_proc_info_t)] +_lib.amdsmi_get_process_info.restype = amdsmi_status_t +amdsmi_get_process_info = _lib.amdsmi_get_process_info + +_lib.amdsmi_get_ecc_error_count.argtypes = [amdsmi_device_handle,POINTER(amdsmi_error_count_t)] +_lib.amdsmi_get_ecc_error_count.restype = amdsmi_status_t +amdsmi_get_ecc_error_count = _lib.amdsmi_get_ecc_error_count + diff --git a/projects/amdsmi/py-interface/setup.py b/projects/amdsmi/py-interface/setup.py new file mode 100644 index 0000000000..6a4bc6480f --- /dev/null +++ b/projects/amdsmi/py-interface/setup.py @@ -0,0 +1,16 @@ +from setuptools import setup + +with open("amdsmi/README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() + +setup( + name='amdsmi', + version='0.1', + description="SMI LIB - AMD GPU Monitoring Library", + long_description=long_description, + long_description_content_type="text/markdown", + packages=['amdsmi'], + package_data={'': ['LICENSE']}, + include_package_data=True, + python_requires=">=3.6", +) diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index cf5938ab16..119aa94a3a 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -62,6 +62,7 @@ #include "amd_smi/impl/amd_smi_system.h" #include "amd_smi/impl/amd_smi_socket.h" #include "amd_smi/impl/amd_smi_gpu_device.h" +#include "amd_smi/impl/amd_smi_uuid.h" #include "rocm_smi/rocm_smi.h" #include "rocm_smi/rocm_smi_common.h" #include "amd_smi/impl/amdgpu_drm.h" @@ -253,7 +254,7 @@ amdsmi_status_t amdsmi_get_board_info(amdsmi_device_handle device_handle, amdsmi static_cast(device_handle); if (gpu_device->check_if_drm_is_supported()) { - status = smi_amdgpu_get_board_info(gpu_device, board_info); + status = smi_amdgpu_get_board_info(gpu_device, board_info); } else { status = rsmi_wrapper(rsmi_dev_name_get, device_handle, board_info->product_name, AMDSMI_PRODUCT_NAME_LENGTH); @@ -492,8 +493,8 @@ amdsmi_get_asic_info(amdsmi_device_handle device_handle, amdsmi_asic_info_t *inf return AMDSMI_STATUS_INVAL; } - struct drm_amdgpu_info_device dev_info = {}; - struct drm_amdgpu_info_vbios vbios = {}; + struct drm_amdgpu_info_device dev_info = {}; + struct drm_amdgpu_info_vbios vbios = {}; char* name; char *tmp; @@ -501,7 +502,7 @@ amdsmi_get_asic_info(amdsmi_device_handle device_handle, amdsmi_asic_info_t *inf static_cast(device_handle); amdsmi_status_t status; if (gpu_device->check_if_drm_is_supported()){ - status = gpu_device->amdgpu_query_info(AMDGPU_INFO_DEV_INFO, sizeof(struct drm_amdgpu_info_device), &dev_info); + status = gpu_device->amdgpu_query_info(AMDGPU_INFO_DEV_INFO, sizeof(struct drm_amdgpu_info_device), &dev_info); if (status != AMDSMI_STATUS_SUCCESS) return status; status = gpu_device->amdgpu_query_vbios(&vbios); if (status != AMDSMI_STATUS_SUCCESS) return status; @@ -965,7 +966,7 @@ amdsmi_get_power_cap_info(amdsmi_device_handle device_handle, status = smi_amdgpu_get_power_cap(gpudevice, &power_cap); info->power_cap = power_cap; - status = smi_amdgpu_get_ranges(gpudevice, CLOCK_TYPE_GFX, + status = smi_amdgpu_get_ranges(gpudevice, CLK_TYPE_GFX, NULL, NULL, &dpm); info->dpm_cap = dpm; @@ -1059,10 +1060,10 @@ amdsmi_status_t amdsmi_dev_gpu_clk_freq_get(amdsmi_device_handle device_handle, return AMDSMI_STATUS_INVAL; // Get from gpu_metrics - if (clk_type == CLOCK_TYPE_VCLK0 || - clk_type == CLOCK_TYPE_VCLK1 || - clk_type == CLOCK_TYPE_DCLK0 || - clk_type == CLOCK_TYPE_DCLK1 ) { + if (clk_type == CLK_TYPE_VCLK0 || + clk_type == CLK_TYPE_VCLK1 || + clk_type == CLK_TYPE_DCLK0 || + clk_type == CLK_TYPE_DCLK1 ) { amdsmi_gpu_metrics_t metric_info; auto r_status = amdsmi_dev_gpu_metrics_info_get( device_handle, &metric_info); @@ -1070,19 +1071,19 @@ amdsmi_status_t amdsmi_dev_gpu_clk_freq_get(amdsmi_device_handle device_handle, return r_status; f->num_supported = 1; - if (clk_type == CLOCK_TYPE_VCLK0) { + if (clk_type == CLK_TYPE_VCLK0) { f->current = metric_info.current_vclk0; f->frequency[0] = metric_info.average_vclk0_frequency; } - if (clk_type == CLOCK_TYPE_VCLK1) { + if (clk_type == CLK_TYPE_VCLK1) { f->current = metric_info.current_vclk1; f->frequency[0] = metric_info.average_vclk1_frequency; } - if (clk_type == CLOCK_TYPE_DCLK0) { + if (clk_type == CLK_TYPE_DCLK0) { f->current = metric_info.current_dclk0; f->frequency[0] = metric_info.average_dclk0_frequency; } - if (clk_type == CLOCK_TYPE_DCLK1) { + if (clk_type == CLK_TYPE_DCLK1) { f->current = metric_info.current_dclk1; f->frequency[0] = metric_info.average_dclk1_frequency; } @@ -1098,10 +1099,10 @@ amdsmi_status_t amdsmi_dev_gpu_clk_freq_get(amdsmi_device_handle device_handle, amdsmi_status_t amdsmi_dev_gpu_clk_freq_set(amdsmi_device_handle device_handle, amdsmi_clk_type_t clk_type, uint64_t freq_bitmask) { // Not support the clock type read from gpu_metrics - if (clk_type == CLOCK_TYPE_VCLK0 || - clk_type == CLOCK_TYPE_VCLK1 || - clk_type == CLOCK_TYPE_DCLK0 || - clk_type == CLOCK_TYPE_DCLK1 ) { + if (clk_type == CLK_TYPE_VCLK0 || + clk_type == CLK_TYPE_VCLK1 || + clk_type == CLK_TYPE_DCLK0 || + clk_type == CLK_TYPE_DCLK1 ) { return AMDSMI_STATUS_NOT_SUPPORTED; } @@ -1269,12 +1270,12 @@ amdsmi_get_vbios_info(amdsmi_device_handle dev, amdsmi_vbios_info_t *info) { if (info == nullptr) { return AMDSMI_STATUS_INVAL; } - struct drm_amdgpu_info_vbios vbios = {}; + struct drm_amdgpu_info_vbios vbios = {}; amd::smi::AMDSmiGPUDevice* gpu_device = static_cast(dev); amdsmi_status_t status; - if (gpu_device->check_if_drm_is_supported()){ + if (gpu_device->check_if_drm_is_supported()){ status = gpu_device->amdgpu_query_vbios(&vbios); if (status != AMDSMI_STATUS_SUCCESS) { return status; @@ -1290,7 +1291,7 @@ amdsmi_get_vbios_info(amdsmi_device_handle dev, amdsmi_vbios_info_t *info) { return AMDSMI_STATUS_NOT_SUPPORTED; } - return AMDSMI_STATUS_SUCCESS; + return AMDSMI_STATUS_SUCCESS; } amdsmi_status_t @@ -1334,13 +1335,13 @@ amdsmi_get_power_limit(amdsmi_device_handle dev, amdsmi_power_limit_t *limit) { } amdsmi_status_t -amdsmi_get_clock_measure(amdsmi_device_handle dev, amdsmi_clk_type_t clk_type, amdsmi_clock_measure_t *info) { +amdsmi_get_clock_measure(amdsmi_device_handle dev, amdsmi_clk_type_t clk_type, amdsmi_clk_measure_t *info) { if (info == nullptr) { return AMDSMI_STATUS_INVAL; } - if (clk_type >= CLOCK_TYPE__MAX) { - printf("Domain value greater or equals CLOCK_TYPE__MAX value. Return code: %d", AMDSMI_STATUS_INVAL); + if (clk_type >= CLK_TYPE__MAX) { + printf("Domain value greater or equals CLK_TYPE__MAX value. Return code: %d", AMDSMI_STATUS_INVAL); return AMDSMI_STATUS_INVAL; } @@ -1362,19 +1363,19 @@ amdsmi_get_clock_measure(amdsmi_device_handle dev, amdsmi_clk_type_t clk_type, a info->max_clk = max_freq; switch (clk_type) { - case CLOCK_TYPE_GFX: + case CLK_TYPE_GFX: info->avg_clk = metrics.average_gfxclk_frequency; info->cur_clk = metrics.current_gfxclk; break; - case CLOCK_TYPE_MEM: + case CLK_TYPE_MEM: info->avg_clk = metrics.average_uclk_frequency; info->cur_clk = metrics.current_uclk; break; - case CLOCK_TYPE_VCLK0: + case CLK_TYPE_VCLK0: info->avg_clk = metrics.average_vclk0_frequency; info->cur_clk = metrics.current_vclk0; break; - case CLOCK_TYPE_VCLK1: + case CLK_TYPE_VCLK1: info->avg_clk = metrics.average_vclk1_frequency; info->cur_clk = metrics.current_vclk1; break; @@ -1485,7 +1486,7 @@ amdsmi_get_temperature_measure(amdsmi_device_handle dev, amdsmi_temperature_type } amdsmi_status_t -amdsmi_get_ras_features_enabled(amdsmi_device_handle device_handle, amdsmi_gpu_block block, amdsmi_ras_err_state_t *state) { +amdsmi_get_ras_block_features_enabled(amdsmi_device_handle device_handle, amdsmi_gpu_block block, amdsmi_ras_err_state_t *state) { if (state == nullptr || block > AMDSMI_GPU_BLOCK_LAST) { return AMDSMI_STATUS_INVAL; } @@ -1610,9 +1611,40 @@ amdsmi_get_process_info(amdsmi_device_handle dev, amdsmi_process_handle process, return AMDSMI_STATUS_SUCCESS; } +amdsmi_status_t +amdsmi_get_power_measure(amdsmi_device_handle dev, amdsmi_power_measure_t *info) { + if (info == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + amdsmi_gpu_metrics_t metrics = {}; + amd::smi::AMDSmiGPUDevice* gpu_device = + static_cast(dev); + amdsmi_status_t status; + + status = amdsmi_dev_gpu_metrics_info_get(dev, &metrics); + if (status != AMDSMI_STATUS_SUCCESS) { + return status; + } + + int64_t voltage_read = 0; + + status = amdsmi_dev_volt_metric_get(dev, AMDSMI_VOLT_TYPE_VDDGFX, AMDSMI_VOLT_CURRENT, &voltage_read); + if (status != AMDSMI_STATUS_SUCCESS) { + return status; + } + + info->voltage_gfx = voltage_read; + + info->average_socket_power = metrics.average_socket_power; + info->energy_accumulator = metrics.energy_accumulator; + + return status; +} + amdsmi_status_t amdsmi_get_target_frequency_range(amdsmi_device_handle dev, amdsmi_clk_type_t clk_type, amdsmi_frequency_range_t *range) { - if (range == nullptr || clk_type > CLOCK_TYPE__MAX) { + if (range == nullptr || clk_type > CLK_TYPE__MAX) { return AMDSMI_STATUS_INVAL; } @@ -1636,16 +1668,16 @@ amdsmi_get_target_frequency_range(amdsmi_device_handle dev, amdsmi_clk_type_t cl range->supported_freq_range.upper_bound = (long)max; max = 0; switch (clk_type) { - case CLOCK_TYPE_GFX: + case CLK_TYPE_GFX: max = metrics.current_gfxclk; break; - case CLOCK_TYPE_MEM: + case CLK_TYPE_MEM: max = metrics.current_uclk; break; - case CLOCK_TYPE_VCLK0: + case CLK_TYPE_VCLK0: max = metrics.current_vclk0; break; - case CLOCK_TYPE_VCLK1: + case CLK_TYPE_VCLK1: max = metrics.current_vclk1; break; default: @@ -1655,3 +1687,158 @@ amdsmi_get_target_frequency_range(amdsmi_device_handle dev, amdsmi_clk_type_t cl return AMDSMI_STATUS_SUCCESS; } + +amdsmi_status_t +amdsmi_get_driver_version(amdsmi_device_handle dev, int *length, char *version) { + if (length == nullptr || version == nullptr) { + return AMDSMI_STATUS_INVAL; + } + amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; + amd::smi::AMDSmiGPUDevice* gpu_device = + static_cast(dev); + status = smi_amdgpu_get_driver_version(gpu_device, length, version); + + return status; +} + +amdsmi_status_t +amdsmi_get_device_uuid(amdsmi_device_handle dev, unsigned int *uuid_length, char *uuid) { + if (uuid_length == nullptr || uuid == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + amd::smi::AMDSmiGPUDevice* gpu_device = + static_cast(dev); + amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; + SMIGPUDEVICE_MUTEX(gpu_device->get_mutex()) + + FILE *fp; + size_t len = AMDSMI_GPU_UUID_SIZE; + ssize_t nread; + amdsmi_asic_info_t asic_info = {}; + const uint8_t fcn = 0xff; + + std::string path = "/sys/class/drm/" + gpu_device->get_gpu_path() + "/device/uuid_info"; + status = amdsmi_get_asic_info(dev, &asic_info); + if (status != AMDSMI_STATUS_SUCCESS) { + printf("Getting asic info failed. Return code: %d", status); + return status; + } + + fp = fopen(path.c_str(), "rb"); + if (!fp) { + /* generate random UUID */ + status = amdsmi_uuid_gen(uuid, strtoul(asic_info.asic_serial, nullptr, AMDSMI_NORMAL_STRING_LENGTH), (uint16_t)asic_info.device_id, fcn); + return status; + } + + nread = getline(&uuid, &len, fp); + if (nread <= 0) { + /* generate random UUID */ + status = amdsmi_uuid_gen(uuid, strtoul(asic_info.asic_serial, nullptr, AMDSMI_NORMAL_STRING_LENGTH), (uint16_t)asic_info.device_id, fcn); + fclose(fp); + return status; + } + + fclose(fp); + return status; +} + +amdsmi_status_t +amdsmi_get_pcie_link_status(amdsmi_device_handle dev, amdsmi_pcie_info_t *info){ + if (info == nullptr) { + return AMDSMI_STATUS_INVAL; + } + amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; + amdsmi_gpu_metrics_t metric_info = {}; + status = amdsmi_dev_gpu_metrics_info_get( + dev, &metric_info); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + info->pcie_lanes = metric_info.pcie_link_width; + info->pcie_speed = metric_info.pcie_link_speed; + + return status; +} + +amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_device_handle dev, amdsmi_pcie_info_t *info) { + if (info == nullptr) { + return AMDSMI_STATUS_INVAL; + } + + amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; + amd::smi::AMDSmiGPUDevice* gpu_device = + static_cast(dev); + + SMIGPUDEVICE_MUTEX(gpu_device->get_mutex()) + + char buff[AMDSMI_NORMAL_STRING_LENGTH]; + FILE* fp; + double pcie_speed = 0; + unsigned pcie_width = 0; + amdsmi_asic_info_t asic_info = {}; + + memset((void *)info, 0, sizeof(*info)); + + std::string path_max_link_width = "/sys/class/drm/" + + gpu_device->get_gpu_path() + "/device/max_link_width"; + fp = fopen(path_max_link_width.c_str(), "r"); + if (fp) { + fscanf(fp, "%d", &pcie_width); + fclose(fp); + } else { + printf("Failed to open file: %s \n", path_max_link_width.c_str()); + return AMDSMI_STATUS_API_FAILED; + } + info->pcie_lanes = (uint16_t)pcie_width; + + std::string path_max_link_speed = "/sys/class/drm/" + + gpu_device->get_gpu_path() + "/device/max_link_speed"; + fp = fopen(path_max_link_speed.c_str(), "r"); + if (fp) { + fscanf(fp, "%lf %s", &pcie_speed, buff); + fclose(fp); + } else { + printf("Failed to open file: %s \n", path_max_link_speed.c_str()); + return AMDSMI_STATUS_API_FAILED; + } + + status = amdsmi_get_asic_info(dev, &asic_info); + if (status != AMDSMI_STATUS_SUCCESS) + return status; + + if (pcie_speed == 0 && asic_info.device_id == 29538) + pcie_speed = 16; + + info->pcie_speed = pcie_speed * 1000; + + return status; +} + +amdsmi_status_t amdsmi_get_device_handle_from_bdf(amdsmi_bdf_t bdf, + amdsmi_device_handle* device_handles, + uint32_t device_count, + amdsmi_device_handle* device_handle){ + if (device_handles == nullptr) { + return AMDSMI_STATUS_INVAL; + } + amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; + + for(auto idx = 0; idx < device_count; idx++) { + amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; + status = get_gpu_device_from_handle(device_handles[idx], &gpu_device); + if (status != AMDSMI_STATUS_SUCCESS) { + return status; + } + amdsmi_bdf_t found_bdf = gpu_device->get_bdf(); + if (bdf.bus_number == found_bdf.bus_number && + bdf.device_number == found_bdf.device_number && + bdf.domain_number == found_bdf.domain_number && + bdf.function_number == found_bdf.function_number) { + *device_handle = device_handles[idx]; + return AMDSMI_STATUS_SUCCESS; + } + } + return AMDSMI_STATUS_API_FAILED; +} diff --git a/projects/amdsmi/src/amd_smi/amd_smi_utils.cc b/projects/amdsmi/src/amd_smi/amd_smi_utils.cc index b8c629de5b..da67596a22 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_utils.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_utils.cc @@ -51,18 +51,18 @@ static bool isAMDGPU(std::string dev_path) { std::string vend_path = dev_path + "/device/vendor"; std::string vbios_v_path = dev_path + "/device/vbios_version"; if (!amd::smi::FileExists(vend_path.c_str())) { - return false; + return false; } if (!amd::smi::FileExists(vbios_v_path.c_str())) { - return false; + return false; } std::ifstream fs; fs.open(vend_path); if (!fs.is_open()) { - return false; + return false; } uint32_t vendor_id; @@ -72,7 +72,7 @@ static bool isAMDGPU(std::string dev_path) { fs.close(); if (vendor_id == kAmdGpuId) { - return true; + return true; } return false; } @@ -199,16 +199,16 @@ amdsmi_status_t smi_amdgpu_get_ranges(amd::smi::AMDSmiGPUDevice* device, amdsmi_ unsigned int max, min, dpm; switch (domain) { - case CLOCK_TYPE_GFX: + case CLK_TYPE_GFX: fullpath += "/pp_dpm_sclk"; break; - case CLOCK_TYPE_MEM: + case CLK_TYPE_MEM: fullpath += "/pp_dpm_mclk"; break; - case CLOCK_TYPE_VCLK0: + case CLK_TYPE_VCLK0: fullpath += "/pp_dpm_vclk"; break; - case CLOCK_TYPE_VCLK1: + case CLK_TYPE_VCLK1: fullpath += "/pp_dpm_vclk1"; break; default: @@ -380,3 +380,81 @@ amdsmi_status_t smi_amdgpu_get_ecc_error_count(amd::smi::AMDSmiGPUDevice* device return AMDSMI_STATUS_SUCCESS; } + +amdsmi_status_t smi_amdgpu_get_driver_version(amd::smi::AMDSmiGPUDevice* device, int *length, char *version) { + if (!device->check_if_drm_is_supported()) { + return AMDSMI_STATUS_NOT_SUPPORTED; + } + SMIGPUDEVICE_MUTEX(device->get_mutex()) + amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; + FILE *fp; + char *tmp, *ptr, *token; + char *ver = NULL; + int i = 0; + size_t len; + + if (length) + len = *length < AMDSMI_MAX_DRIVER_VERSION_LENGTH ? *length : + AMDSMI_MAX_DRIVER_VERSION_LENGTH; + else + len = AMDSMI_MAX_DRIVER_VERSION_LENGTH; + + std::string path = "/sys/module/amdgpu/version"; + + fp = fopen(path.c_str(), "r"); + if (!fp){ + fp = fopen("/proc/version", "r"); + if (!fp) { + status = AMDSMI_STATUS_IO; + return status; + } + + len = 0; + if (getline(&ver, &len, fp) <= 0) { + status = AMDSMI_STATUS_IO; + fclose(fp); + free(ver); + return status; + } + + fclose(fp); + + ptr = ver; + token = strtok_r(ptr, " ", &tmp); + + if (!token) { + free(ver); + status = AMDSMI_STATUS_IO; + return status; + } + for (i = 0; i < 2; i++) { + ptr = strtok_r(NULL, " ", &tmp); + if (!ptr) + break; + } + if (i != 2 || !ptr) { + free(ver); + status = AMDSMI_STATUS_IO; + return status; + } + if (length) + len = *length < AMDSMI_MAX_DRIVER_VERSION_LENGTH ? *length : + AMDSMI_MAX_DRIVER_VERSION_LENGTH; + else + len = AMDSMI_MAX_DRIVER_VERSION_LENGTH; + + strncpy(version, ptr, len); + free(ver); + } else { + if ((len = getline(&version, &len, fp)) <= 0) + status = AMDSMI_STATUS_IO; + + fclose(fp); + if (length) { + *length = version[len-1] == '\n' ? len - 1 : len; + } + version[len-1] = version[len-1] == '\n' ? '\0' : version[len-1]; + } + + return status; +} diff --git a/projects/amdsmi/src/amd_smi/amd_smi_uuid.cc b/projects/amdsmi/src/amd_smi/amd_smi_uuid.cc new file mode 100644 index 0000000000..321b8935d6 --- /dev/null +++ b/projects/amdsmi/src/amd_smi/amd_smi_uuid.cc @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in 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: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * 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 + * AUTHORS 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 IN + * THE SOFTWARE. + */ + +#include "amd_smi/amd_smi.h" +#include "amd_smi/impl/amd_smi_uuid.h" + +#include +#include + +typedef struct uuid_s { + union { + struct { + uint32_t did : 16; + uint32_t fcn : 8; + uint32_t asic_7 : 8; + }; + uint32_t time_low; + }; + uint32_t time_mid : 16; + uint32_t time_high : 12; + uint32_t version : 4; + uint8_t clk_seq_hi : 6; + uint8_t variant : 2; + union { + uint8_t clk_seq_low; + uint8_t asic_6; + }; + uint16_t asic_4; + uint32_t asic_0; +} uuid_t; + +static void print_uuid(char *str, uuid_t *uuid) +{ + sprintf(str, "%08x", uuid->time_low); + sprintf(str + 8, "-"); + sprintf(str + 9, "%04x", uuid->time_mid); + sprintf(str + 13, "-"); + sprintf(str + 14, "%04x", (uuid->version << 12) | uuid->time_high); + sprintf(str + 18, "-"); + sprintf(str + 14 + 5, "%02x", (uuid->variant << 6) | uuid->clk_seq_hi); + sprintf(str + 16 + 5, "%02x", uuid->clk_seq_low); + sprintf(str + 18 + 5, "-"); + sprintf(str + 19 + 5, "%04x", uuid->asic_4); + sprintf(str + 23 + 5, "%08x", uuid->asic_0); + str[31 + 5] = 0; +} + +static void insert_asic_serial(uuid_t *uuid, uint64_t serial) +{ + uuid->asic_0 = (uint32_t)serial; + uuid->asic_4 = (uint16_t)(serial >> 4 * 8) & 0xFFFF; + uuid->asic_6 = (uint8_t)(serial >> 6 * 8) & 0xFF; + uuid->asic_7 = (uint32_t)(serial >> 7 * 8) & 0xFF; +} + +static void insert_did(uuid_t *uuid, uint16_t did) +{ + uuid->did = did; +} + +static void insert_fcn(uuid_t *uuid, uint8_t fcn_idx) +{ + uuid->fcn = fcn_idx; +} + +static void insert_clk_seq(uuid_t *uuid, uint16_t seq) +{ + uuid->clk_seq_low = (uint8_t)seq; + uuid->clk_seq_hi = (seq >> 8) & 0x3fU; +} + +amdsmi_status_t amdsmi_uuid_gen(char *str, uint64_t serial, uint16_t did, uint8_t idx) +{ + uuid_t uuid; + memset(&uuid, 0, sizeof(uuid_t)); + + insert_clk_seq(&uuid, 0); + insert_did(&uuid, did); + insert_fcn(&uuid, idx); + insert_asic_serial(&uuid, serial); + + uuid.version = 1; + uuid.variant = 2; + + print_uuid(str, &uuid); + + return AMDSMI_STATUS_SUCCESS; +} diff --git a/projects/amdsmi/tools/generator.py b/projects/amdsmi/tools/generator.py new file mode 100644 index 0000000000..277075c1e1 --- /dev/null +++ b/projects/amdsmi/tools/generator.py @@ -0,0 +1,504 @@ +# +# Copyright (C) 2022 Advanced Micro Devices. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# 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: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# 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 AUTHORS 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 IN THE SOFTWARE. +# + +import sys +import re +import os +from ctypes import * +from subprocess import call +from subprocess import check_output + +sys.path.append(os.getcwd()) + +import ctypeslib +from ctypeslib.clang2py import main as clang2py + +INTERFACE_SPECIFICATION = sys.argv[1] +OUTPUT_DIRECTORY = sys.argv[2] +LIBRARY_BINARY = sys.argv[3] +OUTPUT_FILE = "amdsmi_wrapper.py" +SMI_LIB_CTYPES = "amdsmi_lib_ctypes.py" +SMI_LIB_RET = "amdsmi_lib_ret.py" + +INTERFACE_FUNCTIONS = os.path.join(OUTPUT_DIRECTORY, "amdsmi_functions.h") + +API_REGEX_MATCHER = r"(\w+\s*\w*[\s\*]+)\s*(\w+)\(([^)]*)\);" +API_REGEX_TYPEDEF = r"typedef\s*(\w+)\s*(.*);" + +# Pointer statuses +NO_POINTER = 0 +SINGLE_POINTER = 1 +DOUBLE_POINTER = 2 +TRIPLE_POINTER = 3 + +clang_include_dir = "/usr/include/" +try: + clang_include_dir = os.path.join( + check_output(["clang", "-print-resource-dir"]).decode("utf-8").strip(), + "include/", + ) +except Exception as e: + print( + "Clang not found on the system. The script might not work properly. {}".format( + e + ) + ) + + +def ParseHeaderFile() -> bool: + """ + This function will parse the data from the main header file, create separate + temporary files which will then be used as arguments for clang2py(). Afterwards, + when the generator successfully completes wrapper generation - these temporary + files will be removed. + + `Parameters`: None. + + `Returns`: + `bool`: True if success, False if failed. + """ + + if not os.path.exists(INTERFACE_SPECIFICATION): + return False + + lib_types = "" + type_read_enablers = [ + "#include ", + "typedef enum amdsmi_init_flags {", + "typedef enum amdsmi_clk_type {", + ] + type_read_disablers = [ + " * @brief Initialization flags", + "} device_type_t;", + "} amdsmi_func_id_value_t;", + ] + reader_mask = False + + with open(INTERFACE_SPECIFICATION, "r") as types: + for i, line in enumerate(types): + if line.strip() in type_read_enablers: + reader_mask = True + if reader_mask: + lib_types += line + if line.strip() in type_read_disablers: + reader_mask = False + + with open(os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_types.h"), "w") as file_saver: + file_saver.write(lib_types) + + lib_ret_out = "" + ret_reader_enablers = ["#include ", "typedef enum amdsmi_status_t {"] + ret_reader_disablers = [" * @brief Initialization flags", "} amdsmi_status_t;"] + reader_mask = False + with open(INTERFACE_SPECIFICATION, "r") as ret_out: + for idx, line in enumerate(ret_out): + if line.strip() in ret_reader_enablers: + reader_mask = True + if reader_mask: + lib_ret_out += line + if line.strip() in ret_reader_disablers: + reader_mask = False + with open(os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_ret.h"), "w") as file_saver: + file_saver.write(lib_ret_out) + + functions_out = "" + functions_reader_enablers = [ + "#include ", + "amdsmi_status_t amdsmi_init(uint64_t init_flags);", + ] + functions_reader_disablers = [ + "typedef enum amdsmi_init_flags {", + "amdsmi_get_ecc_error_count(amdsmi_device_handle dev, amdsmi_error_count_t *ec);", + ] + reader_mask = False + with open(INTERFACE_SPECIFICATION, "r") as ret_out: + for idx, line in enumerate(ret_out): + if line.strip() in functions_reader_enablers: + reader_mask = True + if reader_mask: + functions_out += line + if line.strip() in functions_reader_disablers: + reader_mask = False + with open(INTERFACE_FUNCTIONS, "w") as file_saver: + file_saver.write(functions_out) + + sys.argv = [ + "generator.py", + "--clang-args=-I" + clang_include_dir, + os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_types.h"), + "-o", + os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_ctypes.py"), + ] + clang2py() + + sys.argv = [ + "generator.py", + os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_ret.h"), + "-o", + os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_ret.py"), + ] + clang2py() + + return True + + +def DeducePointerStatus(variable: str) -> int: + """ + Function used to deduce pointer status of a specific variable. + + `Parameters`: + * variable (`str`): Variable string for which the pointer status + is to be deduced. + + `Returns`: + `int`: Degree of pointer deduced (0 for no pointer status found + and 3 for a triple pointer). + """ + if ("***" in variable) or ("**" in variable and "[]" in variable): + return TRIPLE_POINTER + elif ("**" in variable) or ("*" in variable and "[]" in variable): + return DOUBLE_POINTER + elif "*" in variable or "[]" in variable: + return SINGLE_POINTER + return NO_POINTER + + +def TypeCast(cxxtype: str, ptr_status=0) -> str: + """ + Function used to type cast a cxx type to the corresponding ctypes + type. + + `Parameters`: + * cxxtype (`str`): String containing the cxx type. + * ptr_status (`int`): Integer describing pointer status of the + cxx type. + + `Returns`: + `str`: String containing the corresponding ctypes type. + """ + if cxxtype == "void" and ptr_status: + return "c_void_p" + elif cxxtype == "char" and ptr_status: + return "c_char_p" + elif cxxtype == "int": + return "c_int" + elif cxxtype == "unsigned int": + return "c_uint" + elif cxxtype == "unsigned": + return "c_uint" + elif cxxtype == "uint8_t": + return "c_uint8" + elif cxxtype == "uint16_t": + return "c_uint16" + elif cxxtype == "uint32_t": + return "c_uint32" + elif cxxtype == "size_t": + return "c_uint64" + elif cxxtype == "uint64_t": + return "c_uint64" + elif cxxtype == "int8_t": + return "c_int8" + elif cxxtype == "int16_t": + return "c_int16" + elif cxxtype == "int32_t": + return "c_int32" + elif cxxtype == "int64_t": + return "c_int64" + elif cxxtype == "float": + return "c_float" + elif cxxtype == "double": + return "c_double" + elif cxxtype == "char": + return "c_char" + elif cxxtype == "bool": + return "c_bool" + elif cxxtype == "void": + return "" + else: + return cxxtype + + +def GetType(cxxtype: str, ptr_status=0) -> str: + """ + Function used to retrieve ctypes type of a cxx type. + + `Parameters`: + * cxxtype (`str`): String containing the cxx type. + * ptr_status (`int`): Integer representing the pointer + status of the cxx type. + + `Returns`: + `str`: String of the ctypes type that was retrieved. + """ + if cxxtype == "void" and ptr_status == 2: + return "POINTER(" + TypeCast(cxxtype, ptr_status=1) + ")" + elif cxxtype == "void" and ptr_status == 1: + return TypeCast(cxxtype, ptr_status) + elif cxxtype == "char" and ptr_status == 2: + return "POINTER(" + TypeCast(cxxtype, ptr_status=1) + ")" + elif cxxtype == "char" and ptr_status == 1: + return TypeCast(cxxtype, ptr_status) + elif ptr_status == 2: + return "POINTER(POINTER(" + TypeCast(cxxtype) + "))" + elif ptr_status == 1: + return "POINTER(" + TypeCast(cxxtype) + ")" + else: + return TypeCast(cxxtype) + + +def DetectOpaquePointer(variable_type: str, variable: str, ptr_status=0) -> bool: + """ + Function used to check whether a variable is an opaque pointer. + + `Parameters`: + * variable_type (`str`): String containing the variable type. + * variable (`str`): String containing the variable name. + * ptr_status (`int`): Integer representing the pointer status found. + + `Returns`: + `bool`: Bool representing whether an opaque pointer was deduced or not. + """ + if variable_type == "struct" and len(variable.split(" ")) > 1 and ptr_status == 1: + return True + return False + + +def TypeDefConvert(variable_type: str, variable: str) -> str: + """ + Function used to break down a typedef down and extract the cxx type. + This type will then further be converted to a ctypes type. + + `Parameters`: + * variable_type (`str`): String containing the variable type. + * variable (`str`): String containing the variable name. + + `Returns`: + `str`: Finalized string containing the proper definition with ctypes + type. + """ + ptr_status = DeducePointerStatus(variable) + variable = variable.replace("*", " ").strip() + cxxtypedef = str() + if DetectOpaquePointer(variable_type, variable, ptr_status): + variables = variable.split(" ") + cxxtypedef = variables[2] + " = ctypes." + GetType(variables[0], ptr_status) + else: + cxxtypedef = variable + " = ctypes." + GetType(variable_type, ptr_status) + + return cxxtypedef + + +def ParseParameters(parameters: str) -> list: + """ + Function that parses function parameters and returns a list containing + ctypes types for the given parameters. + + An example return value: + [smi_device_handle, POINTER(smi_device_handle), POINTER(smi_vf_config)] + + `Parameters`: + * parameters (`str`): String containing the parameters for parsing. + + `Returns`: + `list`: List containing ctypes types for the given parameters. + """ + if parameters == "": + return [] + + parameter_array = parameters.split(",") + + result = [] + for param in parameter_array: + ptr_status = DeducePointerStatus(param) + param = param.strip().split(" ") + + while "const" in param: + param.remove("const") + + if param[0] == "unsigned" and len(param) == 3: + input = param[0] + " " + param[1] + result.append(GetType(input, ptr_status)) + elif param[0] == "struct" or param[0] == "union" or param[0] == "enum": + result.append(GetType(param[1], ptr_status)) + else: + result.append(GetType(param[0], ptr_status)) + + return "[{}]".format(",".join(result)) + + +def CleanTempFiles() -> None: + """ + This function cleans up the temporary files created by the generator. + + `Parameters`: None. + + `Returns`: None. + """ + os.remove(INTERFACE_FUNCTIONS) + os.remove(os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_ret.h")) + os.remove(os.path.join(OUTPUT_DIRECTORY, "amdsmi_lib_types.h")) + + +def main() -> str: + """ + Py wrapper generator. + + `Parameters`: None. + + `Returns`: + `str`: String containing status message. + """ + api = [] + api_expose = [] + typedef_list = [] + typedef_expose = [] + + if not ParseHeaderFile(): + return "Error - header file missing." + + format_code = ["clang-format", "-i", INTERFACE_FUNCTIONS] + try: + ret = call(format_code) + if ret < 0: + print("Clang-format failed to run") + except Exception as e: + print( + "Clang-format not found on the system. The script might not work properly. {}".format( + e + ) + ) + + with open(INTERFACE_FUNCTIONS) as specification: + file_specification = specification.read() + # find all typedefs and construct typedef_list in format [{typedef_name} = {ctypes_type}] + # typedef_expose is the list containing only the names of typedefs [{typedef_name}] + for variable_type, variable in re.findall( + API_REGEX_TYPEDEF, file_specification + ): + typedef_list.append(TypeDefConvert(variable_type, variable)) + typedef_expose.append(variable.replace("*", "")) + + # Get all components from function declaration(return type, function name, parameters) and + # append to api list + # api = [{return_type} = {ctypes_type}, {function_name} = {name}, {args} = [{ctypes_type}]] + for returnType, functionName, parameters in re.findall( + API_REGEX_MATCHER, file_specification + ): + ptr_status = DeducePointerStatus(returnType) + + returnType = returnType.replace("*", " ").strip() + returnedType = GetType(returnType, ptr_status) + + api.append( + { + "return_type": returnedType, + "function_name": functionName, + "args": ParseParameters(parameters), + } + ) + # api_expose is the list of all functions(function names) in the interface + api_expose.append(functionName) + + api_string = "" + for method in api: + api_string += """ +_lib.{function_name}.argtypes = {argument_array} +_lib.{function_name}.restype = {return_type} +{function_name} = _lib.{function_name} +""".format( + function_name=method["function_name"], + argument_array=method["args"], + return_type=method["return_type"], + ) + + typedef_list_out = "" + for typedef_item in typedef_list: + typedef_list_out += typedef_item + "\n" + + smi_lib_ctypes_out = "" + with open(os.path.join(OUTPUT_DIRECTORY, SMI_LIB_CTYPES), "r") as smi_lib_ctypes: + smi_lib_ctypes_out = smi_lib_ctypes.read() + smi_lib_ctypes_out = smi_lib_ctypes_out.replace("struct_", "") + smi_lib_ctypes_out = smi_lib_ctypes_out.replace("union_", "") + smi_lib_ctypes_out = smi_lib_ctypes_out.replace("POINTER(None)", "c_void_p") + + smi_lib_ret_out = "" + with open(os.path.join(OUTPUT_DIRECTORY, SMI_LIB_RET), "r") as smi_lib_ret: + smi_lib_ret_out = smi_lib_ret.read() + smi_lib_ret_out = smi_lib_ret_out.replace("__all__ =", "__all__ +=") + + with open(os.path.join(OUTPUT_DIRECTORY, OUTPUT_FILE), "w") as out: + out.write( + """ +# +# Copyright (C) 2022 Advanced Micro Devices. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# 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: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# 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 AUTHORS 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 IN THE SOFTWARE. +# + +from ctypes import * +from ctypes import POINTER +from subprocess import run +from subprocess import PIPE +import os + +{SMI_LIB_TYPES} +{SMI_LIB_RET} +{TYPEDEF_LIST} + +__all__ += {API_EXPOSE} +__all__ += {TYPEDEF_EXPOSE} + +_lib = CDLL(os.path.join(os.path.dirname(__file__), "libamd_smi64.so")) + +{API} +""".format( + SMI_LIB_TYPES=smi_lib_ctypes_out, + SMI_LIB_RET=smi_lib_ret_out, + TYPEDEF_LIST=typedef_list_out, + API_EXPOSE=api_expose, + TYPEDEF_EXPOSE=typedef_expose, + BINARY=LIBRARY_BINARY, + API=api_string, + ) + ) + CleanTempFiles() + return "Success - wrapper generated." + + +if __name__ == "__main__": + status = main() + print(status)