From 86de0f441f23bc6269afa132a35fcad464405d34 Mon Sep 17 00:00:00 2001 From: Jason Albert Date: Thu, 1 Dec 2022 13:04:58 -0600 Subject: [PATCH 1/7] Remove tag values from enum/union/struct declarations The tag values largely were not used and were causing doxygen generation issues. In the few cases where the tags were being referenced, clean up those compile issues. Signed-off-by: Jason Albert Change-Id: I7b32eac742fb5af560400c13dda2721705d882bc Signed-off-by: Dalibor Stanisavljevic --- example/amd_smi_drm_example.cc | 4 +- example/amd_smi_nodrm_example.cc | 4 +- include/amd_smi/amdsmi.h | 117 +++----- py-interface/amdsmi_interface.py | 18 +- py-interface/amdsmi_wrapper.py | 462 +++++++++++++++---------------- src/amd_smi/amd_smi.cc | 6 +- 6 files changed, 277 insertions(+), 334 deletions(-) diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index 90e91b72dc..69d9ef12b0 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -631,7 +631,7 @@ int main() { } // Get device name - amdsmi_board_info board_info = {}; + amdsmi_board_info_t board_info = {}; ret = amdsmi_get_board_info(device_handles[j], &board_info); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_board_info:\n"); @@ -676,7 +676,7 @@ int main() { << "\t\tMM IP Count: " << int(caps_info.mm.mm_ip_count) << "\n\n"; - amdsmi_power_cap_info cap_info = {}; + amdsmi_power_cap_info_t cap_info = {}; ret = amdsmi_get_power_cap_info(device_handles[j], 0, &cap_info); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_power_cap_info:\n"); diff --git a/example/amd_smi_nodrm_example.cc b/example/amd_smi_nodrm_example.cc index 8173b66d78..516dfa2e29 100644 --- a/example/amd_smi_nodrm_example.cc +++ b/example/amd_smi_nodrm_example.cc @@ -286,7 +286,7 @@ int main() { }; // Get device name - amdsmi_board_info board_info = {}; + amdsmi_board_info_t board_info = {}; ret = amdsmi_get_board_info(device_handles[j], &board_info); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_board_info:\n"); @@ -331,7 +331,7 @@ int main() { << "\t\tMM IP Count: " << int(caps_info.mm.mm_ip_count) << "\n\n"; - amdsmi_power_cap_info cap_info = {}; + amdsmi_power_cap_info_t cap_info = {}; ret = amdsmi_get_power_cap_info(device_handles[j], 0, &cap_info); CHK_AMDSMI_RET(ret) printf(" Output of amdsmi_get_power_cap_info:\n"); diff --git a/include/amd_smi/amdsmi.h b/include/amd_smi/amdsmi.h index f51c64a274..bed3b74360 100644 --- a/include/amd_smi/amdsmi.h +++ b/include/amd_smi/amdsmi.h @@ -40,7 +40,6 @@ * DEALINGS WITH THE SOFTWARE. * */ - #ifndef INCLUDE_AMDSMI_H_ #define INCLUDE_AMDSMI_H_ @@ -63,7 +62,7 @@ extern "C" { * * Initialization flags may be OR'd together and passed to ::amdsmi_init(). */ -typedef enum amdsmi_init_flags { +typedef enum { AMDSMI_INIT_ALL_DEVICES = 0x0, // Default option AMDSMI_INIT_AMD_CPUS = (1 << 0), AMDSMI_INIT_AMD_GPUS = (1 << 1), @@ -88,9 +87,14 @@ typedef enum amdsmi_init_flags { #define AMDSMI_TIME_FORMAT "%02d:%02d:%02d.%03d" #define AMDSMI_DATE_FORMAT "%04d-%02d-%02d:%02d:%02d:%02d.%03d" -typedef enum amdsmi_mm_ip { AMDSMI_MM_UVD, AMDSMI_MM_VCE, AMDSMI_MM_VCN, AMDSMI_MM__MAX } amdsmi_mm_ip_t; +typedef enum { + AMDSMI_MM_UVD, + AMDSMI_MM_VCE, + AMDSMI_MM_VCN, + AMDSMI_MM__MAX +} amdsmi_mm_ip_t; -typedef enum amdsmi_container_types { +typedef enum { CONTAINER_LXC, CONTAINER_DOCKER, } amdsmi_container_types_t; @@ -102,7 +106,7 @@ typedef void *amdsmi_socket_handle; /** * @brief Device types detectable by AMD SMI */ -typedef enum device_type { +typedef enum { UNKNOWN = 0, AMD_GPU, AMD_CPU, @@ -115,7 +119,7 @@ typedef enum device_type { */ // Please avoid status codes that are multiples of 256 (256, 512, etc..) // Return values in the shell get modulo 256 applied, meaning any multiple of 256 ends up as 0 -typedef enum amdsmi_status_t { +typedef enum { AMDSMI_STATUS_SUCCESS = 0, //!< Call succeeded // Library usage errors AMDSMI_STATUS_INVAL = 1, //!< Invalid parameters @@ -155,7 +159,7 @@ typedef enum amdsmi_status_t { /** * Clock types */ -typedef enum amdsmi_clk_type { +typedef enum { CLK_TYPE_SYS = 0x0, //!< System clock CLK_TYPE_FIRST = CLK_TYPE_SYS, CLK_TYPE_GFX = CLK_TYPE_SYS, @@ -171,15 +175,12 @@ typedef enum amdsmi_clk_type { 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; -/// @endcond /** * @brief This enumeration is used to indicate from which part of the device a * temperature reading should be obtained. */ -typedef enum amdsmi_temperature_type { +typedef enum { TEMPERATURE_TYPE_EDGE, TEMPERATURE_TYPE_FIRST = TEMPERATURE_TYPE_EDGE, TEMPERATURE_TYPE_JUNCTION, @@ -196,7 +197,7 @@ typedef enum amdsmi_temperature_type { * @brief The values of this enum are used to identify the various firmware * blocks. */ -typedef enum amdsmi_fw_block { +typedef enum { FW_ID_SMU = 1, FW_ID_FIRST = FW_ID_SMU, FW_ID_CP_CE, @@ -254,11 +255,8 @@ typedef struct { uint64_t upper_bound; //!< Upper bound of range uint64_t reserved[2]; } amdsmi_range_t; -/// @cond Ignore in docs. -typedef amdsmi_range_t amdsmi_range; -/// @endcond -typedef struct amdsmi_xgmi_info { +typedef struct { uint8_t xgmi_lanes; uint64_t xgmi_hive_id; uint64_t xgmi_node_id; @@ -269,7 +267,7 @@ typedef struct amdsmi_xgmi_info { /** * GPU Capability info */ -typedef struct amdsmi_gpu_caps { +typedef struct { struct { uint32_t gfxip_major; uint32_t gfxip_minor; @@ -289,18 +287,18 @@ typedef struct amdsmi_gpu_caps { uint32_t reserved[5]; } amdsmi_gpu_caps_t; -typedef struct amdsmi_vram_info { +typedef struct { uint32_t vram_total; uint32_t vram_used; } amdsmi_vram_info_t; -typedef struct amdsmi_frequency_range { +typedef struct { amdsmi_range_t supported_freq_range; amdsmi_range_t current_freq_range; uint32_t reserved[8]; } amdsmi_frequency_range_t; -typedef union amdsmi_bdf { +typedef union { struct { uint64_t function_number : 3; uint64_t device_number : 5; @@ -310,7 +308,7 @@ typedef union amdsmi_bdf { uint64_t as_uint; } amdsmi_bdf_t; -typedef struct amdsmi_power_cap_info { +typedef struct { uint64_t power_cap; uint64_t default_power_cap; uint64_t dpm_cap; @@ -319,7 +317,7 @@ typedef struct amdsmi_power_cap_info { uint64_t reserved[3]; } amdsmi_power_cap_info_t; -typedef struct amdsmi_vbios_info { +typedef struct { char name[AMDSMI_MAX_STRING_LENGTH]; uint32_t vbios_version; char build_date[AMDSMI_MAX_DATE_LENGTH]; @@ -328,7 +326,7 @@ typedef struct amdsmi_vbios_info { uint32_t reserved[15]; } amdsmi_vbios_info_t; -typedef struct amdsmi_fw_info { +typedef struct { uint8_t num_fw_info; struct { amdsmi_fw_block_t fw_id; @@ -338,7 +336,7 @@ typedef struct amdsmi_fw_info { uint32_t reserved[7]; } amdsmi_fw_info_t; -typedef struct amdsmi_asic_info { +typedef struct { char market_name[AMDSMI_MAX_STRING_LENGTH]; uint32_t family; /**< Has zero value */ uint32_t vendor_id; //< Use 32 bit to be compatible with other platform. @@ -348,7 +346,7 @@ typedef struct amdsmi_asic_info { char asic_serial[AMDSMI_NORMAL_STRING_LENGTH]; } amdsmi_asic_info_t; -typedef struct amdsmi_board_info { +typedef struct { uint64_t serial_number; bool is_master; char model_number[AMDSMI_NORMAL_STRING_LENGTH]; @@ -358,7 +356,7 @@ typedef struct amdsmi_board_info { char manufacturer_name[AMDSMI_NORMAL_STRING_LENGTH]; } amdsmi_board_info_t; -typedef struct amdsmi_power_measure { +typedef struct { uint32_t average_socket_power; uint64_t energy_accumulator; // v1 mod. (32->64) uint32_t voltage_gfx; // GFX voltage measurement in mV @@ -368,7 +366,7 @@ typedef struct amdsmi_power_measure { uint32_t reserved[9]; } amdsmi_power_measure_t; -typedef struct amdsmi_clk_measure { +typedef struct { uint32_t cur_clk; uint32_t avg_clk; uint32_t min_clk; @@ -376,7 +374,7 @@ typedef struct amdsmi_clk_measure { uint32_t reserved[4]; } amdsmi_clk_measure_t; -typedef struct amdsmi_engine_usage { +typedef struct { uint32_t gfx_activity; uint32_t umc_activity; uint32_t mm_activity[AMDSMI_MAX_MM_IP_COUNT]; @@ -385,7 +383,7 @@ typedef struct amdsmi_engine_usage { typedef uint32_t amdsmi_process_handle; -typedef struct amdsmi_process_info { +typedef struct { char name[AMDSMI_NORMAL_STRING_LENGTH]; amdsmi_process_handle pid; uint64_t mem; /** in bytes */ @@ -440,9 +438,7 @@ typedef enum { AMDSMI_DEV_PERF_LEVEL_UNKNOWN = 0x100 //!< Unknown performance level } amdsmi_dev_perf_level_t; -/// @cond Ignore in docs. -typedef amdsmi_dev_perf_level_t amdsmi_dev_perf_level; -/// @endcond + /** * @brief Available clock types. */ @@ -640,9 +636,6 @@ typedef enum { AMDSMI_TEMP_LAST = AMDSMI_TEMP_HIGHEST } amdsmi_temperature_metric_t; -/// @cond Ignore in docs. -typedef amdsmi_temperature_metric_t amdsmi_temperature_metric; -/// @endcond /** * @brief Voltage Metrics. This enum is used to identify various @@ -698,9 +691,6 @@ typedef enum { //!< Invalid power profile AMDSMI_PWR_PROF_PRST_INVALID = 0xFFFFFFFFFFFFFFFF } amdsmi_power_profile_preset_masks_t; -/// @cond Ignore in docs. -typedef amdsmi_power_profile_preset_masks_t amdsmi_power_profile_preset_masks; -/// @endcond /** * @brief This enum is used to identify different GPU blocks. @@ -729,9 +719,6 @@ typedef enum { //!< for supported blocks AMDSMI_GPU_BLOCK_RESERVED = 0x8000000000000000 } amdsmi_gpu_block_t; -/// @cond Ignore in docs. -typedef amdsmi_gpu_block_t amdsmi_gpu_block; -/// @endcond /** * @brief The current ECC state @@ -771,9 +758,6 @@ typedef enum { AMDSMI_FREQ_IND_MAX = 1, //!< Index used for the maximum frequency value AMDSMI_FREQ_IND_INVALID = 0xFFFFFFFF //!< An invalid frequency index } amdsmi_freq_ind_t; -/// @cond Ignore in docs. -typedef amdsmi_freq_ind_t amdsmi_freq_ind; -/// @endcond /** * @brief XGMI Status @@ -788,9 +772,6 @@ typedef enum { * @brief Bitfield used in various AMDSMI calls */ typedef uint64_t amdsmi_bit_field_t; -/// @cond Ignore in docs. -typedef amdsmi_bit_field_t amdsmi_bit_field; -/// @endcond /** * @brief Reserved Memory Page States @@ -807,7 +788,7 @@ typedef enum { /** * @brief Types for IO Link */ -typedef enum _AMDSMI_IO_LINK_TYPE { +typedef enum { AMDSMI_IOLINK_TYPE_UNDEFINED = 0, //!< unknown type. AMDSMI_IOLINK_TYPE_PCIEXPRESS = 1, //!< PCI Express AMDSMI_IOLINK_TYPE_XGMI = 2, //!< XGMI @@ -829,7 +810,7 @@ typedef enum { /** * @brief The utilization counter data */ -typedef struct { +typedef struct { AMDSMI_UTILIZATION_COUNTER_TYPE type; //!< Utilization counter type uint64_t value; //!< Utilization counter value } amdsmi_utilization_counter_t; @@ -869,9 +850,6 @@ typedef struct { */ uint32_t num_profiles; } amdsmi_power_profile_status_t; -/// @cond Ignore in docs. -typedef amdsmi_power_profile_status_t amdsmi_power_profile_status; -/// @endcond /** * @brief This structure holds information about clock frequencies. @@ -893,9 +871,6 @@ typedef struct { */ uint64_t frequency[AMDSMI_MAX_NUM_FREQUENCIES]; } amdsmi_frequencies_t; -/// @cond Ignore in docs. -typedef amdsmi_frequencies_t amdsmi_frequencies; -/// @endcond /** * @brief This structure holds information about the possible PCIe @@ -915,10 +890,6 @@ typedef struct { uint32_t lanes[AMDSMI_MAX_NUM_FREQUENCIES]; } amdsmi_pcie_bandwidth_t; -/// @cond Ignore in docs. -typedef amdsmi_pcie_bandwidth_t amdsmi_pcie_bandwidth; -/// @endcond - /** * @brief This structure holds version information. */ @@ -929,9 +900,6 @@ typedef struct { const char *build; //!< Build string uint32_t reserved[4]; } amdsmi_version_t; -/// @cond Ignore in docs. -typedef amdsmi_version_t amdsmi_version; -/// @endcond /** * @brief This structure represents a point on the frequency-voltage plane. @@ -940,9 +908,6 @@ typedef struct { uint64_t frequency; //!< Frequency coordinate (in Hz) uint64_t voltage; //!< Voltage coordinate (in mV) } amdsmi_od_vddc_point_t; -/// @cond Ignore in docs. -typedef amdsmi_od_vddc_point_t amdsmi_od_vddc_point; -/// @endcond /** * @brief This structure holds 2 ::amdsmi_range_t's, one for frequency and one for @@ -953,9 +918,6 @@ typedef struct { amdsmi_range_t freq_range; //!< The frequency range for this VDDC Curve point amdsmi_range_t volt_range; //!< The voltage range for this VDDC Curve point } amdsmi_freq_volt_region_t; -/// @cond Ignore in docs. -typedef amdsmi_freq_volt_region_t amdsmi_freq_volt_region; -/// @endcond /** * ::AMDSMI_NUM_VOLTAGE_CURVE_POINTS number of ::amdsmi_od_vddc_point_t's @@ -967,9 +929,6 @@ typedef struct { */ amdsmi_od_vddc_point_t vc_points[AMDSMI_NUM_VOLTAGE_CURVE_POINTS]; } amdsmi_od_volt_curve_t; -/// @cond Ignore in docs. -typedef amdsmi_od_volt_curve_t amdsmi_od_volt_curve; -/// @endcond /** * @brief This structure holds the frequency-voltage values for a device. @@ -987,10 +946,6 @@ typedef struct { amdsmi_od_volt_curve_t curve; uint32_t num_regions; //!< The number of voltage curve regions } amdsmi_od_volt_freq_data_t; -/// @cond Ignore in docs. -typedef amdsmi_od_volt_freq_data_t amdsmi_od_volt_freq_data; -/// @endcond - /** * @brief The following structures hold the gpu metrics values for a device. @@ -999,14 +954,14 @@ typedef amdsmi_od_volt_freq_data_t amdsmi_od_volt_freq_data; /** * @brief Size and version information of metrics data */ -struct amd_metrics_table_header_t { +typedef struct { // TODO(amd) Doxygen documents /// @cond Ignore in docs. uint16_t structure_size; uint8_t format_revision; uint8_t content_revision; /// @endcond -}; +} amd_metrics_table_header_t; /** * @brief The following structure holds the gpu metrics values for a device. @@ -1033,7 +988,7 @@ struct amd_metrics_table_header_t { typedef struct { // TODO(amd) Doxygen documents /// @cond Ignore in docs. - struct amd_metrics_table_header_t common_header; + amd_metrics_table_header_t common_header; /* Temperature */ uint16_t temperature_edge; @@ -1103,7 +1058,7 @@ typedef struct { /** * @brief This structure holds pcie info. */ -typedef struct amdsmi_pcie_info { +typedef struct { uint16_t pcie_lanes; uint32_t pcie_speed; uint32_t reserved[6]; @@ -1133,7 +1088,7 @@ typedef struct amdsmi_func_id_iter_handle * amdsmi_func_id_iter_handle_t; * value may be a function name, or an ennumerated variant value of types * such as ::amdsmi_memory_type_t, ::amdsmi_temperature_metric_t, etc. */ -typedef union amd_id { +typedef union { uint64_t id; //!< uint64_t representation of value const char *name; //!< name string (applicable to functions only) union { @@ -1848,7 +1803,7 @@ amdsmi_get_bad_page_info(amdsmi_device_handle device_handle, uint32_t *num_pages * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_ras_block_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_t block, amdsmi_ras_err_state_t *state); /** diff --git a/py-interface/amdsmi_interface.py b/py-interface/amdsmi_interface.py index fbf122ab8a..14f26a7617 100644 --- a/py-interface/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -421,10 +421,10 @@ def _format_bdf(amdsmi_bdf: amdsmi_wrapper.amdsmi_bdf_t) -> str: 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:] + domain = hex(amdsmi_bdf.c__UA_amdsmi_bdf_t_0.domain_number)[2:].zfill(4) + bus = hex(amdsmi_bdf.c__UA_amdsmi_bdf_t_0.bus_number)[2:].zfill(2) + device = hex(amdsmi_bdf.c__UA_amdsmi_bdf_t_0.device_number)[2:].zfill(2) + function = hex(amdsmi_bdf.c__UA_amdsmi_bdf_t_0.function_number)[2:] return domain + ":" + bus + ":" + device + "." + function @@ -470,11 +470,11 @@ def _parse_bdf(bdf): def _make_amdsmi_bdf_from_list(bdf): if len(bdf) != 4: return None - amdsmi_bdf = amdsmi_wrapper.amdsmi_bdf() - amdsmi_bdf.amdsmi_bdf_0.function_number = bdf[3] - amdsmi_bdf.amdsmi_bdf_0.device_number = bdf[2] - amdsmi_bdf.amdsmi_bdf_0.bus_number = bdf[1] - amdsmi_bdf.amdsmi_bdf_0.domain_number = bdf[0] + amdsmi_bdf = amdsmi_wrapper.amdsmi_bdf_t() + amdsmi_bdf.c__UA_amdsmi_bdf_t_0.function_number = bdf[3] + amdsmi_bdf.c__UA_amdsmi_bdf_t_0.device_number = bdf[2] + amdsmi_bdf.c__UA_amdsmi_bdf_t_0.bus_number = bdf[1] + amdsmi_bdf.c__UA_amdsmi_bdf_t_0.domain_number = bdf[0] return amdsmi_bdf diff --git a/py-interface/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py index fff007ef14..6e88431c22 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -171,8 +171,8 @@ _libraries['libamd_smi.so'] = ctypes.CDLL(os.path.join(os.path.dirname(__file__) -# values for enumeration 'amdsmi_init_flags' -amdsmi_init_flags__enumvalues = { +# values for enumeration 'c__EA_amdsmi_init_flags_t' +c__EA_amdsmi_init_flags_t__enumvalues = { 0: 'AMDSMI_INIT_ALL_DEVICES', 1: 'AMDSMI_INIT_AMD_CPUS', 2: 'AMDSMI_INIT_AMD_GPUS', @@ -184,12 +184,12 @@ 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 +c__EA_amdsmi_init_flags_t = ctypes.c_uint32 # enum +amdsmi_init_flags_t = c__EA_amdsmi_init_flags_t +amdsmi_init_flags_t__enumvalues = c__EA_amdsmi_init_flags_t__enumvalues -# values for enumeration 'amdsmi_mm_ip' -amdsmi_mm_ip__enumvalues = { +# values for enumeration 'c__EA_amdsmi_mm_ip_t' +c__EA_amdsmi_mm_ip_t__enumvalues = { 0: 'AMDSMI_MM_UVD', 1: 'AMDSMI_MM_VCE', 2: 'AMDSMI_MM_VCN', @@ -199,25 +199,25 @@ AMDSMI_MM_UVD = 0 AMDSMI_MM_VCE = 1 AMDSMI_MM_VCN = 2 AMDSMI_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 +c__EA_amdsmi_mm_ip_t = ctypes.c_uint32 # enum +amdsmi_mm_ip_t = c__EA_amdsmi_mm_ip_t +amdsmi_mm_ip_t__enumvalues = c__EA_amdsmi_mm_ip_t__enumvalues -# values for enumeration 'amdsmi_container_types' -amdsmi_container_types__enumvalues = { +# values for enumeration 'c__EA_amdsmi_container_types_t' +c__EA_amdsmi_container_types_t__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 +c__EA_amdsmi_container_types_t = ctypes.c_uint32 # enum +amdsmi_container_types_t = c__EA_amdsmi_container_types_t +amdsmi_container_types_t__enumvalues = c__EA_amdsmi_container_types_t__enumvalues amdsmi_device_handle = ctypes.POINTER(None) amdsmi_socket_handle = ctypes.POINTER(None) -# values for enumeration 'device_type' -device_type__enumvalues = { +# values for enumeration 'c__EA_device_type_t' +c__EA_device_type_t__enumvalues = { 0: 'UNKNOWN', 1: 'AMD_GPU', 2: 'AMD_CPU', @@ -229,12 +229,12 @@ 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 +c__EA_device_type_t = ctypes.c_uint32 # enum +device_type_t = c__EA_device_type_t +device_type_t__enumvalues = c__EA_device_type_t__enumvalues -# values for enumeration 'amdsmi_status_t' -amdsmi_status_t__enumvalues = { +# values for enumeration 'c__EA_amdsmi_status_t' +c__EA_amdsmi_status_t__enumvalues = { 0: 'AMDSMI_STATUS_SUCCESS', 1: 'AMDSMI_STATUS_INVAL', 2: 'AMDSMI_STATUS_NOT_SUPPORTED', @@ -296,10 +296,12 @@ AMDSMI_STATUS_UNEXPECTED_SIZE = 42 AMDSMI_STATUS_UNEXPECTED_DATA = 43 AMDSMI_STATUS_MAP_ERROR = 4294967294 AMDSMI_STATUS_UNKNOWN_ERROR = 4294967295 -amdsmi_status_t = ctypes.c_uint32 # enum +c__EA_amdsmi_status_t = ctypes.c_uint32 # enum +amdsmi_status_t = c__EA_amdsmi_status_t +amdsmi_status_t__enumvalues = c__EA_amdsmi_status_t__enumvalues -# values for enumeration 'amdsmi_clk_type' -amdsmi_clk_type__enumvalues = { +# values for enumeration 'c__EA_amdsmi_clk_type_t' +c__EA_amdsmi_clk_type_t__enumvalues = { 0: 'CLK_TYPE_SYS', 0: 'CLK_TYPE_FIRST', 0: 'CLK_TYPE_GFX', @@ -327,12 +329,12 @@ 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 +c__EA_amdsmi_clk_type_t = ctypes.c_uint32 # enum +amdsmi_clk_type_t = c__EA_amdsmi_clk_type_t +amdsmi_clk_type_t__enumvalues = c__EA_amdsmi_clk_type_t__enumvalues -# values for enumeration 'amdsmi_temperature_type' -amdsmi_temperature_type__enumvalues = { +# values for enumeration 'c__EA_amdsmi_temperature_type_t' +c__EA_amdsmi_temperature_type_t__enumvalues = { 0: 'TEMPERATURE_TYPE_EDGE', 0: 'TEMPERATURE_TYPE_FIRST', 1: 'TEMPERATURE_TYPE_JUNCTION', @@ -354,12 +356,12 @@ 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 +c__EA_amdsmi_temperature_type_t = ctypes.c_uint32 # enum +amdsmi_temperature_type_t = c__EA_amdsmi_temperature_type_t +amdsmi_temperature_type_t__enumvalues = c__EA_amdsmi_temperature_type_t__enumvalues -# values for enumeration 'amdsmi_fw_block' -amdsmi_fw_block__enumvalues = { +# values for enumeration 'c__EA_amdsmi_fw_block_t' +c__EA_amdsmi_fw_block_t__enumvalues = { 1: 'FW_ID_SMU', 1: 'FW_ID_FIRST', 2: 'FW_ID_CP_CE', @@ -455,9 +457,9 @@ 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 +c__EA_amdsmi_fw_block_t = ctypes.c_uint32 # enum +amdsmi_fw_block_t = c__EA_amdsmi_fw_block_t +amdsmi_fw_block_t__enumvalues = c__EA_amdsmi_fw_block_t__enumvalues class struct_c__SA_amdsmi_range_t(Structure): pass @@ -469,12 +471,11 @@ struct_c__SA_amdsmi_range_t._fields_ = [ ] amdsmi_range_t = struct_c__SA_amdsmi_range_t -amdsmi_range = struct_c__SA_amdsmi_range_t -class struct_amdsmi_xgmi_info(Structure): +class struct_c__SA_amdsmi_xgmi_info_t(Structure): pass -struct_amdsmi_xgmi_info._pack_ = 1 # source:False -struct_amdsmi_xgmi_info._fields_ = [ +struct_c__SA_amdsmi_xgmi_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_xgmi_info_t._fields_ = [ ('xgmi_lanes', ctypes.c_ubyte), ('PADDING_0', ctypes.c_ubyte * 7), ('xgmi_hive_id', ctypes.c_uint64), @@ -483,26 +484,26 @@ struct_amdsmi_xgmi_info._fields_ = [ ('reserved', ctypes.c_uint32 * 9), ] -amdsmi_xgmi_info_t = struct_amdsmi_xgmi_info -class struct_amdsmi_gpu_caps(Structure): +amdsmi_xgmi_info_t = struct_c__SA_amdsmi_xgmi_info_t +class struct_c__SA_amdsmi_gpu_caps_t(Structure): pass -class struct_amdsmi_gpu_caps_1(Structure): +class struct_c__SA_amdsmi_gpu_caps_t_1(Structure): pass -struct_amdsmi_gpu_caps_1._pack_ = 1 # source:False -struct_amdsmi_gpu_caps_1._fields_ = [ +struct_c__SA_amdsmi_gpu_caps_t_1._pack_ = 1 # source:False +struct_c__SA_amdsmi_gpu_caps_t_1._fields_ = [ ('mm_ip_count', ctypes.c_ubyte), ('mm_ip_list', ctypes.c_ubyte * 8), ('PADDING_0', ctypes.c_ubyte * 3), ('reserved', ctypes.c_uint32 * 5), ] -class struct_amdsmi_gpu_caps_0(Structure): +class struct_c__SA_amdsmi_gpu_caps_t_0(Structure): pass -struct_amdsmi_gpu_caps_0._pack_ = 1 # source:False -struct_amdsmi_gpu_caps_0._fields_ = [ +struct_c__SA_amdsmi_gpu_caps_t_0._pack_ = 1 # source:False +struct_c__SA_amdsmi_gpu_caps_t_0._fields_ = [ ('gfxip_major', ctypes.c_uint32), ('gfxip_minor', ctypes.c_uint32), ('gfxip_cu_count', ctypes.c_uint16), @@ -510,10 +511,10 @@ struct_amdsmi_gpu_caps_0._fields_ = [ ('reserved', ctypes.c_uint32 * 5), ] -struct_amdsmi_gpu_caps._pack_ = 1 # source:False -struct_amdsmi_gpu_caps._fields_ = [ - ('gfx', struct_amdsmi_gpu_caps_0), - ('mm', struct_amdsmi_gpu_caps_1), +struct_c__SA_amdsmi_gpu_caps_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_gpu_caps_t._fields_ = [ + ('gfx', struct_c__SA_amdsmi_gpu_caps_t_0), + ('mm', struct_c__SA_amdsmi_gpu_caps_t_1), ('ras_supported', ctypes.c_bool), ('max_vf_num', ctypes.c_ubyte), ('PADDING_0', ctypes.c_ubyte * 2), @@ -522,54 +523,54 @@ struct_amdsmi_gpu_caps._fields_ = [ ('reserved', ctypes.c_uint32 * 5), ] -amdsmi_gpu_caps_t = struct_amdsmi_gpu_caps -class struct_amdsmi_vram_info(Structure): +amdsmi_gpu_caps_t = struct_c__SA_amdsmi_gpu_caps_t +class struct_c__SA_amdsmi_vram_info_t(Structure): pass -struct_amdsmi_vram_info._pack_ = 1 # source:False -struct_amdsmi_vram_info._fields_ = [ +struct_c__SA_amdsmi_vram_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_vram_info_t._fields_ = [ ('vram_total', ctypes.c_uint32), ('vram_used', ctypes.c_uint32), ] -amdsmi_vram_info_t = struct_amdsmi_vram_info -class struct_amdsmi_frequency_range(Structure): +amdsmi_vram_info_t = struct_c__SA_amdsmi_vram_info_t +class struct_c__SA_amdsmi_frequency_range_t(Structure): pass -struct_amdsmi_frequency_range._pack_ = 1 # source:False -struct_amdsmi_frequency_range._fields_ = [ +struct_c__SA_amdsmi_frequency_range_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_frequency_range_t._fields_ = [ ('supported_freq_range', amdsmi_range_t), ('current_freq_range', amdsmi_range_t), ('reserved', ctypes.c_uint32 * 8), ] -amdsmi_frequency_range_t = struct_amdsmi_frequency_range -class union_amdsmi_bdf(Union): +amdsmi_frequency_range_t = struct_c__SA_amdsmi_frequency_range_t +class union_c__UA_amdsmi_bdf_t(Union): pass -class struct_amdsmi_bdf_0(Structure): +class struct_c__UA_amdsmi_bdf_t_0(Structure): pass -struct_amdsmi_bdf_0._pack_ = 1 # source:False -struct_amdsmi_bdf_0._fields_ = [ +struct_c__UA_amdsmi_bdf_t_0._pack_ = 1 # source:False +struct_c__UA_amdsmi_bdf_t_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), ] -union_amdsmi_bdf._pack_ = 1 # source:False -union_amdsmi_bdf._fields_ = [ - ('amdsmi_bdf_0', struct_amdsmi_bdf_0), +union_c__UA_amdsmi_bdf_t._pack_ = 1 # source:False +union_c__UA_amdsmi_bdf_t._fields_ = [ + ('c__UA_amdsmi_bdf_t_0', struct_c__UA_amdsmi_bdf_t_0), ('as_uint', ctypes.c_uint64), ] -amdsmi_bdf_t = union_amdsmi_bdf -class struct_amdsmi_power_cap_info(Structure): +amdsmi_bdf_t = union_c__UA_amdsmi_bdf_t +class struct_c__SA_amdsmi_power_cap_info_t(Structure): pass -struct_amdsmi_power_cap_info._pack_ = 1 # source:False -struct_amdsmi_power_cap_info._fields_ = [ +struct_c__SA_amdsmi_power_cap_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_power_cap_info_t._fields_ = [ ('power_cap', ctypes.c_uint64), ('default_power_cap', ctypes.c_uint64), ('dpm_cap', ctypes.c_uint64), @@ -578,12 +579,12 @@ struct_amdsmi_power_cap_info._fields_ = [ ('reserved', ctypes.c_uint64 * 3), ] -amdsmi_power_cap_info_t = struct_amdsmi_power_cap_info -class struct_amdsmi_vbios_info(Structure): +amdsmi_power_cap_info_t = struct_c__SA_amdsmi_power_cap_info_t +class struct_c__SA_amdsmi_vbios_info_t(Structure): pass -struct_amdsmi_vbios_info._pack_ = 1 # source:False -struct_amdsmi_vbios_info._fields_ = [ +struct_c__SA_amdsmi_vbios_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_vbios_info_t._fields_ = [ ('name', ctypes.c_char * 64), ('vbios_version', ctypes.c_uint32), ('build_date', ctypes.c_char * 32), @@ -592,36 +593,36 @@ struct_amdsmi_vbios_info._fields_ = [ ('reserved', ctypes.c_uint32 * 15), ] -amdsmi_vbios_info_t = struct_amdsmi_vbios_info -class struct_amdsmi_fw_info(Structure): +amdsmi_vbios_info_t = struct_c__SA_amdsmi_vbios_info_t +class struct_c__SA_amdsmi_fw_info_t(Structure): pass -class struct_amdsmi_fw_info_0(Structure): +class struct_c__SA_amdsmi_fw_info_t_0(Structure): pass -struct_amdsmi_fw_info_0._pack_ = 1 # source:False -struct_amdsmi_fw_info_0._fields_ = [ +struct_c__SA_amdsmi_fw_info_t_0._pack_ = 1 # source:False +struct_c__SA_amdsmi_fw_info_t_0._fields_ = [ ('fw_id', amdsmi_fw_block_t), ('PADDING_0', ctypes.c_ubyte * 4), ('fw_version', ctypes.c_uint64), ('reserved', ctypes.c_uint64 * 2), ] -struct_amdsmi_fw_info._pack_ = 1 # source:False -struct_amdsmi_fw_info._fields_ = [ +struct_c__SA_amdsmi_fw_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_fw_info_t._fields_ = [ ('num_fw_info', ctypes.c_ubyte), ('PADDING_0', ctypes.c_ubyte * 7), - ('fw_info_list', struct_amdsmi_fw_info_0 * 46), + ('fw_info_list', struct_c__SA_amdsmi_fw_info_t_0 * 46), ('reserved', ctypes.c_uint32 * 7), ('PADDING_1', ctypes.c_ubyte * 4), ] -amdsmi_fw_info_t = struct_amdsmi_fw_info -class struct_amdsmi_asic_info(Structure): +amdsmi_fw_info_t = struct_c__SA_amdsmi_fw_info_t +class struct_c__SA_amdsmi_asic_info_t(Structure): pass -struct_amdsmi_asic_info._pack_ = 1 # source:False -struct_amdsmi_asic_info._fields_ = [ +struct_c__SA_amdsmi_asic_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_asic_info_t._fields_ = [ ('market_name', ctypes.c_char * 64), ('family', ctypes.c_uint32), ('vendor_id', ctypes.c_uint32), @@ -633,12 +634,12 @@ struct_amdsmi_asic_info._fields_ = [ ('PADDING_1', ctypes.c_ubyte * 4), ] -amdsmi_asic_info_t = struct_amdsmi_asic_info -class struct_amdsmi_board_info(Structure): +amdsmi_asic_info_t = struct_c__SA_amdsmi_asic_info_t +class struct_c__SA_amdsmi_board_info_t(Structure): pass -struct_amdsmi_board_info._pack_ = 1 # source:False -struct_amdsmi_board_info._fields_ = [ +struct_c__SA_amdsmi_board_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_board_info_t._fields_ = [ ('serial_number', ctypes.c_uint64), ('is_master', ctypes.c_bool), ('model_number', ctypes.c_char * 32), @@ -649,12 +650,12 @@ struct_amdsmi_board_info._fields_ = [ ('PADDING_0', ctypes.c_ubyte * 7), ] -amdsmi_board_info_t = struct_amdsmi_board_info -class struct_amdsmi_power_measure(Structure): +amdsmi_board_info_t = struct_c__SA_amdsmi_board_info_t +class struct_c__SA_amdsmi_power_measure_t(Structure): pass -struct_amdsmi_power_measure._pack_ = 1 # source:False -struct_amdsmi_power_measure._fields_ = [ +struct_c__SA_amdsmi_power_measure_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_power_measure_t._fields_ = [ ('average_socket_power', ctypes.c_uint32), ('PADDING_0', ctypes.c_ubyte * 4), ('energy_accumulator', ctypes.c_uint64), @@ -666,12 +667,12 @@ struct_amdsmi_power_measure._fields_ = [ ('PADDING_1', ctypes.c_ubyte * 4), ] -amdsmi_power_measure_t = struct_amdsmi_power_measure -class struct_amdsmi_clk_measure(Structure): +amdsmi_power_measure_t = struct_c__SA_amdsmi_power_measure_t +class struct_c__SA_amdsmi_clk_measure_t(Structure): pass -struct_amdsmi_clk_measure._pack_ = 1 # source:False -struct_amdsmi_clk_measure._fields_ = [ +struct_c__SA_amdsmi_clk_measure_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_clk_measure_t._fields_ = [ ('cur_clk', ctypes.c_uint32), ('avg_clk', ctypes.c_uint32), ('min_clk', ctypes.c_uint32), @@ -679,38 +680,38 @@ struct_amdsmi_clk_measure._fields_ = [ ('reserved', ctypes.c_uint32 * 4), ] -amdsmi_clk_measure_t = struct_amdsmi_clk_measure -class struct_amdsmi_engine_usage(Structure): +amdsmi_clk_measure_t = struct_c__SA_amdsmi_clk_measure_t +class struct_c__SA_amdsmi_engine_usage_t(Structure): pass -struct_amdsmi_engine_usage._pack_ = 1 # source:False -struct_amdsmi_engine_usage._fields_ = [ +struct_c__SA_amdsmi_engine_usage_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_engine_usage_t._fields_ = [ ('gfx_activity', ctypes.c_uint32), ('umc_activity', ctypes.c_uint32), ('mm_activity', ctypes.c_uint32 * 8), ('reserved', ctypes.c_uint32 * 6), ] -amdsmi_engine_usage_t = struct_amdsmi_engine_usage +amdsmi_engine_usage_t = struct_c__SA_amdsmi_engine_usage_t amdsmi_process_handle = ctypes.c_uint32 -class struct_amdsmi_process_info(Structure): +class struct_c__SA_amdsmi_proc_info_t(Structure): pass -class struct_amdsmi_process_info_1(Structure): +class struct_c__SA_amdsmi_proc_info_t_1(Structure): pass -struct_amdsmi_process_info_1._pack_ = 1 # source:False -struct_amdsmi_process_info_1._fields_ = [ +struct_c__SA_amdsmi_proc_info_t_1._pack_ = 1 # source:False +struct_c__SA_amdsmi_proc_info_t_1._fields_ = [ ('gtt_mem', ctypes.c_uint64), ('cpu_mem', ctypes.c_uint64), ('vram_mem', ctypes.c_uint64), ] -class struct_amdsmi_process_info_0(Structure): +class struct_c__SA_amdsmi_proc_info_t_0(Structure): pass -struct_amdsmi_process_info_0._pack_ = 1 # source:False -struct_amdsmi_process_info_0._fields_ = [ +struct_c__SA_amdsmi_proc_info_t_0._pack_ = 1 # source:False +struct_c__SA_amdsmi_proc_info_t_0._fields_ = [ ('gfx', ctypes.c_uint16 * 8), ('compute', ctypes.c_uint16 * 8), ('sdma', ctypes.c_uint16 * 8), @@ -718,19 +719,19 @@ struct_amdsmi_process_info_0._fields_ = [ ('dec', ctypes.c_uint16 * 8), ] -struct_amdsmi_process_info._pack_ = 1 # source:False -struct_amdsmi_process_info._fields_ = [ +struct_c__SA_amdsmi_proc_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_proc_info_t._fields_ = [ ('name', ctypes.c_char * 32), ('pid', ctypes.c_uint32), ('PADDING_0', ctypes.c_ubyte * 4), ('mem', ctypes.c_uint64), - ('engine_usage', struct_amdsmi_process_info_0), - ('memory_usage', struct_amdsmi_process_info_1), + ('engine_usage', struct_c__SA_amdsmi_proc_info_t_0), + ('memory_usage', struct_c__SA_amdsmi_proc_info_t_1), ('container_name', ctypes.c_char * 32), ('reserved', ctypes.c_uint32 * 10), ] -amdsmi_proc_info_t = struct_amdsmi_process_info +amdsmi_proc_info_t = struct_c__SA_amdsmi_proc_info_t # values for enumeration 'c__EA_amdsmi_dev_perf_level_t' c__EA_amdsmi_dev_perf_level_t__enumvalues = { @@ -762,8 +763,6 @@ 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 = { @@ -930,8 +929,6 @@ 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 = { @@ -999,8 +996,6 @@ 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 = { @@ -1044,8 +1039,6 @@ 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 = { @@ -1101,8 +1094,6 @@ 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 = { @@ -1117,7 +1108,6 @@ 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 = { @@ -1132,8 +1122,8 @@ 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 = { +# values for enumeration 'c__EA_AMDSMI_IO_LINK_TYPE' +c__EA_AMDSMI_IO_LINK_TYPE__enumvalues = { 0: 'AMDSMI_IOLINK_TYPE_UNDEFINED', 1: 'AMDSMI_IOLINK_TYPE_PCIEXPRESS', 2: 'AMDSMI_IOLINK_TYPE_XGMI', @@ -1145,9 +1135,9 @@ 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 +c__EA_AMDSMI_IO_LINK_TYPE = ctypes.c_uint32 # enum +AMDSMI_IO_LINK_TYPE = c__EA_AMDSMI_IO_LINK_TYPE +AMDSMI_IO_LINK_TYPE__enumvalues = c__EA_AMDSMI_IO_LINK_TYPE__enumvalues # values for enumeration 'c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE' c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE__enumvalues = { @@ -1198,7 +1188,6 @@ struct_c__SA_amdsmi_power_profile_status_t._fields_ = [ ] amdsmi_power_profile_status_t = struct_c__SA_amdsmi_power_profile_status_t -amdsmi_power_profile_status = struct_c__SA_amdsmi_power_profile_status_t class struct_c__SA_amdsmi_frequencies_t(Structure): pass @@ -1210,7 +1199,6 @@ struct_c__SA_amdsmi_frequencies_t._fields_ = [ ] amdsmi_frequencies_t = struct_c__SA_amdsmi_frequencies_t -amdsmi_frequencies = struct_c__SA_amdsmi_frequencies_t class struct_c__SA_amdsmi_pcie_bandwidth_t(Structure): pass @@ -1221,7 +1209,6 @@ struct_c__SA_amdsmi_pcie_bandwidth_t._fields_ = [ ] amdsmi_pcie_bandwidth_t = struct_c__SA_amdsmi_pcie_bandwidth_t -amdsmi_pcie_bandwidth = struct_c__SA_amdsmi_pcie_bandwidth_t class struct_c__SA_amdsmi_version_t(Structure): pass @@ -1236,7 +1223,6 @@ struct_c__SA_amdsmi_version_t._fields_ = [ ] amdsmi_version_t = struct_c__SA_amdsmi_version_t -amdsmi_version = struct_c__SA_amdsmi_version_t class struct_c__SA_amdsmi_od_vddc_point_t(Structure): pass @@ -1247,7 +1233,6 @@ struct_c__SA_amdsmi_od_vddc_point_t._fields_ = [ ] amdsmi_od_vddc_point_t = struct_c__SA_amdsmi_od_vddc_point_t -amdsmi_od_vddc_point = struct_c__SA_amdsmi_od_vddc_point_t class struct_c__SA_amdsmi_freq_volt_region_t(Structure): _pack_ = 1 # source:False _fields_ = [ @@ -1256,7 +1241,6 @@ class struct_c__SA_amdsmi_freq_volt_region_t(Structure): ] amdsmi_freq_volt_region_t = struct_c__SA_amdsmi_freq_volt_region_t -amdsmi_freq_volt_region = struct_c__SA_amdsmi_freq_volt_region_t class struct_c__SA_amdsmi_od_volt_curve_t(Structure): _pack_ = 1 # source:False _fields_ = [ @@ -1264,7 +1248,6 @@ class struct_c__SA_amdsmi_od_volt_curve_t(Structure): ] amdsmi_od_volt_curve_t = struct_c__SA_amdsmi_od_volt_curve_t -amdsmi_od_volt_curve = struct_c__SA_amdsmi_od_volt_curve_t class struct_c__SA_amdsmi_od_volt_freq_data_t(Structure): pass @@ -1280,23 +1263,23 @@ struct_c__SA_amdsmi_od_volt_freq_data_t._fields_ = [ ] amdsmi_od_volt_freq_data_t = struct_c__SA_amdsmi_od_volt_freq_data_t -amdsmi_od_volt_freq_data = struct_c__SA_amdsmi_od_volt_freq_data_t -class struct_amd_metrics_table_header_t(Structure): +class struct_c__SA_amd_metrics_table_header_t(Structure): pass -struct_amd_metrics_table_header_t._pack_ = 1 # source:False -struct_amd_metrics_table_header_t._fields_ = [ +struct_c__SA_amd_metrics_table_header_t._pack_ = 1 # source:False +struct_c__SA_amd_metrics_table_header_t._fields_ = [ ('structure_size', ctypes.c_uint16), ('format_revision', ctypes.c_ubyte), ('content_revision', ctypes.c_ubyte), ] +amd_metrics_table_header_t = struct_c__SA_amd_metrics_table_header_t class struct_c__SA_amdsmi_gpu_metrics_t(Structure): pass struct_c__SA_amdsmi_gpu_metrics_t._pack_ = 1 # source:False struct_c__SA_amdsmi_gpu_metrics_t._fields_ = [ - ('common_header', struct_amd_metrics_table_header_t), + ('common_header', amd_metrics_table_header_t), ('temperature_edge', ctypes.c_uint16), ('temperature_hotspot', ctypes.c_uint16), ('temperature_mem', ctypes.c_uint16), @@ -1345,18 +1328,18 @@ struct_c__SA_amdsmi_error_count_t._fields_ = [ ] amdsmi_error_count_t = struct_c__SA_amdsmi_error_count_t -class struct_amdsmi_pcie_info(Structure): +class struct_c__SA_amdsmi_pcie_info_t(Structure): pass -struct_amdsmi_pcie_info._pack_ = 1 # source:False -struct_amdsmi_pcie_info._fields_ = [ +struct_c__SA_amdsmi_pcie_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_pcie_info_t._fields_ = [ ('pcie_lanes', ctypes.c_uint16), ('PADDING_0', ctypes.c_ubyte * 2), ('pcie_speed', ctypes.c_uint32), ('reserved', ctypes.c_uint32 * 6), ] -amdsmi_pcie_info_t = struct_amdsmi_pcie_info +amdsmi_pcie_info_t = struct_c__SA_amdsmi_pcie_info_t class struct_c__SA_amdsmi_process_info_t(Structure): pass @@ -1375,10 +1358,10 @@ class struct_amdsmi_func_id_iter_handle(Structure): pass amdsmi_func_id_iter_handle_t = ctypes.POINTER(struct_amdsmi_func_id_iter_handle) -class union_amd_id(Union): +class union_c__UA_amdsmi_func_id_value_t(Union): pass -class union_amd_id_0(Union): +class union_c__UA_amdsmi_func_id_value_t_0(Union): _pack_ = 1 # source:False _fields_ = [ ('memory_type', amdsmi_memory_type_t), @@ -1390,14 +1373,14 @@ class union_amd_id_0(Union): ('gpu_block_type', amdsmi_gpu_block_t), ] -union_amd_id._pack_ = 1 # source:False -union_amd_id._fields_ = [ +union_c__UA_amdsmi_func_id_value_t._pack_ = 1 # source:False +union_c__UA_amdsmi_func_id_value_t._fields_ = [ ('id', ctypes.c_uint64), ('name', ctypes.POINTER(ctypes.c_char)), - ('amd_id_0', union_amd_id_0), + ('c__UA_amdsmi_func_id_value_t_0', union_c__UA_amdsmi_func_id_value_t_0), ] -amdsmi_func_id_value_t = union_amd_id +amdsmi_func_id_value_t = union_c__UA_amdsmi_func_id_value_t uint64_t = ctypes.c_uint64 amdsmi_init = _libraries['libamd_smi.so'].amdsmi_init amdsmi_init.restype = amdsmi_status_t @@ -1417,7 +1400,7 @@ amdsmi_get_device_handles.restype = amdsmi_status_t amdsmi_get_device_handles.argtypes = [amdsmi_socket_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.POINTER(None))] amdsmi_get_device_type = _libraries['libamd_smi.so'].amdsmi_get_device_type amdsmi_get_device_type.restype = amdsmi_status_t -amdsmi_get_device_type.argtypes = [amdsmi_device_handle, ctypes.POINTER(device_type)] +amdsmi_get_device_type.argtypes = [amdsmi_device_handle, ctypes.POINTER(c__EA_device_type_t)] amdsmi_get_device_handle_from_bdf = _libraries['libamd_smi.so'].amdsmi_get_device_handle_from_bdf amdsmi_get_device_handle_from_bdf.restype = amdsmi_status_t amdsmi_get_device_handle_from_bdf.argtypes = [amdsmi_bdf_t, ctypes.POINTER(ctypes.POINTER(None))] @@ -1481,7 +1464,7 @@ amdsmi_get_bad_page_info.restype = amdsmi_status_t amdsmi_get_bad_page_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(struct_c__SA_amdsmi_retired_page_record_t)] amdsmi_get_ras_block_features_enabled = _libraries['libamd_smi.so'].amdsmi_get_ras_block_features_enabled amdsmi_get_ras_block_features_enabled.restype = amdsmi_status_t -amdsmi_get_ras_block_features_enabled.argtypes = [amdsmi_device_handle, amdsmi_gpu_block, ctypes.POINTER(c__EA_amdsmi_ras_err_state_t)] +amdsmi_get_ras_block_features_enabled.argtypes = [amdsmi_device_handle, amdsmi_gpu_block_t, ctypes.POINTER(c__EA_amdsmi_ras_err_state_t)] amdsmi_dev_get_memory_busy_percent = _libraries['libamd_smi.so'].amdsmi_dev_get_memory_busy_percent amdsmi_dev_get_memory_busy_percent.restype = amdsmi_status_t amdsmi_dev_get_memory_busy_percent.argtypes = [amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint32)] @@ -1517,10 +1500,10 @@ amdsmi_get_utilization_count.restype = amdsmi_status_t amdsmi_get_utilization_count.argtypes = [amdsmi_device_handle, struct_c__SA_amdsmi_utilization_counter_t * 0, uint32_t, ctypes.POINTER(ctypes.c_uint64)] amdsmi_get_pcie_link_status = _libraries['libamd_smi.so'].amdsmi_get_pcie_link_status amdsmi_get_pcie_link_status.restype = amdsmi_status_t -amdsmi_get_pcie_link_status.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_pcie_info)] +amdsmi_get_pcie_link_status.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_pcie_info_t)] amdsmi_get_pcie_link_caps = _libraries['libamd_smi.so'].amdsmi_get_pcie_link_caps amdsmi_get_pcie_link_caps.restype = amdsmi_status_t -amdsmi_get_pcie_link_caps.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_pcie_info)] +amdsmi_get_pcie_link_caps.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_pcie_info_t)] amdsmi_dev_get_perf_level = _libraries['libamd_smi.so'].amdsmi_dev_get_perf_level amdsmi_dev_get_perf_level.restype = amdsmi_status_t amdsmi_dev_get_perf_level.argtypes = [amdsmi_device_handle, ctypes.POINTER(c__EA_amdsmi_dev_perf_level_t)] @@ -1634,7 +1617,7 @@ amdsmi_get_minmax_bandwidth.restype = amdsmi_status_t amdsmi_get_minmax_bandwidth.argtypes = [amdsmi_device_handle, amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(ctypes.c_uint64)] amdsmi_topo_get_link_type = _libraries['libamd_smi.so'].amdsmi_topo_get_link_type amdsmi_topo_get_link_type.restype = amdsmi_status_t -amdsmi_topo_get_link_type.argtypes = [amdsmi_device_handle, amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(_AMDSMI_IO_LINK_TYPE)] +amdsmi_topo_get_link_type.argtypes = [amdsmi_device_handle, amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint64), ctypes.POINTER(c__EA_AMDSMI_IO_LINK_TYPE)] amdsmi_is_P2P_accessible = _libraries['libamd_smi.so'].amdsmi_is_P2P_accessible amdsmi_is_P2P_accessible.restype = amdsmi_status_t amdsmi_is_P2P_accessible.argtypes = [amdsmi_device_handle, amdsmi_device_handle, ctypes.POINTER(ctypes.c_bool)] @@ -1652,7 +1635,7 @@ amdsmi_dev_close_supported_func_iterator.restype = amdsmi_status_t amdsmi_dev_close_supported_func_iterator.argtypes = [ctypes.POINTER(ctypes.POINTER(struct_amdsmi_func_id_iter_handle))] amdsmi_get_func_iter_value = _libraries['libamd_smi.so'].amdsmi_get_func_iter_value amdsmi_get_func_iter_value.restype = amdsmi_status_t -amdsmi_get_func_iter_value.argtypes = [amdsmi_func_id_iter_handle_t, ctypes.POINTER(union_amd_id)] +amdsmi_get_func_iter_value.argtypes = [amdsmi_func_id_iter_handle_t, ctypes.POINTER(union_c__UA_amdsmi_func_id_value_t)] amdsmi_init_event_notification = _libraries['libamd_smi.so'].amdsmi_init_event_notification amdsmi_init_event_notification.restype = amdsmi_status_t amdsmi_init_event_notification.argtypes = [amdsmi_device_handle] @@ -1667,7 +1650,7 @@ amdsmi_stop_event_notification.restype = amdsmi_status_t amdsmi_stop_event_notification.argtypes = [amdsmi_device_handle] amdsmi_get_device_bdf = _libraries['libamd_smi.so'].amdsmi_get_device_bdf amdsmi_get_device_bdf.restype = amdsmi_status_t -amdsmi_get_device_bdf.argtypes = [amdsmi_device_handle, ctypes.POINTER(union_amdsmi_bdf)] +amdsmi_get_device_bdf.argtypes = [amdsmi_device_handle, ctypes.POINTER(union_c__UA_amdsmi_bdf_t)] amdsmi_get_device_uuid = _libraries['libamd_smi.so'].amdsmi_get_device_uuid amdsmi_get_device_uuid.restype = amdsmi_status_t amdsmi_get_device_uuid.argtypes = [amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_char)] @@ -1676,46 +1659,46 @@ amdsmi_get_driver_version.restype = amdsmi_status_t amdsmi_get_driver_version.argtypes = [amdsmi_device_handle, ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_char)] amdsmi_get_asic_info = _libraries['libamd_smi.so'].amdsmi_get_asic_info amdsmi_get_asic_info.restype = amdsmi_status_t -amdsmi_get_asic_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_asic_info)] +amdsmi_get_asic_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_asic_info_t)] amdsmi_get_board_info = _libraries['libamd_smi.so'].amdsmi_get_board_info amdsmi_get_board_info.restype = amdsmi_status_t -amdsmi_get_board_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_board_info)] +amdsmi_get_board_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_board_info_t)] amdsmi_get_power_cap_info = _libraries['libamd_smi.so'].amdsmi_get_power_cap_info amdsmi_get_power_cap_info.restype = amdsmi_status_t -amdsmi_get_power_cap_info.argtypes = [amdsmi_device_handle, uint32_t, ctypes.POINTER(struct_amdsmi_power_cap_info)] +amdsmi_get_power_cap_info.argtypes = [amdsmi_device_handle, uint32_t, ctypes.POINTER(struct_c__SA_amdsmi_power_cap_info_t)] amdsmi_get_xgmi_info = _libraries['libamd_smi.so'].amdsmi_get_xgmi_info amdsmi_get_xgmi_info.restype = amdsmi_status_t -amdsmi_get_xgmi_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_xgmi_info)] +amdsmi_get_xgmi_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_xgmi_info_t)] amdsmi_get_caps_info = _libraries['libamd_smi.so'].amdsmi_get_caps_info amdsmi_get_caps_info.restype = amdsmi_status_t -amdsmi_get_caps_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_gpu_caps)] +amdsmi_get_caps_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_gpu_caps_t)] amdsmi_get_fw_info = _libraries['libamd_smi.so'].amdsmi_get_fw_info amdsmi_get_fw_info.restype = amdsmi_status_t -amdsmi_get_fw_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_fw_info)] +amdsmi_get_fw_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_fw_info_t)] amdsmi_get_vbios_info = _libraries['libamd_smi.so'].amdsmi_get_vbios_info amdsmi_get_vbios_info.restype = amdsmi_status_t -amdsmi_get_vbios_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_vbios_info)] +amdsmi_get_vbios_info.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_vbios_info_t)] amdsmi_get_gpu_activity = _libraries['libamd_smi.so'].amdsmi_get_gpu_activity amdsmi_get_gpu_activity.restype = amdsmi_status_t -amdsmi_get_gpu_activity.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_engine_usage)] +amdsmi_get_gpu_activity.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_engine_usage_t)] amdsmi_get_power_measure = _libraries['libamd_smi.so'].amdsmi_get_power_measure amdsmi_get_power_measure.restype = amdsmi_status_t -amdsmi_get_power_measure.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_power_measure)] +amdsmi_get_power_measure.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_power_measure_t)] amdsmi_get_clock_measure = _libraries['libamd_smi.so'].amdsmi_get_clock_measure amdsmi_get_clock_measure.restype = amdsmi_status_t -amdsmi_get_clock_measure.argtypes = [amdsmi_device_handle, amdsmi_clk_type_t, ctypes.POINTER(struct_amdsmi_clk_measure)] +amdsmi_get_clock_measure.argtypes = [amdsmi_device_handle, amdsmi_clk_type_t, ctypes.POINTER(struct_c__SA_amdsmi_clk_measure_t)] amdsmi_get_vram_usage = _libraries['libamd_smi.so'].amdsmi_get_vram_usage amdsmi_get_vram_usage.restype = amdsmi_status_t -amdsmi_get_vram_usage.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_amdsmi_vram_info)] +amdsmi_get_vram_usage.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_vram_info_t)] amdsmi_get_target_frequency_range = _libraries['libamd_smi.so'].amdsmi_get_target_frequency_range amdsmi_get_target_frequency_range.restype = amdsmi_status_t -amdsmi_get_target_frequency_range.argtypes = [amdsmi_device_handle, amdsmi_clk_type_t, ctypes.POINTER(struct_amdsmi_frequency_range)] +amdsmi_get_target_frequency_range.argtypes = [amdsmi_device_handle, amdsmi_clk_type_t, ctypes.POINTER(struct_c__SA_amdsmi_frequency_range_t)] amdsmi_get_process_list = _libraries['libamd_smi.so'].amdsmi_get_process_list amdsmi_get_process_list.restype = amdsmi_status_t amdsmi_get_process_list.argtypes = [amdsmi_device_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32)] amdsmi_get_process_info = _libraries['libamd_smi.so'].amdsmi_get_process_info amdsmi_get_process_info.restype = amdsmi_status_t -amdsmi_get_process_info.argtypes = [amdsmi_device_handle, amdsmi_process_handle, ctypes.POINTER(struct_amdsmi_process_info)] +amdsmi_get_process_info.argtypes = [amdsmi_device_handle, amdsmi_process_handle, ctypes.POINTER(struct_c__SA_amdsmi_proc_info_t)] amdsmi_get_ecc_error_count = _libraries['libamd_smi.so'].amdsmi_get_ecc_error_count amdsmi_get_ecc_error_count.restype = amdsmi_status_t amdsmi_get_ecc_error_count.argtypes = [amdsmi_device_handle, ctypes.POINTER(struct_c__SA_amdsmi_error_count_t)] @@ -1842,11 +1825,10 @@ __all__ = \ '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', + 'amd_metrics_table_header_t', 'amdsmi_asic_info_t', + 'amdsmi_bdf_t', 'amdsmi_bit_field_t', 'amdsmi_board_info_t', + 'amdsmi_clk_measure_t', 'amdsmi_clk_type_t', + 'amdsmi_clk_type_t__enumvalues', 'amdsmi_container_types_t', 'amdsmi_container_types_t__enumvalues', 'amdsmi_control_counter', 'amdsmi_counter_command_t', 'amdsmi_counter_command_t__enumvalues', @@ -1874,7 +1856,6 @@ __all__ = \ 'amdsmi_dev_get_volt_metric', 'amdsmi_dev_get_vram_vendor', 'amdsmi_dev_open_supported_func_iterator', 'amdsmi_dev_open_supported_variant_iterator', - 'amdsmi_dev_perf_level', 'amdsmi_dev_perf_level__enumvalues', 'amdsmi_dev_perf_level_t', 'amdsmi_dev_perf_level_t__enumvalues', 'amdsmi_dev_reset_fan', 'amdsmi_dev_reset_gpu', 'amdsmi_dev_reset_xgmi_error', 'amdsmi_dev_set_clk_freq', @@ -1891,17 +1872,15 @@ __all__ = \ '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_evt_notification_type_t__enumvalues', 'amdsmi_freq_ind_t', + 'amdsmi_freq_ind_t__enumvalues', 'amdsmi_freq_volt_region_t', '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_get_asic_info', 'amdsmi_get_bad_page_info', - 'amdsmi_get_board_info', 'amdsmi_get_caps_info', - 'amdsmi_get_clock_measure', 'amdsmi_get_compute_process_gpus', + 'amdsmi_fw_block_t', 'amdsmi_fw_block_t__enumvalues', + 'amdsmi_fw_info_t', 'amdsmi_get_asic_info', + 'amdsmi_get_bad_page_info', 'amdsmi_get_board_info', + 'amdsmi_get_caps_info', 'amdsmi_get_clock_measure', + 'amdsmi_get_compute_process_gpus', 'amdsmi_get_compute_process_info', 'amdsmi_get_compute_process_info_by_pid', 'amdsmi_get_device_bdf', 'amdsmi_get_device_handle_from_bdf', 'amdsmi_get_device_handles', @@ -1919,86 +1898,95 @@ __all__ = \ 'amdsmi_get_utilization_count', 'amdsmi_get_vbios_info', 'amdsmi_get_version', 'amdsmi_get_version_str', 'amdsmi_get_vram_usage', 'amdsmi_get_xgmi_info', - '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', - 'amdsmi_init_event_notification', 'amdsmi_init_flags', - 'amdsmi_init_flags_t', 'amdsmi_init_flags_t__enumvalues', - 'amdsmi_is_P2P_accessible', 'amdsmi_memory_page_status_t', + 'amdsmi_init_event_notification', 'amdsmi_init_flags_t', + 'amdsmi_init_flags_t__enumvalues', 'amdsmi_is_P2P_accessible', + '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_next_func_iter', '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_measure_t', - 'amdsmi_power_profile_preset_masks', - 'amdsmi_power_profile_preset_masks__enumvalues', - 'amdsmi_power_profile_preset_masks_t', + 'amdsmi_memory_type_t__enumvalues', 'amdsmi_mm_ip_t', + 'amdsmi_mm_ip_t__enumvalues', 'amdsmi_next_func_iter', + 'amdsmi_od_vddc_point_t', 'amdsmi_od_volt_curve_t', + 'amdsmi_od_volt_freq_data_t', 'amdsmi_pcie_bandwidth_t', + 'amdsmi_pcie_info_t', 'amdsmi_power_cap_info_t', + 'amdsmi_power_measure_t', '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_read_counter', 'amdsmi_retired_page_record_t', + 'amdsmi_power_profile_status_t', 'amdsmi_proc_info_t', + 'amdsmi_process_handle', 'amdsmi_process_info_t', + 'amdsmi_range_t', 'amdsmi_ras_err_state_t', + 'amdsmi_ras_err_state_t__enumvalues', 'amdsmi_read_counter', + 'amdsmi_retired_page_record_t', 'amdsmi_set_event_notification_mask', 'amdsmi_set_perf_determinism_mode', 'amdsmi_shut_down', 'amdsmi_socket_handle', 'amdsmi_status_string', 'amdsmi_status_t', - 'amdsmi_stop_event_notification', 'amdsmi_sw_component_t', - 'amdsmi_sw_component_t__enumvalues', 'amdsmi_temperature_metric', - 'amdsmi_temperature_metric__enumvalues', + 'amdsmi_status_t__enumvalues', 'amdsmi_stop_event_notification', + 'amdsmi_sw_component_t', 'amdsmi_sw_component_t__enumvalues', 'amdsmi_temperature_metric_t', 'amdsmi_temperature_metric_t__enumvalues', - 'amdsmi_temperature_type', 'amdsmi_temperature_type_t', + 'amdsmi_temperature_type_t', 'amdsmi_temperature_type_t__enumvalues', 'amdsmi_topo_get_link_type', 'amdsmi_topo_get_link_weight', 'amdsmi_topo_get_numa_affinity', 'amdsmi_topo_get_numa_node_number', 'amdsmi_utilization_counter_t', 'amdsmi_vbios_info_t', - 'amdsmi_version', 'amdsmi_version_t', 'amdsmi_voltage_metric_t', + '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', + 'amdsmi_xgmi_status_t__enumvalues', 'c__EA_AMDSMI_IO_LINK_TYPE', 'c__EA_AMDSMI_UTILIZATION_COUNTER_TYPE', + 'c__EA_amdsmi_clk_type_t', 'c__EA_amdsmi_container_types_t', '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_fw_block_t', 'c__EA_amdsmi_gpu_block_t', + 'c__EA_amdsmi_init_flags_t', 'c__EA_amdsmi_memory_page_status_t', + 'c__EA_amdsmi_memory_type_t', 'c__EA_amdsmi_mm_ip_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_ras_err_state_t', 'c__EA_amdsmi_status_t', + 'c__EA_amdsmi_sw_component_t', 'c__EA_amdsmi_temperature_metric_t', + 'c__EA_amdsmi_temperature_type_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', 'size_t', - 'struct_amd_metrics_table_header_t', 'struct_amdsmi_asic_info', - 'struct_amdsmi_bdf_0', 'struct_amdsmi_board_info', - 'struct_amdsmi_clk_measure', 'struct_amdsmi_engine_usage', - 'struct_amdsmi_frequency_range', - 'struct_amdsmi_func_id_iter_handle', 'struct_amdsmi_fw_info', - 'struct_amdsmi_fw_info_0', 'struct_amdsmi_gpu_caps', - 'struct_amdsmi_gpu_caps_0', 'struct_amdsmi_gpu_caps_1', - 'struct_amdsmi_pcie_info', 'struct_amdsmi_power_cap_info', - 'struct_amdsmi_power_measure', 'struct_amdsmi_process_info', - 'struct_amdsmi_process_info_0', 'struct_amdsmi_process_info_1', - 'struct_amdsmi_vbios_info', 'struct_amdsmi_vram_info', - 'struct_amdsmi_xgmi_info', 'struct_c__SA_amdsmi_counter_value_t', + 'c__EA_amdsmi_xgmi_status_t', 'c__EA_device_type_t', + 'device_type_t', 'device_type_t__enumvalues', 'size_t', + 'struct_amdsmi_func_id_iter_handle', + 'struct_c__SA_amd_metrics_table_header_t', + 'struct_c__SA_amdsmi_asic_info_t', + 'struct_c__SA_amdsmi_board_info_t', + 'struct_c__SA_amdsmi_clk_measure_t', + 'struct_c__SA_amdsmi_counter_value_t', + 'struct_c__SA_amdsmi_engine_usage_t', 'struct_c__SA_amdsmi_error_count_t', 'struct_c__SA_amdsmi_evt_notification_data_t', 'struct_c__SA_amdsmi_freq_volt_region_t', 'struct_c__SA_amdsmi_frequencies_t', + 'struct_c__SA_amdsmi_frequency_range_t', + 'struct_c__SA_amdsmi_fw_info_t', + 'struct_c__SA_amdsmi_fw_info_t_0', + 'struct_c__SA_amdsmi_gpu_caps_t', + 'struct_c__SA_amdsmi_gpu_caps_t_0', + 'struct_c__SA_amdsmi_gpu_caps_t_1', 'struct_c__SA_amdsmi_gpu_metrics_t', 'struct_c__SA_amdsmi_od_vddc_point_t', 'struct_c__SA_amdsmi_od_volt_curve_t', 'struct_c__SA_amdsmi_od_volt_freq_data_t', 'struct_c__SA_amdsmi_pcie_bandwidth_t', + 'struct_c__SA_amdsmi_pcie_info_t', + 'struct_c__SA_amdsmi_power_cap_info_t', + 'struct_c__SA_amdsmi_power_measure_t', 'struct_c__SA_amdsmi_power_profile_status_t', + 'struct_c__SA_amdsmi_proc_info_t', + 'struct_c__SA_amdsmi_proc_info_t_0', + 'struct_c__SA_amdsmi_proc_info_t_1', 'struct_c__SA_amdsmi_process_info_t', 'struct_c__SA_amdsmi_range_t', 'struct_c__SA_amdsmi_retired_page_record_t', 'struct_c__SA_amdsmi_utilization_counter_t', - 'struct_c__SA_amdsmi_version_t', 'uint32_t', 'uint64_t', - 'union_amd_id', 'union_amd_id_0', 'union_amdsmi_bdf'] + 'struct_c__SA_amdsmi_vbios_info_t', + 'struct_c__SA_amdsmi_version_t', + 'struct_c__SA_amdsmi_vram_info_t', + 'struct_c__SA_amdsmi_xgmi_info_t', 'struct_c__UA_amdsmi_bdf_t_0', + 'uint32_t', 'uint64_t', 'union_c__UA_amdsmi_bdf_t', + 'union_c__UA_amdsmi_func_id_value_t', + 'union_c__UA_amdsmi_func_id_value_t_0'] diff --git a/src/amd_smi/amd_smi.cc b/src/amd_smi/amd_smi.cc index 5addc9fe02..22e1681107 100644 --- a/src/amd_smi/amd_smi.cc +++ b/src/amd_smi/amd_smi.cc @@ -386,7 +386,7 @@ amdsmi_status_t amdsmi_get_vram_usage(amdsmi_device_handle device_handle, } amdsmi_status_t amdsmi_get_caps_info(amdsmi_device_handle device_handle, - struct amdsmi_gpu_caps *info) { + amdsmi_gpu_caps_t *info) { AMDSMI_CHECK_INIT(); @@ -512,7 +512,7 @@ amdsmi_status_t amdsmi_dev_get_id(amdsmi_device_handle device_handle, // TODO(bliu) : add fw info from libdrm amdsmi_status_t amdsmi_get_fw_info(amdsmi_device_handle device_handle, amdsmi_fw_info_t *info) { - const std::map fw_in_rsmi = { + const std::map fw_in_rsmi = { { FW_ID_ASD, RSMI_FW_BLOCK_ASD}, { FW_ID_CP_CE, RSMI_FW_BLOCK_CE}, { FW_ID_DMCU, RSMI_FW_BLOCK_DMCU}, @@ -1524,7 +1524,7 @@ amdsmi_get_clock_measure(amdsmi_device_handle device_handle, amdsmi_clk_type_t c } amdsmi_status_t -amdsmi_get_ras_block_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_t block, amdsmi_ras_err_state_t *state) { AMDSMI_CHECK_INIT(); if (state == nullptr || block > AMDSMI_GPU_BLOCK_LAST) { From 013400bee7fb47284398f162b0e079c2e2eaab85 Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Mon, 9 Jan 2023 11:19:35 -0600 Subject: [PATCH 2/7] Added AMD-SMI Linux Baremetal Change-Id: I39ec76f4e4a8ca32eba10f4541585b2284e71539 Signed-off-by: Maisam Arif --- amd_smi_cli/BDF.py | 96 ++++ amd_smi_cli/_version.py | 1 + amd_smi_cli/amd_smi.py | 31 ++ amd_smi_cli/amd_smi_commands.py | 91 ++++ amd_smi_cli/amd_smi_helpers.py | 151 ++++++ amd_smi_cli/amd_smi_init.py | 71 +++ amd_smi_cli/amd_smi_logger.py | 46 ++ amd_smi_cli/amd_smi_modules.py | 97 ++++ amd_smi_cli/amd_smi_parser.py | 619 ++++++++++++++++++++++++ amd_smi_cli/amdsmiBindings.py | 818 ++++++++++++++++++++++++++++++++ example/amd_smi_drm_example.cc | 2 + 11 files changed, 2023 insertions(+) create mode 100644 amd_smi_cli/BDF.py create mode 100644 amd_smi_cli/_version.py create mode 100644 amd_smi_cli/amd_smi.py create mode 100644 amd_smi_cli/amd_smi_commands.py create mode 100644 amd_smi_cli/amd_smi_helpers.py create mode 100644 amd_smi_cli/amd_smi_init.py create mode 100644 amd_smi_cli/amd_smi_logger.py create mode 100644 amd_smi_cli/amd_smi_modules.py create mode 100644 amd_smi_cli/amd_smi_parser.py create mode 100644 amd_smi_cli/amdsmiBindings.py diff --git a/amd_smi_cli/BDF.py b/amd_smi_cli/BDF.py new file mode 100644 index 0000000000..a4cf29f3da --- /dev/null +++ b/amd_smi_cli/BDF.py @@ -0,0 +1,96 @@ +import logging +import platform +import re + + +class BDF(object): + """ BDF Class to cast and compare BDF objects using built-in python comparators + + Useful for validating a BDF string and converting it to a BDF object + This allows us to handle BDF objects in a pythonic way + + Attributes: + __eq__: The equals comparator + __: An integer count of the eggs we have laid. + """ + + def __init__(self, bdf): + """Init a BDF object""" + if isinstance(bdf, BDF): + self.segment, self.bus, self.device, self.function = tuple(bdf) + else: + if bdf.startswith("BDF("): + bdf = bdf.replace('BDF(', '').replace(')', '') + # Tell if this is baremetal vs Virtualization + self.operating_system = platform.system() + + try: + bdf_components = [int(x, 16) for x in re.split('[:.]', bdf)] + except ValueError as e: + logging.error(f"Invalid string passed: {bdf}") + raise e + + self.segment = bdf_components[0] if len(bdf_components) == 4 else 0 + self.bus, self.device, self.function = bdf_components[-3:] + if self.segment > 65535: + raise ValueError("BDF Segment can't be greater than 65535") + if self.bus > 255: + raise ValueError("BDF Bus can't be greater than 255") + if self.device > 31: + raise ValueError("BDF Device can't be greater than 31") + if self.function > 7: + raise ValueError("BDF Function can't be greater than 7") + + def __eq__(self, passed_bdf): + """Overrides the == operator and allows for BDF objects to be compared to BDF strings""" + + # Only accept strings and BDF objects + if isinstance(passed_bdf, str): + if passed_bdf == '': + return False + passed_bdf = BDF(passed_bdf) + elif not isinstance(passed_bdf, BDF): + return False + + if self.segment == passed_bdf.segment and \ + self.bus == passed_bdf.bus and \ + self.device == passed_bdf.device and \ + self.function == passed_bdf.function: + return True + else: + return False + + def __ne__(self, passed_bdf): + """Overrides the != operator and allows for BDF objects to be compared to BDF strings""" + # Since we overrided the == operator we can use that to make this simple + return not self == passed_bdf + + def __add__(self, passed_bdf): + """Overrides the + operator and allows for concatenation""" + return str(self) + passed_bdf + + def __radd__(self, passed_bdf): + """Overrides the + operator and allows for concatenation""" + return passed_bdf + str(self) + + def __str__(self): + """Cast BDF object to a string""" + return "{:04X}:{:02X}:{:02X}:{}".format(self.segment, self.bus, self.device, self.function) + + def __repr__(self): + """How the BDF object is represented""" + return f"BDF({self})" + + def __iter__(self): + """Make the BDF object iterable over its 4 values""" + yield from (self.segment, self.bus, self.device, self.function) + + def __contains__(self, passed_bdf): + """Overrided the 'in' comparator in python""" + passed_bdf = str(BDF(passed_bdf)) + + bdf_regex = "(?:[0-6]?[0-9a-fA-F]{1,4}:)?[0-2]?[0-9a-fA-F]{1,2}:[0-9a-fA-F]{1,2}\.[0-7]" + for match in re.findall(bdf_regex, passed_bdf): + if self == match: + return True + return False diff --git a/amd_smi_cli/_version.py b/amd_smi_cli/_version.py new file mode 100644 index 0000000000..b3c06d4883 --- /dev/null +++ b/amd_smi_cli/_version.py @@ -0,0 +1 @@ +__version__ = "0.0.1" \ No newline at end of file diff --git a/amd_smi_cli/amd_smi.py b/amd_smi_cli/amd_smi.py new file mode 100644 index 0000000000..88c9d9c3c3 --- /dev/null +++ b/amd_smi_cli/amd_smi.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 + +# from amd_smi_init import * + +from amd_smi_commands import AMD_SMI_Commands +from amd_smi_parser import AMD_SMI_Parser + + +# sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool + + +if __name__ == "__main__": + amd_smi_commands = AMD_SMI_Commands() + amd_smi_parser = AMD_SMI_Parser(amd_smi_commands.version, + amd_smi_commands.discovery, + amd_smi_commands.static, + amd_smi_commands.firmware, + amd_smi_commands.bad_pages, + amd_smi_commands.metric, + amd_smi_commands.process, + amd_smi_commands.profile, + amd_smi_commands.event, + amd_smi_commands.topology, + amd_smi_commands.set_value, + amd_smi_commands.reset, + amd_smi_commands.misc, + amd_smi_commands.gpu_v) + + args = amd_smi_parser.parse_args() + args.func(args) # This needs to be there to handle subparsers with no subcommands + # AMDSMI logger print out json, csv, or string diff --git a/amd_smi_cli/amd_smi_commands.py b/amd_smi_cli/amd_smi_commands.py new file mode 100644 index 0000000000..e5ea6b8478 --- /dev/null +++ b/amd_smi_cli/amd_smi_commands.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 + +import platform +import signal +import subprocess +import sys +import time +import traceback + +from pathlib import Path + +# from amd_smi_init import * +from BDF import BDF +from _version import __version__ + +from amd_smi_logger import AMD_SMI_Logger + + + +class AMD_SMI_Commands(object): + # def __init__(self, amd_smi_logger) -> None: + # logger = amd_smi_logger + # # Make an AMD-SMI-Object-Logger only with the commands object on init + # # Call the logger when we want to store a print: + # # self.logger.store_output(gpu_id, string) # store in ordered dict + # Every function prints the logger at the end + # logger.printoutput(args.json, args.csv) # Which in Logger handles and checks for json or csv + # Check if init can accept args given, if so then init can be used to call watch functions for looping + + + def version(self, args): + kernel_version = 123 + print(f'AMD-SMI version: {__version__} | Kernel version: {kernel_version}') + + + def discovery(self, args): + print('discovery test') + + + def static(self, args): + #This is where the arg handling comes through + print(args.asic) + print(args.bus) + print(args.driver) + print('static test') + + + def firmware(self, args): + print('firmware test') + + + def bad_pages(self, args): + # Retired Pages + print('Bad Pages test') + + + def metric(self, args): + print('Metric test') + + + def process(self, args): + print('Process Test') + + + def profile(self, args): + print('Profile test') + + + def event(self, args): + print('event test') + + + def topology(self, args): + print('topology test') + + + def set_value(self, args): + print('set_value test') + + + def reset(self, args): + print('reset test') + + + def misc(self, args): + print('misc test') + + + def gpu_v(self, args): + print('misc test') + diff --git a/amd_smi_cli/amd_smi_helpers.py b/amd_smi_cli/amd_smi_helpers.py new file mode 100644 index 0000000000..e23c792a19 --- /dev/null +++ b/amd_smi_cli/amd_smi_helpers.py @@ -0,0 +1,151 @@ +#!/usr/bin/python3 + +import argparse +import platform +import signal +import subprocess +import sys +import time +import traceback +import logging + +from pathlib import Path + +from BDF import BDF +from amd_smi_init import * + + +class AMD_SMI_Helpers(object): + def __init__(self) -> None: + # implement basic config for debug logs + self.operating_system = platform.system() + self._is_hypervisor = False + self._is_virtual_os = False + self._is_baremetal = False + self._is_linux = False + self._is_windows = False + + self.virtual_operating_systems_product_names = ['KVM', 'VirtualBox', 'VMware'] #@TODO get KVM example + + if self.operating_system.startswith('Linux'): + self._is_linux = True + # logging.debug(f'whatever:{self._is_linux}') + # KVM hypervisor check @TODO + + product_name = '' + product_name_path = Path('/sys/class/dmi/id/product_name') + if product_name_path.exists(): + product_name = product_name_path.read_text().strip() + + if product_name == '': + # Unable to determine product_name default to baremetal + self._is_baremetal = True + else: + for vm_os in self.virtual_operating_systems_product_names: + if product_name.startswith(vm_os): + # Log that this is a virtual OS + self._is_virtual_os = True + break + + # The current way I determine if a system is baremetal by deduction of the other two arguments + self._is_baremetal = not self._is_hypervisor and not self._is_virtual_os + + + if self.operating_system.startswith('VMkernel'): + self._is_hypervisor = True + + + if self.operating_system.startswith('Window'): + # Check Powershell for Hyper-V enablement + self._is_windows = True + + # Get-CimInstance -ClassName Win32_ComputerSystem Manufacturer + + + # if self.product_name == '' and not self._is_hypervisor: + # self._is_virtual_os = any(self.product_name.startswith(virtual_os) for virtual_os in self.virtual_operating_systems) + + + # self.operating_system = '' + + + def os_info(self): + # Return OS info + # operating_system = + + + # if sys.platform.startswith('win'): + + # elif sys.platform.startswith('linux'): + + return True + + + def is_virtual_os(self): + return self._is_virtual_os + + + def is_hypervisor(self): + # Returns True if hypervisor is enabled on the system + return self._is_hypervisor + + + def is_baremetal(self): + # Returns True if system is baremetal, if system is hypervisor this should return False + return self._is_baremetal + + + + def is_linux(self): + return self._is_linux + + + def is_windows(self): + return self._is_windows + + + def get_gpu_choices(self): + # Return in format {gpu_index : (BDF, UUID)} + + gpu_choices = {} + gpu_index = '1' + gpu_bdf = BDF('0000:23:00.0') + gpu_uuid = '1234' + gpu_choices[gpu_index] = (gpu_bdf, gpu_uuid) + return gpu_choices + + + def get_devices(self): + pass + + + def get_device_from_socket(self): + pass + + + def get_amd_gpu_bdfs(self): + pass + + + def get_amd_cpu_bdfs(self): + pass + + + + # def getBus(device): + # """ Return the bus identifier of a given device + + # @param device: DRM device identifier + # """ + # bdfid = c_uint64(0) + # ret = rocmsmi.rsmi_dev_pci_id_get(device, byref(bdfid)) + + # # BDFID = ((DOMAIN & 0xffffffff) << 32) | ((BUS & 0xff) << 8) |((DEVICE & 0x1f) <<3 ) | (FUNCTION & 0x7) + # domain = (bdfid.value >> 32) & 0xffffffff + # bus = (bdfid.value >> 8) & 0xff + # device = (bdfid.value >> 3) & 0x1f + # function = bdfid.value & 0x7 + + # pic_id = '{:04X}:{:02X}:{:02X}.{:0X}'.format(domain, bus, device, function) + # if rsmi_ret_ok(ret, device): + # return pic_id diff --git a/amd_smi_cli/amd_smi_init.py b/amd_smi_cli/amd_smi_init.py new file mode 100644 index 0000000000..b6daa1abc0 --- /dev/null +++ b/amd_smi_cli/amd_smi_init.py @@ -0,0 +1,71 @@ +#!/usr/bin/python3 + +### Handle init singularly +# Python imports module does not re-execute code on import + +import atexit +import logging +import signal +import sys + +from pathlib import Path + +# Handle bindings for windows, Hyper-v and KVM seperately +from amdsmiBindings import * + +# Using basic python logging for user errors and development +# logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) # Logging for Development +logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR) # User level logging + +# On initial import set initialized variable +amd_smi_initialized = False + +def check_return(return_code, error_statment): #@TODO would raising an exception be better? + if return_code != amdsmi_status.AMDSMI_STATUS_SUCCESS: + logging.error(error_statment) + sys.exit(return_code) + + +def check_amdgpu_driver(): #@TODO Handle KVM logic + """ Returns true if amdgpu is found in the list of initialized modules """ + amd_gpu_status_file = Path("/sys/module/amdgpu/initstate") + + if amd_gpu_status_file.exists(): + if amd_gpu_status_file.read_text().strip() == 'live': + return True + + return False + + +def init_amd_smi(flag=amdsmi_init_flags.AMD_SMI_INIT_AMD_GPUS): + """ Initializes AMD-SMI """ + # Check if amdgpu driver is up + if check_amdgpu_driver(): + # Only init AMD GPUs for now, waiting for future support for AMD CPUs + init_status = amdsmi.amdsmi_init(flag) + check_return(return_code=init_status, error_statment=f'AMD SMI initialization returned {init_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') + logging.info('amd-smi initialized successfully') + else: + logging.error('Driver not initialized (amdgpu not found in modules)') + exit(-1) + + +def amdsmi_shut_down(): + """ Shutdown AMD-SMI """ + # Only init AMD GPUs for now, waiting for future support for AMD CPUs + shut_down_status = amdsmi.amdsmi_shut_down() + check_return(return_code=shut_down_status, error_statment=f'AMD SMI Shutdown code returned {shut_down_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') + logging.debug('amd-smi shutdown successfully') + + +def signal_handler(sig, frame): + logging.debug(f'Handling signal: {sig}') + sys.exit(0) + + +if not amd_smi_initialized: + init_amd_smi() + amd_smi_initialized = True + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) + atexit.register(amdsmi_shut_down) diff --git a/amd_smi_cli/amd_smi_logger.py b/amd_smi_cli/amd_smi_logger.py new file mode 100644 index 0000000000..5826be47f6 --- /dev/null +++ b/amd_smi_cli/amd_smi_logger.py @@ -0,0 +1,46 @@ +#!/usr/bin/python3 + +# import orderedDict +import json + +class AMD_SMI_Logger(object): + def __init__(self) -> None: + # self.card = {} + # backwards compatability + pass + + def store_output(self, target_device, log): + pass + + def print_output(self, format=''): + # JSON, CSV, text + # split into 3 different formats + # for elem in self.cards: + # print pretty + pass + + def print_json(self): + # json_data = '[{"ID":10,"Name":"Pankaj","Role":"CEO"},' \ + # '{"ID":20,"Name":"David Lee","Role":"Editor"}]' + + # json_object = json.loads(json_data) + + # json_formatted_str = json.dumps(json_object, indent=2) + + # print(json_formatted_str) + pass + + def print_csv(self): + # # Opening JSON file and loading the data + # # into the variable data + # with open('data.json') as json_file: + # data = json.load(json_file) + + # employee_data = data['emp_details'] + + # # now we will open a file for writing + # data_file = open('data_file.csv', 'w') + + # # create the csv writer object + # csv_writer = csv.writer(data_file) + pass \ No newline at end of file diff --git a/amd_smi_cli/amd_smi_modules.py b/amd_smi_cli/amd_smi_modules.py new file mode 100644 index 0000000000..97556b9d14 --- /dev/null +++ b/amd_smi_cli/amd_smi_modules.py @@ -0,0 +1,97 @@ +#!/usr/bin/python3 + +import argparse +import platform +import signal +import subprocess +import sys +import time +import traceback + +from pathlib import Path + +import BDF +from amd_smi_init import * + +class AMD_SMI_Modules(object): + def __init__(self) -> None: + pass + + + def get_socket_handles(self): + ### Returns tuple of (int, list of ctypes: socket_handles) + socket_count = c_uint32(0) + return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), None) + check_return(return_code=return_code, error_statment="Invalid get_socket_handles request") + + sockets = [0] * socket_count.value # 1 + socket_handles = (c_void_p * socket_count.value)(*sockets) # That is a pointer, not a multiplication + return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), socket_handles) + check_return(return_code=return_code, error_statment=f"Invalid get_socket_handles with {socket_count.value} sockets") + return (socket_count.value, socket_handles) + + + def get_device_handles(self, socket_handle): + """Gets the Device Handles that are in the current socket""" + ### Returns tuple of (int, list of ctypes: device_handles) + device_count = c_uint32(0) + return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), None) + check_return(return_code=return_code, error_statment="Invalid get_device_handles request") + + devices = [0] * device_count.value + device_handles = (c_void_p * len(devices))(*devices) + return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), byref(device_handles)) + check_return(return_code=return_code, error_statment=f"Invalid get_device_handles with {device_count.value} devices") + return (device_count.value, device_handles) + + + def get_socket_info(self, socket_handle): + """ Given a socket_handle, return the socket_info, which is just a BDF object""" + socket_info = create_string_buffer(128) # createstringbuffer or something??? c_char_p + return_code = amdsmi.amdsmi_get_socket_info(socket_handle, byref(socket_info), c_size_t(128)) + check_return(return_code=return_code, error_statment="Invalid get_socket_info request") + socket_bdf = BDF.BDF(socket_info.value.decode()) + return(socket_bdf) + + + def get_device_type(self, device_handle, format=True): + # format: True for string; False for int + # Returns device_type string for the given device_handle + dev_type = c_int(0) + return_code = amdsmi.amdsmi_get_device_type(device_handle, byref(dev_type)) + check_return(return_code=return_code, error_statment="Invalid get_device_type request") + + if format == True: # Return string + return device_type__enumvalues[dev_type.value] + + return dev_type.value # Return int + + + def get_device_bdf(self, device_handle): + + # class amdsmi_bdf_t (Union): + # _fields_ = [ + # ('bdf_submodule', bdf_submodule), + # ('as_uint', c_uint64) + # ] + bdf = amdsmi_bdf_t() + # bdf.bdf_submodule + + + + return_code = amdsmi.amdsmi_get_device_bdf(device_handle, bdf) + check_return(return_code=return_code, error_statment="Invalid amdsmi_get_device_bdf request") + return (bdf) + + + def get_device_handle_from_bdf(self, bdf): + pass + + + def get_fan_speed(self, bdf): + pass + + def show_retired_pages(self): + # num_pages = c_uint32() + # records = rsmi_retired_page_record_t() + pass \ No newline at end of file diff --git a/amd_smi_cli/amd_smi_parser.py b/amd_smi_cli/amd_smi_parser.py new file mode 100644 index 0000000000..0edf07417f --- /dev/null +++ b/amd_smi_cli/amd_smi_parser.py @@ -0,0 +1,619 @@ +#!/usr/bin/python3 + +import argparse +import platform + +from _version import __version__ +from amd_smi_helpers import AMD_SMI_Helpers + +# sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool + +class AMD_SMI_Parser(argparse.ArgumentParser): + + def __init__(self, version, discovery, static, firmware, bad_pages, metric, + process, profile, event,topology, set_value, reset, misc, gpu_v): + + # Helper variables + self.amd_smi_helpers = AMD_SMI_Helpers() + self.gpu_choices = self.amd_smi_helpers.get_gpu_choices() + self.vf_choices = ['3','2','1'] + + # Adjust argument parser options + super().__init__( + formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90), + # formatter_class=argparse.ArgumentDefaultsHelpFormatter, + description=f'AMD System Management Interface | Version: {__version__}', #@TODO add the enviornment + add_help=True, + prog='amd-smi') + + # Setup subparsers + subparsers = self.add_subparsers( + title="AMD-SMI Commands", + parser_class=argparse.ArgumentParser, + required=True, + help='Descriptions:', + # dest='cmd', + metavar="") + + # Add all subparsers + # Add --json, --csv,--file,--loglevel, watch, watch_time, & iterations && backwards compatability --gpuvsmi --rocmsmi + self.add_version_parser(subparsers, version) + self.add_discovery_parser(subparsers, discovery) + self.add_static_parser(subparsers, static) + self.add_firmware_parser(subparsers, firmware) + self.add_bad_pages_parser(subparsers, bad_pages) + self.add_metric_parser(subparsers, metric) + self.add_process_parser(subparsers, process) + self.add_profile_parser(subparsers, profile) + self.add_event_parser(subparsers, event) + self.add_topology_parser(subparsers, topology) + # self.add_set_value_parser(subparsers, set_value) + self.add_reset_parser(subparsers, reset) + self.add_misc_parser(subparsers, misc) + self.add_gpu_v_parser(subparsers, misc) + + + def add_version_parser(self, subparsers, func): + # Subparser help text + version_help = "Display version information" + + # Create version subparser + version_parser = subparsers.add_parser('version', help=version_help, description=None) + version_parser._optionals.title = None + version_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + version_parser.set_defaults(func=func) + + + def add_discovery_parser(self, subparsers, func): + # Subparser help text + discovery_help = "Display discovery information" + discovery_subcommand_help = """Lists all the devices on the system and the links between devices. + Lists all the sockets and for each socket, GPUs and/or CPUs associated to + that socket alongside some basic information for each device. + In virtualization environment, it can also list VFs associated to each + GPU with some basic information for each VF.""" + + # Create discovery subparser + discovery_parser = subparsers.add_parser('discovery', help=discovery_help, description=discovery_subcommand_help) + discovery_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + discovery_parser.set_defaults(func=func) + + + def add_static_parser(self, subparsers, func): + # Subparser help text + static_help = "Gets static information about the specified GPU" + static_subcommand_help = """If no argument is provided, return static information for all GPUs on the system. + If no static argument is specified all static information will be displayed.""" + static_optionals_title = "Static Arguments" + + # Optional arguments help text + gpu_help = "Select a GPU from the possible choices" + vf_help = """Gets general information about the specified VF (timeslice, fb info, …). + Available only on virtualization OSs""" + asic_help = "All asic information" + bus_help = "All bus information" + vbios_help = "All video bios information (if available)" + limit_help = "All limit metric values (i.e. power and thermal limits)" + driver_help = "Displays driver version" + caps_help = "All caps information" + + # Options arguments help text for Hypervisors and Baremetal + ras_help = "Displays RAS features information" + board_help = "All board information" # Linux Baremetal only @TODO is applicable to Azure + + # Options arguments help text for Hypervisors + dfc_help = "All DFC FW table information" + fb_help = "Displays Frame Buffer information" + num_vf_help = "Displays number of supported and enabled VFs" + + # Create static subparser + static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help) + static_parser._optionals.title = static_optionals_title + static_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + static_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = static_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + static_parser.add_argument('-a', '--asic', action='store_true', required=False, help=asic_help) + static_parser.add_argument('-b', '--bus', action='store_true', required=False, help=bus_help) + static_parser.add_argument('-v', '--vbios', action='store_true', required=False, help=vbios_help) + static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help) + static_parser.add_argument('-d', '--driver', action='store_true', required=False, help=driver_help) + static_parser.add_argument('-c', '--caps', action='store_true', required=False, help=caps_help) + + # Options to display on Hypervisors and Baremetal + if self.amd_smi_helpers.is_hypervisor() or self.amd_smi_helpers.is_baremetal(): + static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) + if self.amd_smi_helpers.is_linux(): #@TODO Check if applicable to Azure + static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) + + # Options to only display on a Hypervisor + if self.amd_smi_helpers.is_hypervisor(): + device_args.add_argument('--vf', action='store', help=vf_help, choices=self.vf_choices) + static_parser.add_argument('-du', '--dfc-ucode', action='store_true', required=False, help=dfc_help) + static_parser.add_argument('-f', '--fb-info', action='store_true', required=False, help=fb_help) + static_parser.add_argument('-n', '--num-vf', action='store_true', required=False, help=num_vf_help) + + + def add_firmware_parser(self, subparsers, func): + # Subparser help text + firmware_help = "Gets firmware information about the specified GPU" + firmware_subcommand_help = "If no argument is provided, return firmware information for all GPUs on the system." + firmware_optionals_title = "Firmware Arguments" + + # Optional arguments help text + gpu_help = "Select a GPU from the possible choices" + vf_help = """Gets general information about the specified VF (timeslice, fb info, …). + Available only on virtualization OSs""" + fw_list_help = "All FW list information" + err_records_help = "All error records information" + + # Create firmware subparser + firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help) + firmware_parser._optionals.title = firmware_optionals_title + firmware_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + firmware_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = firmware_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + firmware_parser.add_argument('-f', '--fw-list', action='store_true', required=False, help=fw_list_help) # Redundant? + + # Options to only display on a Hypervisor + if self.amd_smi_helpers.is_hypervisor(): + device_args.add_argument('--vf', action='store', help=vf_help, choices=self.vf_choices) + firmware_parser.add_argument('-e', '--error-records', action='store_true', required=False, help=err_records_help) + + + def add_bad_pages_parser(self, subparsers, func): #@TODO Retired pages? + if not (self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): + # The bad_pages subcommand is only applicable to Linux Baremetal systems + return + + # Subparser help text + bad_pages_help = "Gets bad page information about the specified GPU" + bad_pages_subcommand_help = "If no argument is provided, return bad page information for all GPUs on the system." + bad_pages_optionals_title = "Bad pages Arguments" + + # Optional arguments help text + gpu_help = "Select a GPU from the possible choices" + pending_help = "Displays all pending retired pages" + retired_help = "Displays retired pages" #@TODO Wording + un_res_help = "Displays unreservable pages" + + # Create bad_pages subparser + bad_pages_parser = subparsers.add_parser('bad_pages', help=bad_pages_help, description=bad_pages_subcommand_help) + bad_pages_parser._optionals.title = bad_pages_optionals_title + bad_pages_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + bad_pages_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = bad_pages_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + bad_pages_parser.add_argument('-p', '--pending', action='store_true', required=False, help=pending_help) + bad_pages_parser.add_argument('-r', '--retired', action='store_true', required=False, help=retired_help) + bad_pages_parser.add_argument('-u', '--un-res', action='store_true', required=False, help=un_res_help) + + + def add_metric_parser(self, subparsers, func): + # Subparser help text + metric_help = "Gets metric/performance information about the specified GPU" + metric_subcommand_help = """If no argument is provided, return metric information for all GPUs on the system. + If no metric argument is specified all metric information will be displayed.""" + metric_optionals_title = "Metric arguments" + + # Optional arguments help text + gpu_help = "Select a GPU from the possible choices" + vf_help = """Gets general information about the specified VF (timeslice, fb info, …). + Available only on virtualization OSs""" + usage_help = "All metrics usage information" + + # Help text for Arguments only Available on Virtual OS and Baremetal platforms + fb_usage_help = "Total and used framebuffer" + + # Help text for Arguments only on Hypervisor and Baremetal platforms + power_help = "Current power usage" + clock_help = "Average, max, and current clock frequencies" + temperature_help = "Current temperatures" + ecc_help = "Number of ECC errors" + pcie_help = "Current PCIe speed and width" + voltage_help = "Current GPU voltages" + + # Help text for Arguments only on Linux Baremetal platforms + fan_help = "Current fan speed" + pcie_usage_help = "Estimated PCIe link usage" + vc_help = "Display voltage curve" + overdrive_help = "Current GPU clock overdrive level" + mo_help = "Current memory clock overdrive level" + perf_level_help = "Current DPM performance level" + replay_count_help = "PCIe replay count" + xgmi_err_help = "XGMI error information since last read" + energy_help = "Amount of energy consumed" #@TODO ? Available only on host Linux Baremetal platforms + + # Help text for Arguments only on Hypervisors + schedule_help = "All scheduling information" + guard_help = "All guard information" + guest_help = "All guest data information" + + # Create metric subparser + metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help) + metric_parser._optionals.title = metric_optionals_title + metric_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + metric_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = metric_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + metric_parser.add_argument('-u', '--usage', action='store_true', required=False, help=usage_help) + + # Optional Args for Virtual OS and Baremetal systems + if self.amd_smi_helpers.is_virtual_os() or self.amd_smi_helpers.is_baremetal(): + metric_parser.add_argument('-b', '--fb-usage', action='store_true', required=False, help=fb_usage_help) + + # Optional Args for Hypervisors and Baremetal systems + if self.amd_smi_helpers.is_hypervisor() or self.amd_smi_helpers.is_baremetal(): + metric_parser.add_argument('-p', '--power', action='store_true', required=False, help=power_help) + metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help) + metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help) + metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) + metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help) + metric_parser.add_argument('-v', '--voltage', action='store_true', required=False, help=voltage_help) + + # Optional Args for Linux Baremetal Systems #@TODO Discuss logic if Linux Hypervisors would be allowed to have this + if self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux(): + metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help) + metric_parser.add_argument('-s', '--pcie-usage', action='store_true', required=False, help=pcie_usage_help) + metric_parser.add_argument('-V', '--voltage-curve', action='store_true', required=False, help=vc_help) + metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help) + metric_parser.add_argument('-m', '--mem-overdrive', action='store_true', required=False, help=mo_help) + metric_parser.add_argument('-l', '--perf-level', action='store_true', required=False, help=perf_level_help) + metric_parser.add_argument('-r', '--replay-count', action='store_true', required=False, help=replay_count_help) + metric_parser.add_argument('-x', '--xgmi-err', action='store_true', required=False, help=xgmi_err_help) + metric_parser.add_argument('-E', '--energy', action='store_true', required=False, help=energy_help) + + # Options to only display to Hypervisors + if self.amd_smi_helpers.is_hypervisor(): + device_args.add_argument('--vf', action='store', help=vf_help, choices=self.vf_choices) + metric_parser.add_argument('-s', '--schedule', action='store_true', required=False, help=schedule_help) + metric_parser.add_argument('-g', '--guard', action='store_true', required=False, help=guard_help) + metric_parser.add_argument('-G', '--guest', action='store_true', required=False, help=guest_help) + + + def add_process_parser(self, subparsers, func): + if self.amd_smi_helpers.is_hypervisor(): + # Don't add this subparser on Hypervisors + return + + # Subparser help text + process_help = "Lists general process information running on the specified GPU" + process_subcommand_help = """If no argument is provided, returns information for all GPUs on the system. + If no argument is provided all process information will be displayed.""" + process_optionals_title = "Process arguments" + + # Required arguments help text + gpu_help = "Select a GPU from the possible choices" + + # Help text for Arguments only on Guest and BM platforms + general_help = "pid, process name, memory usage" + engine_help = "All engine usages" + pid_help = "Gets all process information about the specified process based on Process ID" + name_help = """Gets all process information about the specified process based on Process Name. + If multiple processes have the same name information is returned for all of them.""" #@TODO wording + + # Create process subparser + process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help) + process_parser._optionals.title = process_optionals_title + process_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + process_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = process_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + process_parser.add_argument('-g', '--general', action='store_true', required=False, help=general_help) + process_parser.add_argument('-e', '--engine', action='store_true', required=False, help=engine_help) + process_parser.add_argument('-p', '--pid', action='store', required=False, help=pid_help) + process_parser.add_argument('-n', '--name', action='store', required=False, help=name_help) + + + def add_profile_parser(self, subparsers, func): + if not (self.amd_smi_helpers.is_windows() and self.amd_smi_helpers.is_hypervisor()): + # This subparser only applies to Azure Hyper-V systems + return + + # Subparser help text + profile_help = "Displays information about all profiles and current profile" + profile_subcommand_help = "If no argument is provided, returns information for all GPUs on the system." + profile_optionals_title = "Profile Arguments" + + # Required arguments help text + gpu_help = "Select a GPU from the possible choices" + + # Create profile subparser + profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help) + profile_parser._optionals.title = profile_optionals_title + profile_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + profile_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = profile_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + + def add_event_parser(self, subparsers, func): + if self.amd_smi_helpers.is_linux() and not self.amd_smi_helpers.is_virtual_os(): + # This subparser only applies to Linux BareMetal & Linux Hypervisors + return + + # Subparser help text + event_help = "Displays event information for the given GPU" + event_subcommand_help = "If no argument is provided, returns event information for all GPUs on the system." + event_optionals_title = "Event Arguments" + + # Required arguments help text + gpu_help = "Select a GPU from the possible choices" + + # Create event subparser + event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help) + event_parser._optionals.title = event_optionals_title + event_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + event_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = event_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + + def add_topology_parser(self, subparsers, func): + if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): + # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work + return + + # Subparser help text + topology_help = "Displays topology information of the devices." + topology_subcommand_help = "If no argument is provided, returns information for all GPUs on the system." + topology_optionals_title = "Topology arguments" + + # Required arguments help text + gpu_help = "Select a GPU from the possible choices" + + # Help text for Arguments only on Guest and BM platforms + topo_access_help = "Displays link accessibility between GPUs" + topo_weight_help = "Displays relative weight between GPUs" + topo_hops_help = "Displays the number of hops between GPUs" + topo_type_help = "Displays the link type between GPUs." + topo_numa_help = "Displays the numa nodes." + + # Create topology subparser + topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help) + topology_parser._optionals.title = topology_optionals_title + topology_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + topology_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = topology_parser.add_mutually_exclusive_group() + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + topology_parser.add_argument('-a', '--topo-access', action='store_true', required=False, help=topo_access_help) + topology_parser.add_argument('-w', '--topo-weight', action='store_true', required=False, help=topo_weight_help) + topology_parser.add_argument('-o', '--topo-hops', action='store_true', required=False, help=topo_hops_help) + topology_parser.add_argument('-t', '--topo-type', action='store_true', required=False, help=topo_type_help) + topology_parser.add_argument('-n', '--topo-numa', action='store_true', required=False, help=topo_numa_help) + + + def add_set_value_parser(self, subparsers, func): + if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): + # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work + return + + # Subparser help text + set_value_help = "Set options for devices." + set_value_subcommand_help = "The user must specify one of the options for the set configuration." + set_value_optionals_title = "Set Arguments" + + # Required arguments help text + gpu_help = "Select a GPU from the possible choices" + + # Help text for Arguments only on Guest and BM platforms + set_clk_help = "Sets clock frequency levels for specified clocks" + set_sclk_help = "Sets GPU clock frequency levels" + set_mclk_help = "Sets memory clock frequency levels" + set_pcie_help = "Sets PCIe clock frequency levels" + set_slevel_help = "Change GPU clock frequency and voltage for a specific level" + set_mlevel_help = "Change GPU memory frequency and voltage for a specific level" + set_vc_help = "Change SCLK voltage curve for a specified point" + set_srange_help = "Sets min and max SCLK speed" + set_mrange_help = "Sets min and max MCLK speed" + set_fan_help = "Sets GPU fan speed (level or %)" + set_perf_level_help = "Sets performance level" + set_overdrive_help = "Set GPU overdrive level" + set_mem_overdrive_help = "Set memory overclock overdrive level" + set_power_overdrive_help = "Set the maximum GPU power using power overdrive in Watts" + set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes" + set_perf_det_help = "Set GPU clock frequency limit to get minimal performance variation" + ras_enable_help = "Enable RAS for specified block and error type" + ras_disable_help = "Disable RAS for specified block and error type." + ras_inject_help = "Inject RAS poison for specified block" + +# -c, --setclk +# . +# -s, --setsclk +# . +# -m, --setmclk +# . +# -p, --setpcie +# . +# -S, --setslevel +# . +# -M, --setmlevel +# . +# -v, --setvc +# . +# -r, --setsrange +# +# -R, --setmrange +# . +# -f, --setfan +# +# -pl, --setperflevel +# +# -o, --setoverdrive % +# Set GPU overdrive level. +# -O, --setmemoverdrive % +# Set memory overclock overdrive level. +# -po, --setpoweroverdrive +# Set the maximum GPU power using power overdrive in Watts. +# -P, --setprofile +# Set power profile level (#) or a quoted string of custom profile attributes (“ # # # # “) +# -pd, --setperfdet +# Set GPU clock frequency limit to get minimal performance variation. +# -re, --rasenable +# Enable RAS for specified block and error type. +# -rd, --rasdisable +# Disable RAS for specified block and error type. +# -ri, --rasinject +# Inject RAS poison for specified block + + # Create set_value subparser + set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) + set_value_parser._optionals.title = set_value_optionals_title + set_value_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + set_value_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = set_value_parser.add_mutually_exclusive_group(required=True) + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + set_value_parser.add_argument('-c', '--setclk', action='store', required=False, help=topo_access_help) + set_value_parser.add_argument('-s', '--topo-weight', action='store', required=False, help=topo_weight_help) + set_value_parser.add_argument('-m', '--topo-hops', action='store', required=False, help=topo_hops_help) + set_value_parser.add_argument('-p', '--topo-type', action='store', required=False, help=topo_type_help) + set_value_parser.add_argument('-S', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-M', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-v', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-r', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-R', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-f', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-pl', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-o' '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-O', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-po', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-P', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-pd', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-re', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-rd', '--topo-numa', action='store', required=False, help=topo_numa_help) + set_value_parser.add_argument('-ri', '--topo-numa', action='store', required=False, help=topo_numa_help) + + + def add_reset_parser(self, subparsers, func): + if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): + # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work + return + + # Subparser help text + reset_help = "Reset options for devices." + reset_subcommand_help = "The user must specify one of the options to reset devices." + reset_optionals_title = "Reset Arguments" + + # Required arguments help text + gpu_help = "Select a GPU from the possible choices" + + # Help text for Arguments only on Guest and BM platforms + gpureset_help = "Reset the specified GPU" + resetclk_help = "Reset clocks and overdrive to default" + resetfans_help = "Reset fans to automatic (driver) control" + resetprofile_help = "Reset power profile back to default" + resetpoweroverdrive_help = "Set the maximum GPU power back to the device default state" + resetxgmierr_help = "Reset XGMI error counts" + resetperfdet_help = "Disable performance determinism" + + # Create reset subparser + reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help) + reset_parser._optionals.title = reset_optionals_title + reset_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + reset_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = reset_parser.add_mutually_exclusive_group(required=True) + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + reset_parser.add_argument('-g', '--gpureset', action='store_true', required=False, help=gpureset_help) + reset_parser.add_argument('-c', '--resetclk', action='store_true', required=False, help=resetclk_help) + reset_parser.add_argument('-f', '--resetfans', action='store_true', required=False, help=resetfans_help) + reset_parser.add_argument('-p', '--resetprofile', action='store_true', required=False, help=resetprofile_help) + reset_parser.add_argument('-o', '--resetpoweroverdrive', action='store_true', required=False, help=resetpoweroverdrive_help) + reset_parser.add_argument('-x', '--resetxgmierr', action='store_true', required=False, help=resetxgmierr_help) + reset_parser.add_argument('-d', '--resetperfdet', action='store_true', required=False, help=resetperfdet_help) + + + def add_misc_parser(self, subparsers, func): + if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): + # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work + return + + # Subparser help text + misc_help = "The miscellaneous options" + misc_subcommand_help = "The user must specify one of the options to reset devices." + misc_optionals_title = "Misc Arguments" + + # Optional arguments help text + gpu_help = "Select a GPU from the possible choices" + load_help = "Load clock, fan, performance, and profile settings from a given file." + save_help = "Save clock, fan, performance, and profile settings to a given file." + + # Create misc subparser + misc_parser = subparsers.add_parser('misc', help=misc_help, description=misc_subcommand_help) + misc_parser._optionals.title = misc_optionals_title + misc_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + misc_parser.set_defaults(func=func) + + # Mutually Exclusive Args within the subparser + device_args = misc_parser.add_mutually_exclusive_group(required=True) + device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # Optional Args + misc_parser.add_argument('-l', '--load', action='store', type=open, required=False, help=load_help) + misc_parser.add_argument('-s', '--save', action='store', type=open, required=False, help=save_help) + + + # def add_gpu_v_parser(self, subparsers, func): + # if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): + # # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work + # return + + # # Subparser help text + # gpu_v_help = "The gpu_v options" + # gpu_v_subcommand_help = "The user must specify one of the options to reset devices." + # gpu_v_optionals_title = "gpu_v Arguments" + + # # Optional arguments help text + # gpu_help = "Select a GPU from the possible choices" + # load_help = "Load clock, fan, performance, and profile settings from a given file." + # save_help = "Save clock, fan, performance, and profile settings to a given file." + + # # Create gpu_v subparser + # gpu_v_parser = subparsers.add_parser('gpu_v', help=gpu_v_help, description=gpu_v_subcommand_help) + # gpu_v_parser._optionals.title = gpu_v_optionals_title + # gpu_v_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) + # gpu_v_parser.set_defaults(func=func) + + # # Mutually Exclusive Args within the subparser + # device_args = gpu_v_parser.add_mutually_exclusive_group(required=True) + # device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) + + # # Optional Args + # gpu_v_parser.add_argument('-l', '--load', action='store', type=open, required=False, help=load_help) + # gpu_v_parser.add_argument('-s', '--save', action='store', type=open, required=False, help=save_help) diff --git a/amd_smi_cli/amdsmiBindings.py b/amd_smi_cli/amdsmiBindings.py new file mode 100644 index 0000000000..df9222d537 --- /dev/null +++ b/amd_smi_cli/amdsmiBindings.py @@ -0,0 +1,818 @@ +#!/usr/bin/env python3 +"""! @brief AMD_SMI FFI""" + +from ctypes import * +from enum import Enum +import os + + +path_amdsmi = '/opt/rocm/lib/libamd_smi64.so' #@TODO make this dynamic + +try: + cdll.LoadLibrary(path_amdsmi) + amdsmi = CDLL(path_amdsmi) +except OSError: + print("Unable to load libamd_smi64.so library\n") + exit(1) + +## +# @brief Initialization flags +# +# may be OR'd together and passed to smi.amdsmi_init() +## + +class amdsmi_init_flags(c_int): + AMD_SMI_INIT_ALL_DEVICES = 0x0 # Default option + AMD_SMI_INIT_AMD_CPUS = (1 << 0) + AMD_SMI_INIT_AMD_GPUS = (1 << 1) + AMD_SMI_INIT_NON_AMD_CPUS = (1 << 2) + AMD_SMI_INIT_NON_AMD_GPUS = (1 << 3) + +# Maximum size definitions GPUVSMI +AMDSMI_MAX_MM_IP_COUNT = 8 +AMDSMI_MAX_DATE_LENGTH = 32 # YYYY-MM-DD:HH:MM:SS.MSC # +AMDSMI_MAX_STRING_LENGTH = 64 +AMDSMI_NORMAL_STRING_LENGTH = 32 +AMDSMI_MAX_DEVICES = 32 +AMDSMI_MAX_NAME = 32 +AMDSMI_MAX_DRIVER_VERSION_LENGTH = 80 +AMDSMI_PRODUCT_NAME_LENGTH = 128 +AMDSMI_MAX_CONTAINER_TYPE = 2 + +AMDSMI_GPU_UUID_SIZE = 38 + + +class amdsmi_mm_ip(c_int): + MM_UVD = 0 + MM_VCE = 1 + MM_VCN = 2 + MM__MAX = 3 + + +class amdsmi_container_types(c_int): + CONTAINER_LXC = 0 + CONTAINER_DOCKER = 1 + +# ! opaque handler point to underlying implementation +amdsmi_device_handle = POINTER(c_uint) +amdsmi_socket_handle = POINTER(c_uint) + +class device_type(c_int): + UNKNOWN = 0 + AMD_GPU = 1 + AMD_CPU = 2 + NON_AMD_GPU = 3 + NON_AMD_CPU = 4 + +device_type__enumvalues = { + 0: 'UNKNOWN', + 1: 'AMD_GPU', + 2: 'AMD_CPU', + 3: 'NON_AMD_GPU', + 4: 'NON_AMD_CPU', +} + +#Error codes retured by amd_smi_lib functions +class amdsmi_status(c_int): + AMDSMI_STATUS_SUCCESS = 0 # Call succeeded + AMDSMI_STATUS_INVAL = 1 # Invalid parameters + AMDSMI_STATUS_NOT_SUPPORTED = 2 # Command not supported + AMDSMI_STATUS_FILE_ERROR = 3 # Problem accessing a file. + AMDSMI_STATUS_NO_PERM = 4 # Permission Denied + AMDSMI_STATUS_OUT_OF_RESOURCES = 5 # Not enough memory + AMDSMI_STATUS_INTERNAL_EXCEPTION = 6 # An internal exception was caught + AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS = 7 # The provided input is out of allowable or safe range + AMDSMI_STATUS_INIT_ERROR = 8 # An error occurred when initializing internal data structures + AMDSMI_STATUS_NOT_YET_IMPLEMENTED = 9 # Not implemented yet + AMDSMI_STATUS_NOT_FOUND = 10 # Device Not found + AMDSMI_STATUS_INSUFFICIENT_SIZE = 11 # Not enough resources were available for the operation + AMDSMI_STATUS_INTERRUPT = 12 # An interrupt occurred during execution of function + AMDSMI_STATUS_UNEXPECTED_SIZE = 13 # An unexpected amount of data was read + AMDSMI_STATUS_NO_DATA = 14 # No data was found for a given input + AMDSMI_STATUS_UNEXPECTED_DATA = 15 # The data read or provided to function is not what was expected + AMDSMI_STATUS_BUSY = 16 # Device busy + AMDSMI_STATUS_REFCOUNT_OVERFLOW = 17 # An internal reference counter exceeded INT32_MAX + AMDSMI_LIB_START = 1000 + AMDSMI_STATUS_FAIL_LOAD_MODULE = AMDSMI_LIB_START # Fail to load lib + AMDSMI_STATUS_FAIL_LOAD_SYMBOL = 1001 + AMDSMI_STATUS_DRM_ERROR = 1002 # Error when call libdrm + AMDSMI_STATUS_IO = 1003 # Error + AMDSMI_STATUS_FAULT = 1004 # Bad address + AMDSMI_STATUS_API_FAILED = 1005 # API call failed + AMDSMI_STATUS_TIMEOUT = 1006 # Timeout in API call + AMDSMI_STATUS_NO_SLOT = 1007 # No more free slot + AMDSMI_STATUS_RETRY = 1008 # Retry operation + AMDSMI_STATUS_NOT_INIT = 1009 # Device not initialized + AMDSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF # An unknown error occurred + +amdsmi_status_t = amdsmi_status +#Clock types +class amdsmi_clk_type (c_int): + CLK_TYPE_SYS = 0x0, # System clock + CLK_TYPE_FIRST = CLK_TYPE_SYS + CLK_TYPE_GFX = CLK_TYPE_SYS + CLK_TYPE_DF = 0x1 # Data Fabric clock (for ASICs + # running on a separate clock) + CLK_TYPE_DCEF = 0x2 # Display Controller Engine clock + CLK_TYPE_SOC = 0x3 + CLK_TYPE_MEM = 0x4 + CLK_TYPE_PCIE = 0x5 + CLK_TYPE_VCLK0 = 0x6 + CLK_TYPE_VCLK1 = 0x7 + CLK_TYPE_DCLK0 = 0x8 + CLK_TYPE_DCLK1 = 0x9 + CLK_TYPE__MAX = CLK_TYPE_DCLK1 + +amdsmi_clk_type_t = amdsmi_clk_type +#This enumeration is used to indicate from which part of the device a +# temperature reading should be obtained +class amdsmi_temperature_type (c_int): + TEMPERATURE_TYPE_EDGE = 0 + TEMPERATURE_TYPE_FIRST = TEMPERATURE_TYPE_EDGE + 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 = TEMPERATURE_TYPE_PLX + +#The values of this enum are used to identify the various firmware +#blocks. +class amdsmi_fw_block_t (c_int): + FW_ID_SMU = 1 + FW_ID_FIRST = FW_ID_SMU + 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 # eRAM + FW_ID_DMCU_ISR = 23 # ISR + 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 + +#This structure represents a range (e.g., frequencies or voltages) + +class amdsmi_range_t (Structure): + _fields_ = [ + ('lower_bound', c_uint64), + ('upper_bound', c_uint64), + ] + +class amdsmi_xgmi_info_t (Structure): + _fields_ = [ + ('xgmi_lanes', c_uint8), + ('xgmi_hive_id', c_uint64), + ('xgmi_node_id', c_uint64), + ('index', c_uint32), + ] + +#GPU Capability info + +class gfx (Structure): + _fields_ = [ + ('gfxip_major', c_uint32), + ('gfxip_minor', c_uint32), + ('gfxip_cu_count', c_uint16)] + +class mm (Structure): + _fields_ = [ + ('mm_ip_count', c_uint8), + ('mm_ip_list', c_uint8 * AMDSMI_MAX_MM_IP_COUNT) + ] +class amdsmi_gpu_caps_t (Structure): + _fields_ = [ + ('gfx', gfx), + ('mm', mm), + ('ras_supported', c_bool), + ('max_vf_num', c_uint8), + ('gfx_ip_count', c_uint32), + ('dma_ip_count', c_uint32) + ] + +class amdsmi_vram_info (Structure): + _fields_ = [ + ('vram_total', c_uint32), + ('vram_used', c_uint32), + ] + +class amdsmi_frequency_range_t(Structure): + _fields_ = [ + ('supported_freq_range', amdsmi_range_t), + ('current_freq_range', amdsmi_range_t), + ] + +class bdf_submodule (Structure): + _fields_ = [ + ('function_number', c_uint64, 3), + ('device_number', c_uint64, 5), + ('bus_number', c_uint64, 8), + ('domain_number', c_uint64, 48), + ] +class amdsmi_bdf_t (Union): + _fields_ = [ + ('bdf_submodule', bdf_submodule), + ('as_uint', c_uint64) + ] + +class amdsmi_power_cap_info_t (Structure): + _fields_ = [ + ('power_cap', c_uint64), + ('default_power_cap', c_uint64), + ('dpm_cap', c_uint64), + ('min_power_cap', c_uint64), + ('max_power_cap', c_uint64) + ] + +class amdsmi_vbios_info_t (Structure): + _fields_ =[ + ('name', c_char * AMDSMI_MAX_STRING_LENGTH), + ('vbios_version', c_uint32), + ('build_date', c_char * AMDSMI_MAX_DATE_LENGTH), + ('part_number', c_char * AMDSMI_MAX_STRING_LENGTH), + ('vbios_version_string', c_char * AMDSMI_NORMAL_STRING_LENGTH) + ] + +class fw_info_list (Structure): + _fields_ = [ + ('fw_id', amdsmi_fw_block_t), + ('fw_version', c_uint64) + ] +class amdsmi_fw_info_t (Structure): + _fields_ =[ + ('num_fw_info', c_uint8), + ('fw_info_list', fw_info_list * amdsmi_fw_block_t.FW_ID__MAX) + ] + +class amdsmi_asic_info_t (Structure): + _fields_ = [ + ('market_name', c_char * AMDSMI_MAX_STRING_LENGTH), + ('family', c_uint32), + ('vendor_id', c_uint32), + ('subvendor_id', c_uint32), + ('device_id', c_uint64), + ('rev_id', c_uint32), + ('asic_serial', c_char * AMDSMI_NORMAL_STRING_LENGTH) + ] + +class amdsmi_board_info (Structure): + _fields_ = [ + ('serial_number', c_uint64), + ('is_master', c_bool), + ('model_number', c_char * AMDSMI_NORMAL_STRING_LENGTH), + ('product_serial', c_char * AMDSMI_NORMAL_STRING_LENGTH), + ('fru_id', c_char * AMDSMI_NORMAL_STRING_LENGTH), + ('product_name', c_char * AMDSMI_PRODUCT_NAME_LENGTH), + ('manufacturer_name', c_char * AMDSMI_NORMAL_STRING_LENGTH), + ] + +class amdsmi_temperature_t (Structure): + _fields_ = [ + ('cur_temp', c_uint32) + ] + +class amdsmi_temperature_limit_t (Structure): + _fields_ = [ + ('limit', c_uint32) + ] + +class amdsmi_power_limit_t (Structure): + _fields_ = [ + ('limit', c_uint32) + ] + +class amdsmi_power_measure (Structure): + _fields_ = [ + ('average_socket_power', c_uint32), + ('energy_accumulator', c_uint64), + ('voltage_gfx', c_uint32), + ('voltage_soc', c_uint32), + ('voltage_mem', c_uint32), + ] + +class amdsmi_clk_measure_t (Structure): + _fields_ = [ + ('cur_clk', c_uint32), + ('avg_clk', c_uint32), + ('min_clk', c_uint32), + ('max_clk', c_uint32) + ] + +class amdsmi_engine_usage_t (Structure): + _fields_ = [ + ('gfx_activity', c_uint32), + ('umc_activity', c_uint32), + ('mm_activity', c_uint32 * AMDSMI_MAX_MM_IP_COUNT) + ] + +amdsmi_process_handle = c_uint32 + +class memory_usage (Structure): + _fields_ = [ + ('gtt_mem', c_uint64), + ('cpu_mem', c_uint64), + ('vram_mem', c_uint64) + ] + + +class engine_usage (Structure): + _fields_ = [ + ('gfx', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), + ('compute', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), + ('sdma', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), + ('enc', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), + ('dec',c_uint16 * AMDSMI_MAX_MM_IP_COUNT) + ] +class amdsmi_proc_info_t(Structure): + _fields_ = [ + ('name', c_char * AMDSMI_NORMAL_STRING_LENGTH), + ('pid', amdsmi_process_handle), + ('mem', c_uint64), + ('engine_usage', engine_usage), + ('memory_usage', memory_usage), + ('container_name', c_char * AMDSMI_NORMAL_STRING_LENGTH) + + ] +amdsmi_process_info = amdsmi_proc_info_t + +# Guaranteed maximum possible number of supported frequencies +AMDSMI_MAX_NUM_FREQUENCIES = 32 + +# The number of points that make up a voltage-frequency curve definition +AMDSMI_NUM_VOLTAGE_CURVE_POINTS = 3 + +class amdsmi_dev_perf_level_t (c_int): + AMDSMI_DEV_PERF_LEVEL_AUTO = 0 # Performance level is "auto" + AMDSMI_DEV_PERF_LEVEL_FIRST = AMDSMI_DEV_PERF_LEVEL_AUTO + AMDSMI_DEV_PERF_LEVEL_HIGH = 1 # Keep PowerPlay levels "high", regardless of workload + AMDSMI_DEV_PERF_LEVEL_MANUAL = 2 # Only use values defined by manually setting the AMDSMI_CLK_TYPE_SYS speed + AMDSMI_DEV_PERF_LEVEL_STABLE_STD = 3 # Stable power state with profiling clocks + AMDSMI_DEV_PERF_LEVEL_STABLE_PEAK = 4 # Stable power state with peak clocks + AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK = 5 # Stable power state with minimum memory clock + AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK = 6 # Stable power state with minimum system clock + AMDSMI_DEV_PERF_LEVEL_DETERMINISM = 7 # Performance determinism state + AMDSMI_DEV_PERF_LEVEL_LAST = AMDSMI_DEV_PERF_LEVEL_DETERMINISM + AMDSMI_DEV_PERF_LEVEL_UNKNOWN = 0x100 # Unknown performance level + +amdsmi_dev_perf_level = amdsmi_dev_perf_level_t + +class amdsmi_sw_component_t (c_int): + AMDSMI_SW_COMP_FIRST = 0x0 + AMDSMI_SW_COMP_DRIVER = AMDSMI_SW_COMP_FIRST # Driver + AMDSMI_SW_COMP_LAST = AMDSMI_SW_COMP_DRIVER + +amdsmi_event_handle_t = c_uint64 + + +#Event Groups +# Enum denoting an event group. The value of the enum is the +# base value for all the event enums in the group. +class amdsmi_event_group_t (c_int): + AMDSMI_EVNT_GRP_XGMI = 0 # Data Fabric(XGMI) related events + AMDSMI_EVNT_GRP_XGMI_DATA_OUT = 10 # XGMI Outbound data + AMDSMI_EVNT_GRP_INVALID = 0xFFFFFFFF + +# Event types +# Event type enum. Events belonging to a particular event group +# ::amdsmi_event_group_t should begin enumerating at the ::amdsmi_event_group_t +# value for that group. + +class amdsmi_event_type_t (c_int): + AMDSMI_EVNT_FIRST = amdsmi_event_group_t.AMDSMI_EVNT_GRP_XGMI + AMDSMI_EVNT_XGMI_FIRST = amdsmi_event_group_t.AMDSMI_EVNT_GRP_XGMI + AMDSMI_EVNT_XGMI_0_NOP_TX = AMDSMI_EVNT_XGMI_FIRST # NOPs sent to neighbor 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 = AMDSMI_EVNT_XGMI_DATA_OUT_5 + AMDSMI_EVNT_LAST = AMDSMI_EVNT_XGMI_DATA_OUT_LAST + +class amdsmi_counter_command_t (c_int): + AMDSMI_CNTR_CMD_START = 0 + AMDSMI_CNTR_CMD_STOP = 1 + +class amdsmi_counter_value_t (Structure): + _fields_ = [ + ('value', c_uint64), + ('time_enabled', c_uint64), + ('time_running', c_uint64) + ] + +class amdsmi_evt_notification_type_t (c_int): + AMDSMI_EVT_NOTIF_VMFAULT = 1 # VM page fault + AMDSMI_EVT_NOTIF_FIRST = AMDSMI_EVT_NOTIF_VMFAULT, + AMDSMI_EVT_NOTIF_THERMAL_THROTTLE = 2, + AMDSMI_EVT_NOTIF_GPU_PRE_RESET = 3, + AMDSMI_EVT_NOTIF_GPU_POST_RESET = 4, + AMDSMI_EVT_NOTIF_LAST = AMDSMI_EVT_NOTIF_GPU_POST_RESET + +# function to generate event bitmask from event id +def AMDSMI_EVENT_MASK_FROM_INDEX (i): + return c_ulonglong(1 << (i - 1)) + +MAX_EVENT_NOTIFICATION_MSG_SIZE = 64 + +# Event notification data returned from event notification API +class amdsmi_evt_notification_data_t (Structure): + _fields_ = [ + ('device_handle', c_void_p), # Handler of device that corresponds to the event + ('event', amdsmi_evt_notification_type_t), # Event type + ('message', c_char * MAX_EVENT_NOTIFICATION_MSG_SIZE) # Event message + ] + +# Temperature Metrics. This enum is used to identify various +# temperature metrics. Corresponding values will be in millidegress Celcius. + +class amdsmi_temperature_metric_t (c_int): + AMDSMI_TEMP_CURRENT = 0 # Temperature current value + AMDSMI_TEMP_FIRST = AMDSMI_TEMP_CURRENT + AMDSMI_TEMP_MAX = 1 # Temperature max value + AMDSMI_TEMP_MIN = 2 # Temperature min value + AMDSMI_TEMP_MAX_HYST = 3 # Temperature hysteresis value for max limit (This is an absolute temperature, not a delta) + AMDSMI_TEMP_MIN_HYST = 4 # Temperature hysteresis value for min limit (not a delta) + AMDSMI_TEMP_CRITICAL = 5 # Temperature critical max value, typically greater than corresponding temp_max values. + AMDSMI_TEMP_CRITICAL_HYST = 6 # Temperature hysteresis value for critical limit. (not a delta) + AMDSMI_TEMP_EMERGENCY = 7 # Temperature emergency max value, for chips supporting more than two upper temperature + # limits. Must be equal or greater than corresponding temp_crit values. + AMDSMI_TEMP_EMERGENCY_HYST = 8 # Temperature hysteresis value for emergency limit. (not a delta). + AMDSMI_TEMP_CRIT_MIN = 9 # Temperature critical min value, typically lower than corresponding temperature min values + AMDSMI_TEMP_CRIT_MIN_HYST = 10 # Temperature hysteresis value for critical minimum limit. (not a delta) + AMDSMI_TEMP_OFFSET = 11 # Temperature offset which is added to the temperature reading by the chip. + AMDSMI_TEMP_LOWEST = 12 # Historical minimum temperature. + AMDSMI_TEMP_HIGHEST = 13 # Historical maximum temperature. + AMDSMI_TEMP_LAST = AMDSMI_TEMP_HIGHEST + +class amdsmi_voltage_metric_t (c_int): + AMDSMI_VOLT_CURRENT = 0 # Voltage current value. + AMDSMI_VOLT_FIRST = AMDSMI_VOLT_CURRENT + AMDSMI_VOLT_MAX = 1 # Voltage max value. + AMDSMI_VOLT_MIN_CRIT = 2 # Voltage critical min value. + AMDSMI_VOLT_MIN = 3 # Voltage min value. + AMDSMI_VOLT_MAX_CRIT = 4 # Voltage critical max value. + AMDSMI_VOLT_AVERAGE = 5 # Average voltage. + AMDSMI_VOLT_LOWEST = 6 # Historical minimum voltage. + AMDSMI_VOLT_HIGHEST = 7 # Historical maximum voltage. + AMDSMI_VOLT_LAST = AMDSMI_VOLT_HIGHEST + +# This ennumeration is used to indicate which type of +# voltage reading should be obtained. + +class amdsmi_voltage_type_t (c_int): + AMDSMI_VOLT_TYPE_FIRST = 0 + AMDSMI_VOLT_TYPE_VDDGFX = AMDSMI_VOLT_TYPE_FIRST # Vddgfx GPU voltage + AMDSMI_VOLT_TYPE_LAST = AMDSMI_VOLT_TYPE_VDDGFX + AMDSMI_VOLT_TYPE_INVALID = 0xFFFFFFFF # Invalid type + +# Pre-set Profile Selections. These bitmasks can be AND'd with the +# ::amdsmi_power_profile_status_t.available_profiles returned from +# ::amdsmi_dev_power_profile_presets_get to determine which power profiles +# are supported by the system. + +class amdsmi_power_profile_preset_masks_t (c_int): + AMDSMI_PWR_PROF_PRST_CUSTOM_MASK = 0x1 # Custom Power Profile + AMDSMI_PWR_PROF_PRST_VIDEO_MASK = 0x2 # Video Power Profile + AMDSMI_PWR_PROF_PRST_POWER_SAVING_MASK = 0x4 # Power Saving Profile + AMDSMI_PWR_PROF_PRST_COMPUTE_MASK = 0x8 # Compute Saving Profile + AMDSMI_PWR_PROF_PRST_VR_MASK = 0x10 # VR Power Profile + + # 3D Full Screen Power Profile + AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK = 0x20 + AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT = 0x40 # Default Boot Up Profile + AMDSMI_PWR_PROF_PRST_LAST = AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT + + # Invalid power profile + AMDSMI_PWR_PROF_PRST_INVALID = 0xFFFFFFFFFFFFFFFF + +class amdsmi_gpu_block_t (c_int): + AMDSMI_GPU_BLOCK_INVALID = 0x0000000000000000 # Used to indicate an invalid block + AMDSMI_GPU_BLOCK_FIRST = 0x0000000000000001 + + AMDSMI_GPU_BLOCK_UMC = AMDSMI_GPU_BLOCK_FIRST # UMC block + AMDSMI_GPU_BLOCK_SDMA = 0x0000000000000002 # SDMA block + AMDSMI_GPU_BLOCK_GFX = 0x0000000000000004 # GFX block + AMDSMI_GPU_BLOCK_MMHUB = 0x0000000000000008 # MMHUB block + AMDSMI_GPU_BLOCK_ATHUB = 0x0000000000000010 # ATHUB block + AMDSMI_GPU_BLOCK_PCIE_BIF = 0x0000000000000020 # PCIE_BIF block + AMDSMI_GPU_BLOCK_HDP = 0x0000000000000040 # HDP block + AMDSMI_GPU_BLOCK_XGMI_WAFL = 0x0000000000000080 # XGMI block + AMDSMI_GPU_BLOCK_DF = 0x0000000000000100 # DF block + AMDSMI_GPU_BLOCK_SMN = 0x0000000000000200 # SMN block + AMDSMI_GPU_BLOCK_SEM = 0x0000000000000400 # SEM block + AMDSMI_GPU_BLOCK_MP0 = 0x0000000000000800 # MP0 block + AMDSMI_GPU_BLOCK_MP1 = 0x0000000000001000 # MP1 block + AMDSMI_GPU_BLOCK_FUSE = 0x0000000000002000 # Fuse block + + AMDSMI_GPU_BLOCK_LAST = AMDSMI_GPU_BLOCK_FUSE # The highest bit position for supported blocks + AMDSMI_GPU_BLOCK_RESERVED = 0x8000000000000000 + +class amdsmi_ras_err_state_t (c_int): + AMDSMI_RAS_ERR_STATE_NONE = 0 # No current errors + AMDSMI_RAS_ERR_STATE_DISABLED = 1 # ECC is disabled + AMDSMI_RAS_ERR_STATE_PARITY = 2 # ECC errors present, but type unknown + AMDSMI_RAS_ERR_STATE_SING_C = 3 # Single correctable error + AMDSMI_RAS_ERR_STATE_MULT_UC = 4 # Multiple uncorrectable errors + AMDSMI_RAS_ERR_STATE_POISON = 5 # Firmware detected error and isolated page. Treat as uncorrectable. + AMDSMI_RAS_ERR_STATE_ENABLED = 6 # ECC is enabled + + AMDSMI_RAS_ERR_STATE_LAST = AMDSMI_RAS_ERR_STATE_ENABLED + AMDSMI_RAS_ERR_STATE_INVALID = 0xFFFFFFFF + +class amdsmi_memory_type_t (c_int): + AMDSMI_MEM_TYPE_FIRST = 0 + + AMDSMI_MEM_TYPE_VRAM = AMDSMI_MEM_TYPE_FIRST # VRAM memory + AMDSMI_MEM_TYPE_VIS_VRAM = 1 # VRAM memory that is visible + AMDSMI_MEM_TYPE_GTT = 2 # GTT memory + + AMDSMI_MEM_TYPE_LAST = AMDSMI_MEM_TYPE_GTT + +class amdsmi_freq_ind_t (c_int): + AMDSMI_FREQ_IND_MIN = 0 # Index used for the minimum frequency value + AMDSMI_FREQ_IND_MAX = 1 # Index used for the maximum frequency value + AMDSMI_FREQ_IND_INVALID = 0xFFFFFFFF # An invalid frequency index + +class amdsmi_xgmi_status_t (c_int): + AMDSMI_XGMI_STATUS_NO_ERRORS = 0 + AMDSMI_XGMI_STATUS_ERROR = 1 + AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS = 2 + +amdsmi_bit_field_t = c_uint64() +amdsmi_bit_field = amdsmi_bit_field_t + +# Reserved Memory Page States +class amdsmi_memory_page_status_t (c_int): + AMDSMI_MEM_PAGE_STATUS_RESERVED = 0 # Reserved. This gpu page is reserved and not available for use + AMDSMI_MEM_PAGE_STATUS_PENDING = 1 # Pending. This gpu page is marked as bad + # and will be marked reserved at the next window. + AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE = 2 # Unable to reserve this page + +# Types for IO Link +class AMDSMI_IO_LINK_TYPE (c_int): + AMDSMI_IOLINK_TYPE_UNDEFINED = 0 # unknown type. + AMDSMI_IOLINK_TYPE_PCIEXPRESS = 1 # PCI Express + AMDSMI_IOLINK_TYPE_XGMI = 2 # XGMI + AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES = 3 # Number of IO Link types + AMDSMI_IOLINK_TYPE_SIZE = 0xFFFFFFFF # Max of IO Link types + +# The utilization counter type +class AMDSMI_UTILIZATION_COUNTER_TYPE (c_int): + AMDSMI_UTILIZATION_COUNTER_FIRST = 0 # GFX Activity + AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = AMDSMI_UTILIZATION_COUNTER_FIRST + AMDSMI_COARSE_GRAIN_MEM_ACTIVITY = 1 # Memory Activity + AMDSMI_UTILIZATION_COUNTER_LAST = AMDSMI_COARSE_GRAIN_MEM_ACTIVITY + +# Reserved Memory Page Record +class amdsmi_utilization_counter_t (Structure): + _fields_=[ + ('page_address', c_uint64), + ('page_size', c_uint64), + ('status', amdsmi_memory_page_status_t), + ] + +# Number of possible power profiles that a system could support +AMDSMI_MAX_NUM_POWER_PROFILES = (sizeof(amdsmi_bit_field_t) * 8) + +# This structure contains information about which power profiles are +# supported by the system for a given device, and which power profile is currently active. + +class amdsmi_power_profile_status_t (Structure): + _fields_ = [ + ('available_profiles', c_uint64), # Which profiles are supported by this system + ('current', amdsmi_power_profile_preset_masks_t), # Which power profile is currently active + ('num_profiles', c_uint32) # How many power profiles are available + ] + +# This structure holds information about clock frequencies. +class amdsmi_frequencies_t (Structure): + _fields_ = [ + ('num_supported', c_uint32), # The number of supported frequencies + ('current', c_uint32), # The current frequency index + ('frequency', c_uint64 * AMDSMI_MAX_NUM_FREQUENCIES), # List of frequencies. + # Only the first num_supported frequencies are valid. + ] + +#This structure holds information about the possible PCIe +#bandwidths. Specifically, the possible transfer rates and their +#associated numbers of lanes are stored here. +class amdsmi_pcie_bandwidth_t (Structure): + _fields_ = [ + ('transfer_rate', amdsmi_frequencies_t), # Transfer rates (T/s) that are possible + ('lanes', c_uint32 * AMDSMI_MAX_NUM_FREQUENCIES), # List of lanes for corresponding transfer rate. + # Only the first num_supported bandwidths are valid. + ] + +# This structure holds version information. + +class amdsmi_version_t (Structure): + _fields_ = [ + ('major', c_uint32), # Major version + ('minor', c_uint32), # Minor version + ('patch', c_uint32), # Patch, build or stepping version + ('build', c_char_p), # Build string + ] + +# This structure represents a point on the frequency-voltage plane. +class amdsmi_od_vddc_point_t (Structure): + _fields_ = [ + ('frequency', c_uint64), # Frequency coordinate (in Hz) + ('voltage', c_uint64), # Voltage coordinate (in mV) + ] + +# This structure holds 2 ::amdsmi_range_t's, one for frequency and one for +# voltage. These 2 ranges indicate the range of possible values for the +# corresponding ::amdsmi_od_vddc_point_t. + +class amdsmi_freq_volt_region_t (Structure): + _fields_ = [ + ('freq_range', amdsmi_range_t), # The frequency range for this VDDC Curve point + ('volt_range', amdsmi_range_t), # The voltage range for this VDDC Curve point + ] + +# Array of ::AMDSMI_NUM_VOLTAGE_CURVE_POINTS ::amdsmi_od_vddc_point_t's that +# make up the voltage frequency curve points. + +class amdsmi_od_volt_curve_t (Structure): + _fields_ = [ + # Array of ::AMDSMI_NUM_VOLTAGE_CURVE_POINTS ::amdsmi_od_vddc_point_t's that + # make up the voltage frequency curve points. + ('vc_points', amdsmi_od_vddc_point_t * AMDSMI_NUM_VOLTAGE_CURVE_POINTS) + ] + +# This structure holds the frequency-voltage values for a device. +class amdsmi_od_volt_freq_data_t (Structure): + _fields_ = [ + ('curr_sclk_range', amdsmi_range_t), # The current SCLK frequency range + ('curr_mclk_range', amdsmi_range_t), # The current MCLK frequency range; (upper bound only) + ('sclk_freq_limits', amdsmi_range_t), # The range possible of SCLK values + ('mclk_freq_limits', amdsmi_range_t), # The range possible of MCLK values + ('curve', amdsmi_od_volt_curve_t), # The current voltage curve + ('num_regions', c_uint32), # The number of voltage curve regions + ] + +# The following structures hold the gpu metrics values for a device. +# Size and version information of metrics data + +class amd_metrics_table_header_t (Structure): + _fields_ = [ + ('structure_size', c_uint16), + ('format_revision', c_ubyte), + ('content_revision', c_ubyte), + ] + +AMDSMI_GPU_METRICS_API_FORMAT_VER = 1 +AMDSMI_GPU_METRICS_API_CONTENT_VER_1 = 1 +AMDSMI_GPU_METRICS_API_CONTENT_VER_2 = 2 +AMDSMI_GPU_METRICS_API_CONTENT_VER_3 = 3 + +AMDSMI_NUM_HBM_INSTANCES = 4 # This should match NUM_HBM_INSTANCES +CENTRIGRADE_TO_MILLI_CENTIGRADE = 1000 # Unit conversion factor for HBM temperatures + +class amdsmi_gpu_metrics_t (Structure): + _fields_ = [ + ('common_header', amd_metrics_table_header_t), + # Temperature + ('temperature_edge', c_uint16), + ('temperature_hotspot', c_uint16), + ('temperature_mem', c_uint16), + ('temperature_vrgfx', c_uint16), + ('temperature_vrsoc', c_uint16), + ('temperature_vrmem', c_uint16), + # Utilization + ('average_gfx_activity', c_uint16), + ('average_umc_activity', c_uint16), + ('average_mm_activity', c_uint16), + # Power/Energy + ('average_socket_power', c_uint16), + ('energy_accumulator', c_uint64), + # Driver attached timestamp (in ns) + ('system_clock_counter', c_uint64), + # Average clocks + ('average_gfxclk_frequency', c_uint16), + ('average_socclk_frequency', c_uint16), + ('average_uclk_frequency', c_uint16), + ('average_vclk0_frequency', c_uint16), + ('average_dclk0_frequency', c_uint16), + ('average_vclk1_frequency', c_uint16), + ('average_dclk1_frequency', c_uint16), + # Current clocks + ('current_gfxclk', c_uint16), + ('current_socclk', c_uint16), + ('current_uclk', c_uint16), + ('current_vclk0', c_uint16), + ('current_dclk0', c_uint16), + ('current_vclk1', c_uint16), + ('current_dclk1', c_uint16), + # Throttle status + ('throttle_status', c_uint32), + # Fans + ('current_fan_speed', c_uint16), + # Link width/speed + ('pcie_link_width', c_uint16), # v1 mod.(8->16) + ('pcie_link_speed', c_uint16), # in 0.1 GT/s; v1 mod. (8->16) + ('padding', c_uint16), # new in v1 + ('gfx_activity_acc', c_uint32), # new in v1 + ('mem_actvity_acc', c_uint32), # new in v1 + ('temperature_hbm', c_uint16 * AMDSMI_NUM_HBM_INSTANCES) # new in v1 + ] + +# This structure holds error counts. +class amdsmi_error_count_t (Structure): + _fields_ = [ + ('correctable_count', c_uint64), # Accumulated correctable errors + ('uncorrectable_count', c_uint64) # Accumulated uncorrectable errors + ] + +# This structure holds pcie info. +class amdsmi_pcie_info_t (Structure): + _fields_ = [ + ('pcie_lanes', c_uint16), + ('pcie_speed', c_uint16), + ] + +class amdsmi_process_info_t (Structure): + _fields_ = [ + ('process_id', c_uint32), # Process ID + ('pasid', c_uint32), # PASID + ('vram_usage', c_uint64), # VRAM usage + ('sdma_usage', c_uint64), # SDMA usage in microseconds + ('cu_occupancy', c_uint32), # Compute Unit usage in percent + ] + +# Opaque handle to function-support object +class amdsmi_func_id_iter_handle(Structure): + pass +amdsmi_func_id_iter_handle_t = POINTER(amdsmi_func_id_iter_handle) + +# Place-holder "variant" for functions that have don't have any variants, +# but do have monitors or sensors. + +AMDSMI_DEFAULT_VARIANT = 0xFFFFFFFFFFFFFFFF + +class submodule_union(Union): + _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), + ] +class amdsmi_func_id_value_t (Union): + _fields_ = [ + ('id', c_uint64), + ('name', c_char_p), + ('submodule', submodule_union) + ] + +amd_id = amdsmi_func_id_value_t \ No newline at end of file diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index 69d9ef12b0..b4228dc3d9 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -259,6 +259,8 @@ int main() { // Get device type. Since the amdsmi is initialized with // AMD_SMI_INIT_AMD_GPUS, the device_type must be AMD_GPU. device_type_t device_type = {}; + std::cout << "Device Handle: " << device_handles[j] << std::endl; + ret = amdsmi_get_device_type(device_handles[j], &device_type); CHK_AMDSMI_RET(ret) if (device_type != AMD_GPU) { From 3eadf3a2163604dab63db235dc5d64033f7e7d6e Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Wed, 18 Jan 2023 03:41:27 -0600 Subject: [PATCH 3/7] Adjusted folder naming and moved amdsmi_cli into amdsmi project folder Change-Id: I4b7c42161fc92450f496483e5b49c7def6810437 --- .gitignore | 5 + CMakeLists.txt | 4 +- amd_smi_cli/amd_smi_modules.py | 97 ------------------- {py-interface => amdsmi}/README.md | 0 {py-interface => amdsmi}/__init__.py | 3 +- {amd_smi_cli => amdsmi}/_version.py | 0 {amd_smi_cli => amdsmi/amdsmi_cli}/BDF.py | 0 .../amd_smi.py => amdsmi/amdsmi_cli/amdsmi.py | 5 +- .../amdsmi_cli}/amdsmiBindings.py | 0 .../amdsmi_cli/amdsmi_commands.py | 14 +-- .../amdsmi_cli/amdsmi_helpers.py | 2 +- .../amdsmi_cli/amdsmi_init.py | 29 ++---- .../amdsmi_cli/amdsmi_logger.py | 0 .../amdsmi_cli/amdsmi_parser.py | 4 +- {py-interface => amdsmi}/amdsmi_exception.py | 2 +- {py-interface => amdsmi}/amdsmi_interface.py | 19 ++-- {py-interface => amdsmi}/amdsmi_wrapper.py | 7 +- {py-interface => amdsmi}/rocm_smi_tool.py | 0 amdsmi/setup.py | 21 ++++ py-interface/setup.py | 16 --- 20 files changed, 65 insertions(+), 163 deletions(-) delete mode 100644 amd_smi_cli/amd_smi_modules.py rename {py-interface => amdsmi}/README.md (100%) rename {py-interface => amdsmi}/__init__.py (99%) rename {amd_smi_cli => amdsmi}/_version.py (100%) rename {amd_smi_cli => amdsmi/amdsmi_cli}/BDF.py (100%) rename amd_smi_cli/amd_smi.py => amdsmi/amdsmi_cli/amdsmi.py (93%) mode change 100644 => 100755 rename {amd_smi_cli => amdsmi/amdsmi_cli}/amdsmiBindings.py (100%) rename amd_smi_cli/amd_smi_commands.py => amdsmi/amdsmi_cli/amdsmi_commands.py (77%) rename amd_smi_cli/amd_smi_helpers.py => amdsmi/amdsmi_cli/amdsmi_helpers.py (99%) rename amd_smi_cli/amd_smi_init.py => amdsmi/amdsmi_cli/amdsmi_init.py (55%) rename amd_smi_cli/amd_smi_logger.py => amdsmi/amdsmi_cli/amdsmi_logger.py (100%) rename amd_smi_cli/amd_smi_parser.py => amdsmi/amdsmi_cli/amdsmi_parser.py (99%) rename {py-interface => amdsmi}/amdsmi_exception.py (99%) rename {py-interface => amdsmi}/amdsmi_interface.py (99%) rename {py-interface => amdsmi}/amdsmi_wrapper.py (99%) rename {py-interface => amdsmi}/rocm_smi_tool.py (100%) create mode 100644 amdsmi/setup.py delete mode 100644 py-interface/setup.py diff --git a/.gitignore b/.gitignore index d87e07ee63..5b157b6f4b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ DEBIAN/postinst DEBIAN/prerm RPM/ docs/*.pdf + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*.egg-* diff --git a/CMakeLists.txt b/CMakeLists.txt index 31aa11d5dc..e00040d309 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,10 +155,10 @@ if(PYTHON3 AND PIP3) python3 ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/generator.py -o ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi_wrapper.py -i ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi.h -l ${CMAKE_CURRENT_BINARY_DIR}/src/libamd_smi.so COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi_wrapper.py - ${CMAKE_CURRENT_SOURCE_DIR}/py-interface/ + ${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(PY_INTERFACE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/py_interface") set(PACKAGE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/python_package/amdsmi") add_custom_target( diff --git a/amd_smi_cli/amd_smi_modules.py b/amd_smi_cli/amd_smi_modules.py deleted file mode 100644 index 97556b9d14..0000000000 --- a/amd_smi_cli/amd_smi_modules.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/python3 - -import argparse -import platform -import signal -import subprocess -import sys -import time -import traceback - -from pathlib import Path - -import BDF -from amd_smi_init import * - -class AMD_SMI_Modules(object): - def __init__(self) -> None: - pass - - - def get_socket_handles(self): - ### Returns tuple of (int, list of ctypes: socket_handles) - socket_count = c_uint32(0) - return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), None) - check_return(return_code=return_code, error_statment="Invalid get_socket_handles request") - - sockets = [0] * socket_count.value # 1 - socket_handles = (c_void_p * socket_count.value)(*sockets) # That is a pointer, not a multiplication - return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), socket_handles) - check_return(return_code=return_code, error_statment=f"Invalid get_socket_handles with {socket_count.value} sockets") - return (socket_count.value, socket_handles) - - - def get_device_handles(self, socket_handle): - """Gets the Device Handles that are in the current socket""" - ### Returns tuple of (int, list of ctypes: device_handles) - device_count = c_uint32(0) - return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), None) - check_return(return_code=return_code, error_statment="Invalid get_device_handles request") - - devices = [0] * device_count.value - device_handles = (c_void_p * len(devices))(*devices) - return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), byref(device_handles)) - check_return(return_code=return_code, error_statment=f"Invalid get_device_handles with {device_count.value} devices") - return (device_count.value, device_handles) - - - def get_socket_info(self, socket_handle): - """ Given a socket_handle, return the socket_info, which is just a BDF object""" - socket_info = create_string_buffer(128) # createstringbuffer or something??? c_char_p - return_code = amdsmi.amdsmi_get_socket_info(socket_handle, byref(socket_info), c_size_t(128)) - check_return(return_code=return_code, error_statment="Invalid get_socket_info request") - socket_bdf = BDF.BDF(socket_info.value.decode()) - return(socket_bdf) - - - def get_device_type(self, device_handle, format=True): - # format: True for string; False for int - # Returns device_type string for the given device_handle - dev_type = c_int(0) - return_code = amdsmi.amdsmi_get_device_type(device_handle, byref(dev_type)) - check_return(return_code=return_code, error_statment="Invalid get_device_type request") - - if format == True: # Return string - return device_type__enumvalues[dev_type.value] - - return dev_type.value # Return int - - - def get_device_bdf(self, device_handle): - - # class amdsmi_bdf_t (Union): - # _fields_ = [ - # ('bdf_submodule', bdf_submodule), - # ('as_uint', c_uint64) - # ] - bdf = amdsmi_bdf_t() - # bdf.bdf_submodule - - - - return_code = amdsmi.amdsmi_get_device_bdf(device_handle, bdf) - check_return(return_code=return_code, error_statment="Invalid amdsmi_get_device_bdf request") - return (bdf) - - - def get_device_handle_from_bdf(self, bdf): - pass - - - def get_fan_speed(self, bdf): - pass - - def show_retired_pages(self): - # num_pages = c_uint32() - # records = rsmi_retired_page_record_t() - pass \ No newline at end of file diff --git a/py-interface/README.md b/amdsmi/README.md similarity index 100% rename from py-interface/README.md rename to amdsmi/README.md diff --git a/py-interface/__init__.py b/amdsmi/__init__.py similarity index 99% rename from py-interface/__init__.py rename to amdsmi/__init__.py index 82c8dd1d8c..18531e0128 100644 --- a/py-interface/__init__.py +++ b/amdsmi/__init__.py @@ -177,7 +177,6 @@ from .amdsmi_interface import amdsmi_is_P2P_accessible from .amdsmi_interface import amdsmi_get_xgmi_info # # Enums - from .amdsmi_interface import AmdSmiInitFlags from .amdsmi_interface import AmdSmiContainerTypes from .amdsmi_interface import AmdSmiDeviceType @@ -205,8 +204,8 @@ from .amdsmi_interface import AmdSmiIoLinkType from .amdsmi_interface import AmdSmiUtilizationCounterType from .amdsmi_interface import AmdSmiSwComponent from .amdsmi_interface import AmdSmiIoLinkType -# Exceptions +# Exceptions from .amdsmi_exception import AmdSmiLibraryException from .amdsmi_exception import AmdSmiRetryException from .amdsmi_exception import AmdSmiParameterException diff --git a/amd_smi_cli/_version.py b/amdsmi/_version.py similarity index 100% rename from amd_smi_cli/_version.py rename to amdsmi/_version.py diff --git a/amd_smi_cli/BDF.py b/amdsmi/amdsmi_cli/BDF.py similarity index 100% rename from amd_smi_cli/BDF.py rename to amdsmi/amdsmi_cli/BDF.py diff --git a/amd_smi_cli/amd_smi.py b/amdsmi/amdsmi_cli/amdsmi.py old mode 100644 new mode 100755 similarity index 93% rename from amd_smi_cli/amd_smi.py rename to amdsmi/amdsmi_cli/amdsmi.py index 88c9d9c3c3..9bc25f5fb9 --- a/amd_smi_cli/amd_smi.py +++ b/amdsmi/amdsmi_cli/amdsmi.py @@ -2,9 +2,8 @@ # from amd_smi_init import * -from amd_smi_commands import AMD_SMI_Commands -from amd_smi_parser import AMD_SMI_Parser - +from amdsmi_commands import AMD_SMI_Commands +from amdsmi_parser import AMD_SMI_Parser # sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool diff --git a/amd_smi_cli/amdsmiBindings.py b/amdsmi/amdsmi_cli/amdsmiBindings.py similarity index 100% rename from amd_smi_cli/amdsmiBindings.py rename to amdsmi/amdsmi_cli/amdsmiBindings.py diff --git a/amd_smi_cli/amd_smi_commands.py b/amdsmi/amdsmi_cli/amdsmi_commands.py similarity index 77% rename from amd_smi_cli/amd_smi_commands.py rename to amdsmi/amdsmi_cli/amdsmi_commands.py index e5ea6b8478..a6a8cbc16e 100644 --- a/amd_smi_cli/amd_smi_commands.py +++ b/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -13,9 +13,8 @@ from pathlib import Path from BDF import BDF from _version import __version__ -from amd_smi_logger import AMD_SMI_Logger - - +from amdsmi_logger import AMD_SMI_Logger +from amdsmi_helpers import * class AMD_SMI_Commands(object): # def __init__(self, amd_smi_logger) -> None: @@ -30,8 +29,10 @@ class AMD_SMI_Commands(object): def version(self, args): kernel_version = 123 - print(f'AMD-SMI version: {__version__} | Kernel version: {kernel_version}') - + amdsmi_lib_version = amdsmi_interface.amdsmi_get_version() + {'major': 1, 'minor': 0, 'patch': 0, 'build': '0'} + amdsmi_lib_version_str = f'{amdsmi_lib_version["major"]}.{amdsmi_lib_version["minor"]}.{amdsmi_lib_version["patch"]}' + print(f'AMD-SMI Tool: {__version__} | AMD-SMI Library version: {amdsmi_lib_version_str} | Kernel version: {kernel_version}') def discovery(self, args): print('discovery test') @@ -46,7 +47,8 @@ class AMD_SMI_Commands(object): def firmware(self, args): - print('firmware test') + for elem in range(100000): + time.sleep(1) def bad_pages(self, args): diff --git a/amd_smi_cli/amd_smi_helpers.py b/amdsmi/amdsmi_cli/amdsmi_helpers.py similarity index 99% rename from amd_smi_cli/amd_smi_helpers.py rename to amdsmi/amdsmi_cli/amdsmi_helpers.py index e23c792a19..21c5f8104f 100644 --- a/amd_smi_cli/amd_smi_helpers.py +++ b/amdsmi/amdsmi_cli/amdsmi_helpers.py @@ -12,7 +12,7 @@ import logging from pathlib import Path from BDF import BDF -from amd_smi_init import * +from amdsmi_init import * class AMD_SMI_Helpers(object): diff --git a/amd_smi_cli/amd_smi_init.py b/amdsmi/amdsmi_cli/amdsmi_init.py similarity index 55% rename from amd_smi_cli/amd_smi_init.py rename to amdsmi/amdsmi_cli/amdsmi_init.py index b6daa1abc0..ef64e5a3cd 100644 --- a/amd_smi_cli/amd_smi_init.py +++ b/amdsmi/amdsmi_cli/amdsmi_init.py @@ -11,7 +11,8 @@ import sys from pathlib import Path # Handle bindings for windows, Hyper-v and KVM seperately -from amdsmiBindings import * +import amdsmi_interface + # Using basic python logging for user errors and development # logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) # Logging for Development @@ -20,11 +21,6 @@ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR) # # On initial import set initialized variable amd_smi_initialized = False -def check_return(return_code, error_statment): #@TODO would raising an exception be better? - if return_code != amdsmi_status.AMDSMI_STATUS_SUCCESS: - logging.error(error_statment) - sys.exit(return_code) - def check_amdgpu_driver(): #@TODO Handle KVM logic """ Returns true if amdgpu is found in the list of initialized modules """ @@ -37,29 +33,20 @@ def check_amdgpu_driver(): #@TODO Handle KVM logic return False -def init_amd_smi(flag=amdsmi_init_flags.AMD_SMI_INIT_AMD_GPUS): +def init_amd_smi(flag=amdsmi_interface.AmdSmiInitFlags.AMD_GPUS): """ Initializes AMD-SMI """ - # Check if amdgpu driver is up + # Check if amdgpu driver is up & Handle error gracefully if check_amdgpu_driver(): # Only init AMD GPUs for now, waiting for future support for AMD CPUs - init_status = amdsmi.amdsmi_init(flag) - check_return(return_code=init_status, error_statment=f'AMD SMI initialization returned {init_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') - logging.info('amd-smi initialized successfully') + amdsmi_interface.amdsmi_init(flag) + logging.info('amd-smi initialized successfully') # without errors really else: logging.error('Driver not initialized (amdgpu not found in modules)') exit(-1) -def amdsmi_shut_down(): - """ Shutdown AMD-SMI """ - # Only init AMD GPUs for now, waiting for future support for AMD CPUs - shut_down_status = amdsmi.amdsmi_shut_down() - check_return(return_code=shut_down_status, error_statment=f'AMD SMI Shutdown code returned {shut_down_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') - logging.debug('amd-smi shutdown successfully') - - def signal_handler(sig, frame): - logging.debug(f'Handling signal: {sig}') + logging.info(f'Handling signal: {sig}') sys.exit(0) @@ -68,4 +55,4 @@ if not amd_smi_initialized: amd_smi_initialized = True signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) - atexit.register(amdsmi_shut_down) + atexit.register(amdsmi_interface.amdsmi_shut_down) diff --git a/amd_smi_cli/amd_smi_logger.py b/amdsmi/amdsmi_cli/amdsmi_logger.py similarity index 100% rename from amd_smi_cli/amd_smi_logger.py rename to amdsmi/amdsmi_cli/amdsmi_logger.py diff --git a/amd_smi_cli/amd_smi_parser.py b/amdsmi/amdsmi_cli/amdsmi_parser.py similarity index 99% rename from amd_smi_cli/amd_smi_parser.py rename to amdsmi/amdsmi_cli/amdsmi_parser.py index 0edf07417f..d5bd4b4186 100644 --- a/amd_smi_cli/amd_smi_parser.py +++ b/amdsmi/amdsmi_cli/amdsmi_parser.py @@ -4,7 +4,7 @@ import argparse import platform from _version import __version__ -from amd_smi_helpers import AMD_SMI_Helpers +from amdsmi_helpers import AMD_SMI_Helpers # sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool @@ -50,7 +50,7 @@ class AMD_SMI_Parser(argparse.ArgumentParser): # self.add_set_value_parser(subparsers, set_value) self.add_reset_parser(subparsers, reset) self.add_misc_parser(subparsers, misc) - self.add_gpu_v_parser(subparsers, misc) + # self.add_gpu_v_parser(subparsers, misc) def add_version_parser(self, subparsers, func): diff --git a/py-interface/amdsmi_exception.py b/amdsmi/amdsmi_exception.py similarity index 99% rename from py-interface/amdsmi_exception.py rename to amdsmi/amdsmi_exception.py index 2659a44fe0..4e23060c13 100644 --- a/py-interface/amdsmi_exception.py +++ b/amdsmi/amdsmi_exception.py @@ -20,7 +20,7 @@ # from enum import IntEnum -from . import amdsmi_wrapper +import amdsmi_wrapper class AmdSmiRetCode(IntEnum): diff --git a/py-interface/amdsmi_interface.py b/amdsmi/amdsmi_interface.py similarity index 99% rename from py-interface/amdsmi_interface.py rename to amdsmi/amdsmi_interface.py index 14f26a7617..1473579566 100644 --- a/py-interface/amdsmi_interface.py +++ b/amdsmi/amdsmi_interface.py @@ -25,8 +25,8 @@ from typing import Union, Any, Dict, List, Tuple from enum import IntEnum from collections.abc import Iterable -from . import amdsmi_wrapper -from .amdsmi_exception import * +import amdsmi_wrapper +from amdsmi_exception import * class AmdSmiInitFlags(IntEnum): @@ -498,8 +498,7 @@ def amdsmi_get_socket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: socket_count.value)() _check_res( amdsmi_wrapper.amdsmi_get_socket_handles( - ctypes.byref(socket_count), socket_handles - ) + ctypes.byref(socket_count), socket_handles) ) sockets = [ amdsmi_wrapper.amdsmi_socket_handle(socket_handles[sock_idx]) @@ -513,12 +512,16 @@ def amdsmi_get_socket_info(socket_handle): if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_socket_handle): raise AmdSmiParameterException( socket_handle, amdsmi_wrapper.amdsmi_socket_handle) + socket_info = ctypes.create_string_buffer(128) + + _check_res( + amdsmi_wrapper.get_socket_info( + socket_handle, ctypes.byref(socket_info), ctypes.c_size_t(128)) + ) - return { - "name": "" - } - + return socket_info.value.decode() +# This input is different, also this List defintion doesn't really work because you never return that, you return a list of lists def amdsmi_get_device_handles() -> List[amdsmi_wrapper.amdsmi_device_handle]: socket_handles = amdsmi_get_socket_handles() devices = [] diff --git a/py-interface/amdsmi_wrapper.py b/amdsmi/amdsmi_wrapper.py similarity index 99% rename from py-interface/amdsmi_wrapper.py rename to amdsmi/amdsmi_wrapper.py index 6e88431c22..20eb758661 100644 --- a/py-interface/amdsmi_wrapper.py +++ b/amdsmi/amdsmi_wrapper.py @@ -165,11 +165,10 @@ def char_pointer_cast(string, encoding='utf-8'): return ctypes.cast(string, ctypes.POINTER(ctypes.c_char)) - +# Change this to more dynamic later or in /opt/rocm/lib/libamd_smi64.so _libraries = {} -_libraries['libamd_smi.so'] = ctypes.CDLL(os.path.join(os.path.dirname(__file__), 'libamd_smi.so')) - - +amd_smi_lib_so_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../build/src/libamd_smi.so')) +_libraries['libamd_smi.so'] = ctypes.CDLL(amd_smi_lib_so_path) # values for enumeration 'c__EA_amdsmi_init_flags_t' c__EA_amdsmi_init_flags_t__enumvalues = { diff --git a/py-interface/rocm_smi_tool.py b/amdsmi/rocm_smi_tool.py similarity index 100% rename from py-interface/rocm_smi_tool.py rename to amdsmi/rocm_smi_tool.py diff --git a/amdsmi/setup.py b/amdsmi/setup.py new file mode 100644 index 0000000000..ee28d92576 --- /dev/null +++ b/amdsmi/setup.py @@ -0,0 +1,21 @@ +from setuptools import setup, find_packages +from _version import __version__ + +with open("README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() + +setup( + name='amdsmi', + version=__version__, + description="SMI LIB - AMD GPU Monitoring Library", + long_description=long_description, + long_description_content_type="text/markdown", + packages=find_packages(), # can be customized later, but works for now + package_data={'': ['LICENSE']}, + include_package_data=True, + python_requires=">=3.6", +) + +# To build wheel +# python3 -m pip install -U wheel +# python3 setup.py bdist_wheel \ No newline at end of file diff --git a/py-interface/setup.py b/py-interface/setup.py deleted file mode 100644 index 6a4bc6480f..0000000000 --- a/py-interface/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -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", -) From bf79fe432328da07f11e8149b5a5ce130f26e325 Mon Sep 17 00:00:00 2001 From: Dalibor Stanisavljevic Date: Wed, 18 Jan 2023 15:57:50 +0100 Subject: [PATCH 4/7] SWDEV-378294 - Fixed failing tests Change-Id: Ie0f9dedd6901e05b1a5ca7846624c127d92ed67f Signed-off-by: Dalibor Stanisavljevic --- README.md | 2 +- tests/amd_smi_test/functional/frequencies_read_write.cc | 4 ++-- tests/amd_smi_test/functional/volt_freq_curv_read.cc | 6 +++--- tests/amd_smi_test/test_base.cc | 2 +- tests/amd_smi_test/test_common.cc | 2 +- tests/amd_smi_test/test_common.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a8ca2343f1..edfcecde0f 100755 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ int main() { } // Get device name - amdsmi_board_info board_info; + amdsmi_board_info_t board_info; ret = amdsmi_get_board_info(device_handles[j], &board_info); std::cout << "\tdevice " << j <<"\n\t\tName:" << board_info.product_name << std::endl; diff --git a/tests/amd_smi_test/functional/frequencies_read_write.cc b/tests/amd_smi_test/functional/frequencies_read_write.cc index 17185486f3..818662683c 100755 --- a/tests/amd_smi_test/functional/frequencies_read_write.cc +++ b/tests/amd_smi_test/functional/frequencies_read_write.cc @@ -93,7 +93,7 @@ void TestFrequenciesReadWrite::Run(void) { amdsmi_status_t ret; amdsmi_frequencies_t f; uint32_t freq_bitmask; - amdsmi_clk_type amdsmi_clk; + amdsmi_clk_type_t amdsmi_clk; TestBase::Run(); if (setup_failed_) { @@ -106,7 +106,7 @@ void TestFrequenciesReadWrite::Run(void) { for (uint32_t clk = (uint32_t)CLK_TYPE_FIRST; clk <= CLK_TYPE__MAX; ++clk) { - amdsmi_clk = (amdsmi_clk_type)clk; + amdsmi_clk = (amdsmi_clk_type_t)clk; auto freq_read = [&]() -> bool { // Skip CLK_TYPE_PCIE, which does not supported in rocm-smi. diff --git a/tests/amd_smi_test/functional/volt_freq_curv_read.cc b/tests/amd_smi_test/functional/volt_freq_curv_read.cc index e2da710dd9..a0c18ee7ba 100755 --- a/tests/amd_smi_test/functional/volt_freq_curv_read.cc +++ b/tests/amd_smi_test/functional/volt_freq_curv_read.cc @@ -84,7 +84,7 @@ void TestVoltCurvRead::Close() { TestBase::Close(); } -static void pt_rng_Mhz(std::string title, amdsmi_range *r) { +static void pt_rng_Mhz(std::string title, amdsmi_range_t *r) { assert(r != nullptr); std::cout << title << std::endl; @@ -92,7 +92,7 @@ static void pt_rng_Mhz(std::string title, amdsmi_range *r) { r->upper_bound/1000000 << " MHz" << std::endl; } -static void pt_rng_mV(std::string title, amdsmi_range *r) { +static void pt_rng_mV(std::string title, amdsmi_range_t *r) { assert(r != nullptr); std::cout << title << std::endl; @@ -105,7 +105,7 @@ static void print_pnt(amdsmi_od_vddc_point_t *pt) { std::endl; std::cout << "\t\t** Voltage: " << pt->voltage << "mV" << std::endl; } -static void pt_vddc_curve(amdsmi_od_volt_curve *c) { +static void pt_vddc_curve(amdsmi_od_volt_curve_t *c) { assert(c != nullptr); for (uint32_t i = 0; i < AMDSMI_NUM_VOLTAGE_CURVE_POINTS; ++i) { diff --git a/tests/amd_smi_test/test_base.cc b/tests/amd_smi_test/test_base.cc index 4131aedb65..2ae7662076 100644 --- a/tests/amd_smi_test/test_base.cc +++ b/tests/amd_smi_test/test_base.cc @@ -173,7 +173,7 @@ void TestBase::PrintDeviceHeader(amdsmi_device_handle dv_ind) { std::cout << "\t**Device ID: 0x" << std::hex << val_ui16 << std::endl; } - amdsmi_board_info board_info; + amdsmi_board_info_t board_info; err = amdsmi_get_board_info(dv_ind, &board_info); CHK_ERR_ASRT(err) IF_VERB(STANDARD) { diff --git a/tests/amd_smi_test/test_common.cc b/tests/amd_smi_test/test_common.cc index 033694f3f0..2aec2708bc 100644 --- a/tests/amd_smi_test/test_common.cc +++ b/tests/amd_smi_test/test_common.cc @@ -214,7 +214,7 @@ const char *GetErrStateNameStr(amdsmi_ras_err_state_t st) { const std::string GetVoltSensorNameStr(amdsmi_voltage_type_t st) { return kVoltSensorNameMap.at(st); } -const char *FreqEnumToStr(amdsmi_clk_type amdsmi_clk) { +const char *FreqEnumToStr(amdsmi_clk_type_t amdsmi_clk) { static_assert(CLK_TYPE__MAX == CLK_TYPE_DCLK1, "FreqEnumToStr() needs to be updated"); switch (amdsmi_clk) { diff --git a/tests/amd_smi_test/test_common.h b/tests/amd_smi_test/test_common.h index d8ab88fcda..51de1f4c04 100644 --- a/tests/amd_smi_test/test_common.h +++ b/tests/amd_smi_test/test_common.h @@ -66,7 +66,7 @@ void PrintTestHeader(uint32_t dv_ind); const char *GetPerfLevelStr(amdsmi_dev_perf_level_t lvl); const char *GetBlockNameStr(amdsmi_gpu_block_t id); const char *GetErrStateNameStr(amdsmi_ras_err_state_t st); -const char *FreqEnumToStr(amdsmi_clk_type amdsmi_clk); +const char *FreqEnumToStr(amdsmi_clk_type_t amdsmi_clk); const std::string GetVoltSensorNameStr(amdsmi_voltage_type_t st); #if ENABLE_SMI From ed8f865341da542d46a8d4166f7a6db7675cb5c0 Mon Sep 17 00:00:00 2001 From: Dalibor Stanisavljevic Date: Thu, 19 Jan 2023 15:33:01 +0100 Subject: [PATCH 5/7] Revert "Adjusted folder naming and moved amdsmi_cli into amdsmi project folder" This reverts commit 3eadf3a2163604dab63db235dc5d64033f7e7d6e because build failed Change-Id: Id9efa22f3e1167e1b1bb235b449aef60256c0e24 Signed-off-by: Dalibor Stanisavljevic --- .gitignore | 5 - CMakeLists.txt | 4 +- {amdsmi/amdsmi_cli => amd_smi_cli}/BDF.py | 0 {amdsmi => amd_smi_cli}/_version.py | 0 .../amdsmi.py => amd_smi_cli/amd_smi.py | 5 +- .../amd_smi_commands.py | 14 ++- .../amd_smi_helpers.py | 2 +- .../amd_smi_init.py | 29 ++++-- .../amd_smi_logger.py | 0 amd_smi_cli/amd_smi_modules.py | 97 +++++++++++++++++++ .../amd_smi_parser.py | 4 +- .../amdsmiBindings.py | 0 amdsmi/setup.py | 21 ---- {amdsmi => py-interface}/README.md | 0 {amdsmi => py-interface}/__init__.py | 3 +- {amdsmi => py-interface}/amdsmi_exception.py | 2 +- {amdsmi => py-interface}/amdsmi_interface.py | 19 ++-- {amdsmi => py-interface}/amdsmi_wrapper.py | 7 +- {amdsmi => py-interface}/rocm_smi_tool.py | 0 py-interface/setup.py | 16 +++ 20 files changed, 163 insertions(+), 65 deletions(-) rename {amdsmi/amdsmi_cli => amd_smi_cli}/BDF.py (100%) rename {amdsmi => amd_smi_cli}/_version.py (100%) rename amdsmi/amdsmi_cli/amdsmi.py => amd_smi_cli/amd_smi.py (93%) mode change 100755 => 100644 rename amdsmi/amdsmi_cli/amdsmi_commands.py => amd_smi_cli/amd_smi_commands.py (77%) rename amdsmi/amdsmi_cli/amdsmi_helpers.py => amd_smi_cli/amd_smi_helpers.py (99%) rename amdsmi/amdsmi_cli/amdsmi_init.py => amd_smi_cli/amd_smi_init.py (55%) rename amdsmi/amdsmi_cli/amdsmi_logger.py => amd_smi_cli/amd_smi_logger.py (100%) create mode 100644 amd_smi_cli/amd_smi_modules.py rename amdsmi/amdsmi_cli/amdsmi_parser.py => amd_smi_cli/amd_smi_parser.py (99%) rename {amdsmi/amdsmi_cli => amd_smi_cli}/amdsmiBindings.py (100%) delete mode 100644 amdsmi/setup.py rename {amdsmi => py-interface}/README.md (100%) rename {amdsmi => py-interface}/__init__.py (99%) rename {amdsmi => py-interface}/amdsmi_exception.py (99%) rename {amdsmi => py-interface}/amdsmi_interface.py (99%) rename {amdsmi => py-interface}/amdsmi_wrapper.py (99%) rename {amdsmi => py-interface}/rocm_smi_tool.py (100%) create mode 100644 py-interface/setup.py diff --git a/.gitignore b/.gitignore index 5b157b6f4b..d87e07ee63 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,3 @@ DEBIAN/postinst DEBIAN/prerm RPM/ docs/*.pdf - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*.egg-* diff --git a/CMakeLists.txt b/CMakeLists.txt index e00040d309..31aa11d5dc 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,10 +155,10 @@ if(PYTHON3 AND PIP3) python3 ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/generator.py -o ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi_wrapper.py -i ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi.h -l ${CMAKE_CURRENT_BINARY_DIR}/src/libamd_smi.so COMMAND cp ${CMAKE_CURRENT_BINARY_DIR}/amdsmi_wrapper/amdsmi_wrapper.py - ${CMAKE_CURRENT_SOURCE_DIR}/py_interface/ + ${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(PY_INTERFACE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/py-interface") set(PACKAGE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/python_package/amdsmi") add_custom_target( diff --git a/amdsmi/amdsmi_cli/BDF.py b/amd_smi_cli/BDF.py similarity index 100% rename from amdsmi/amdsmi_cli/BDF.py rename to amd_smi_cli/BDF.py diff --git a/amdsmi/_version.py b/amd_smi_cli/_version.py similarity index 100% rename from amdsmi/_version.py rename to amd_smi_cli/_version.py diff --git a/amdsmi/amdsmi_cli/amdsmi.py b/amd_smi_cli/amd_smi.py old mode 100755 new mode 100644 similarity index 93% rename from amdsmi/amdsmi_cli/amdsmi.py rename to amd_smi_cli/amd_smi.py index 9bc25f5fb9..88c9d9c3c3 --- a/amdsmi/amdsmi_cli/amdsmi.py +++ b/amd_smi_cli/amd_smi.py @@ -2,8 +2,9 @@ # from amd_smi_init import * -from amdsmi_commands import AMD_SMI_Commands -from amdsmi_parser import AMD_SMI_Parser +from amd_smi_commands import AMD_SMI_Commands +from amd_smi_parser import AMD_SMI_Parser + # sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool diff --git a/amdsmi/amdsmi_cli/amdsmi_commands.py b/amd_smi_cli/amd_smi_commands.py similarity index 77% rename from amdsmi/amdsmi_cli/amdsmi_commands.py rename to amd_smi_cli/amd_smi_commands.py index a6a8cbc16e..e5ea6b8478 100644 --- a/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/amd_smi_cli/amd_smi_commands.py @@ -13,8 +13,9 @@ from pathlib import Path from BDF import BDF from _version import __version__ -from amdsmi_logger import AMD_SMI_Logger -from amdsmi_helpers import * +from amd_smi_logger import AMD_SMI_Logger + + class AMD_SMI_Commands(object): # def __init__(self, amd_smi_logger) -> None: @@ -29,10 +30,8 @@ class AMD_SMI_Commands(object): def version(self, args): kernel_version = 123 - amdsmi_lib_version = amdsmi_interface.amdsmi_get_version() - {'major': 1, 'minor': 0, 'patch': 0, 'build': '0'} - amdsmi_lib_version_str = f'{amdsmi_lib_version["major"]}.{amdsmi_lib_version["minor"]}.{amdsmi_lib_version["patch"]}' - print(f'AMD-SMI Tool: {__version__} | AMD-SMI Library version: {amdsmi_lib_version_str} | Kernel version: {kernel_version}') + print(f'AMD-SMI version: {__version__} | Kernel version: {kernel_version}') + def discovery(self, args): print('discovery test') @@ -47,8 +46,7 @@ class AMD_SMI_Commands(object): def firmware(self, args): - for elem in range(100000): - time.sleep(1) + print('firmware test') def bad_pages(self, args): diff --git a/amdsmi/amdsmi_cli/amdsmi_helpers.py b/amd_smi_cli/amd_smi_helpers.py similarity index 99% rename from amdsmi/amdsmi_cli/amdsmi_helpers.py rename to amd_smi_cli/amd_smi_helpers.py index 21c5f8104f..e23c792a19 100644 --- a/amdsmi/amdsmi_cli/amdsmi_helpers.py +++ b/amd_smi_cli/amd_smi_helpers.py @@ -12,7 +12,7 @@ import logging from pathlib import Path from BDF import BDF -from amdsmi_init import * +from amd_smi_init import * class AMD_SMI_Helpers(object): diff --git a/amdsmi/amdsmi_cli/amdsmi_init.py b/amd_smi_cli/amd_smi_init.py similarity index 55% rename from amdsmi/amdsmi_cli/amdsmi_init.py rename to amd_smi_cli/amd_smi_init.py index ef64e5a3cd..b6daa1abc0 100644 --- a/amdsmi/amdsmi_cli/amdsmi_init.py +++ b/amd_smi_cli/amd_smi_init.py @@ -11,8 +11,7 @@ import sys from pathlib import Path # Handle bindings for windows, Hyper-v and KVM seperately -import amdsmi_interface - +from amdsmiBindings import * # Using basic python logging for user errors and development # logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) # Logging for Development @@ -21,6 +20,11 @@ logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR) # # On initial import set initialized variable amd_smi_initialized = False +def check_return(return_code, error_statment): #@TODO would raising an exception be better? + if return_code != amdsmi_status.AMDSMI_STATUS_SUCCESS: + logging.error(error_statment) + sys.exit(return_code) + def check_amdgpu_driver(): #@TODO Handle KVM logic """ Returns true if amdgpu is found in the list of initialized modules """ @@ -33,20 +37,29 @@ def check_amdgpu_driver(): #@TODO Handle KVM logic return False -def init_amd_smi(flag=amdsmi_interface.AmdSmiInitFlags.AMD_GPUS): +def init_amd_smi(flag=amdsmi_init_flags.AMD_SMI_INIT_AMD_GPUS): """ Initializes AMD-SMI """ - # Check if amdgpu driver is up & Handle error gracefully + # Check if amdgpu driver is up if check_amdgpu_driver(): # Only init AMD GPUs for now, waiting for future support for AMD CPUs - amdsmi_interface.amdsmi_init(flag) - logging.info('amd-smi initialized successfully') # without errors really + init_status = amdsmi.amdsmi_init(flag) + check_return(return_code=init_status, error_statment=f'AMD SMI initialization returned {init_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') + logging.info('amd-smi initialized successfully') else: logging.error('Driver not initialized (amdgpu not found in modules)') exit(-1) +def amdsmi_shut_down(): + """ Shutdown AMD-SMI """ + # Only init AMD GPUs for now, waiting for future support for AMD CPUs + shut_down_status = amdsmi.amdsmi_shut_down() + check_return(return_code=shut_down_status, error_statment=f'AMD SMI Shutdown code returned {shut_down_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') + logging.debug('amd-smi shutdown successfully') + + def signal_handler(sig, frame): - logging.info(f'Handling signal: {sig}') + logging.debug(f'Handling signal: {sig}') sys.exit(0) @@ -55,4 +68,4 @@ if not amd_smi_initialized: amd_smi_initialized = True signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) - atexit.register(amdsmi_interface.amdsmi_shut_down) + atexit.register(amdsmi_shut_down) diff --git a/amdsmi/amdsmi_cli/amdsmi_logger.py b/amd_smi_cli/amd_smi_logger.py similarity index 100% rename from amdsmi/amdsmi_cli/amdsmi_logger.py rename to amd_smi_cli/amd_smi_logger.py diff --git a/amd_smi_cli/amd_smi_modules.py b/amd_smi_cli/amd_smi_modules.py new file mode 100644 index 0000000000..97556b9d14 --- /dev/null +++ b/amd_smi_cli/amd_smi_modules.py @@ -0,0 +1,97 @@ +#!/usr/bin/python3 + +import argparse +import platform +import signal +import subprocess +import sys +import time +import traceback + +from pathlib import Path + +import BDF +from amd_smi_init import * + +class AMD_SMI_Modules(object): + def __init__(self) -> None: + pass + + + def get_socket_handles(self): + ### Returns tuple of (int, list of ctypes: socket_handles) + socket_count = c_uint32(0) + return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), None) + check_return(return_code=return_code, error_statment="Invalid get_socket_handles request") + + sockets = [0] * socket_count.value # 1 + socket_handles = (c_void_p * socket_count.value)(*sockets) # That is a pointer, not a multiplication + return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), socket_handles) + check_return(return_code=return_code, error_statment=f"Invalid get_socket_handles with {socket_count.value} sockets") + return (socket_count.value, socket_handles) + + + def get_device_handles(self, socket_handle): + """Gets the Device Handles that are in the current socket""" + ### Returns tuple of (int, list of ctypes: device_handles) + device_count = c_uint32(0) + return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), None) + check_return(return_code=return_code, error_statment="Invalid get_device_handles request") + + devices = [0] * device_count.value + device_handles = (c_void_p * len(devices))(*devices) + return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), byref(device_handles)) + check_return(return_code=return_code, error_statment=f"Invalid get_device_handles with {device_count.value} devices") + return (device_count.value, device_handles) + + + def get_socket_info(self, socket_handle): + """ Given a socket_handle, return the socket_info, which is just a BDF object""" + socket_info = create_string_buffer(128) # createstringbuffer or something??? c_char_p + return_code = amdsmi.amdsmi_get_socket_info(socket_handle, byref(socket_info), c_size_t(128)) + check_return(return_code=return_code, error_statment="Invalid get_socket_info request") + socket_bdf = BDF.BDF(socket_info.value.decode()) + return(socket_bdf) + + + def get_device_type(self, device_handle, format=True): + # format: True for string; False for int + # Returns device_type string for the given device_handle + dev_type = c_int(0) + return_code = amdsmi.amdsmi_get_device_type(device_handle, byref(dev_type)) + check_return(return_code=return_code, error_statment="Invalid get_device_type request") + + if format == True: # Return string + return device_type__enumvalues[dev_type.value] + + return dev_type.value # Return int + + + def get_device_bdf(self, device_handle): + + # class amdsmi_bdf_t (Union): + # _fields_ = [ + # ('bdf_submodule', bdf_submodule), + # ('as_uint', c_uint64) + # ] + bdf = amdsmi_bdf_t() + # bdf.bdf_submodule + + + + return_code = amdsmi.amdsmi_get_device_bdf(device_handle, bdf) + check_return(return_code=return_code, error_statment="Invalid amdsmi_get_device_bdf request") + return (bdf) + + + def get_device_handle_from_bdf(self, bdf): + pass + + + def get_fan_speed(self, bdf): + pass + + def show_retired_pages(self): + # num_pages = c_uint32() + # records = rsmi_retired_page_record_t() + pass \ No newline at end of file diff --git a/amdsmi/amdsmi_cli/amdsmi_parser.py b/amd_smi_cli/amd_smi_parser.py similarity index 99% rename from amdsmi/amdsmi_cli/amdsmi_parser.py rename to amd_smi_cli/amd_smi_parser.py index d5bd4b4186..0edf07417f 100644 --- a/amdsmi/amdsmi_cli/amdsmi_parser.py +++ b/amd_smi_cli/amd_smi_parser.py @@ -4,7 +4,7 @@ import argparse import platform from _version import __version__ -from amdsmi_helpers import AMD_SMI_Helpers +from amd_smi_helpers import AMD_SMI_Helpers # sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool @@ -50,7 +50,7 @@ class AMD_SMI_Parser(argparse.ArgumentParser): # self.add_set_value_parser(subparsers, set_value) self.add_reset_parser(subparsers, reset) self.add_misc_parser(subparsers, misc) - # self.add_gpu_v_parser(subparsers, misc) + self.add_gpu_v_parser(subparsers, misc) def add_version_parser(self, subparsers, func): diff --git a/amdsmi/amdsmi_cli/amdsmiBindings.py b/amd_smi_cli/amdsmiBindings.py similarity index 100% rename from amdsmi/amdsmi_cli/amdsmiBindings.py rename to amd_smi_cli/amdsmiBindings.py diff --git a/amdsmi/setup.py b/amdsmi/setup.py deleted file mode 100644 index ee28d92576..0000000000 --- a/amdsmi/setup.py +++ /dev/null @@ -1,21 +0,0 @@ -from setuptools import setup, find_packages -from _version import __version__ - -with open("README.md", "r", encoding="utf-8") as fh: - long_description = fh.read() - -setup( - name='amdsmi', - version=__version__, - description="SMI LIB - AMD GPU Monitoring Library", - long_description=long_description, - long_description_content_type="text/markdown", - packages=find_packages(), # can be customized later, but works for now - package_data={'': ['LICENSE']}, - include_package_data=True, - python_requires=">=3.6", -) - -# To build wheel -# python3 -m pip install -U wheel -# python3 setup.py bdist_wheel \ No newline at end of file diff --git a/amdsmi/README.md b/py-interface/README.md similarity index 100% rename from amdsmi/README.md rename to py-interface/README.md diff --git a/amdsmi/__init__.py b/py-interface/__init__.py similarity index 99% rename from amdsmi/__init__.py rename to py-interface/__init__.py index 18531e0128..82c8dd1d8c 100644 --- a/amdsmi/__init__.py +++ b/py-interface/__init__.py @@ -177,6 +177,7 @@ from .amdsmi_interface import amdsmi_is_P2P_accessible from .amdsmi_interface import amdsmi_get_xgmi_info # # Enums + from .amdsmi_interface import AmdSmiInitFlags from .amdsmi_interface import AmdSmiContainerTypes from .amdsmi_interface import AmdSmiDeviceType @@ -204,8 +205,8 @@ from .amdsmi_interface import AmdSmiIoLinkType from .amdsmi_interface import AmdSmiUtilizationCounterType from .amdsmi_interface import AmdSmiSwComponent from .amdsmi_interface import AmdSmiIoLinkType - # Exceptions + from .amdsmi_exception import AmdSmiLibraryException from .amdsmi_exception import AmdSmiRetryException from .amdsmi_exception import AmdSmiParameterException diff --git a/amdsmi/amdsmi_exception.py b/py-interface/amdsmi_exception.py similarity index 99% rename from amdsmi/amdsmi_exception.py rename to py-interface/amdsmi_exception.py index 4e23060c13..2659a44fe0 100644 --- a/amdsmi/amdsmi_exception.py +++ b/py-interface/amdsmi_exception.py @@ -20,7 +20,7 @@ # from enum import IntEnum -import amdsmi_wrapper +from . import amdsmi_wrapper class AmdSmiRetCode(IntEnum): diff --git a/amdsmi/amdsmi_interface.py b/py-interface/amdsmi_interface.py similarity index 99% rename from amdsmi/amdsmi_interface.py rename to py-interface/amdsmi_interface.py index 1473579566..14f26a7617 100644 --- a/amdsmi/amdsmi_interface.py +++ b/py-interface/amdsmi_interface.py @@ -25,8 +25,8 @@ from typing import Union, Any, Dict, List, Tuple from enum import IntEnum from collections.abc import Iterable -import amdsmi_wrapper -from amdsmi_exception import * +from . import amdsmi_wrapper +from .amdsmi_exception import * class AmdSmiInitFlags(IntEnum): @@ -498,7 +498,8 @@ def amdsmi_get_socket_handles() -> List[amdsmi_wrapper.amdsmi_socket_handle]: socket_count.value)() _check_res( amdsmi_wrapper.amdsmi_get_socket_handles( - ctypes.byref(socket_count), socket_handles) + ctypes.byref(socket_count), socket_handles + ) ) sockets = [ amdsmi_wrapper.amdsmi_socket_handle(socket_handles[sock_idx]) @@ -512,16 +513,12 @@ def amdsmi_get_socket_info(socket_handle): if not isinstance(socket_handle, amdsmi_wrapper.amdsmi_socket_handle): raise AmdSmiParameterException( socket_handle, amdsmi_wrapper.amdsmi_socket_handle) - socket_info = ctypes.create_string_buffer(128) - - _check_res( - amdsmi_wrapper.get_socket_info( - socket_handle, ctypes.byref(socket_info), ctypes.c_size_t(128)) - ) - return socket_info.value.decode() + return { + "name": "" + } + -# This input is different, also this List defintion doesn't really work because you never return that, you return a list of lists def amdsmi_get_device_handles() -> List[amdsmi_wrapper.amdsmi_device_handle]: socket_handles = amdsmi_get_socket_handles() devices = [] diff --git a/amdsmi/amdsmi_wrapper.py b/py-interface/amdsmi_wrapper.py similarity index 99% rename from amdsmi/amdsmi_wrapper.py rename to py-interface/amdsmi_wrapper.py index 20eb758661..6e88431c22 100644 --- a/amdsmi/amdsmi_wrapper.py +++ b/py-interface/amdsmi_wrapper.py @@ -165,10 +165,11 @@ def char_pointer_cast(string, encoding='utf-8'): return ctypes.cast(string, ctypes.POINTER(ctypes.c_char)) -# Change this to more dynamic later or in /opt/rocm/lib/libamd_smi64.so + _libraries = {} -amd_smi_lib_so_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../build/src/libamd_smi.so')) -_libraries['libamd_smi.so'] = ctypes.CDLL(amd_smi_lib_so_path) +_libraries['libamd_smi.so'] = ctypes.CDLL(os.path.join(os.path.dirname(__file__), 'libamd_smi.so')) + + # values for enumeration 'c__EA_amdsmi_init_flags_t' c__EA_amdsmi_init_flags_t__enumvalues = { diff --git a/amdsmi/rocm_smi_tool.py b/py-interface/rocm_smi_tool.py similarity index 100% rename from amdsmi/rocm_smi_tool.py rename to py-interface/rocm_smi_tool.py diff --git a/py-interface/setup.py b/py-interface/setup.py new file mode 100644 index 0000000000..6a4bc6480f --- /dev/null +++ b/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", +) From 6aa91da74ccb139fbc2899e006c685bec7752ada Mon Sep 17 00:00:00 2001 From: Maisam Arif Date: Thu, 19 Jan 2023 11:41:42 -0500 Subject: [PATCH 6/7] Revert "Added AMD-SMI Linux Baremetal" This reverts commit 013400bee7fb47284398f162b0e079c2e2eaab85. Reason for revert: Branch is still WIP Change-Id: I75eec813b3d81049f033fe0a534251bd69eeca0e --- amd_smi_cli/BDF.py | 96 ---- amd_smi_cli/_version.py | 1 - amd_smi_cli/amd_smi.py | 31 -- amd_smi_cli/amd_smi_commands.py | 91 ---- amd_smi_cli/amd_smi_helpers.py | 151 ------ amd_smi_cli/amd_smi_init.py | 71 --- amd_smi_cli/amd_smi_logger.py | 46 -- amd_smi_cli/amd_smi_modules.py | 97 ---- amd_smi_cli/amd_smi_parser.py | 619 ------------------------ amd_smi_cli/amdsmiBindings.py | 818 -------------------------------- example/amd_smi_drm_example.cc | 2 - 11 files changed, 2023 deletions(-) delete mode 100644 amd_smi_cli/BDF.py delete mode 100644 amd_smi_cli/_version.py delete mode 100644 amd_smi_cli/amd_smi.py delete mode 100644 amd_smi_cli/amd_smi_commands.py delete mode 100644 amd_smi_cli/amd_smi_helpers.py delete mode 100644 amd_smi_cli/amd_smi_init.py delete mode 100644 amd_smi_cli/amd_smi_logger.py delete mode 100644 amd_smi_cli/amd_smi_modules.py delete mode 100644 amd_smi_cli/amd_smi_parser.py delete mode 100644 amd_smi_cli/amdsmiBindings.py diff --git a/amd_smi_cli/BDF.py b/amd_smi_cli/BDF.py deleted file mode 100644 index a4cf29f3da..0000000000 --- a/amd_smi_cli/BDF.py +++ /dev/null @@ -1,96 +0,0 @@ -import logging -import platform -import re - - -class BDF(object): - """ BDF Class to cast and compare BDF objects using built-in python comparators - - Useful for validating a BDF string and converting it to a BDF object - This allows us to handle BDF objects in a pythonic way - - Attributes: - __eq__: The equals comparator - __: An integer count of the eggs we have laid. - """ - - def __init__(self, bdf): - """Init a BDF object""" - if isinstance(bdf, BDF): - self.segment, self.bus, self.device, self.function = tuple(bdf) - else: - if bdf.startswith("BDF("): - bdf = bdf.replace('BDF(', '').replace(')', '') - # Tell if this is baremetal vs Virtualization - self.operating_system = platform.system() - - try: - bdf_components = [int(x, 16) for x in re.split('[:.]', bdf)] - except ValueError as e: - logging.error(f"Invalid string passed: {bdf}") - raise e - - self.segment = bdf_components[0] if len(bdf_components) == 4 else 0 - self.bus, self.device, self.function = bdf_components[-3:] - if self.segment > 65535: - raise ValueError("BDF Segment can't be greater than 65535") - if self.bus > 255: - raise ValueError("BDF Bus can't be greater than 255") - if self.device > 31: - raise ValueError("BDF Device can't be greater than 31") - if self.function > 7: - raise ValueError("BDF Function can't be greater than 7") - - def __eq__(self, passed_bdf): - """Overrides the == operator and allows for BDF objects to be compared to BDF strings""" - - # Only accept strings and BDF objects - if isinstance(passed_bdf, str): - if passed_bdf == '': - return False - passed_bdf = BDF(passed_bdf) - elif not isinstance(passed_bdf, BDF): - return False - - if self.segment == passed_bdf.segment and \ - self.bus == passed_bdf.bus and \ - self.device == passed_bdf.device and \ - self.function == passed_bdf.function: - return True - else: - return False - - def __ne__(self, passed_bdf): - """Overrides the != operator and allows for BDF objects to be compared to BDF strings""" - # Since we overrided the == operator we can use that to make this simple - return not self == passed_bdf - - def __add__(self, passed_bdf): - """Overrides the + operator and allows for concatenation""" - return str(self) + passed_bdf - - def __radd__(self, passed_bdf): - """Overrides the + operator and allows for concatenation""" - return passed_bdf + str(self) - - def __str__(self): - """Cast BDF object to a string""" - return "{:04X}:{:02X}:{:02X}:{}".format(self.segment, self.bus, self.device, self.function) - - def __repr__(self): - """How the BDF object is represented""" - return f"BDF({self})" - - def __iter__(self): - """Make the BDF object iterable over its 4 values""" - yield from (self.segment, self.bus, self.device, self.function) - - def __contains__(self, passed_bdf): - """Overrided the 'in' comparator in python""" - passed_bdf = str(BDF(passed_bdf)) - - bdf_regex = "(?:[0-6]?[0-9a-fA-F]{1,4}:)?[0-2]?[0-9a-fA-F]{1,2}:[0-9a-fA-F]{1,2}\.[0-7]" - for match in re.findall(bdf_regex, passed_bdf): - if self == match: - return True - return False diff --git a/amd_smi_cli/_version.py b/amd_smi_cli/_version.py deleted file mode 100644 index b3c06d4883..0000000000 --- a/amd_smi_cli/_version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.0.1" \ No newline at end of file diff --git a/amd_smi_cli/amd_smi.py b/amd_smi_cli/amd_smi.py deleted file mode 100644 index 88c9d9c3c3..0000000000 --- a/amd_smi_cli/amd_smi.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python3 - -# from amd_smi_init import * - -from amd_smi_commands import AMD_SMI_Commands -from amd_smi_parser import AMD_SMI_Parser - - -# sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool - - -if __name__ == "__main__": - amd_smi_commands = AMD_SMI_Commands() - amd_smi_parser = AMD_SMI_Parser(amd_smi_commands.version, - amd_smi_commands.discovery, - amd_smi_commands.static, - amd_smi_commands.firmware, - amd_smi_commands.bad_pages, - amd_smi_commands.metric, - amd_smi_commands.process, - amd_smi_commands.profile, - amd_smi_commands.event, - amd_smi_commands.topology, - amd_smi_commands.set_value, - amd_smi_commands.reset, - amd_smi_commands.misc, - amd_smi_commands.gpu_v) - - args = amd_smi_parser.parse_args() - args.func(args) # This needs to be there to handle subparsers with no subcommands - # AMDSMI logger print out json, csv, or string diff --git a/amd_smi_cli/amd_smi_commands.py b/amd_smi_cli/amd_smi_commands.py deleted file mode 100644 index e5ea6b8478..0000000000 --- a/amd_smi_cli/amd_smi_commands.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/python3 - -import platform -import signal -import subprocess -import sys -import time -import traceback - -from pathlib import Path - -# from amd_smi_init import * -from BDF import BDF -from _version import __version__ - -from amd_smi_logger import AMD_SMI_Logger - - - -class AMD_SMI_Commands(object): - # def __init__(self, amd_smi_logger) -> None: - # logger = amd_smi_logger - # # Make an AMD-SMI-Object-Logger only with the commands object on init - # # Call the logger when we want to store a print: - # # self.logger.store_output(gpu_id, string) # store in ordered dict - # Every function prints the logger at the end - # logger.printoutput(args.json, args.csv) # Which in Logger handles and checks for json or csv - # Check if init can accept args given, if so then init can be used to call watch functions for looping - - - def version(self, args): - kernel_version = 123 - print(f'AMD-SMI version: {__version__} | Kernel version: {kernel_version}') - - - def discovery(self, args): - print('discovery test') - - - def static(self, args): - #This is where the arg handling comes through - print(args.asic) - print(args.bus) - print(args.driver) - print('static test') - - - def firmware(self, args): - print('firmware test') - - - def bad_pages(self, args): - # Retired Pages - print('Bad Pages test') - - - def metric(self, args): - print('Metric test') - - - def process(self, args): - print('Process Test') - - - def profile(self, args): - print('Profile test') - - - def event(self, args): - print('event test') - - - def topology(self, args): - print('topology test') - - - def set_value(self, args): - print('set_value test') - - - def reset(self, args): - print('reset test') - - - def misc(self, args): - print('misc test') - - - def gpu_v(self, args): - print('misc test') - diff --git a/amd_smi_cli/amd_smi_helpers.py b/amd_smi_cli/amd_smi_helpers.py deleted file mode 100644 index e23c792a19..0000000000 --- a/amd_smi_cli/amd_smi_helpers.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/python3 - -import argparse -import platform -import signal -import subprocess -import sys -import time -import traceback -import logging - -from pathlib import Path - -from BDF import BDF -from amd_smi_init import * - - -class AMD_SMI_Helpers(object): - def __init__(self) -> None: - # implement basic config for debug logs - self.operating_system = platform.system() - self._is_hypervisor = False - self._is_virtual_os = False - self._is_baremetal = False - self._is_linux = False - self._is_windows = False - - self.virtual_operating_systems_product_names = ['KVM', 'VirtualBox', 'VMware'] #@TODO get KVM example - - if self.operating_system.startswith('Linux'): - self._is_linux = True - # logging.debug(f'whatever:{self._is_linux}') - # KVM hypervisor check @TODO - - product_name = '' - product_name_path = Path('/sys/class/dmi/id/product_name') - if product_name_path.exists(): - product_name = product_name_path.read_text().strip() - - if product_name == '': - # Unable to determine product_name default to baremetal - self._is_baremetal = True - else: - for vm_os in self.virtual_operating_systems_product_names: - if product_name.startswith(vm_os): - # Log that this is a virtual OS - self._is_virtual_os = True - break - - # The current way I determine if a system is baremetal by deduction of the other two arguments - self._is_baremetal = not self._is_hypervisor and not self._is_virtual_os - - - if self.operating_system.startswith('VMkernel'): - self._is_hypervisor = True - - - if self.operating_system.startswith('Window'): - # Check Powershell for Hyper-V enablement - self._is_windows = True - - # Get-CimInstance -ClassName Win32_ComputerSystem Manufacturer - - - # if self.product_name == '' and not self._is_hypervisor: - # self._is_virtual_os = any(self.product_name.startswith(virtual_os) for virtual_os in self.virtual_operating_systems) - - - # self.operating_system = '' - - - def os_info(self): - # Return OS info - # operating_system = - - - # if sys.platform.startswith('win'): - - # elif sys.platform.startswith('linux'): - - return True - - - def is_virtual_os(self): - return self._is_virtual_os - - - def is_hypervisor(self): - # Returns True if hypervisor is enabled on the system - return self._is_hypervisor - - - def is_baremetal(self): - # Returns True if system is baremetal, if system is hypervisor this should return False - return self._is_baremetal - - - - def is_linux(self): - return self._is_linux - - - def is_windows(self): - return self._is_windows - - - def get_gpu_choices(self): - # Return in format {gpu_index : (BDF, UUID)} - - gpu_choices = {} - gpu_index = '1' - gpu_bdf = BDF('0000:23:00.0') - gpu_uuid = '1234' - gpu_choices[gpu_index] = (gpu_bdf, gpu_uuid) - return gpu_choices - - - def get_devices(self): - pass - - - def get_device_from_socket(self): - pass - - - def get_amd_gpu_bdfs(self): - pass - - - def get_amd_cpu_bdfs(self): - pass - - - - # def getBus(device): - # """ Return the bus identifier of a given device - - # @param device: DRM device identifier - # """ - # bdfid = c_uint64(0) - # ret = rocmsmi.rsmi_dev_pci_id_get(device, byref(bdfid)) - - # # BDFID = ((DOMAIN & 0xffffffff) << 32) | ((BUS & 0xff) << 8) |((DEVICE & 0x1f) <<3 ) | (FUNCTION & 0x7) - # domain = (bdfid.value >> 32) & 0xffffffff - # bus = (bdfid.value >> 8) & 0xff - # device = (bdfid.value >> 3) & 0x1f - # function = bdfid.value & 0x7 - - # pic_id = '{:04X}:{:02X}:{:02X}.{:0X}'.format(domain, bus, device, function) - # if rsmi_ret_ok(ret, device): - # return pic_id diff --git a/amd_smi_cli/amd_smi_init.py b/amd_smi_cli/amd_smi_init.py deleted file mode 100644 index b6daa1abc0..0000000000 --- a/amd_smi_cli/amd_smi_init.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/python3 - -### Handle init singularly -# Python imports module does not re-execute code on import - -import atexit -import logging -import signal -import sys - -from pathlib import Path - -# Handle bindings for windows, Hyper-v and KVM seperately -from amdsmiBindings import * - -# Using basic python logging for user errors and development -# logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG) # Logging for Development -logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR) # User level logging - -# On initial import set initialized variable -amd_smi_initialized = False - -def check_return(return_code, error_statment): #@TODO would raising an exception be better? - if return_code != amdsmi_status.AMDSMI_STATUS_SUCCESS: - logging.error(error_statment) - sys.exit(return_code) - - -def check_amdgpu_driver(): #@TODO Handle KVM logic - """ Returns true if amdgpu is found in the list of initialized modules """ - amd_gpu_status_file = Path("/sys/module/amdgpu/initstate") - - if amd_gpu_status_file.exists(): - if amd_gpu_status_file.read_text().strip() == 'live': - return True - - return False - - -def init_amd_smi(flag=amdsmi_init_flags.AMD_SMI_INIT_AMD_GPUS): - """ Initializes AMD-SMI """ - # Check if amdgpu driver is up - if check_amdgpu_driver(): - # Only init AMD GPUs for now, waiting for future support for AMD CPUs - init_status = amdsmi.amdsmi_init(flag) - check_return(return_code=init_status, error_statment=f'AMD SMI initialization returned {init_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') - logging.info('amd-smi initialized successfully') - else: - logging.error('Driver not initialized (amdgpu not found in modules)') - exit(-1) - - -def amdsmi_shut_down(): - """ Shutdown AMD-SMI """ - # Only init AMD GPUs for now, waiting for future support for AMD CPUs - shut_down_status = amdsmi.amdsmi_shut_down() - check_return(return_code=shut_down_status, error_statment=f'AMD SMI Shutdown code returned {shut_down_status} (the expected value is {amdsmi_status_t.AMDSMI_STATUS_SUCCESS})') - logging.debug('amd-smi shutdown successfully') - - -def signal_handler(sig, frame): - logging.debug(f'Handling signal: {sig}') - sys.exit(0) - - -if not amd_smi_initialized: - init_amd_smi() - amd_smi_initialized = True - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - atexit.register(amdsmi_shut_down) diff --git a/amd_smi_cli/amd_smi_logger.py b/amd_smi_cli/amd_smi_logger.py deleted file mode 100644 index 5826be47f6..0000000000 --- a/amd_smi_cli/amd_smi_logger.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/python3 - -# import orderedDict -import json - -class AMD_SMI_Logger(object): - def __init__(self) -> None: - # self.card = {} - # backwards compatability - pass - - def store_output(self, target_device, log): - pass - - def print_output(self, format=''): - # JSON, CSV, text - # split into 3 different formats - # for elem in self.cards: - # print pretty - pass - - def print_json(self): - # json_data = '[{"ID":10,"Name":"Pankaj","Role":"CEO"},' \ - # '{"ID":20,"Name":"David Lee","Role":"Editor"}]' - - # json_object = json.loads(json_data) - - # json_formatted_str = json.dumps(json_object, indent=2) - - # print(json_formatted_str) - pass - - def print_csv(self): - # # Opening JSON file and loading the data - # # into the variable data - # with open('data.json') as json_file: - # data = json.load(json_file) - - # employee_data = data['emp_details'] - - # # now we will open a file for writing - # data_file = open('data_file.csv', 'w') - - # # create the csv writer object - # csv_writer = csv.writer(data_file) - pass \ No newline at end of file diff --git a/amd_smi_cli/amd_smi_modules.py b/amd_smi_cli/amd_smi_modules.py deleted file mode 100644 index 97556b9d14..0000000000 --- a/amd_smi_cli/amd_smi_modules.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/python3 - -import argparse -import platform -import signal -import subprocess -import sys -import time -import traceback - -from pathlib import Path - -import BDF -from amd_smi_init import * - -class AMD_SMI_Modules(object): - def __init__(self) -> None: - pass - - - def get_socket_handles(self): - ### Returns tuple of (int, list of ctypes: socket_handles) - socket_count = c_uint32(0) - return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), None) - check_return(return_code=return_code, error_statment="Invalid get_socket_handles request") - - sockets = [0] * socket_count.value # 1 - socket_handles = (c_void_p * socket_count.value)(*sockets) # That is a pointer, not a multiplication - return_code = amdsmi.amdsmi_get_socket_handles(byref(socket_count), socket_handles) - check_return(return_code=return_code, error_statment=f"Invalid get_socket_handles with {socket_count.value} sockets") - return (socket_count.value, socket_handles) - - - def get_device_handles(self, socket_handle): - """Gets the Device Handles that are in the current socket""" - ### Returns tuple of (int, list of ctypes: device_handles) - device_count = c_uint32(0) - return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), None) - check_return(return_code=return_code, error_statment="Invalid get_device_handles request") - - devices = [0] * device_count.value - device_handles = (c_void_p * len(devices))(*devices) - return_code = amdsmi.amdsmi_get_device_handles(socket_handle, byref(device_count), byref(device_handles)) - check_return(return_code=return_code, error_statment=f"Invalid get_device_handles with {device_count.value} devices") - return (device_count.value, device_handles) - - - def get_socket_info(self, socket_handle): - """ Given a socket_handle, return the socket_info, which is just a BDF object""" - socket_info = create_string_buffer(128) # createstringbuffer or something??? c_char_p - return_code = amdsmi.amdsmi_get_socket_info(socket_handle, byref(socket_info), c_size_t(128)) - check_return(return_code=return_code, error_statment="Invalid get_socket_info request") - socket_bdf = BDF.BDF(socket_info.value.decode()) - return(socket_bdf) - - - def get_device_type(self, device_handle, format=True): - # format: True for string; False for int - # Returns device_type string for the given device_handle - dev_type = c_int(0) - return_code = amdsmi.amdsmi_get_device_type(device_handle, byref(dev_type)) - check_return(return_code=return_code, error_statment="Invalid get_device_type request") - - if format == True: # Return string - return device_type__enumvalues[dev_type.value] - - return dev_type.value # Return int - - - def get_device_bdf(self, device_handle): - - # class amdsmi_bdf_t (Union): - # _fields_ = [ - # ('bdf_submodule', bdf_submodule), - # ('as_uint', c_uint64) - # ] - bdf = amdsmi_bdf_t() - # bdf.bdf_submodule - - - - return_code = amdsmi.amdsmi_get_device_bdf(device_handle, bdf) - check_return(return_code=return_code, error_statment="Invalid amdsmi_get_device_bdf request") - return (bdf) - - - def get_device_handle_from_bdf(self, bdf): - pass - - - def get_fan_speed(self, bdf): - pass - - def show_retired_pages(self): - # num_pages = c_uint32() - # records = rsmi_retired_page_record_t() - pass \ No newline at end of file diff --git a/amd_smi_cli/amd_smi_parser.py b/amd_smi_cli/amd_smi_parser.py deleted file mode 100644 index 0edf07417f..0000000000 --- a/amd_smi_cli/amd_smi_parser.py +++ /dev/null @@ -1,619 +0,0 @@ -#!/usr/bin/python3 - -import argparse -import platform - -from _version import __version__ -from amd_smi_helpers import AMD_SMI_Helpers - -# sudo /src/out/ubuntu-20.04/20.04/bin/rocm-smi -bc --json | python -m json.tool - -class AMD_SMI_Parser(argparse.ArgumentParser): - - def __init__(self, version, discovery, static, firmware, bad_pages, metric, - process, profile, event,topology, set_value, reset, misc, gpu_v): - - # Helper variables - self.amd_smi_helpers = AMD_SMI_Helpers() - self.gpu_choices = self.amd_smi_helpers.get_gpu_choices() - self.vf_choices = ['3','2','1'] - - # Adjust argument parser options - super().__init__( - formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90), - # formatter_class=argparse.ArgumentDefaultsHelpFormatter, - description=f'AMD System Management Interface | Version: {__version__}', #@TODO add the enviornment - add_help=True, - prog='amd-smi') - - # Setup subparsers - subparsers = self.add_subparsers( - title="AMD-SMI Commands", - parser_class=argparse.ArgumentParser, - required=True, - help='Descriptions:', - # dest='cmd', - metavar="") - - # Add all subparsers - # Add --json, --csv,--file,--loglevel, watch, watch_time, & iterations && backwards compatability --gpuvsmi --rocmsmi - self.add_version_parser(subparsers, version) - self.add_discovery_parser(subparsers, discovery) - self.add_static_parser(subparsers, static) - self.add_firmware_parser(subparsers, firmware) - self.add_bad_pages_parser(subparsers, bad_pages) - self.add_metric_parser(subparsers, metric) - self.add_process_parser(subparsers, process) - self.add_profile_parser(subparsers, profile) - self.add_event_parser(subparsers, event) - self.add_topology_parser(subparsers, topology) - # self.add_set_value_parser(subparsers, set_value) - self.add_reset_parser(subparsers, reset) - self.add_misc_parser(subparsers, misc) - self.add_gpu_v_parser(subparsers, misc) - - - def add_version_parser(self, subparsers, func): - # Subparser help text - version_help = "Display version information" - - # Create version subparser - version_parser = subparsers.add_parser('version', help=version_help, description=None) - version_parser._optionals.title = None - version_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - version_parser.set_defaults(func=func) - - - def add_discovery_parser(self, subparsers, func): - # Subparser help text - discovery_help = "Display discovery information" - discovery_subcommand_help = """Lists all the devices on the system and the links between devices. - Lists all the sockets and for each socket, GPUs and/or CPUs associated to - that socket alongside some basic information for each device. - In virtualization environment, it can also list VFs associated to each - GPU with some basic information for each VF.""" - - # Create discovery subparser - discovery_parser = subparsers.add_parser('discovery', help=discovery_help, description=discovery_subcommand_help) - discovery_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - discovery_parser.set_defaults(func=func) - - - def add_static_parser(self, subparsers, func): - # Subparser help text - static_help = "Gets static information about the specified GPU" - static_subcommand_help = """If no argument is provided, return static information for all GPUs on the system. - If no static argument is specified all static information will be displayed.""" - static_optionals_title = "Static Arguments" - - # Optional arguments help text - gpu_help = "Select a GPU from the possible choices" - vf_help = """Gets general information about the specified VF (timeslice, fb info, …). - Available only on virtualization OSs""" - asic_help = "All asic information" - bus_help = "All bus information" - vbios_help = "All video bios information (if available)" - limit_help = "All limit metric values (i.e. power and thermal limits)" - driver_help = "Displays driver version" - caps_help = "All caps information" - - # Options arguments help text for Hypervisors and Baremetal - ras_help = "Displays RAS features information" - board_help = "All board information" # Linux Baremetal only @TODO is applicable to Azure - - # Options arguments help text for Hypervisors - dfc_help = "All DFC FW table information" - fb_help = "Displays Frame Buffer information" - num_vf_help = "Displays number of supported and enabled VFs" - - # Create static subparser - static_parser = subparsers.add_parser('static', help=static_help, description=static_subcommand_help) - static_parser._optionals.title = static_optionals_title - static_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - static_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = static_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - static_parser.add_argument('-a', '--asic', action='store_true', required=False, help=asic_help) - static_parser.add_argument('-b', '--bus', action='store_true', required=False, help=bus_help) - static_parser.add_argument('-v', '--vbios', action='store_true', required=False, help=vbios_help) - static_parser.add_argument('-l', '--limit', action='store_true', required=False, help=limit_help) - static_parser.add_argument('-d', '--driver', action='store_true', required=False, help=driver_help) - static_parser.add_argument('-c', '--caps', action='store_true', required=False, help=caps_help) - - # Options to display on Hypervisors and Baremetal - if self.amd_smi_helpers.is_hypervisor() or self.amd_smi_helpers.is_baremetal(): - static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help) - if self.amd_smi_helpers.is_linux(): #@TODO Check if applicable to Azure - static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help) - - # Options to only display on a Hypervisor - if self.amd_smi_helpers.is_hypervisor(): - device_args.add_argument('--vf', action='store', help=vf_help, choices=self.vf_choices) - static_parser.add_argument('-du', '--dfc-ucode', action='store_true', required=False, help=dfc_help) - static_parser.add_argument('-f', '--fb-info', action='store_true', required=False, help=fb_help) - static_parser.add_argument('-n', '--num-vf', action='store_true', required=False, help=num_vf_help) - - - def add_firmware_parser(self, subparsers, func): - # Subparser help text - firmware_help = "Gets firmware information about the specified GPU" - firmware_subcommand_help = "If no argument is provided, return firmware information for all GPUs on the system." - firmware_optionals_title = "Firmware Arguments" - - # Optional arguments help text - gpu_help = "Select a GPU from the possible choices" - vf_help = """Gets general information about the specified VF (timeslice, fb info, …). - Available only on virtualization OSs""" - fw_list_help = "All FW list information" - err_records_help = "All error records information" - - # Create firmware subparser - firmware_parser = subparsers.add_parser('firmware', help=firmware_help, description=firmware_subcommand_help) - firmware_parser._optionals.title = firmware_optionals_title - firmware_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - firmware_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = firmware_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - firmware_parser.add_argument('-f', '--fw-list', action='store_true', required=False, help=fw_list_help) # Redundant? - - # Options to only display on a Hypervisor - if self.amd_smi_helpers.is_hypervisor(): - device_args.add_argument('--vf', action='store', help=vf_help, choices=self.vf_choices) - firmware_parser.add_argument('-e', '--error-records', action='store_true', required=False, help=err_records_help) - - - def add_bad_pages_parser(self, subparsers, func): #@TODO Retired pages? - if not (self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): - # The bad_pages subcommand is only applicable to Linux Baremetal systems - return - - # Subparser help text - bad_pages_help = "Gets bad page information about the specified GPU" - bad_pages_subcommand_help = "If no argument is provided, return bad page information for all GPUs on the system." - bad_pages_optionals_title = "Bad pages Arguments" - - # Optional arguments help text - gpu_help = "Select a GPU from the possible choices" - pending_help = "Displays all pending retired pages" - retired_help = "Displays retired pages" #@TODO Wording - un_res_help = "Displays unreservable pages" - - # Create bad_pages subparser - bad_pages_parser = subparsers.add_parser('bad_pages', help=bad_pages_help, description=bad_pages_subcommand_help) - bad_pages_parser._optionals.title = bad_pages_optionals_title - bad_pages_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - bad_pages_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = bad_pages_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - bad_pages_parser.add_argument('-p', '--pending', action='store_true', required=False, help=pending_help) - bad_pages_parser.add_argument('-r', '--retired', action='store_true', required=False, help=retired_help) - bad_pages_parser.add_argument('-u', '--un-res', action='store_true', required=False, help=un_res_help) - - - def add_metric_parser(self, subparsers, func): - # Subparser help text - metric_help = "Gets metric/performance information about the specified GPU" - metric_subcommand_help = """If no argument is provided, return metric information for all GPUs on the system. - If no metric argument is specified all metric information will be displayed.""" - metric_optionals_title = "Metric arguments" - - # Optional arguments help text - gpu_help = "Select a GPU from the possible choices" - vf_help = """Gets general information about the specified VF (timeslice, fb info, …). - Available only on virtualization OSs""" - usage_help = "All metrics usage information" - - # Help text for Arguments only Available on Virtual OS and Baremetal platforms - fb_usage_help = "Total and used framebuffer" - - # Help text for Arguments only on Hypervisor and Baremetal platforms - power_help = "Current power usage" - clock_help = "Average, max, and current clock frequencies" - temperature_help = "Current temperatures" - ecc_help = "Number of ECC errors" - pcie_help = "Current PCIe speed and width" - voltage_help = "Current GPU voltages" - - # Help text for Arguments only on Linux Baremetal platforms - fan_help = "Current fan speed" - pcie_usage_help = "Estimated PCIe link usage" - vc_help = "Display voltage curve" - overdrive_help = "Current GPU clock overdrive level" - mo_help = "Current memory clock overdrive level" - perf_level_help = "Current DPM performance level" - replay_count_help = "PCIe replay count" - xgmi_err_help = "XGMI error information since last read" - energy_help = "Amount of energy consumed" #@TODO ? Available only on host Linux Baremetal platforms - - # Help text for Arguments only on Hypervisors - schedule_help = "All scheduling information" - guard_help = "All guard information" - guest_help = "All guest data information" - - # Create metric subparser - metric_parser = subparsers.add_parser('metric', help=metric_help, description=metric_subcommand_help) - metric_parser._optionals.title = metric_optionals_title - metric_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - metric_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = metric_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - metric_parser.add_argument('-u', '--usage', action='store_true', required=False, help=usage_help) - - # Optional Args for Virtual OS and Baremetal systems - if self.amd_smi_helpers.is_virtual_os() or self.amd_smi_helpers.is_baremetal(): - metric_parser.add_argument('-b', '--fb-usage', action='store_true', required=False, help=fb_usage_help) - - # Optional Args for Hypervisors and Baremetal systems - if self.amd_smi_helpers.is_hypervisor() or self.amd_smi_helpers.is_baremetal(): - metric_parser.add_argument('-p', '--power', action='store_true', required=False, help=power_help) - metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help) - metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help) - metric_parser.add_argument('-e', '--ecc', action='store_true', required=False, help=ecc_help) - metric_parser.add_argument('-P', '--pcie', action='store_true', required=False, help=pcie_help) - metric_parser.add_argument('-v', '--voltage', action='store_true', required=False, help=voltage_help) - - # Optional Args for Linux Baremetal Systems #@TODO Discuss logic if Linux Hypervisors would be allowed to have this - if self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux(): - metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help) - metric_parser.add_argument('-s', '--pcie-usage', action='store_true', required=False, help=pcie_usage_help) - metric_parser.add_argument('-V', '--voltage-curve', action='store_true', required=False, help=vc_help) - metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help) - metric_parser.add_argument('-m', '--mem-overdrive', action='store_true', required=False, help=mo_help) - metric_parser.add_argument('-l', '--perf-level', action='store_true', required=False, help=perf_level_help) - metric_parser.add_argument('-r', '--replay-count', action='store_true', required=False, help=replay_count_help) - metric_parser.add_argument('-x', '--xgmi-err', action='store_true', required=False, help=xgmi_err_help) - metric_parser.add_argument('-E', '--energy', action='store_true', required=False, help=energy_help) - - # Options to only display to Hypervisors - if self.amd_smi_helpers.is_hypervisor(): - device_args.add_argument('--vf', action='store', help=vf_help, choices=self.vf_choices) - metric_parser.add_argument('-s', '--schedule', action='store_true', required=False, help=schedule_help) - metric_parser.add_argument('-g', '--guard', action='store_true', required=False, help=guard_help) - metric_parser.add_argument('-G', '--guest', action='store_true', required=False, help=guest_help) - - - def add_process_parser(self, subparsers, func): - if self.amd_smi_helpers.is_hypervisor(): - # Don't add this subparser on Hypervisors - return - - # Subparser help text - process_help = "Lists general process information running on the specified GPU" - process_subcommand_help = """If no argument is provided, returns information for all GPUs on the system. - If no argument is provided all process information will be displayed.""" - process_optionals_title = "Process arguments" - - # Required arguments help text - gpu_help = "Select a GPU from the possible choices" - - # Help text for Arguments only on Guest and BM platforms - general_help = "pid, process name, memory usage" - engine_help = "All engine usages" - pid_help = "Gets all process information about the specified process based on Process ID" - name_help = """Gets all process information about the specified process based on Process Name. - If multiple processes have the same name information is returned for all of them.""" #@TODO wording - - # Create process subparser - process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help) - process_parser._optionals.title = process_optionals_title - process_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - process_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = process_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - process_parser.add_argument('-g', '--general', action='store_true', required=False, help=general_help) - process_parser.add_argument('-e', '--engine', action='store_true', required=False, help=engine_help) - process_parser.add_argument('-p', '--pid', action='store', required=False, help=pid_help) - process_parser.add_argument('-n', '--name', action='store', required=False, help=name_help) - - - def add_profile_parser(self, subparsers, func): - if not (self.amd_smi_helpers.is_windows() and self.amd_smi_helpers.is_hypervisor()): - # This subparser only applies to Azure Hyper-V systems - return - - # Subparser help text - profile_help = "Displays information about all profiles and current profile" - profile_subcommand_help = "If no argument is provided, returns information for all GPUs on the system." - profile_optionals_title = "Profile Arguments" - - # Required arguments help text - gpu_help = "Select a GPU from the possible choices" - - # Create profile subparser - profile_parser = subparsers.add_parser('profile', help=profile_help, description=profile_subcommand_help) - profile_parser._optionals.title = profile_optionals_title - profile_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - profile_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = profile_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - - def add_event_parser(self, subparsers, func): - if self.amd_smi_helpers.is_linux() and not self.amd_smi_helpers.is_virtual_os(): - # This subparser only applies to Linux BareMetal & Linux Hypervisors - return - - # Subparser help text - event_help = "Displays event information for the given GPU" - event_subcommand_help = "If no argument is provided, returns event information for all GPUs on the system." - event_optionals_title = "Event Arguments" - - # Required arguments help text - gpu_help = "Select a GPU from the possible choices" - - # Create event subparser - event_parser = subparsers.add_parser('event', help=event_help, description=event_subcommand_help) - event_parser._optionals.title = event_optionals_title - event_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - event_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = event_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - - def add_topology_parser(self, subparsers, func): - if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): - # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work - return - - # Subparser help text - topology_help = "Displays topology information of the devices." - topology_subcommand_help = "If no argument is provided, returns information for all GPUs on the system." - topology_optionals_title = "Topology arguments" - - # Required arguments help text - gpu_help = "Select a GPU from the possible choices" - - # Help text for Arguments only on Guest and BM platforms - topo_access_help = "Displays link accessibility between GPUs" - topo_weight_help = "Displays relative weight between GPUs" - topo_hops_help = "Displays the number of hops between GPUs" - topo_type_help = "Displays the link type between GPUs." - topo_numa_help = "Displays the numa nodes." - - # Create topology subparser - topology_parser = subparsers.add_parser('topology', help=topology_help, description=topology_subcommand_help) - topology_parser._optionals.title = topology_optionals_title - topology_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - topology_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = topology_parser.add_mutually_exclusive_group() - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - topology_parser.add_argument('-a', '--topo-access', action='store_true', required=False, help=topo_access_help) - topology_parser.add_argument('-w', '--topo-weight', action='store_true', required=False, help=topo_weight_help) - topology_parser.add_argument('-o', '--topo-hops', action='store_true', required=False, help=topo_hops_help) - topology_parser.add_argument('-t', '--topo-type', action='store_true', required=False, help=topo_type_help) - topology_parser.add_argument('-n', '--topo-numa', action='store_true', required=False, help=topo_numa_help) - - - def add_set_value_parser(self, subparsers, func): - if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): - # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work - return - - # Subparser help text - set_value_help = "Set options for devices." - set_value_subcommand_help = "The user must specify one of the options for the set configuration." - set_value_optionals_title = "Set Arguments" - - # Required arguments help text - gpu_help = "Select a GPU from the possible choices" - - # Help text for Arguments only on Guest and BM platforms - set_clk_help = "Sets clock frequency levels for specified clocks" - set_sclk_help = "Sets GPU clock frequency levels" - set_mclk_help = "Sets memory clock frequency levels" - set_pcie_help = "Sets PCIe clock frequency levels" - set_slevel_help = "Change GPU clock frequency and voltage for a specific level" - set_mlevel_help = "Change GPU memory frequency and voltage for a specific level" - set_vc_help = "Change SCLK voltage curve for a specified point" - set_srange_help = "Sets min and max SCLK speed" - set_mrange_help = "Sets min and max MCLK speed" - set_fan_help = "Sets GPU fan speed (level or %)" - set_perf_level_help = "Sets performance level" - set_overdrive_help = "Set GPU overdrive level" - set_mem_overdrive_help = "Set memory overclock overdrive level" - set_power_overdrive_help = "Set the maximum GPU power using power overdrive in Watts" - set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes" - set_perf_det_help = "Set GPU clock frequency limit to get minimal performance variation" - ras_enable_help = "Enable RAS for specified block and error type" - ras_disable_help = "Disable RAS for specified block and error type." - ras_inject_help = "Inject RAS poison for specified block" - -# -c, --setclk -# . -# -s, --setsclk -# . -# -m, --setmclk -# . -# -p, --setpcie -# . -# -S, --setslevel -# . -# -M, --setmlevel -# . -# -v, --setvc -# . -# -r, --setsrange -# -# -R, --setmrange -# . -# -f, --setfan -# -# -pl, --setperflevel -# -# -o, --setoverdrive % -# Set GPU overdrive level. -# -O, --setmemoverdrive % -# Set memory overclock overdrive level. -# -po, --setpoweroverdrive -# Set the maximum GPU power using power overdrive in Watts. -# -P, --setprofile -# Set power profile level (#) or a quoted string of custom profile attributes (“ # # # # “) -# -pd, --setperfdet -# Set GPU clock frequency limit to get minimal performance variation. -# -re, --rasenable -# Enable RAS for specified block and error type. -# -rd, --rasdisable -# Disable RAS for specified block and error type. -# -ri, --rasinject -# Inject RAS poison for specified block - - # Create set_value subparser - set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help) - set_value_parser._optionals.title = set_value_optionals_title - set_value_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - set_value_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = set_value_parser.add_mutually_exclusive_group(required=True) - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - set_value_parser.add_argument('-c', '--setclk', action='store', required=False, help=topo_access_help) - set_value_parser.add_argument('-s', '--topo-weight', action='store', required=False, help=topo_weight_help) - set_value_parser.add_argument('-m', '--topo-hops', action='store', required=False, help=topo_hops_help) - set_value_parser.add_argument('-p', '--topo-type', action='store', required=False, help=topo_type_help) - set_value_parser.add_argument('-S', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-M', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-v', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-r', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-R', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-f', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-pl', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-o' '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-O', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-po', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-P', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-pd', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-re', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-rd', '--topo-numa', action='store', required=False, help=topo_numa_help) - set_value_parser.add_argument('-ri', '--topo-numa', action='store', required=False, help=topo_numa_help) - - - def add_reset_parser(self, subparsers, func): - if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): - # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work - return - - # Subparser help text - reset_help = "Reset options for devices." - reset_subcommand_help = "The user must specify one of the options to reset devices." - reset_optionals_title = "Reset Arguments" - - # Required arguments help text - gpu_help = "Select a GPU from the possible choices" - - # Help text for Arguments only on Guest and BM platforms - gpureset_help = "Reset the specified GPU" - resetclk_help = "Reset clocks and overdrive to default" - resetfans_help = "Reset fans to automatic (driver) control" - resetprofile_help = "Reset power profile back to default" - resetpoweroverdrive_help = "Set the maximum GPU power back to the device default state" - resetxgmierr_help = "Reset XGMI error counts" - resetperfdet_help = "Disable performance determinism" - - # Create reset subparser - reset_parser = subparsers.add_parser('reset', help=reset_help, description=reset_subcommand_help) - reset_parser._optionals.title = reset_optionals_title - reset_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - reset_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = reset_parser.add_mutually_exclusive_group(required=True) - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - reset_parser.add_argument('-g', '--gpureset', action='store_true', required=False, help=gpureset_help) - reset_parser.add_argument('-c', '--resetclk', action='store_true', required=False, help=resetclk_help) - reset_parser.add_argument('-f', '--resetfans', action='store_true', required=False, help=resetfans_help) - reset_parser.add_argument('-p', '--resetprofile', action='store_true', required=False, help=resetprofile_help) - reset_parser.add_argument('-o', '--resetpoweroverdrive', action='store_true', required=False, help=resetpoweroverdrive_help) - reset_parser.add_argument('-x', '--resetxgmierr', action='store_true', required=False, help=resetxgmierr_help) - reset_parser.add_argument('-d', '--resetperfdet', action='store_true', required=False, help=resetperfdet_help) - - - def add_misc_parser(self, subparsers, func): - if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): - # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work - return - - # Subparser help text - misc_help = "The miscellaneous options" - misc_subcommand_help = "The user must specify one of the options to reset devices." - misc_optionals_title = "Misc Arguments" - - # Optional arguments help text - gpu_help = "Select a GPU from the possible choices" - load_help = "Load clock, fan, performance, and profile settings from a given file." - save_help = "Save clock, fan, performance, and profile settings to a given file." - - # Create misc subparser - misc_parser = subparsers.add_parser('misc', help=misc_help, description=misc_subcommand_help) - misc_parser._optionals.title = misc_optionals_title - misc_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - misc_parser.set_defaults(func=func) - - # Mutually Exclusive Args within the subparser - device_args = misc_parser.add_mutually_exclusive_group(required=True) - device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # Optional Args - misc_parser.add_argument('-l', '--load', action='store', type=open, required=False, help=load_help) - misc_parser.add_argument('-s', '--save', action='store', type=open, required=False, help=save_help) - - - # def add_gpu_v_parser(self, subparsers, func): - # if not(self.amd_smi_helpers.is_baremetal() and self.amd_smi_helpers.is_linux()): - # # This subparser is only applicable to Baremetal Linux @TODO confirm how KVM should work - # return - - # # Subparser help text - # gpu_v_help = "The gpu_v options" - # gpu_v_subcommand_help = "The user must specify one of the options to reset devices." - # gpu_v_optionals_title = "gpu_v Arguments" - - # # Optional arguments help text - # gpu_help = "Select a GPU from the possible choices" - # load_help = "Load clock, fan, performance, and profile settings from a given file." - # save_help = "Save clock, fan, performance, and profile settings to a given file." - - # # Create gpu_v subparser - # gpu_v_parser = subparsers.add_parser('gpu_v', help=gpu_v_help, description=gpu_v_subcommand_help) - # gpu_v_parser._optionals.title = gpu_v_optionals_title - # gpu_v_parser.formatter_class=lambda prog: argparse.ArgumentDefaultsHelpFormatter(prog, max_help_position=80, width=90) - # gpu_v_parser.set_defaults(func=func) - - # # Mutually Exclusive Args within the subparser - # device_args = gpu_v_parser.add_mutually_exclusive_group(required=True) - # device_args.add_argument('--gpu', action='store', help=gpu_help, choices=self.gpu_choices) - - # # Optional Args - # gpu_v_parser.add_argument('-l', '--load', action='store', type=open, required=False, help=load_help) - # gpu_v_parser.add_argument('-s', '--save', action='store', type=open, required=False, help=save_help) diff --git a/amd_smi_cli/amdsmiBindings.py b/amd_smi_cli/amdsmiBindings.py deleted file mode 100644 index df9222d537..0000000000 --- a/amd_smi_cli/amdsmiBindings.py +++ /dev/null @@ -1,818 +0,0 @@ -#!/usr/bin/env python3 -"""! @brief AMD_SMI FFI""" - -from ctypes import * -from enum import Enum -import os - - -path_amdsmi = '/opt/rocm/lib/libamd_smi64.so' #@TODO make this dynamic - -try: - cdll.LoadLibrary(path_amdsmi) - amdsmi = CDLL(path_amdsmi) -except OSError: - print("Unable to load libamd_smi64.so library\n") - exit(1) - -## -# @brief Initialization flags -# -# may be OR'd together and passed to smi.amdsmi_init() -## - -class amdsmi_init_flags(c_int): - AMD_SMI_INIT_ALL_DEVICES = 0x0 # Default option - AMD_SMI_INIT_AMD_CPUS = (1 << 0) - AMD_SMI_INIT_AMD_GPUS = (1 << 1) - AMD_SMI_INIT_NON_AMD_CPUS = (1 << 2) - AMD_SMI_INIT_NON_AMD_GPUS = (1 << 3) - -# Maximum size definitions GPUVSMI -AMDSMI_MAX_MM_IP_COUNT = 8 -AMDSMI_MAX_DATE_LENGTH = 32 # YYYY-MM-DD:HH:MM:SS.MSC # -AMDSMI_MAX_STRING_LENGTH = 64 -AMDSMI_NORMAL_STRING_LENGTH = 32 -AMDSMI_MAX_DEVICES = 32 -AMDSMI_MAX_NAME = 32 -AMDSMI_MAX_DRIVER_VERSION_LENGTH = 80 -AMDSMI_PRODUCT_NAME_LENGTH = 128 -AMDSMI_MAX_CONTAINER_TYPE = 2 - -AMDSMI_GPU_UUID_SIZE = 38 - - -class amdsmi_mm_ip(c_int): - MM_UVD = 0 - MM_VCE = 1 - MM_VCN = 2 - MM__MAX = 3 - - -class amdsmi_container_types(c_int): - CONTAINER_LXC = 0 - CONTAINER_DOCKER = 1 - -# ! opaque handler point to underlying implementation -amdsmi_device_handle = POINTER(c_uint) -amdsmi_socket_handle = POINTER(c_uint) - -class device_type(c_int): - UNKNOWN = 0 - AMD_GPU = 1 - AMD_CPU = 2 - NON_AMD_GPU = 3 - NON_AMD_CPU = 4 - -device_type__enumvalues = { - 0: 'UNKNOWN', - 1: 'AMD_GPU', - 2: 'AMD_CPU', - 3: 'NON_AMD_GPU', - 4: 'NON_AMD_CPU', -} - -#Error codes retured by amd_smi_lib functions -class amdsmi_status(c_int): - AMDSMI_STATUS_SUCCESS = 0 # Call succeeded - AMDSMI_STATUS_INVAL = 1 # Invalid parameters - AMDSMI_STATUS_NOT_SUPPORTED = 2 # Command not supported - AMDSMI_STATUS_FILE_ERROR = 3 # Problem accessing a file. - AMDSMI_STATUS_NO_PERM = 4 # Permission Denied - AMDSMI_STATUS_OUT_OF_RESOURCES = 5 # Not enough memory - AMDSMI_STATUS_INTERNAL_EXCEPTION = 6 # An internal exception was caught - AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS = 7 # The provided input is out of allowable or safe range - AMDSMI_STATUS_INIT_ERROR = 8 # An error occurred when initializing internal data structures - AMDSMI_STATUS_NOT_YET_IMPLEMENTED = 9 # Not implemented yet - AMDSMI_STATUS_NOT_FOUND = 10 # Device Not found - AMDSMI_STATUS_INSUFFICIENT_SIZE = 11 # Not enough resources were available for the operation - AMDSMI_STATUS_INTERRUPT = 12 # An interrupt occurred during execution of function - AMDSMI_STATUS_UNEXPECTED_SIZE = 13 # An unexpected amount of data was read - AMDSMI_STATUS_NO_DATA = 14 # No data was found for a given input - AMDSMI_STATUS_UNEXPECTED_DATA = 15 # The data read or provided to function is not what was expected - AMDSMI_STATUS_BUSY = 16 # Device busy - AMDSMI_STATUS_REFCOUNT_OVERFLOW = 17 # An internal reference counter exceeded INT32_MAX - AMDSMI_LIB_START = 1000 - AMDSMI_STATUS_FAIL_LOAD_MODULE = AMDSMI_LIB_START # Fail to load lib - AMDSMI_STATUS_FAIL_LOAD_SYMBOL = 1001 - AMDSMI_STATUS_DRM_ERROR = 1002 # Error when call libdrm - AMDSMI_STATUS_IO = 1003 # Error - AMDSMI_STATUS_FAULT = 1004 # Bad address - AMDSMI_STATUS_API_FAILED = 1005 # API call failed - AMDSMI_STATUS_TIMEOUT = 1006 # Timeout in API call - AMDSMI_STATUS_NO_SLOT = 1007 # No more free slot - AMDSMI_STATUS_RETRY = 1008 # Retry operation - AMDSMI_STATUS_NOT_INIT = 1009 # Device not initialized - AMDSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF # An unknown error occurred - -amdsmi_status_t = amdsmi_status -#Clock types -class amdsmi_clk_type (c_int): - CLK_TYPE_SYS = 0x0, # System clock - CLK_TYPE_FIRST = CLK_TYPE_SYS - CLK_TYPE_GFX = CLK_TYPE_SYS - CLK_TYPE_DF = 0x1 # Data Fabric clock (for ASICs - # running on a separate clock) - CLK_TYPE_DCEF = 0x2 # Display Controller Engine clock - CLK_TYPE_SOC = 0x3 - CLK_TYPE_MEM = 0x4 - CLK_TYPE_PCIE = 0x5 - CLK_TYPE_VCLK0 = 0x6 - CLK_TYPE_VCLK1 = 0x7 - CLK_TYPE_DCLK0 = 0x8 - CLK_TYPE_DCLK1 = 0x9 - CLK_TYPE__MAX = CLK_TYPE_DCLK1 - -amdsmi_clk_type_t = amdsmi_clk_type -#This enumeration is used to indicate from which part of the device a -# temperature reading should be obtained -class amdsmi_temperature_type (c_int): - TEMPERATURE_TYPE_EDGE = 0 - TEMPERATURE_TYPE_FIRST = TEMPERATURE_TYPE_EDGE - 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 = TEMPERATURE_TYPE_PLX - -#The values of this enum are used to identify the various firmware -#blocks. -class amdsmi_fw_block_t (c_int): - FW_ID_SMU = 1 - FW_ID_FIRST = FW_ID_SMU - 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 # eRAM - FW_ID_DMCU_ISR = 23 # ISR - 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 - -#This structure represents a range (e.g., frequencies or voltages) - -class amdsmi_range_t (Structure): - _fields_ = [ - ('lower_bound', c_uint64), - ('upper_bound', c_uint64), - ] - -class amdsmi_xgmi_info_t (Structure): - _fields_ = [ - ('xgmi_lanes', c_uint8), - ('xgmi_hive_id', c_uint64), - ('xgmi_node_id', c_uint64), - ('index', c_uint32), - ] - -#GPU Capability info - -class gfx (Structure): - _fields_ = [ - ('gfxip_major', c_uint32), - ('gfxip_minor', c_uint32), - ('gfxip_cu_count', c_uint16)] - -class mm (Structure): - _fields_ = [ - ('mm_ip_count', c_uint8), - ('mm_ip_list', c_uint8 * AMDSMI_MAX_MM_IP_COUNT) - ] -class amdsmi_gpu_caps_t (Structure): - _fields_ = [ - ('gfx', gfx), - ('mm', mm), - ('ras_supported', c_bool), - ('max_vf_num', c_uint8), - ('gfx_ip_count', c_uint32), - ('dma_ip_count', c_uint32) - ] - -class amdsmi_vram_info (Structure): - _fields_ = [ - ('vram_total', c_uint32), - ('vram_used', c_uint32), - ] - -class amdsmi_frequency_range_t(Structure): - _fields_ = [ - ('supported_freq_range', amdsmi_range_t), - ('current_freq_range', amdsmi_range_t), - ] - -class bdf_submodule (Structure): - _fields_ = [ - ('function_number', c_uint64, 3), - ('device_number', c_uint64, 5), - ('bus_number', c_uint64, 8), - ('domain_number', c_uint64, 48), - ] -class amdsmi_bdf_t (Union): - _fields_ = [ - ('bdf_submodule', bdf_submodule), - ('as_uint', c_uint64) - ] - -class amdsmi_power_cap_info_t (Structure): - _fields_ = [ - ('power_cap', c_uint64), - ('default_power_cap', c_uint64), - ('dpm_cap', c_uint64), - ('min_power_cap', c_uint64), - ('max_power_cap', c_uint64) - ] - -class amdsmi_vbios_info_t (Structure): - _fields_ =[ - ('name', c_char * AMDSMI_MAX_STRING_LENGTH), - ('vbios_version', c_uint32), - ('build_date', c_char * AMDSMI_MAX_DATE_LENGTH), - ('part_number', c_char * AMDSMI_MAX_STRING_LENGTH), - ('vbios_version_string', c_char * AMDSMI_NORMAL_STRING_LENGTH) - ] - -class fw_info_list (Structure): - _fields_ = [ - ('fw_id', amdsmi_fw_block_t), - ('fw_version', c_uint64) - ] -class amdsmi_fw_info_t (Structure): - _fields_ =[ - ('num_fw_info', c_uint8), - ('fw_info_list', fw_info_list * amdsmi_fw_block_t.FW_ID__MAX) - ] - -class amdsmi_asic_info_t (Structure): - _fields_ = [ - ('market_name', c_char * AMDSMI_MAX_STRING_LENGTH), - ('family', c_uint32), - ('vendor_id', c_uint32), - ('subvendor_id', c_uint32), - ('device_id', c_uint64), - ('rev_id', c_uint32), - ('asic_serial', c_char * AMDSMI_NORMAL_STRING_LENGTH) - ] - -class amdsmi_board_info (Structure): - _fields_ = [ - ('serial_number', c_uint64), - ('is_master', c_bool), - ('model_number', c_char * AMDSMI_NORMAL_STRING_LENGTH), - ('product_serial', c_char * AMDSMI_NORMAL_STRING_LENGTH), - ('fru_id', c_char * AMDSMI_NORMAL_STRING_LENGTH), - ('product_name', c_char * AMDSMI_PRODUCT_NAME_LENGTH), - ('manufacturer_name', c_char * AMDSMI_NORMAL_STRING_LENGTH), - ] - -class amdsmi_temperature_t (Structure): - _fields_ = [ - ('cur_temp', c_uint32) - ] - -class amdsmi_temperature_limit_t (Structure): - _fields_ = [ - ('limit', c_uint32) - ] - -class amdsmi_power_limit_t (Structure): - _fields_ = [ - ('limit', c_uint32) - ] - -class amdsmi_power_measure (Structure): - _fields_ = [ - ('average_socket_power', c_uint32), - ('energy_accumulator', c_uint64), - ('voltage_gfx', c_uint32), - ('voltage_soc', c_uint32), - ('voltage_mem', c_uint32), - ] - -class amdsmi_clk_measure_t (Structure): - _fields_ = [ - ('cur_clk', c_uint32), - ('avg_clk', c_uint32), - ('min_clk', c_uint32), - ('max_clk', c_uint32) - ] - -class amdsmi_engine_usage_t (Structure): - _fields_ = [ - ('gfx_activity', c_uint32), - ('umc_activity', c_uint32), - ('mm_activity', c_uint32 * AMDSMI_MAX_MM_IP_COUNT) - ] - -amdsmi_process_handle = c_uint32 - -class memory_usage (Structure): - _fields_ = [ - ('gtt_mem', c_uint64), - ('cpu_mem', c_uint64), - ('vram_mem', c_uint64) - ] - - -class engine_usage (Structure): - _fields_ = [ - ('gfx', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), - ('compute', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), - ('sdma', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), - ('enc', c_uint16 * AMDSMI_MAX_MM_IP_COUNT), - ('dec',c_uint16 * AMDSMI_MAX_MM_IP_COUNT) - ] -class amdsmi_proc_info_t(Structure): - _fields_ = [ - ('name', c_char * AMDSMI_NORMAL_STRING_LENGTH), - ('pid', amdsmi_process_handle), - ('mem', c_uint64), - ('engine_usage', engine_usage), - ('memory_usage', memory_usage), - ('container_name', c_char * AMDSMI_NORMAL_STRING_LENGTH) - - ] -amdsmi_process_info = amdsmi_proc_info_t - -# Guaranteed maximum possible number of supported frequencies -AMDSMI_MAX_NUM_FREQUENCIES = 32 - -# The number of points that make up a voltage-frequency curve definition -AMDSMI_NUM_VOLTAGE_CURVE_POINTS = 3 - -class amdsmi_dev_perf_level_t (c_int): - AMDSMI_DEV_PERF_LEVEL_AUTO = 0 # Performance level is "auto" - AMDSMI_DEV_PERF_LEVEL_FIRST = AMDSMI_DEV_PERF_LEVEL_AUTO - AMDSMI_DEV_PERF_LEVEL_HIGH = 1 # Keep PowerPlay levels "high", regardless of workload - AMDSMI_DEV_PERF_LEVEL_MANUAL = 2 # Only use values defined by manually setting the AMDSMI_CLK_TYPE_SYS speed - AMDSMI_DEV_PERF_LEVEL_STABLE_STD = 3 # Stable power state with profiling clocks - AMDSMI_DEV_PERF_LEVEL_STABLE_PEAK = 4 # Stable power state with peak clocks - AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_MCLK = 5 # Stable power state with minimum memory clock - AMDSMI_DEV_PERF_LEVEL_STABLE_MIN_SCLK = 6 # Stable power state with minimum system clock - AMDSMI_DEV_PERF_LEVEL_DETERMINISM = 7 # Performance determinism state - AMDSMI_DEV_PERF_LEVEL_LAST = AMDSMI_DEV_PERF_LEVEL_DETERMINISM - AMDSMI_DEV_PERF_LEVEL_UNKNOWN = 0x100 # Unknown performance level - -amdsmi_dev_perf_level = amdsmi_dev_perf_level_t - -class amdsmi_sw_component_t (c_int): - AMDSMI_SW_COMP_FIRST = 0x0 - AMDSMI_SW_COMP_DRIVER = AMDSMI_SW_COMP_FIRST # Driver - AMDSMI_SW_COMP_LAST = AMDSMI_SW_COMP_DRIVER - -amdsmi_event_handle_t = c_uint64 - - -#Event Groups -# Enum denoting an event group. The value of the enum is the -# base value for all the event enums in the group. -class amdsmi_event_group_t (c_int): - AMDSMI_EVNT_GRP_XGMI = 0 # Data Fabric(XGMI) related events - AMDSMI_EVNT_GRP_XGMI_DATA_OUT = 10 # XGMI Outbound data - AMDSMI_EVNT_GRP_INVALID = 0xFFFFFFFF - -# Event types -# Event type enum. Events belonging to a particular event group -# ::amdsmi_event_group_t should begin enumerating at the ::amdsmi_event_group_t -# value for that group. - -class amdsmi_event_type_t (c_int): - AMDSMI_EVNT_FIRST = amdsmi_event_group_t.AMDSMI_EVNT_GRP_XGMI - AMDSMI_EVNT_XGMI_FIRST = amdsmi_event_group_t.AMDSMI_EVNT_GRP_XGMI - AMDSMI_EVNT_XGMI_0_NOP_TX = AMDSMI_EVNT_XGMI_FIRST # NOPs sent to neighbor 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 = AMDSMI_EVNT_XGMI_DATA_OUT_5 - AMDSMI_EVNT_LAST = AMDSMI_EVNT_XGMI_DATA_OUT_LAST - -class amdsmi_counter_command_t (c_int): - AMDSMI_CNTR_CMD_START = 0 - AMDSMI_CNTR_CMD_STOP = 1 - -class amdsmi_counter_value_t (Structure): - _fields_ = [ - ('value', c_uint64), - ('time_enabled', c_uint64), - ('time_running', c_uint64) - ] - -class amdsmi_evt_notification_type_t (c_int): - AMDSMI_EVT_NOTIF_VMFAULT = 1 # VM page fault - AMDSMI_EVT_NOTIF_FIRST = AMDSMI_EVT_NOTIF_VMFAULT, - AMDSMI_EVT_NOTIF_THERMAL_THROTTLE = 2, - AMDSMI_EVT_NOTIF_GPU_PRE_RESET = 3, - AMDSMI_EVT_NOTIF_GPU_POST_RESET = 4, - AMDSMI_EVT_NOTIF_LAST = AMDSMI_EVT_NOTIF_GPU_POST_RESET - -# function to generate event bitmask from event id -def AMDSMI_EVENT_MASK_FROM_INDEX (i): - return c_ulonglong(1 << (i - 1)) - -MAX_EVENT_NOTIFICATION_MSG_SIZE = 64 - -# Event notification data returned from event notification API -class amdsmi_evt_notification_data_t (Structure): - _fields_ = [ - ('device_handle', c_void_p), # Handler of device that corresponds to the event - ('event', amdsmi_evt_notification_type_t), # Event type - ('message', c_char * MAX_EVENT_NOTIFICATION_MSG_SIZE) # Event message - ] - -# Temperature Metrics. This enum is used to identify various -# temperature metrics. Corresponding values will be in millidegress Celcius. - -class amdsmi_temperature_metric_t (c_int): - AMDSMI_TEMP_CURRENT = 0 # Temperature current value - AMDSMI_TEMP_FIRST = AMDSMI_TEMP_CURRENT - AMDSMI_TEMP_MAX = 1 # Temperature max value - AMDSMI_TEMP_MIN = 2 # Temperature min value - AMDSMI_TEMP_MAX_HYST = 3 # Temperature hysteresis value for max limit (This is an absolute temperature, not a delta) - AMDSMI_TEMP_MIN_HYST = 4 # Temperature hysteresis value for min limit (not a delta) - AMDSMI_TEMP_CRITICAL = 5 # Temperature critical max value, typically greater than corresponding temp_max values. - AMDSMI_TEMP_CRITICAL_HYST = 6 # Temperature hysteresis value for critical limit. (not a delta) - AMDSMI_TEMP_EMERGENCY = 7 # Temperature emergency max value, for chips supporting more than two upper temperature - # limits. Must be equal or greater than corresponding temp_crit values. - AMDSMI_TEMP_EMERGENCY_HYST = 8 # Temperature hysteresis value for emergency limit. (not a delta). - AMDSMI_TEMP_CRIT_MIN = 9 # Temperature critical min value, typically lower than corresponding temperature min values - AMDSMI_TEMP_CRIT_MIN_HYST = 10 # Temperature hysteresis value for critical minimum limit. (not a delta) - AMDSMI_TEMP_OFFSET = 11 # Temperature offset which is added to the temperature reading by the chip. - AMDSMI_TEMP_LOWEST = 12 # Historical minimum temperature. - AMDSMI_TEMP_HIGHEST = 13 # Historical maximum temperature. - AMDSMI_TEMP_LAST = AMDSMI_TEMP_HIGHEST - -class amdsmi_voltage_metric_t (c_int): - AMDSMI_VOLT_CURRENT = 0 # Voltage current value. - AMDSMI_VOLT_FIRST = AMDSMI_VOLT_CURRENT - AMDSMI_VOLT_MAX = 1 # Voltage max value. - AMDSMI_VOLT_MIN_CRIT = 2 # Voltage critical min value. - AMDSMI_VOLT_MIN = 3 # Voltage min value. - AMDSMI_VOLT_MAX_CRIT = 4 # Voltage critical max value. - AMDSMI_VOLT_AVERAGE = 5 # Average voltage. - AMDSMI_VOLT_LOWEST = 6 # Historical minimum voltage. - AMDSMI_VOLT_HIGHEST = 7 # Historical maximum voltage. - AMDSMI_VOLT_LAST = AMDSMI_VOLT_HIGHEST - -# This ennumeration is used to indicate which type of -# voltage reading should be obtained. - -class amdsmi_voltage_type_t (c_int): - AMDSMI_VOLT_TYPE_FIRST = 0 - AMDSMI_VOLT_TYPE_VDDGFX = AMDSMI_VOLT_TYPE_FIRST # Vddgfx GPU voltage - AMDSMI_VOLT_TYPE_LAST = AMDSMI_VOLT_TYPE_VDDGFX - AMDSMI_VOLT_TYPE_INVALID = 0xFFFFFFFF # Invalid type - -# Pre-set Profile Selections. These bitmasks can be AND'd with the -# ::amdsmi_power_profile_status_t.available_profiles returned from -# ::amdsmi_dev_power_profile_presets_get to determine which power profiles -# are supported by the system. - -class amdsmi_power_profile_preset_masks_t (c_int): - AMDSMI_PWR_PROF_PRST_CUSTOM_MASK = 0x1 # Custom Power Profile - AMDSMI_PWR_PROF_PRST_VIDEO_MASK = 0x2 # Video Power Profile - AMDSMI_PWR_PROF_PRST_POWER_SAVING_MASK = 0x4 # Power Saving Profile - AMDSMI_PWR_PROF_PRST_COMPUTE_MASK = 0x8 # Compute Saving Profile - AMDSMI_PWR_PROF_PRST_VR_MASK = 0x10 # VR Power Profile - - # 3D Full Screen Power Profile - AMDSMI_PWR_PROF_PRST_3D_FULL_SCR_MASK = 0x20 - AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT = 0x40 # Default Boot Up Profile - AMDSMI_PWR_PROF_PRST_LAST = AMDSMI_PWR_PROF_PRST_BOOTUP_DEFAULT - - # Invalid power profile - AMDSMI_PWR_PROF_PRST_INVALID = 0xFFFFFFFFFFFFFFFF - -class amdsmi_gpu_block_t (c_int): - AMDSMI_GPU_BLOCK_INVALID = 0x0000000000000000 # Used to indicate an invalid block - AMDSMI_GPU_BLOCK_FIRST = 0x0000000000000001 - - AMDSMI_GPU_BLOCK_UMC = AMDSMI_GPU_BLOCK_FIRST # UMC block - AMDSMI_GPU_BLOCK_SDMA = 0x0000000000000002 # SDMA block - AMDSMI_GPU_BLOCK_GFX = 0x0000000000000004 # GFX block - AMDSMI_GPU_BLOCK_MMHUB = 0x0000000000000008 # MMHUB block - AMDSMI_GPU_BLOCK_ATHUB = 0x0000000000000010 # ATHUB block - AMDSMI_GPU_BLOCK_PCIE_BIF = 0x0000000000000020 # PCIE_BIF block - AMDSMI_GPU_BLOCK_HDP = 0x0000000000000040 # HDP block - AMDSMI_GPU_BLOCK_XGMI_WAFL = 0x0000000000000080 # XGMI block - AMDSMI_GPU_BLOCK_DF = 0x0000000000000100 # DF block - AMDSMI_GPU_BLOCK_SMN = 0x0000000000000200 # SMN block - AMDSMI_GPU_BLOCK_SEM = 0x0000000000000400 # SEM block - AMDSMI_GPU_BLOCK_MP0 = 0x0000000000000800 # MP0 block - AMDSMI_GPU_BLOCK_MP1 = 0x0000000000001000 # MP1 block - AMDSMI_GPU_BLOCK_FUSE = 0x0000000000002000 # Fuse block - - AMDSMI_GPU_BLOCK_LAST = AMDSMI_GPU_BLOCK_FUSE # The highest bit position for supported blocks - AMDSMI_GPU_BLOCK_RESERVED = 0x8000000000000000 - -class amdsmi_ras_err_state_t (c_int): - AMDSMI_RAS_ERR_STATE_NONE = 0 # No current errors - AMDSMI_RAS_ERR_STATE_DISABLED = 1 # ECC is disabled - AMDSMI_RAS_ERR_STATE_PARITY = 2 # ECC errors present, but type unknown - AMDSMI_RAS_ERR_STATE_SING_C = 3 # Single correctable error - AMDSMI_RAS_ERR_STATE_MULT_UC = 4 # Multiple uncorrectable errors - AMDSMI_RAS_ERR_STATE_POISON = 5 # Firmware detected error and isolated page. Treat as uncorrectable. - AMDSMI_RAS_ERR_STATE_ENABLED = 6 # ECC is enabled - - AMDSMI_RAS_ERR_STATE_LAST = AMDSMI_RAS_ERR_STATE_ENABLED - AMDSMI_RAS_ERR_STATE_INVALID = 0xFFFFFFFF - -class amdsmi_memory_type_t (c_int): - AMDSMI_MEM_TYPE_FIRST = 0 - - AMDSMI_MEM_TYPE_VRAM = AMDSMI_MEM_TYPE_FIRST # VRAM memory - AMDSMI_MEM_TYPE_VIS_VRAM = 1 # VRAM memory that is visible - AMDSMI_MEM_TYPE_GTT = 2 # GTT memory - - AMDSMI_MEM_TYPE_LAST = AMDSMI_MEM_TYPE_GTT - -class amdsmi_freq_ind_t (c_int): - AMDSMI_FREQ_IND_MIN = 0 # Index used for the minimum frequency value - AMDSMI_FREQ_IND_MAX = 1 # Index used for the maximum frequency value - AMDSMI_FREQ_IND_INVALID = 0xFFFFFFFF # An invalid frequency index - -class amdsmi_xgmi_status_t (c_int): - AMDSMI_XGMI_STATUS_NO_ERRORS = 0 - AMDSMI_XGMI_STATUS_ERROR = 1 - AMDSMI_XGMI_STATUS_MULTIPLE_ERRORS = 2 - -amdsmi_bit_field_t = c_uint64() -amdsmi_bit_field = amdsmi_bit_field_t - -# Reserved Memory Page States -class amdsmi_memory_page_status_t (c_int): - AMDSMI_MEM_PAGE_STATUS_RESERVED = 0 # Reserved. This gpu page is reserved and not available for use - AMDSMI_MEM_PAGE_STATUS_PENDING = 1 # Pending. This gpu page is marked as bad - # and will be marked reserved at the next window. - AMDSMI_MEM_PAGE_STATUS_UNRESERVABLE = 2 # Unable to reserve this page - -# Types for IO Link -class AMDSMI_IO_LINK_TYPE (c_int): - AMDSMI_IOLINK_TYPE_UNDEFINED = 0 # unknown type. - AMDSMI_IOLINK_TYPE_PCIEXPRESS = 1 # PCI Express - AMDSMI_IOLINK_TYPE_XGMI = 2 # XGMI - AMDSMI_IOLINK_TYPE_NUMIOLINKTYPES = 3 # Number of IO Link types - AMDSMI_IOLINK_TYPE_SIZE = 0xFFFFFFFF # Max of IO Link types - -# The utilization counter type -class AMDSMI_UTILIZATION_COUNTER_TYPE (c_int): - AMDSMI_UTILIZATION_COUNTER_FIRST = 0 # GFX Activity - AMDSMI_COARSE_GRAIN_GFX_ACTIVITY = AMDSMI_UTILIZATION_COUNTER_FIRST - AMDSMI_COARSE_GRAIN_MEM_ACTIVITY = 1 # Memory Activity - AMDSMI_UTILIZATION_COUNTER_LAST = AMDSMI_COARSE_GRAIN_MEM_ACTIVITY - -# Reserved Memory Page Record -class amdsmi_utilization_counter_t (Structure): - _fields_=[ - ('page_address', c_uint64), - ('page_size', c_uint64), - ('status', amdsmi_memory_page_status_t), - ] - -# Number of possible power profiles that a system could support -AMDSMI_MAX_NUM_POWER_PROFILES = (sizeof(amdsmi_bit_field_t) * 8) - -# This structure contains information about which power profiles are -# supported by the system for a given device, and which power profile is currently active. - -class amdsmi_power_profile_status_t (Structure): - _fields_ = [ - ('available_profiles', c_uint64), # Which profiles are supported by this system - ('current', amdsmi_power_profile_preset_masks_t), # Which power profile is currently active - ('num_profiles', c_uint32) # How many power profiles are available - ] - -# This structure holds information about clock frequencies. -class amdsmi_frequencies_t (Structure): - _fields_ = [ - ('num_supported', c_uint32), # The number of supported frequencies - ('current', c_uint32), # The current frequency index - ('frequency', c_uint64 * AMDSMI_MAX_NUM_FREQUENCIES), # List of frequencies. - # Only the first num_supported frequencies are valid. - ] - -#This structure holds information about the possible PCIe -#bandwidths. Specifically, the possible transfer rates and their -#associated numbers of lanes are stored here. -class amdsmi_pcie_bandwidth_t (Structure): - _fields_ = [ - ('transfer_rate', amdsmi_frequencies_t), # Transfer rates (T/s) that are possible - ('lanes', c_uint32 * AMDSMI_MAX_NUM_FREQUENCIES), # List of lanes for corresponding transfer rate. - # Only the first num_supported bandwidths are valid. - ] - -# This structure holds version information. - -class amdsmi_version_t (Structure): - _fields_ = [ - ('major', c_uint32), # Major version - ('minor', c_uint32), # Minor version - ('patch', c_uint32), # Patch, build or stepping version - ('build', c_char_p), # Build string - ] - -# This structure represents a point on the frequency-voltage plane. -class amdsmi_od_vddc_point_t (Structure): - _fields_ = [ - ('frequency', c_uint64), # Frequency coordinate (in Hz) - ('voltage', c_uint64), # Voltage coordinate (in mV) - ] - -# This structure holds 2 ::amdsmi_range_t's, one for frequency and one for -# voltage. These 2 ranges indicate the range of possible values for the -# corresponding ::amdsmi_od_vddc_point_t. - -class amdsmi_freq_volt_region_t (Structure): - _fields_ = [ - ('freq_range', amdsmi_range_t), # The frequency range for this VDDC Curve point - ('volt_range', amdsmi_range_t), # The voltage range for this VDDC Curve point - ] - -# Array of ::AMDSMI_NUM_VOLTAGE_CURVE_POINTS ::amdsmi_od_vddc_point_t's that -# make up the voltage frequency curve points. - -class amdsmi_od_volt_curve_t (Structure): - _fields_ = [ - # Array of ::AMDSMI_NUM_VOLTAGE_CURVE_POINTS ::amdsmi_od_vddc_point_t's that - # make up the voltage frequency curve points. - ('vc_points', amdsmi_od_vddc_point_t * AMDSMI_NUM_VOLTAGE_CURVE_POINTS) - ] - -# This structure holds the frequency-voltage values for a device. -class amdsmi_od_volt_freq_data_t (Structure): - _fields_ = [ - ('curr_sclk_range', amdsmi_range_t), # The current SCLK frequency range - ('curr_mclk_range', amdsmi_range_t), # The current MCLK frequency range; (upper bound only) - ('sclk_freq_limits', amdsmi_range_t), # The range possible of SCLK values - ('mclk_freq_limits', amdsmi_range_t), # The range possible of MCLK values - ('curve', amdsmi_od_volt_curve_t), # The current voltage curve - ('num_regions', c_uint32), # The number of voltage curve regions - ] - -# The following structures hold the gpu metrics values for a device. -# Size and version information of metrics data - -class amd_metrics_table_header_t (Structure): - _fields_ = [ - ('structure_size', c_uint16), - ('format_revision', c_ubyte), - ('content_revision', c_ubyte), - ] - -AMDSMI_GPU_METRICS_API_FORMAT_VER = 1 -AMDSMI_GPU_METRICS_API_CONTENT_VER_1 = 1 -AMDSMI_GPU_METRICS_API_CONTENT_VER_2 = 2 -AMDSMI_GPU_METRICS_API_CONTENT_VER_3 = 3 - -AMDSMI_NUM_HBM_INSTANCES = 4 # This should match NUM_HBM_INSTANCES -CENTRIGRADE_TO_MILLI_CENTIGRADE = 1000 # Unit conversion factor for HBM temperatures - -class amdsmi_gpu_metrics_t (Structure): - _fields_ = [ - ('common_header', amd_metrics_table_header_t), - # Temperature - ('temperature_edge', c_uint16), - ('temperature_hotspot', c_uint16), - ('temperature_mem', c_uint16), - ('temperature_vrgfx', c_uint16), - ('temperature_vrsoc', c_uint16), - ('temperature_vrmem', c_uint16), - # Utilization - ('average_gfx_activity', c_uint16), - ('average_umc_activity', c_uint16), - ('average_mm_activity', c_uint16), - # Power/Energy - ('average_socket_power', c_uint16), - ('energy_accumulator', c_uint64), - # Driver attached timestamp (in ns) - ('system_clock_counter', c_uint64), - # Average clocks - ('average_gfxclk_frequency', c_uint16), - ('average_socclk_frequency', c_uint16), - ('average_uclk_frequency', c_uint16), - ('average_vclk0_frequency', c_uint16), - ('average_dclk0_frequency', c_uint16), - ('average_vclk1_frequency', c_uint16), - ('average_dclk1_frequency', c_uint16), - # Current clocks - ('current_gfxclk', c_uint16), - ('current_socclk', c_uint16), - ('current_uclk', c_uint16), - ('current_vclk0', c_uint16), - ('current_dclk0', c_uint16), - ('current_vclk1', c_uint16), - ('current_dclk1', c_uint16), - # Throttle status - ('throttle_status', c_uint32), - # Fans - ('current_fan_speed', c_uint16), - # Link width/speed - ('pcie_link_width', c_uint16), # v1 mod.(8->16) - ('pcie_link_speed', c_uint16), # in 0.1 GT/s; v1 mod. (8->16) - ('padding', c_uint16), # new in v1 - ('gfx_activity_acc', c_uint32), # new in v1 - ('mem_actvity_acc', c_uint32), # new in v1 - ('temperature_hbm', c_uint16 * AMDSMI_NUM_HBM_INSTANCES) # new in v1 - ] - -# This structure holds error counts. -class amdsmi_error_count_t (Structure): - _fields_ = [ - ('correctable_count', c_uint64), # Accumulated correctable errors - ('uncorrectable_count', c_uint64) # Accumulated uncorrectable errors - ] - -# This structure holds pcie info. -class amdsmi_pcie_info_t (Structure): - _fields_ = [ - ('pcie_lanes', c_uint16), - ('pcie_speed', c_uint16), - ] - -class amdsmi_process_info_t (Structure): - _fields_ = [ - ('process_id', c_uint32), # Process ID - ('pasid', c_uint32), # PASID - ('vram_usage', c_uint64), # VRAM usage - ('sdma_usage', c_uint64), # SDMA usage in microseconds - ('cu_occupancy', c_uint32), # Compute Unit usage in percent - ] - -# Opaque handle to function-support object -class amdsmi_func_id_iter_handle(Structure): - pass -amdsmi_func_id_iter_handle_t = POINTER(amdsmi_func_id_iter_handle) - -# Place-holder "variant" for functions that have don't have any variants, -# but do have monitors or sensors. - -AMDSMI_DEFAULT_VARIANT = 0xFFFFFFFFFFFFFFFF - -class submodule_union(Union): - _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), - ] -class amdsmi_func_id_value_t (Union): - _fields_ = [ - ('id', c_uint64), - ('name', c_char_p), - ('submodule', submodule_union) - ] - -amd_id = amdsmi_func_id_value_t \ No newline at end of file diff --git a/example/amd_smi_drm_example.cc b/example/amd_smi_drm_example.cc index b4228dc3d9..69d9ef12b0 100644 --- a/example/amd_smi_drm_example.cc +++ b/example/amd_smi_drm_example.cc @@ -259,8 +259,6 @@ int main() { // Get device type. Since the amdsmi is initialized with // AMD_SMI_INIT_AMD_GPUS, the device_type must be AMD_GPU. device_type_t device_type = {}; - std::cout << "Device Handle: " << device_handles[j] << std::endl; - ret = amdsmi_get_device_type(device_handles[j], &device_type); CHK_AMDSMI_RET(ret) if (device_type != AMD_GPU) { From 6ee793ca0326668fe50a2b11ab59120e1e08c690 Mon Sep 17 00:00:00 2001 From: "Galantsev, Dmitrii" Date: Wed, 18 Jan 2023 15:00:21 -0600 Subject: [PATCH 7/7] SWDEV-340919 - Move examples and tests install dir Previous install locations: - /opt/rocm/share/example/amd-smi - /opt/rocm/share/tests/amd-smi New install locations: - /opt/rocm/share/amd_smi/example - /opt/rocm/share/amd_smi/tests Change-Id: I305477b9f66bdc5963923efe6da1c01f87ea2085 Signed-off-by: Galantsev, Dmitrii --- CMakeLists.txt | 3 +++ cmake_modules/help_package.cmake | 4 +++- example/CMakeLists.txt | 4 ++-- tests/amd_smi_test/CMakeLists.txt | 2 +- tests/rocm_smi_test/CMakeLists.txt | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31aa11d5dc..a709822e95 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,6 +55,8 @@ include(GNUInstallDirs) option(BUILD_TESTS "Build test suite" OFF) option(ENABLE_LDCONFIG "Set library links and caches using ldconfig." ON) +# Set share path here because project name != amd_smi +set(SHARE_INSTALL_PREFIX "share/${AMD_SMI}" CACHE STRING "Tests and Example install directory") # Packaging directives set(CPACK_PACKAGE_NAME ${AMD_SMI_PACKAGE} @@ -212,6 +214,7 @@ install( #License file set(CPACK_RPM_PACKAGE_LICENSE "NCSA") +# docs are installed into different share directory from tests and examples install( FILES ${CPACK_RESOURCE_FILE_LICENSE} DESTINATION share/doc/${AMD_SMI} diff --git a/cmake_modules/help_package.cmake b/cmake_modules/help_package.cmake index e1d74f4114..94f71ce5d1 100644 --- a/cmake_modules/help_package.cmake +++ b/cmake_modules/help_package.cmake @@ -14,13 +14,15 @@ function(generic_add_rocm) set(CMAKE_INSTALL_PREFIX ${ROCM_DIR} CACHE STRING "Default installation directory.") set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE STRING "Default packaging prefix.") - set(SHARE_INSTALL_PREFIX "share/${CMAKE_PROJECT_NAME}" CACHE STRING "Tests and Example install directory") # add package search paths set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} /usr/local PARENT_SCOPE) set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/lib64 /usr/lib/x86_64-linux-gnu PARENT_SCOPE) endfunction() function(generic_package) + # Used by test and example CMakeLists + set(SHARE_INSTALL_PREFIX "share/${CMAKE_PROJECT_NAME}" CACHE STRING "Tests and Example install directory") + if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.4.0) message("Compiler version is " ${CMAKE_CXX_COMPILER_VERSION}) message(FATAL_ERROR "Require at least gcc-5.4.0") diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index ba375c27cd..f8cbbb41b9 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -4,7 +4,7 @@ # copy .cc files into install directory install( DIRECTORY ./ - DESTINATION share/example/amd-smi + DESTINATION ${SHARE_INSTALL_PREFIX}/example FILES_MATCHING PATTERN "*.cc") @@ -12,7 +12,7 @@ install( install( FILES CMakeLists.txt.in RENAME CMakeLists.txt - DESTINATION share/example/amd-smi) + DESTINATION ${SHARE_INSTALL_PREFIX}/example) # compile example files but do not install # this is only useful if running from build directory diff --git a/tests/amd_smi_test/CMakeLists.txt b/tests/amd_smi_test/CMakeLists.txt index 090ce93d7d..93c2bbab04 100644 --- a/tests/amd_smi_test/CMakeLists.txt +++ b/tests/amd_smi_test/CMakeLists.txt @@ -68,5 +68,5 @@ target_link_libraries(${TEST} amd_smi c stdc++ pthread GTest::gtest_main) # TODO: Remove GTest from here in the future and rely on INSTALL_GTEST? install( TARGETS ${TEST} gtest gtest_main - DESTINATION ${SHARE_INSTALL_PREFIX}/tests/amd_smi + DESTINATION ${SHARE_INSTALL_PREFIX}/tests COMPONENT tests) diff --git a/tests/rocm_smi_test/CMakeLists.txt b/tests/rocm_smi_test/CMakeLists.txt index 30fde142ab..456cb225fe 100755 --- a/tests/rocm_smi_test/CMakeLists.txt +++ b/tests/rocm_smi_test/CMakeLists.txt @@ -60,5 +60,5 @@ target_link_libraries(${TEST} rocm_smi64 c stdc++ pthread GTest::gtest_main) #install( # TARGETS ${TEST} -# DESTINATION ${SHARE_INSTALL_PREFIX}/tests/amd_smi +# DESTINATION ${SHARE_INSTALL_PREFIX}/tests # COMPONENT tests)