48a4cda75c
* Add common module * Added information to help with unknowns * Allow paring of cmds * change cmd print default * Reduce cmds to be tested --------- Signed-off-by: amd-josnarlo <joseph.narlo@amd.com> Co-authored-by: amd-josnarlo <joseph.narlo@amd.com>
534 γραμμές
26 KiB
Python
534 γραμμές
26 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) Advanced Micro Devices. All rights reserved.
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
# this software and associated documentation files (the "Software"), to deal in
|
|
# the Software without restriction, including without limitation the rights to
|
|
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
# the Software, and to permit persons to whom the Software is furnished to do so,
|
|
# subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
import ctypes
|
|
import inspect
|
|
import json
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
amdsmi_path = os.environ.get('AMDSMI_PATH', '/opt/rocm/share/amd_smi')
|
|
if not os.path.exists(amdsmi_path):
|
|
raise FileNotFoundError(f'AMDSMI_PATH "{amdsmi_path}" does not exist. Please set the correct path in your environment.')
|
|
sys.path.append(amdsmi_path)
|
|
try:
|
|
import amdsmi
|
|
except ImportError:
|
|
raise ImportError(f'Could not import the "amdsmi" module from "{amdsmi_path}"')
|
|
|
|
|
|
class Common(unittest.TestCase):
|
|
def __init__(self, verbose, *args, **kwargs):
|
|
self.verbose = verbose
|
|
self.max_num_physical_devices = amdsmi.amdsmi_interface.AMDSMI_MAX_NUM_XCP * amdsmi.amdsmi_interface.AMDSMI_MAX_DEVICES
|
|
self.PASS = 'AMDSMI_STATUS_SUCCESS'
|
|
self.FAIL = 'AMDSMI_STATUS_INVAL'
|
|
self.ANY_FAIL = 'ANY_FAIL'
|
|
|
|
# Tests marked wtih either of these flags will be skipped
|
|
# and need to be implemented later.
|
|
self.TODO_SKIP_FAIL = True
|
|
self.TODO_SKIP_NOT_COMPLETE = True
|
|
|
|
self.virtualization_mode_map = \
|
|
{
|
|
'0': 'UNKNOWN',
|
|
'1': 'BAREMETAL',
|
|
'2': 'HOST',
|
|
'3': 'GUEST',
|
|
'4': 'PASSTHROUGH'
|
|
}
|
|
|
|
try:
|
|
amdsmi.amdsmi_init()
|
|
|
|
# Get gpu
|
|
self.processors = amdsmi.amdsmi_get_processor_handles()
|
|
self.virt_mode = []
|
|
self.asic_info = []
|
|
self.board_info = []
|
|
#self.uuids = []
|
|
#self.bdfs = []
|
|
for i, gpu in enumerate(self.processors):
|
|
#uuid = amdsmi.amdsmi_get_gpu_device_uuid(gpu)
|
|
#self.uuids.append(uuid)
|
|
#bdf = amdsmi.amdsmi_get_gpu_device_bdf(gpu)
|
|
#self.bdfs.append(bdf)
|
|
# Get virtualization mode info
|
|
if False:
|
|
self.virt_mode.append(amdsmi.amdsmi_get_gpu_virtualization_mode(gpu))
|
|
ret = amdsmi.amdsmi_get_gpu_virtualization_mode(gpu)
|
|
mode_name = self.virtualization_mode_map[str(int(ret['mode']))]
|
|
self.virt_mode.append({'mode': mode_name})
|
|
|
|
# Get asic info
|
|
self.asic_info.append(amdsmi.amdsmi_get_gpu_asic_info(gpu))
|
|
# Get board info
|
|
self.board_info.append(amdsmi.amdsmi_get_gpu_board_info(gpu))
|
|
|
|
amdsmi.amdsmi_shut_down()
|
|
except amdsmi.AmdSmiLibraryException as e:
|
|
print(f'In class Common, Cannot get processor information, {e}')
|
|
|
|
self.not_supported_error_codes = \
|
|
[
|
|
( '2', 'AMDSMI_STATUS_NOT_SUPPORTED'),
|
|
( '3', 'AMDSMI_STATUS_NOT_YET_IMPLEMENTED'),
|
|
('49', 'AMDSMI_STATUS_NO_HSMP_MSG_SUP')
|
|
]
|
|
|
|
self.error_map = \
|
|
{
|
|
'0': 'AMDSMI_STATUS_SUCCESS',
|
|
'1': 'AMDSMI_STATUS_INVAL',
|
|
'2': 'AMDSMI_STATUS_NOT_SUPPORTED',
|
|
'3': 'AMDSMI_STATUS_NOT_YET_IMPLEMENTED',
|
|
'4': 'AMDSMI_STATUS_FAIL_LOAD_MODULE',
|
|
'5': 'AMDSMI_STATUS_FAIL_LOAD_SYMBOL',
|
|
'6': 'AMDSMI_STATUS_DRM_ERROR',
|
|
'7': 'AMDSMI_STATUS_API_FAILED',
|
|
'8': 'AMDSMI_STATUS_TIMEOUT',
|
|
'9': 'AMDSMI_STATUS_RETRY',
|
|
'10': 'AMDSMI_STATUS_NO_PERM',
|
|
'11': 'AMDSMI_STATUS_INTERRUPT',
|
|
'12': 'AMDSMI_STATUS_IO',
|
|
'13': 'AMDSMI_STATUS_ADDRESS_FAULT',
|
|
'14': 'AMDSMI_STATUS_FILE_ERROR',
|
|
'15': 'AMDSMI_STATUS_OUT_OF_RESOURCES',
|
|
'16': 'AMDSMI_STATUS_INTERNAL_EXCEPTION',
|
|
'17': 'AMDSMI_STATUS_INPUT_OUT_OF_BOUNDS',
|
|
'18': 'AMDSMI_STATUS_INIT_ERROR',
|
|
'19': 'AMDSMI_STATUS_REFCOUNT_OVERFLOW',
|
|
'30': 'AMDSMI_STATUS_BUSY',
|
|
'31': 'AMDSMI_STATUS_NOT_FOUND',
|
|
'32': 'AMDSMI_STATUS_NOT_INIT',
|
|
'33': 'AMDSMI_STATUS_NO_SLOT',
|
|
'34': 'AMDSMI_STATUS_DRIVER_NOT_LOADED',
|
|
'39': 'AMDSMI_STATUS_MORE_DATA',
|
|
'40': 'AMDSMI_STATUS_NO_DATA',
|
|
'41': 'AMDSMI_STATUS_INSUFFICIENT_SIZE',
|
|
'42': 'AMDSMI_STATUS_UNEXPECTED_SIZE',
|
|
'43': 'AMDSMI_STATUS_UNEXPECTED_DATA',
|
|
'44': 'AMDSMI_STATUS_NON_AMD_CPU',
|
|
'45': 'AMDSMI_STATUS_NO_ENERGY_DRV',
|
|
'46': 'AMDSMI_STATUS_NO_MSR_DRV',
|
|
'47': 'AMDSMI_STATUS_NO_HSMP_DRV',
|
|
'48': 'AMDSMI_STATUS_NO_HSMP_SUP',
|
|
'49': 'AMDSMI_STATUS_NO_HSMP_MSG_SUP',
|
|
'50': 'AMDSMI_STATUS_HSMP_TIMEOUT',
|
|
'51': 'AMDSMI_STATUS_NO_DRV',
|
|
'52': 'AMDSMI_STATUS_FILE_NOT_FOUND',
|
|
'53': 'AMDSMI_STATUS_ARG_PTR_NULL',
|
|
'54': 'AMDSMI_STATUS_AMDGPU_RESTART_ERR',
|
|
'55': 'AMDSMI_STATUS_SETTING_UNAVAILABLE',
|
|
'56': 'AMDSMI_STATUS_CORRUPTED_EEPROM',
|
|
'0xFFFFFFFE': 'AMDSMI_STATUS_MAP_ERROR',
|
|
'0xFFFFFFFF': 'AMDSMI_STATUS_UNKNOWN_ERROR'
|
|
}
|
|
|
|
self.status_types = \
|
|
[
|
|
('SUCCESS', amdsmi.AmdSmiStatus.SUCCESS, self.PASS),
|
|
('INVAL', amdsmi.AmdSmiStatus.INVAL, self.PASS),
|
|
('NOT_SUPPORTED', amdsmi.AmdSmiStatus.NOT_SUPPORTED, self.PASS),
|
|
('NOT_YET_IMPLEMENTED', amdsmi.AmdSmiStatus.NOT_YET_IMPLEMENTED, self.PASS),
|
|
('FAIL_LOAD_MODULE', amdsmi.AmdSmiStatus.FAIL_LOAD_MODULE, self.PASS),
|
|
('FAIL_LOAD_SYMBOL', amdsmi.AmdSmiStatus.FAIL_LOAD_SYMBOL, self.PASS),
|
|
('DRM_ERROR', amdsmi.AmdSmiStatus.DRM_ERROR, self.PASS),
|
|
('API_FAILED', amdsmi.AmdSmiStatus.API_FAILED, self.PASS),
|
|
('TIMEOUT', amdsmi.AmdSmiStatus.TIMEOUT, self.PASS),
|
|
('RETRY', amdsmi.AmdSmiStatus.RETRY, self.PASS),
|
|
('NO_PERM', amdsmi.AmdSmiStatus.NO_PERM, self.PASS),
|
|
('INTERRUPT', amdsmi.AmdSmiStatus.INTERRUPT, self.PASS),
|
|
('IO', amdsmi.AmdSmiStatus.IO, self.PASS),
|
|
('ADDRESS_FAULT', amdsmi.AmdSmiStatus.ADDRESS_FAULT, self.PASS),
|
|
('FILE_ERROR', amdsmi.AmdSmiStatus.FILE_ERROR, self.PASS),
|
|
('OUT_OF_RESOURCES', amdsmi.AmdSmiStatus.OUT_OF_RESOURCES, self.PASS),
|
|
('INTERNAL_EXCEPTION', amdsmi.AmdSmiStatus.INTERNAL_EXCEPTION, self.PASS),
|
|
('INPUT_OUT_OF_BOUNDS', amdsmi.AmdSmiStatus.INPUT_OUT_OF_BOUNDS, self.PASS),
|
|
('INIT_ERROR', amdsmi.AmdSmiStatus.INIT_ERROR, self.PASS),
|
|
('REFCOUNT_OVERFLOW', amdsmi.AmdSmiStatus.REFCOUNT_OVERFLOW, self.PASS),
|
|
('DIRECTORY_NOT_FOUND', amdsmi.AmdSmiStatus.DIRECTORY_NOT_FOUND, self.PASS),
|
|
('BUSY', amdsmi.AmdSmiStatus.BUSY, self.PASS),
|
|
('NOT_FOUND', amdsmi.AmdSmiStatus.NOT_FOUND, self.PASS),
|
|
('NOT_INIT', amdsmi.AmdSmiStatus.NOT_INIT, self.PASS),
|
|
('NO_SLOT', amdsmi.AmdSmiStatus.NO_SLOT, self.PASS),
|
|
('DRIVER_NOT_LOADED', amdsmi.AmdSmiStatus.DRIVER_NOT_LOADED, self.PASS),
|
|
('MORE_DATA', amdsmi.AmdSmiStatus.MORE_DATA, self.PASS),
|
|
('NO_DATA', amdsmi.AmdSmiStatus.NO_DATA, self.PASS),
|
|
('INSUFFICIENT_SIZE', amdsmi.AmdSmiStatus.INSUFFICIENT_SIZE, self.PASS),
|
|
('UNEXPECTED_SIZE', amdsmi.AmdSmiStatus.UNEXPECTED_SIZE, self.PASS),
|
|
('UNEXPECTED_DATA', amdsmi.AmdSmiStatus.UNEXPECTED_DATA, self.PASS),
|
|
('NON_AMD_CPU', amdsmi.AmdSmiStatus.NON_AMD_CPU, self.PASS),
|
|
('NO_ENERGY_DRV', amdsmi.AmdSmiStatus.NO_ENERGY_DRV, self.PASS),
|
|
('NO_MSR_DRV', amdsmi.AmdSmiStatus.NO_MSR_DRV, self.PASS),
|
|
('NO_HSMP_DRV', amdsmi.AmdSmiStatus.NO_HSMP_DRV, self.PASS),
|
|
('NO_HSMP_SUP', amdsmi.AmdSmiStatus.NO_HSMP_SUP, self.PASS),
|
|
('NO_HSMP_MSG_SUP', amdsmi.AmdSmiStatus.NO_HSMP_MSG_SUP, self.PASS),
|
|
('HSMP_TIMEOUT', amdsmi.AmdSmiStatus.HSMP_TIMEOUT, self.PASS),
|
|
('NO_DRV', amdsmi.AmdSmiStatus.NO_DRV, self.PASS),
|
|
('FILE_NOT_FOUND', amdsmi.AmdSmiStatus.FILE_NOT_FOUND, self.PASS),
|
|
('ARG_PTR_NULL', amdsmi.AmdSmiStatus.ARG_PTR_NULL, self.PASS),
|
|
('AMDGPU_RESTART_ERR', amdsmi.AmdSmiStatus.AMDGPU_RESTART_ERR, self.PASS),
|
|
('SETTING_UNAVAILABLE', amdsmi.AmdSmiStatus.SETTING_UNAVAILABLE, self.PASS),
|
|
('CORRUPTED_EEPROM', amdsmi.AmdSmiStatus.CORRUPTED_EEPROM, self.PASS),
|
|
('MAP_ERROR', amdsmi.AmdSmiStatus.MAP_ERROR, self.PASS),
|
|
('UNKNOWN_ERROR', amdsmi.AmdSmiStatus.UNKNOWN_ERROR, self.PASS)
|
|
]
|
|
|
|
self.clk_types = \
|
|
[
|
|
('SYS', amdsmi.AmdSmiClkType.SYS, self.PASS),
|
|
('GFX', amdsmi.AmdSmiClkType.GFX, self.PASS),
|
|
('DF', amdsmi.AmdSmiClkType.DF, self.PASS),
|
|
('DCEF', amdsmi.AmdSmiClkType.DCEF, [self.PASS, self.FAIL]),
|
|
('SOC', amdsmi.AmdSmiClkType.SOC, self.PASS),
|
|
('MEM', amdsmi.AmdSmiClkType.MEM, self.PASS),
|
|
('PCIE', amdsmi.AmdSmiClkType.PCIE, [self.PASS, self.FAIL]),
|
|
('VCLK0', amdsmi.AmdSmiClkType.VCLK0, self.PASS),
|
|
('VCLK1', amdsmi.AmdSmiClkType.VCLK1, self.PASS),
|
|
('DCLK0', amdsmi.AmdSmiClkType.DCLK0, self.PASS),
|
|
('DCLK1', amdsmi.AmdSmiClkType.DCLK1, self.PASS)
|
|
]
|
|
|
|
self.clk_limit_types = \
|
|
[
|
|
('MIN', amdsmi.AmdSmiClkLimitType.MIN, self.PASS),
|
|
('MAX', amdsmi.AmdSmiClkLimitType.MAX, self.PASS)
|
|
]
|
|
|
|
self.io_bw_encodings = \
|
|
[
|
|
('AGG_BW0', amdsmi.amdsmi_interface.amdsmi_wrapper.AGG_BW0, self.PASS),
|
|
('RD_BW0', amdsmi.amdsmi_interface.amdsmi_wrapper.RD_BW0, self.PASS),
|
|
('WR_BW0', amdsmi.amdsmi_interface.amdsmi_wrapper.WR_BW0, self.PASS)
|
|
]
|
|
|
|
self.gpu_blocks = \
|
|
[
|
|
('INVALID', amdsmi.AmdSmiGpuBlock.INVALID, self.FAIL),
|
|
('UMC', amdsmi.AmdSmiGpuBlock.UMC, self.PASS),
|
|
('SDMA', amdsmi.AmdSmiGpuBlock.SDMA, self.PASS),
|
|
('GFX', amdsmi.AmdSmiGpuBlock.GFX, self.PASS),
|
|
('MMHUB', amdsmi.AmdSmiGpuBlock.MMHUB, self.PASS),
|
|
('ATHUB', amdsmi.AmdSmiGpuBlock.ATHUB, self.PASS),
|
|
('PCIE_BIF', amdsmi.AmdSmiGpuBlock.PCIE_BIF, self.PASS),
|
|
('HDP', amdsmi.AmdSmiGpuBlock.HDP, self.PASS),
|
|
('XGMI_WAFL', amdsmi.AmdSmiGpuBlock.XGMI_WAFL, self.PASS),
|
|
('DF', amdsmi.AmdSmiGpuBlock.DF, self.PASS),
|
|
('SMN', amdsmi.AmdSmiGpuBlock.SMN, self.PASS),
|
|
('SEM', amdsmi.AmdSmiGpuBlock.SEM, self.PASS),
|
|
('MP0', amdsmi.AmdSmiGpuBlock.MP0, self.PASS),
|
|
('MP1', amdsmi.AmdSmiGpuBlock.MP1, self.PASS),
|
|
('FUSE', amdsmi.AmdSmiGpuBlock.FUSE, self.PASS),
|
|
('MCA', amdsmi.AmdSmiGpuBlock.MCA, self.PASS),
|
|
('VCN', amdsmi.AmdSmiGpuBlock.VCN, self.PASS),
|
|
('JPEG', amdsmi.AmdSmiGpuBlock.JPEG, self.PASS),
|
|
('IH', amdsmi.AmdSmiGpuBlock.IH, self.PASS),
|
|
('MPIO', amdsmi.AmdSmiGpuBlock.MPIO, self.PASS),
|
|
('RESERVED', amdsmi.AmdSmiGpuBlock.RESERVED, self.FAIL)
|
|
]
|
|
|
|
self.memory_types = \
|
|
[
|
|
('VRAM', amdsmi.AmdSmiMemoryType.VRAM, self.PASS),
|
|
('VIS_VRAM', amdsmi.AmdSmiMemoryType.VIS_VRAM, self.PASS),
|
|
('GTT', amdsmi.AmdSmiMemoryType.GTT, self.PASS)
|
|
]
|
|
|
|
self.reg_types = \
|
|
[
|
|
('XGMI', amdsmi.AmdSmiRegType.XGMI, self.PASS),
|
|
('WAFL', amdsmi.AmdSmiRegType.WAFL, self.PASS),
|
|
('PCIE', amdsmi.AmdSmiRegType.PCIE, self.PASS),
|
|
('USR', amdsmi.AmdSmiRegType.USR, self.PASS),
|
|
('USR1', amdsmi.AmdSmiRegType.USR1, self.PASS)
|
|
]
|
|
|
|
self.voltage_metrics = \
|
|
[
|
|
('CURRENT', amdsmi.AmdSmiVoltageMetric.CURRENT, self.PASS),
|
|
('MAX', amdsmi.AmdSmiVoltageMetric.MAX, self.PASS),
|
|
('MIN_CRIT', amdsmi.AmdSmiVoltageMetric.MIN_CRIT, self.PASS),
|
|
('MIN', amdsmi.AmdSmiVoltageMetric.MIN, self.PASS),
|
|
('MAX_CRIT', amdsmi.AmdSmiVoltageMetric.MAX_CRIT, self.PASS),
|
|
('AVERAGE', amdsmi.AmdSmiVoltageMetric.AVERAGE, self.PASS),
|
|
('LOWEST', amdsmi.AmdSmiVoltageMetric.LOWEST, self.PASS),
|
|
('HIGHEST', amdsmi.AmdSmiVoltageMetric.HIGHEST, self.PASS)
|
|
]
|
|
|
|
self.voltage_types = \
|
|
[
|
|
('VDDGFX', amdsmi.AmdSmiVoltageType.VDDGFX, self.PASS),
|
|
('VDDBOARD', amdsmi.AmdSmiVoltageType.VDDBOARD, self.PASS),
|
|
('INVALID', amdsmi.AmdSmiVoltageType.INVALID, self.FAIL)
|
|
]
|
|
|
|
self.link_types = \
|
|
[
|
|
('AMDSMI_LINK_TYPE_INTERNAL', amdsmi.AmdSmiLinkType.AMDSMI_LINK_TYPE_INTERNAL, self.PASS),
|
|
('AMDSMI_LINK_TYPE_XGMI', amdsmi.AmdSmiLinkType.AMDSMI_LINK_TYPE_XGMI, self.PASS),
|
|
('AMDSMI_LINK_TYPE_PCIE', amdsmi.AmdSmiLinkType.AMDSMI_LINK_TYPE_PCIE, self.PASS),
|
|
('AMDSMI_LINK_TYPE_NOT_APPLICABLE', amdsmi.AmdSmiLinkType.AMDSMI_LINK_TYPE_NOT_APPLICABLE, self.FAIL),
|
|
('AMDSMI_LINK_TYPE_UNKNOWN', amdsmi.AmdSmiLinkType.AMDSMI_LINK_TYPE_UNKNOWN, self.FAIL)
|
|
]
|
|
|
|
self.temperature_types = \
|
|
[
|
|
('EDGE', amdsmi.AmdSmiTemperatureType.EDGE, self.PASS),
|
|
('HOTSPOT', amdsmi.AmdSmiTemperatureType.HOTSPOT, self.PASS),
|
|
('JUNCTION', amdsmi.AmdSmiTemperatureType.JUNCTION, self.PASS),
|
|
('VRAM', amdsmi.AmdSmiTemperatureType.VRAM, self.PASS),
|
|
('HBM_0', amdsmi.AmdSmiTemperatureType.HBM_0, self.PASS),
|
|
('HBM_1', amdsmi.AmdSmiTemperatureType.HBM_1, self.PASS),
|
|
('HBM_2', amdsmi.AmdSmiTemperatureType.HBM_2, self.PASS),
|
|
('HBM_3', amdsmi.AmdSmiTemperatureType.HBM_3, self.PASS),
|
|
('PLX', amdsmi.AmdSmiTemperatureType.PLX, self.PASS)
|
|
]
|
|
|
|
self.temperature_metrics = \
|
|
[
|
|
('CURRENT', amdsmi.AmdSmiTemperatureMetric.CURRENT, self.PASS),
|
|
('MAX', amdsmi.AmdSmiTemperatureMetric.MAX, self.PASS),
|
|
('MIN', amdsmi.AmdSmiTemperatureMetric.MIN, self.PASS),
|
|
('MAX_HYST', amdsmi.AmdSmiTemperatureMetric.MAX_HYST, self.PASS),
|
|
('MIN_HYST', amdsmi.AmdSmiTemperatureMetric.MIN_HYST, self.PASS),
|
|
('CRITICAL', amdsmi.AmdSmiTemperatureMetric.CRITICAL, self.PASS),
|
|
('CRITICAL_HYST', amdsmi.AmdSmiTemperatureMetric.CRITICAL_HYST, self.PASS),
|
|
('EMERGENCY', amdsmi.AmdSmiTemperatureMetric.EMERGENCY, self.PASS),
|
|
('EMERGENCY_HYST', amdsmi.AmdSmiTemperatureMetric.EMERGENCY_HYST, self.PASS),
|
|
('CRIT_MIN', amdsmi.AmdSmiTemperatureMetric.CRIT_MIN, self.PASS),
|
|
('CRIT_MIN_HYST', amdsmi.AmdSmiTemperatureMetric.CRIT_MIN_HYST, self.PASS),
|
|
('OFFSET', amdsmi.AmdSmiTemperatureMetric.OFFSET, self.PASS),
|
|
('LOWEST', amdsmi.AmdSmiTemperatureMetric.LOWEST, self.PASS),
|
|
('HIGHEST', amdsmi.AmdSmiTemperatureMetric.HIGHEST, self.PASS)
|
|
]
|
|
|
|
self.utilization_counter_types = \
|
|
[
|
|
('COARSE_GRAIN_GFX_ACTIVITY', amdsmi.AmdSmiUtilizationCounterType.COARSE_GRAIN_GFX_ACTIVITY, self.PASS),
|
|
('COARSE_GRAIN_MEM_ACTIVITY', amdsmi.AmdSmiUtilizationCounterType.COARSE_GRAIN_MEM_ACTIVITY, self.PASS),
|
|
('COARSE_DECODER_ACTIVITY', amdsmi.AmdSmiUtilizationCounterType.COARSE_DECODER_ACTIVITY, self.PASS),
|
|
('FINE_GRAIN_GFX_ACTIVITY', amdsmi.AmdSmiUtilizationCounterType.FINE_GRAIN_GFX_ACTIVITY, self.PASS),
|
|
('FINE_GRAIN_MEM_ACTIVITY', amdsmi.AmdSmiUtilizationCounterType.FINE_GRAIN_MEM_ACTIVITY, self.PASS),
|
|
('FINE_DECODER_ACTIVITY', amdsmi.AmdSmiUtilizationCounterType.FINE_DECODER_ACTIVITY, self.PASS),
|
|
('UTILIZATION_COUNTER_FIRST', amdsmi.AmdSmiUtilizationCounterType.UTILIZATION_COUNTER_FIRST, self.PASS),
|
|
('UTILIZATION_COUNTER_LAST', amdsmi.AmdSmiUtilizationCounterType.UTILIZATION_COUNTER_LAST, self.PASS),
|
|
('UTILIZATION_COUNTER_BAD', 100, self.FAIL)
|
|
]
|
|
|
|
self.event_groups = \
|
|
[
|
|
('XGMI', amdsmi.AmdSmiEventGroup.XGMI, self.PASS),
|
|
('XGMI_DATA_OUT', amdsmi.AmdSmiEventGroup.XGMI_DATA_OUT, self.PASS),
|
|
('GRP_INVALID', amdsmi.AmdSmiEventGroup.GRP_INVALID, self.FAIL)
|
|
]
|
|
|
|
self.event_types = \
|
|
[
|
|
('XGMI_0_NOP_TX', amdsmi.AmdSmiEventType.XGMI_0_NOP_TX, self.PASS),
|
|
('XGMI_0_REQUEST_TX', amdsmi.AmdSmiEventType.XGMI_0_REQUEST_TX, self.PASS),
|
|
('XGMI_0_RESPONSE_TX', amdsmi.AmdSmiEventType.XGMI_0_RESPONSE_TX, self.PASS),
|
|
('XGMI_0_BEATS_TX', amdsmi.AmdSmiEventType.XGMI_0_BEATS_TX, self.PASS),
|
|
('XGMI_1_NOP_TX', amdsmi.AmdSmiEventType.XGMI_1_NOP_TX, self.PASS),
|
|
('XGMI_1_REQUEST_TX', amdsmi.AmdSmiEventType.XGMI_1_REQUEST_TX, self.PASS),
|
|
('XGMI_1_RESPONSE_TX', amdsmi.AmdSmiEventType.XGMI_1_RESPONSE_TX, self.PASS),
|
|
('XGMI_1_BEATS_TX', amdsmi.AmdSmiEventType.XGMI_1_BEATS_TX, self.PASS),
|
|
('XGMI_DATA_OUT_0', amdsmi.AmdSmiEventType.XGMI_DATA_OUT_0, self.PASS),
|
|
('XGMI_DATA_OUT_1', amdsmi.AmdSmiEventType.XGMI_DATA_OUT_1, self.PASS),
|
|
('XGMI_DATA_OUT_2', amdsmi.AmdSmiEventType.XGMI_DATA_OUT_2, self.PASS),
|
|
('XGMI_DATA_OUT_3', amdsmi.AmdSmiEventType.XGMI_DATA_OUT_3, self.PASS),
|
|
('XGMI_DATA_OUT_4', amdsmi.AmdSmiEventType.XGMI_DATA_OUT_4, self.PASS),
|
|
('XGMI_DATA_OUT_5', amdsmi.AmdSmiEventType.XGMI_DATA_OUT_5, self.PASS)
|
|
]
|
|
|
|
self.counter_commands = \
|
|
[
|
|
('CMD_START', amdsmi.AmdSmiCounterCommand.CMD_START, self.PASS),
|
|
('CMD_STOP', amdsmi.AmdSmiCounterCommand.CMD_STOP, self.PASS)
|
|
]
|
|
|
|
self.compute_partition_types = \
|
|
[
|
|
('SPX', amdsmi.AmdSmiComputePartitionType.SPX, self.PASS),
|
|
('DPX', amdsmi.AmdSmiComputePartitionType.DPX, self.PASS),
|
|
('TPX', amdsmi.AmdSmiComputePartitionType.TPX, self.PASS),
|
|
('QPX', amdsmi.AmdSmiComputePartitionType.QPX, self.PASS),
|
|
('CPX', amdsmi.AmdSmiComputePartitionType.CPX, self.PASS),
|
|
('INVALID', amdsmi.AmdSmiComputePartitionType.INVALID, self.FAIL)
|
|
]
|
|
|
|
self.memory_partition_types = \
|
|
[
|
|
('NPS1', amdsmi.AmdSmiMemoryPartitionType.NPS1, self.PASS),
|
|
('NPS2', amdsmi.AmdSmiMemoryPartitionType.NPS2, self.PASS),
|
|
('NPS4', amdsmi.AmdSmiMemoryPartitionType.NPS4, self.PASS),
|
|
('NPS8', amdsmi.AmdSmiMemoryPartitionType.NPS8, self.PASS),
|
|
('UNKNOWN', amdsmi.AmdSmiMemoryPartitionType.UNKNOWN, self.FAIL)
|
|
]
|
|
|
|
self.freq_inds = \
|
|
[
|
|
('MIN', amdsmi.AmdSmiFreqInd.MIN, self.PASS),
|
|
('MAX', amdsmi.AmdSmiFreqInd.MAX, self.PASS),
|
|
('INVALID', amdsmi.AmdSmiFreqInd.INVALID, self.FAIL)
|
|
]
|
|
|
|
self.power_profile_preset_masks = \
|
|
[
|
|
('CUSTOM_MASK', amdsmi.AmdSmiPowerProfilePresetMasks.CUSTOM_MASK, self.PASS),
|
|
('VIDEO_MASK', amdsmi.AmdSmiPowerProfilePresetMasks.VIDEO_MASK, self.PASS),
|
|
('POWER_SAVING_MASK', amdsmi.AmdSmiPowerProfilePresetMasks.POWER_SAVING_MASK, self.PASS),
|
|
('COMPUTE_MASK', amdsmi.AmdSmiPowerProfilePresetMasks.COMPUTE_MASK, self.PASS),
|
|
('VR_MASK', amdsmi.AmdSmiPowerProfilePresetMasks.VR_MASK, self.PASS),
|
|
('THREE_D_FULL_SCR_MASK', amdsmi.AmdSmiPowerProfilePresetMasks.THREE_D_FULL_SCR_MASK, self.PASS),
|
|
('BOOTUP_DEFAULT', amdsmi.AmdSmiPowerProfilePresetMasks.BOOTUP_DEFAULT, self.PASS)
|
|
]
|
|
|
|
self.processor_types = \
|
|
[
|
|
('UNKNOWN', amdsmi.AmdSmiProcessorType.UNKNOWN, self.FAIL),
|
|
('AMD_GPU', amdsmi.AmdSmiProcessorType.AMD_GPU, self.PASS),
|
|
('AMD_CPU', amdsmi.AmdSmiProcessorType.AMD_CPU, self.PASS),
|
|
('NON_AMD_GPU', amdsmi.AmdSmiProcessorType.NON_AMD_GPU, self.PASS),
|
|
('NON_AMD_CPU', amdsmi.AmdSmiProcessorType.NON_AMD_CPU, self.PASS),
|
|
('AMD_CPU_CORE', amdsmi.AmdSmiProcessorType.AMD_CPU_CORE, self.PASS),
|
|
('AMD_APU', amdsmi.AmdSmiProcessorType.AMD_APU, self.PASS)
|
|
]
|
|
|
|
self.dev_perf_levels = \
|
|
[
|
|
('AUTO', amdsmi.AmdSmiDevPerfLevel.AUTO, self.PASS),
|
|
('LOW', amdsmi.AmdSmiDevPerfLevel.LOW, self.PASS),
|
|
('HIGH', amdsmi.AmdSmiDevPerfLevel.HIGH, self.PASS),
|
|
('MANUAL', amdsmi.AmdSmiDevPerfLevel.MANUAL, self.PASS),
|
|
('STABLE_STD', amdsmi.AmdSmiDevPerfLevel.STABLE_STD, self.PASS),
|
|
('STABLE_PEAK', amdsmi.AmdSmiDevPerfLevel.STABLE_PEAK, self.PASS),
|
|
('STABLE_MIN_MCLK', amdsmi.AmdSmiDevPerfLevel.STABLE_MIN_MCLK, self.PASS),
|
|
('STABLE_MIN_SCLK', amdsmi.AmdSmiDevPerfLevel.STABLE_MIN_SCLK, self.PASS),
|
|
('DETERMINISM', amdsmi.AmdSmiDevPerfLevel.DETERMINISM, self.PASS),
|
|
('UNKNOWN', amdsmi.AmdSmiDevPerfLevel.UNKNOWN, self.FAIL)
|
|
]
|
|
|
|
def print(self, msg, data=None):
|
|
if self.verbose == 2:
|
|
if data is None:
|
|
print(msg, flush=True)
|
|
elif any(data in value for value in self.not_supported_error_codes):
|
|
print(f'{msg} {data}', flush=True)
|
|
else:
|
|
if isinstance(data, str) and data in self.error_map.values():
|
|
print(msg, end='')
|
|
else:
|
|
print(msg)
|
|
if isinstance(data, dict) or isinstance(data, list):
|
|
print(json.dumps(data, sort_keys=False, indent=4), flush=True)
|
|
else:
|
|
print(data)
|
|
return
|
|
|
|
def print_func_name(self, msg=None):
|
|
if self.verbose == 2:
|
|
stk = inspect.stack()
|
|
if stk[1].function == '_callSetUp':
|
|
return
|
|
print(f'\n## {stk[1].function}()', flush=True)
|
|
if msg:
|
|
print(msg, flush=True)
|
|
return
|
|
|
|
def print_device_header(self, i, gpu):
|
|
# Print virtualization mode info
|
|
msg = f'virtualization mode(gpu={i})'
|
|
self.print(f'\t{msg}')
|
|
mode = self.virt_mode[i]['mode']
|
|
self.print(f'\t\tmode : {mode}')
|
|
# Print asic info
|
|
msg = f'asic info(gpu={i})'
|
|
self.print(f'\t{msg}')
|
|
for key, value in self.asic_info[i].items():
|
|
self.print(f'\t\t{key} : {value}')
|
|
# Print board info
|
|
msg = f'board info(gpu={i})'
|
|
self.print(f'\t{msg}')
|
|
for key, value in self.board_info[i].items():
|
|
self.print(f'\t\t{key} : {value}')
|
|
return
|
|
|
|
def get_error_code(self, exc):
|
|
error_code = '-1'
|
|
error_code_name = 'UNKNOWN_ERROR'
|
|
if hasattr(exc, 'get_error_code'):
|
|
error_code = str(exc.get_error_code())
|
|
if error_code in self.error_map:
|
|
error_code_name = self.error_map[error_code]
|
|
return (error_code, error_code_name)
|
|
|
|
def check_ret(self, msg, exc, expected_code_name=None, printIt=True):
|
|
if isinstance(exc, str) and not len(exc):
|
|
error_code_name = expected_code_name
|
|
if error_code_name in self.error_map.values():
|
|
for key, value in self.error_map.items():
|
|
if value == error_code_name:
|
|
error_code = key
|
|
break
|
|
else:
|
|
error_code = '-1'
|
|
elif hasattr(exc, 'get_error_code'):
|
|
error_code, error_code_name = self.get_error_code(exc)
|
|
else:
|
|
error_code = str(exc).split(':')[0]
|
|
error_code_name = 'AMDSMI_STATUS_INVAL'
|
|
|
|
# Check for when there are multiple passing conditions
|
|
if isinstance(expected_code_name, list):
|
|
for ec in expected_code_name:
|
|
rc = self.check_ret(msg, exc, ec, False) # Do not print msg, otherwise multiple msgs printed
|
|
if not rc:
|
|
rc = self.check_ret(msg, exc, ec) # Call check again so msg is printed
|
|
return rc
|
|
|
|
# No expected results found
|
|
if msg:
|
|
print(f'{msg}\n', end='')
|
|
print(f'Test FAILED with expected results {expected_code_name} but received {error_code_name}', flush=True)
|
|
return True
|
|
|
|
# Check for single passing condition
|
|
status_msg = ''
|
|
status_ret = False
|
|
if any(error_code in value for value in self.not_supported_error_codes):
|
|
status_msg = f'\tAPI RETURNED {error_code_name}'
|
|
elif error_code_name == expected_code_name:
|
|
status_msg = f'\tTest PASSED with expected result {expected_code_name}'
|
|
elif error_code_name != self.PASS and expected_code_name == self.ANY_FAIL:
|
|
status_msg = f'\tTest PASSED with expected result {expected_code_name} and received {error_code_name}'
|
|
else:
|
|
status_msg = f'\tTest FAILED with expected result {expected_code_name} but received {error_code_name}'
|
|
status_ret = True
|
|
if self.verbose == 2 and printIt:
|
|
if msg:
|
|
print(f'{msg}\n', end='')
|
|
print(f'{status_msg}', flush=True)
|
|
return status_ret
|
|
|