87b9faf926
Generating .whl has proved to be difficult with AMD CI. Switch to directly installing python projects instead. Change-Id: I8a4c2fe22fc872865bba7da3a3386513efd5269a Signed-off-by: Galantsev, Dmitrii <dmitrii.galantsev@amd.com>
1207 lines
53 KiB
Python
1207 lines
53 KiB
Python
#!/usr/bin/env python3
|
|
#
|
|
# Copyright (C) 2023 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.
|
|
#
|
|
|
|
"""AMDSMICommands
|
|
|
|
This class contains all the commands corresponding to AMDSMIParser
|
|
Each command function will interact with AMDSMILogger to handle
|
|
displaying the output to the specified compatibility, format, and
|
|
destination.
|
|
|
|
"""
|
|
|
|
from _version import __version__
|
|
|
|
from amdsmi_helpers import AMDSMIHelpers
|
|
from amdsmi_logger import AMDSMILogger
|
|
from amdsmi import amdsmi_interface
|
|
|
|
|
|
class AMDSMICommands():
|
|
def __init__(self, compatibility='amdsmi',
|
|
format='human_readable',
|
|
destination='stdout') -> None:
|
|
self.helpers = AMDSMIHelpers()
|
|
self.logger = AMDSMILogger(compatibility=compatibility,
|
|
format=format,
|
|
destination=destination)
|
|
self.device_handles = amdsmi_interface.amdsmi_get_device_handles()
|
|
|
|
|
|
def version(self, args):
|
|
"""Print Version String
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
"""
|
|
kernel_component = amdsmi_interface.AmdSmiSwComponent.DRIVER
|
|
kernel_version = amdsmi_interface.amdsmi_get_version_str(sw_component=kernel_component)
|
|
amdsmi_lib_version = amdsmi_interface.amdsmi_get_version()
|
|
major = amdsmi_lib_version["major"]
|
|
minor = amdsmi_lib_version["minor"]
|
|
patch = amdsmi_lib_version["patch"]
|
|
amdsmi_lib_version_str = f'{major}.{minor}.{patch}'
|
|
|
|
self.logger.output['tool'] = 'AMDSMI Tool'
|
|
self.logger.output['version'] = f'{__version__}'
|
|
self.logger.output['amdsmi_library_version'] = f'{amdsmi_lib_version_str}'
|
|
self.logger.output['kernel_version'] = f'{kernel_version}'
|
|
|
|
if self.logger.is_human_readable_format():
|
|
print(f'AMDSMI Tool: {__version__} | '\
|
|
f'AMDSMI Library version: {amdsmi_lib_version_str} | '\
|
|
f'Kernel version: {kernel_version}')
|
|
elif self.logger.is_json_format() or self.logger.is_csv_format():
|
|
self.logger.print_output()
|
|
|
|
|
|
def discovery(self, args, multiple_devices=False, gpu=None):
|
|
"""Get Discovery information for target gpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu:
|
|
args.gpu = gpu
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.discovery(args, multiple_devices=True, gpu=device_handle)
|
|
self.logger.print_output(multiple_device_output=True)
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
bdf = amdsmi_interface.amdsmi_get_device_bdf(args.gpu)
|
|
uuid = amdsmi_interface.amdsmi_get_device_uuid(args.gpu)
|
|
|
|
# Store values based on format
|
|
if self.logger.is_human_readable_format():
|
|
self.logger.store_output(args.gpu, 'AMDSMI_SPACING_REMOVAL', {'bdf':bdf, 'uuid':uuid})
|
|
else:
|
|
self.logger.store_output(args.gpu, 'bdf', bdf)
|
|
self.logger.store_output(args.gpu, 'uuid', uuid)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
# compatibility with gpuvsmi needs a list for single gpu
|
|
if self.logger.is_gpuvsmi_compatibility() and not multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
self.logger.print_output(multiple_device_output=True)
|
|
else:
|
|
self.logger.print_output()
|
|
|
|
|
|
def static(self, args, multiple_devices=False, gpu=None, asic=None,
|
|
bus=None, vbios=None, limit=None, driver=None, caps=None,
|
|
ras=None, board=None):
|
|
"""Get Static information for target gpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
asic (bool, optional): Value override for args.asic. Defaults to None.
|
|
bus (bool, optional): Value override for args.bus. Defaults to None.
|
|
vbios (bool, optional): Value override for args.vbios. Defaults to None.
|
|
limit (bool, optional): Value override for args.limit. Defaults to None.
|
|
driver (bool, optional): Value override for args.driver. Defaults to None.
|
|
caps (bool, optional): Value override for args.caps. Defaults to None.
|
|
ras (bool, optional): Value override for args.ras. Defaults to None.
|
|
board (bool, optional): Value override for args.board. Defaults to None.
|
|
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if asic:
|
|
args.asic = asic
|
|
if bus:
|
|
args.bus = bus
|
|
if vbios:
|
|
args.vbios = vbios
|
|
if limit:
|
|
args.limit = limit
|
|
if driver:
|
|
args.driver = driver
|
|
if caps:
|
|
args.caps = caps
|
|
if ras:
|
|
args.ras = ras
|
|
if board:
|
|
args.board = board
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.static(args, multiple_devices=True, gpu=device_handle)
|
|
self.logger.print_output(multiple_device_output=True)
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
# If all arguments are False, it means that no argument was passed and the entire static should be printed
|
|
if not any([args.asic, args.bus, args.vbios, args.limit, args.driver, args.caps, args.ras, args.board]):
|
|
args.asic = args.bus = args.vbios = args.limit = args.driver = args.caps = args.ras = args.board = True
|
|
|
|
values_dict = {}
|
|
|
|
if args.asic:
|
|
asic_info = amdsmi_interface.amdsmi_get_asic_info(args.gpu)
|
|
asic_info['family'] = hex(asic_info['family'])
|
|
asic_info['vendor_id'] = hex(asic_info['vendor_id'])
|
|
asic_info['device_id'] = hex(asic_info['device_id'])
|
|
asic_info['rev_id'] = hex(asic_info['rev_id'])
|
|
if asic_info['asic_serial'] != '':
|
|
asic_info['asic_serial'] = '0x' + asic_info['asic_serial']
|
|
|
|
values_dict['asic'] = asic_info
|
|
if args.bus:
|
|
bus_info = amdsmi_interface.amdsmi_get_pcie_link_caps(args.gpu)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit ='MT/s'
|
|
bus_info['pcie_speed'] = f"{bus_info['pcie_speed']} {unit}"
|
|
|
|
bus_output_info = {}
|
|
bus_output_info['bdf'] = amdsmi_interface.amdsmi_get_device_bdf(args.gpu)
|
|
bus_output_info.update(bus_info)
|
|
|
|
values_dict['bus'] = bus_output_info
|
|
if args.vbios:
|
|
vbios_info = amdsmi_interface.amdsmi_get_vbios_info(args.gpu)
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
vbios_info['version'] = vbios_info.pop('vbios_version_string')
|
|
vbios_info['build_date'] = vbios_info.pop('build_date')
|
|
vbios_info['part_number'] = vbios_info.pop('part_number')
|
|
vbios_info['vbios_version'] = vbios_info.pop('vbios_version')
|
|
|
|
values_dict['vbios'] = vbios_info
|
|
if args.board:
|
|
board_info = amdsmi_interface.amdsmi_get_board_info(args.gpu)
|
|
board_info['serial_number'] = hex(board_info['serial_number'])
|
|
board_info['product_serial'] = '0x' + board_info['product_serial']
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
board_info['product_number'] = board_info.pop('product_serial')
|
|
board_info['product_name'] = board_info.pop('product_name')
|
|
|
|
values_dict['board'] = board_info
|
|
if args.limit:
|
|
power_limit = amdsmi_interface.amdsmi_get_power_measure(args.gpu)['power_limit']
|
|
temp_edge_limit = amdsmi_interface.amdsmi_dev_get_temp_metric(args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
|
temp_junction_limit = amdsmi_interface.amdsmi_dev_get_temp_metric(args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.JUNCTION, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
|
temp_vram_limit = amdsmi_interface.amdsmi_dev_get_temp_metric(args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.VRAM, amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'W'
|
|
power_limit = f"{power_limit} {unit}"
|
|
|
|
unit = 'C'
|
|
temp_edge_limit = f"{temp_edge_limit} {unit}"
|
|
temp_junction_limit = f"{temp_junction_limit} {unit}"
|
|
temp_vram_limit = f"{temp_vram_limit} {unit}"
|
|
|
|
limit_info = {}
|
|
limit_info['power'] = power_limit
|
|
limit_info['temperature_edge'] = temp_edge_limit
|
|
limit_info['temperature_junction'] = temp_junction_limit
|
|
limit_info['temperature_vram'] = temp_vram_limit
|
|
|
|
values_dict['limit'] = limit_info
|
|
if args.driver:
|
|
driver_info = {}
|
|
driver_info['driver_version'] = amdsmi_interface.amdsmi_get_driver_version(args.gpu)
|
|
|
|
values_dict['driver'] = driver_info
|
|
if args.ras:
|
|
try:
|
|
ras_info = amdsmi_interface.amdsmi_get_ras_block_features_enabled(args.gpu)
|
|
values_dict['ras'] = ras_info
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
values_dict['ras'] = err.get_error_info()
|
|
if args.caps:
|
|
caps_info = amdsmi_interface.amdsmi_get_caps_info(args.gpu)
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
del caps_info['ras_supported']
|
|
caps_info['gfx'] = caps_info.pop('gfx')
|
|
|
|
if self.logger.is_human_readable_format():
|
|
for capability_name, capability_value in caps_info.items():
|
|
if isinstance(capability_value, list):
|
|
caps_info[capability_name] = f"{capability_value}"
|
|
|
|
values_dict['caps'] = caps_info
|
|
|
|
# Store values in logger.output
|
|
self.logger.store_output(args.gpu, 'values', values_dict)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
self.logger.print_output()
|
|
|
|
|
|
def firmware(self, args, multiple_devices=False, gpu=None, fw_list=True):
|
|
""" Get Firmware information for target gpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
fw_list (bool, optional): True to get list of all firmware information
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if fw_list: # Currently a compatiblity option of gpuv-smi
|
|
args.fw_list = fw_list
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.firmware(args, multiple_devices=True, gpu=device_handle)
|
|
self.logger.print_output(multiple_device_output=True)
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
values_dict = {}
|
|
|
|
if args.fw_list:
|
|
fw_info = amdsmi_interface.amdsmi_get_fw_info(args.gpu)
|
|
|
|
for fw_index, fw_entry in enumerate(fw_info['fw_list']):
|
|
# Change fw_name to fw_id
|
|
fw_entry['fw_id'] = fw_entry.pop('fw_name').name.strip('FW_ID_')
|
|
fw_entry['fw_version'] = fw_entry.pop('fw_version')
|
|
firmware_identifier = 'FW'
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
firmware_identifier = 'UCODE'
|
|
fw_entry['name'] = fw_entry.pop('fw_id')
|
|
fw_entry['version'] = fw_entry.pop('fw_version')
|
|
|
|
# Add custom human readable formatting
|
|
if self.logger.is_human_readable_format():
|
|
fw_info['fw_list'][fw_index] = {f'{firmware_identifier} {fw_index}': fw_entry}
|
|
else:
|
|
fw_info['fw_list'][fw_index] = fw_entry
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
fw_info['ucode_list'] = fw_info.pop('fw_list')
|
|
|
|
values_dict.update(fw_info)
|
|
|
|
# Store values in logger.output
|
|
self.logger.store_output(args.gpu, 'values', values_dict)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
self.logger.print_output()
|
|
|
|
|
|
def bad_pages(self, args, multiple_devices=False, gpu=None, retired=None, pending=None, un_res=None):
|
|
""" Get bad pages information for target gpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
retired (bool, optional) - Value override for args.retired
|
|
pending (bool, optional) - Value override for args.pending
|
|
un_res (bool, optional) - Value override for args.un_res
|
|
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if retired:
|
|
args.retired = retired
|
|
if pending:
|
|
args.pending = pending
|
|
if un_res:
|
|
args.un_res = un_res
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.bad_pages(args, multiple_devices=True, gpu=device_handle)
|
|
self.logger.print_output(multiple_device_output=True)
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
# If all arguments are False, the print all bad_page information
|
|
if not any([args.retired, args.pending, args.un_res]):
|
|
args.retired = args.pending = args.un_res = True
|
|
|
|
values_dict = {}
|
|
bad_page_err_output = ''
|
|
|
|
try:
|
|
bad_page_info = amdsmi_interface.amdsmi_get_bad_page_info(args.gpu)
|
|
bad_page_error = False
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
bad_page_err_output = err.get_error_info()
|
|
bad_page_error = True
|
|
|
|
if isinstance(bad_page_info, str):
|
|
pass
|
|
else:
|
|
if args.retired:
|
|
if bad_page_error:
|
|
bad_page_info_output = bad_page_err_output
|
|
else:
|
|
bad_page_info_output = []
|
|
for bad_page in bad_page_info:
|
|
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.RESERVED:
|
|
bad_page_info_entry = {}
|
|
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
|
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
|
bad_page_info_entry["status"] = bad_page["status"].name
|
|
|
|
bad_page_info_output.append(bad_page_info_entry)
|
|
# Remove brackets if there is only one value
|
|
if len(bad_page_info_output) == 1:
|
|
bad_page_info_output = bad_page_info_output[0]
|
|
|
|
values_dict['retired'] = bad_page_info_output
|
|
|
|
if args.pending:
|
|
if bad_page_error:
|
|
bad_page_info_output = bad_page_err_output
|
|
else:
|
|
bad_page_info_output = []
|
|
for bad_page in bad_page_info:
|
|
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.PENDING:
|
|
bad_page_info_entry = {}
|
|
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
|
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
|
bad_page_info_entry["status"] = bad_page["status"].name
|
|
|
|
bad_page_info_output.append(bad_page_info_entry)
|
|
# Remove brackets if there is only one value
|
|
if len(bad_page_info_output) == 1:
|
|
bad_page_info_output = bad_page_info_output[0]
|
|
|
|
values_dict['pending'] = bad_page_info_output
|
|
|
|
if args.un_res:
|
|
if bad_page_error:
|
|
bad_page_info_output = bad_page_err_output
|
|
else:
|
|
bad_page_info_output = []
|
|
for bad_page in bad_page_info:
|
|
if bad_page["status"] == amdsmi_interface.AmdSmiMemoryPageStatus.UNRESERVABLE:
|
|
bad_page_info_entry = {}
|
|
bad_page_info_entry["page_address"] = bad_page["page_address"]
|
|
bad_page_info_entry["page_size"] = bad_page["page_size"]
|
|
bad_page_info_entry["status"] = bad_page["status"].name
|
|
|
|
bad_page_info_output.append(bad_page_info_entry)
|
|
# Remove brackets if there is only one value
|
|
if len(bad_page_info_output) == 1:
|
|
bad_page_info_output = bad_page_info_output[0]
|
|
|
|
values_dict['un_res'] = bad_page_info_output
|
|
|
|
# Store values in logger.output
|
|
self.logger.store_output(args.gpu, 'values', values_dict)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
self.logger.print_output()
|
|
|
|
|
|
def metric(self, args, multiple_devices=False, watching_output=False, gpu=None,
|
|
usage=None, watch=None, watch_time=None, iterations=None, fb_usage=None, power=None,
|
|
clock=None, temperature=None, ecc=None, pcie=None, voltage=None, fan=None,
|
|
pcie_usage=None, voltage_curve=None, overdrive=None, mem_overdrive=None,
|
|
perf_level=None, replay_count=None, xgmi_err=None, energy=None, mem_usage=None):
|
|
"""Get Metric information for target gpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
watching_output (bool, optional): True if watch option has been set. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
usage (bool, optional): Value override for args.usage. Defaults to None.
|
|
watch (Positive int, optional): Value override for args.watch. Defaults to None.
|
|
watch_time (Positive int, optional): Value override for args.watch_time. Defaults to None.
|
|
iterations (Positive int, optional): Value override for args.iterations. Defaults to None.
|
|
fb_usage (bool, optional): Value override for args.fb_usage. Defaults to None.
|
|
power (bool, optional): Value override for args.power. Defaults to None.
|
|
clock (bool, optional): Value override for args.clock. Defaults to None.
|
|
temperature (bool, optional): Value override for args.temperature. Defaults to None.
|
|
ecc (bool, optional): Value override for args.ecc. Defaults to None.
|
|
pcie (bool, optional): Value override for args.pcie. Defaults to None.
|
|
voltage (bool, optional): Value override for args.voltage. Defaults to None.
|
|
fan (bool, optional): Value override for args.fan. Defaults to None.
|
|
pcie_usage (bool, optional): Value override for args.pcie_usage. Defaults to None.
|
|
voltage_curve (bool, optional): Value override for args.voltage_curve. Defaults to None.
|
|
overdrive (bool, optional): Value override for args.overdrive. Defaults to None.
|
|
mem_overdrive (bool, optional): Value override for args.mem_overdrive. Defaults to None.
|
|
perf_level (bool, optional): Value override for args.perf_level. Defaults to None.
|
|
replay_count (bool, optional): Value override for args.replay_count. Defaults to None.
|
|
xgmi_err (bool, optional): Value override for args.xgmi_err. Defaults to None.
|
|
energy (bool, optional): Value override for args.energy. Defaults to None.
|
|
mem_usage (bool, optional): Value override for args.mem_usage. Defaults to None.
|
|
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if usage:
|
|
args.usage = usage
|
|
if watch:
|
|
args.watch = watch
|
|
if watch_time:
|
|
args.watch_time = watch_time
|
|
if iterations:
|
|
args.iterations = iterations
|
|
if fb_usage:
|
|
args.fb_usage = fb_usage
|
|
if power:
|
|
args.power = power
|
|
if clock:
|
|
args.clock = clock
|
|
if temperature:
|
|
args.temperature = temperature
|
|
if ecc:
|
|
args.ecc = ecc
|
|
if pcie:
|
|
args.pcie = pcie
|
|
if voltage:
|
|
args.voltage = voltage
|
|
if fan:
|
|
args.fan = fan
|
|
if pcie_usage:
|
|
args.pcie_usage = pcie_usage
|
|
if voltage_curve:
|
|
args.voltage_curve = voltage_curve
|
|
if overdrive:
|
|
args.overdrive = overdrive
|
|
if mem_overdrive:
|
|
args.mem_overdrive = mem_overdrive
|
|
if perf_level:
|
|
args.perf_level = perf_level
|
|
if replay_count:
|
|
args.replay_count = replay_count
|
|
if xgmi_err:
|
|
args.xgmi_err = xgmi_err
|
|
if energy:
|
|
args.energy = energy
|
|
if mem_usage:
|
|
args.mem_usage = mem_usage
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle watch logic, will only enter this block once
|
|
if args.watch:
|
|
args = self.helpers.handle_watch(args=args, subcommand=self.metric)
|
|
self.logger.print_output(watch_output=True) # Print at the end of watch ( final flush )
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.metric(args, multiple_devices=True, watching_output=False, gpu=device_handle)
|
|
|
|
self.logger.print_output(multiple_device_output=True)
|
|
# End of multiple gpus add to watch_output
|
|
if watching_output:
|
|
self.logger.store_watch_output(multiple_devices=True)
|
|
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
# Check if any of the options have been set, if not then set them all to true
|
|
if not any([args.usage, args.fb_usage, args.power, args.clock, args.temperature, args.ecc, args.pcie, args.voltage, args.fan,
|
|
args.pcie_usage, args.voltage_curve, args.overdrive, args.mem_overdrive, args.perf_level,
|
|
args.replay_count, args.xgmi_err, args.energy, mem_usage]):
|
|
args.usage = args.fb_usage = args.power = args.clock = args.temperature = args.ecc = args.pcie = args.voltage = args.fan = \
|
|
args.pcie_usage = args.voltage_curve = args.overdrive = args.mem_overdrive = args.perf_level = \
|
|
args.replay_count = args.xgmi_err = args.energy = mem_usage = True
|
|
|
|
# Add timestamp and store values for specified arguments
|
|
values_dict = {}
|
|
if args.usage:
|
|
engine_usage = amdsmi_interface.amdsmi_get_gpu_activity(args.gpu)
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
engine_usage['gfx_usage'] = engine_usage.pop('gfx_activity')
|
|
engine_usage['mem_usage'] = engine_usage.pop('umc_activity')
|
|
engine_usage['mm_usage_list'] = engine_usage.pop('mm_activity')
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = '%'
|
|
for usage_name, usage_value in engine_usage.items():
|
|
engine_usage[usage_name] = f"{usage_value} {unit}"
|
|
|
|
values_dict['usage'] = engine_usage
|
|
if args.fb_usage:
|
|
vram_usage = amdsmi_interface.amdsmi_get_vram_usage(args.gpu)
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
vram_usage['fb_total'] = vram_usage.pop('vram_total')
|
|
vram_usage['fb_used'] = vram_usage.pop('vram_used')
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'MB'
|
|
for vram_name, vram_value in vram_usage.items():
|
|
vram_usage[vram_name] = f"{vram_value} {unit}"
|
|
|
|
values_dict['fb_usage'] = vram_usage
|
|
if args.power:
|
|
average_socket_power = amdsmi_interface.amdsmi_get_power_measure(args.gpu)['average_socket_power']
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
pass
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'W'
|
|
average_socket_power = f"{average_socket_power} {unit}"
|
|
|
|
values_dict['power'] = average_socket_power
|
|
if args.clock:
|
|
clock_gfx = amdsmi_interface.amdsmi_get_clock_measure(args.gpu, amdsmi_interface.AmdSmiClkType.GFX)
|
|
clock_mem = amdsmi_interface.amdsmi_get_clock_measure(args.gpu, amdsmi_interface.AmdSmiClkType.MEM)
|
|
|
|
clocks = {'gfx': clock_gfx,
|
|
'mem': clock_mem}
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'MHz'
|
|
for clock_target, clock_metric_values in clocks.items():
|
|
for clock_type, clock_value in clock_metric_values.items():
|
|
clocks[clock_target][clock_type] = f"{clock_value} {unit}"
|
|
|
|
values_dict['clock'] = clocks
|
|
if args.temperature:
|
|
temperature_edge_current = amdsmi_interface.amdsmi_dev_get_temp_metric(
|
|
args.gpu, amdsmi_interface.AmdSmiTemperatureType.EDGE, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
|
temperature_junction_current = amdsmi_interface.amdsmi_dev_get_temp_metric(
|
|
args.gpu, amdsmi_interface.AmdSmiTemperatureType.JUNCTION, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
|
temperature_vram_current = amdsmi_interface.amdsmi_dev_get_temp_metric(
|
|
args.gpu, amdsmi_interface.AmdSmiTemperatureType.VRAM, amdsmi_interface.AmdSmiTemperatureMetric.CURRENT)
|
|
|
|
temperatures = { 'edge': temperature_edge_current,
|
|
'hotspot': temperature_junction_current,
|
|
'mem': temperature_vram_current}
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
temperatures = { 'edge_temperature': temperature_edge_current,
|
|
'hotspot_temperature': temperature_junction_current,
|
|
'mem_temperature': temperature_vram_current}
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = '\N{DEGREE SIGN}C'
|
|
for temperature_value in temperatures:
|
|
temperatures[temperature_value] = f"{temperatures[temperature_value]} {unit}"
|
|
|
|
values_dict['temperature'] = temperatures
|
|
if args.ecc:
|
|
try:
|
|
values_dict['ecc'] = amdsmi_interface.amdsmi_get_ecc_error_count(args.gpu)
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
values_dict['ecc'] = err.get_error_info()
|
|
|
|
if args.pcie:
|
|
pcie_link_status = amdsmi_interface.amdsmi_get_pcie_link_caps(args.gpu)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit ='MT/s'
|
|
pcie_link_status['pcie_speed'] = f"{pcie_link_status['pcie_speed']} {unit}"
|
|
|
|
if self.logger.is_gpuvsmi_compatibility():
|
|
pcie_link_status['current_width'] = pcie_link_status.pop('pcie_lanes')
|
|
pcie_link_status['current_speed'] = pcie_link_status.pop('pcie_speed')
|
|
|
|
values_dict['pcie'] = pcie_link_status
|
|
if args.voltage:
|
|
volt_metric = amdsmi_interface.amdsmi_dev_get_volt_metric(
|
|
args.gpu, amdsmi_interface.AmdSmiVoltageType.VDDGFX, amdsmi_interface.AmdSmiVoltageMetric.CURRENT)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'mV'
|
|
volt_metric = f"{volt_metric} {unit}"
|
|
|
|
values_dict['voltage'] = volt_metric
|
|
if args.fan:
|
|
fan_speed = amdsmi_interface.amdsmi_dev_get_fan_speed(args.gpu, 0)
|
|
fan_max = amdsmi_interface.amdsmi_dev_get_fan_speed_max(args.gpu, 0)
|
|
fan_rpm = amdsmi_interface.amdsmi_dev_get_fan_rpms(args.gpu, 0)
|
|
|
|
if fan_max <= 0:
|
|
fan_percent = 'Unable to detect fan speed'
|
|
else:
|
|
fan_percent = round((float(fan_speed) / float(fan_max)) * 100, 2)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = '%'
|
|
fan_percent = f"{fan_percent} {unit}"
|
|
|
|
values_dict['fan'] = {'speed': fan_speed,
|
|
'max' : fan_max,
|
|
'rpm' : fan_rpm,
|
|
'usage' : fan_percent}
|
|
if args.pcie_usage:
|
|
try:
|
|
pcie_link_status = amdsmi_interface.amdsmi_get_pcie_link_status(args.gpu)
|
|
pcie_link_status_call = True
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
pcie_link_status = err.get_error_info()
|
|
pcie_link_status_call = False
|
|
|
|
if self.logger.is_human_readable_format() and pcie_link_status_call:
|
|
unit ='MT/s'
|
|
pcie_link_status['pcie_speed'] = f"{pcie_link_status['pcie_speed']} {unit}"
|
|
|
|
values_dict['pcie_usage'] = pcie_link_status
|
|
if args.voltage_curve:
|
|
try:
|
|
od_volt = amdsmi_interface.amdsmi_dev_get_od_volt_info(args.gpu)
|
|
voltage_curve_error = False
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
values_dict["voltage_curve"] = err.get_error_info()
|
|
voltage_curve_error = True
|
|
|
|
if not voltage_curve_error:
|
|
voltage_point_dict = {}
|
|
|
|
for point in range(3):
|
|
frequency = int(od_volt["curve.vc_points"][point].frequency / 1000000)
|
|
voltage = int(od_volt["curve.vc_points"][point].voltage)
|
|
voltage_point_dict[f'voltage_point_{point}'] = f"{frequency}Mhz {voltage}mV"
|
|
|
|
values_dict['voltage_curve'] = voltage_point_dict
|
|
if args.overdrive:
|
|
overdrive_level = amdsmi_interface.amdsmi_dev_get_overdrive_level(args.gpu)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = '%'
|
|
overdrive_level = f"{overdrive_level} {unit}"
|
|
|
|
values_dict['overdrive'] = overdrive_level
|
|
if args.mem_overdrive:
|
|
values_dict['mem_overdrive'] = amdsmi_interface.AmdSmiRetCode.NOT_IMPLEMENTED
|
|
if args.perf_level:
|
|
perf_level = amdsmi_interface.amdsmi_dev_get_perf_level(args.gpu)
|
|
values_dict['perf_level'] = perf_level
|
|
if args.replay_count:
|
|
pci_replay_counter = amdsmi_interface.amdsmi_dev_get_pci_replay_counter(args.gpu)
|
|
values_dict['replay_count'] = pci_replay_counter
|
|
if args.xgmi_err:
|
|
try:
|
|
values_dict['xgmi_err'] = amdsmi_interface.amdsmi_dev_xgmi_error_status(args.gpu)
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
values_dict['xgmi_err'] = err.get_error_info()
|
|
if args.energy:
|
|
energy = amdsmi_interface.amdsmi_get_power_measure(args.gpu)['energy_accumulator']
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'J'
|
|
energy = f"{energy} {unit}"
|
|
|
|
values_dict['energy'] = energy
|
|
if args.mem_usage:
|
|
memory_total_vram = amdsmi_interface.amdsmi_dev_get_memory_total(args.gpu, amdsmi_interface.AmdSmiMemoryType.VRAM)
|
|
memory_total_vis_vram = amdsmi_interface.amdsmi_dev_get_memory_total(args.gpu, amdsmi_interface.AmdSmiMemoryType.VIS_VRAM)
|
|
memory_total_gtt = amdsmi_interface.amdsmi_dev_get_memory_total(args.gpu, amdsmi_interface.AmdSmiMemoryType.GTT)
|
|
|
|
memory_total = {}
|
|
# Convert mem_usage to megabytes
|
|
memory_total['vram'] = memory_total_vram // (1024*1024)
|
|
memory_total['vis_vram'] = memory_total_vis_vram // (1024*1024)
|
|
memory_total['gtt'] = memory_total_gtt // (1024*1024)
|
|
|
|
if self.logger.is_human_readable_format():
|
|
unit = 'MB'
|
|
energy = f"{energy} {unit}"
|
|
memory_total['vram'] = f"{memory_total['vram']} {unit}"
|
|
memory_total['vis_vram'] = f"{memory_total['vis_vram']} {unit}"
|
|
memory_total['gtt'] = f"{memory_total['gtt']} {unit}"
|
|
|
|
|
|
values_dict['mem_usage'] = memory_total
|
|
|
|
# Store values in logger.output
|
|
self.logger.store_output(args.gpu, 'values', values_dict)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
self.logger.print_output()
|
|
|
|
if watching_output: # End of single gpu add to watch_output
|
|
self.logger.store_watch_output(multiple_devices=False)
|
|
|
|
|
|
def process(self, args, multiple_devices=False, watching_output=False,
|
|
gpu=None, general=None, engine=None, pid=None, name=None,
|
|
watch=None, watch_time=None, iterations=None):
|
|
"""Get Process Information from the target GPU
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
watching_output (bool, optional): True if watch option has been set. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
general (bool, optional): Value override for args.general. Defaults to None.
|
|
engine (bool, optional): Value override for args.engine. Defaults to None.
|
|
pid (Positive int, optional): Value override for args.pid. Defaults to None.
|
|
name (str, optional): Value override for args.name. Defaults to None.
|
|
watch (Positive int, optional): Value override for args.watch. Defaults to None.
|
|
watch_time (Positive int, optional): Value override for args.watch_time. Defaults to None.
|
|
iterations (Positive int, optional): Value override for args.iterations. Defaults to None.
|
|
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if general:
|
|
args.general = general
|
|
if engine:
|
|
args.engine = engine
|
|
if pid:
|
|
args.pid = pid
|
|
if name:
|
|
args.name = name
|
|
if watch:
|
|
args.watch = watch
|
|
if watch_time:
|
|
args.watch_time = watch_time
|
|
if iterations:
|
|
args.iterations = iterations
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle watch logic, will only enter this block once
|
|
if args.watch:
|
|
args = self.helpers.handle_watch(args=args, subcommand=self.process)
|
|
self.logger.print_output(watch_output=True) # Print at the end of watch ( final flush )
|
|
return
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.process(args, multiple_devices=True, watching_output=False, gpu=device_handle)
|
|
|
|
self.logger.print_output(multiple_device_output=True)
|
|
# End of multiple gpus add to watch_output
|
|
if watching_output:
|
|
self.logger.store_watch_output(multiple_devices=True)
|
|
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
# Populate initial processes
|
|
process_list = amdsmi_interface.amdsmi_get_process_list(args.gpu)
|
|
filtered_process_values = []
|
|
for process_handle in process_list:
|
|
process_info = amdsmi_interface.amdsmi_get_process_info(args.gpu, process_handle)
|
|
process_info['mem_usage'] = process_info.pop('mem')
|
|
process_info['usage'] = process_info.pop('engine_usage')
|
|
|
|
# Convert mem_usage to megabytes
|
|
|
|
mem_usage_mb = (process_info['mem_usage']//1024) // 1024
|
|
if mem_usage_mb < 0:
|
|
process_info['mem_usage'] = (process_info['mem_usage']//1024)
|
|
mem_usage_unit = 'B'
|
|
else:
|
|
process_info['mem_usage'] = mem_usage_mb
|
|
|
|
if self.logger.is_human_readable_format():
|
|
mem_usage_unit = 'MB'
|
|
engine_usage_unit = '%'
|
|
process_info['mem_usage'] = f"{process_info['mem_usage']} {mem_usage_unit}"
|
|
|
|
for usage_metric in process_info['usage']:
|
|
process_info['usage'][usage_metric] = f"{process_info['usage'][usage_metric]} {engine_usage_unit}"
|
|
for usage_metric in process_info['memory_usage']:
|
|
process_info['memory_usage'][usage_metric] = f"{process_info['memory_usage'][usage_metric]} {engine_usage_unit}"
|
|
|
|
filtered_process_values.append({'process_info': process_info})
|
|
|
|
# Arguments will filter the populated processes
|
|
# General and Engine to expose process_info values
|
|
if args.general or args.engine:
|
|
for process_info in filtered_process_values:
|
|
if args.general and args.engine:
|
|
del process_info['process_info']['memory_usage']
|
|
elif args.general:
|
|
del process_info['process_info']['memory_usage']
|
|
del process_info['process_info']['usage'] # Used in engine
|
|
elif args.engine:
|
|
del process_info['process_info']['memory_usage']
|
|
del process_info['process_info']['mem_usage'] # Used in general
|
|
|
|
# Filter out non specified pids
|
|
if args.pid:
|
|
process_pids = []
|
|
for process_info in filtered_process_values:
|
|
pid = str(process_info['process_info']['pid'])
|
|
if str(args.pid) == pid:
|
|
process_pids.append(process_info)
|
|
filtered_process_values = process_pids
|
|
|
|
# Filter out non specified process names
|
|
if args.name:
|
|
process_names = []
|
|
for process_info in filtered_process_values:
|
|
process_name = str(process_info['process_info']['name']).lower()
|
|
if str(args.name).lower() == process_name:
|
|
process_names.append(process_info)
|
|
filtered_process_values = process_names
|
|
|
|
# Remove brackets if there is only one value
|
|
if len(filtered_process_values) == 1:
|
|
filtered_process_values = filtered_process_values[0]
|
|
|
|
# Store values in logger.output
|
|
if filtered_process_values == []:
|
|
self.logger.store_output(args.gpu, 'values', {'process_info': 'Not Found'})
|
|
else:
|
|
self.logger.store_output(args.gpu, 'values', filtered_process_values)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
self.logger.print_output()
|
|
|
|
if watching_output: # End of single gpu add to watch_output
|
|
self.logger.store_watch_output(multiple_devices=False)
|
|
|
|
|
|
def profile(self, args):
|
|
"""Not applicable to linux baremetal"""
|
|
print('Profile test')
|
|
|
|
|
|
def event(self, args):
|
|
print('event test')
|
|
|
|
|
|
def topology(self, args, multiple_devices=False, gpu=None, topo_access=None,
|
|
topo_weight=None, topo_hops=None, topo_type=None, topo_numa=None):
|
|
""" Get topology information for target gpus
|
|
The compatibility mode for this will only be in amdsmi & rocm-smi
|
|
params:
|
|
args - argparser args to pass to subcommand
|
|
multiple_devices (bool) - True if checking for multiple devices
|
|
gpu (device_handle) - device_handle for target device
|
|
topo_access (bool) - Value override for args.topo_access
|
|
topo_weight (bool) - Value override for args.topo_weight
|
|
topo_hops (bool) - Value override for args.topo_hops
|
|
topo_type (bool) - Value override for args.topo_type
|
|
topo_numa (bool) - Value override for args.topo_numa
|
|
return:
|
|
Nothing
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if topo_access: args.topo_access = topo_access
|
|
if topo_weight: args.topo_weight = topo_weight
|
|
if topo_hops: args.topo_hops = topo_hops
|
|
if topo_type: args.topo_type = topo_type
|
|
if topo_numa: args.topo_numa = topo_numa
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
pass
|
|
if len(args.gpu) == 1:
|
|
# args.gpu = args.gpu[0]
|
|
pass
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
# Handle all args being false
|
|
|
|
# If all arguments are False, it means that no argument was passed and the entire topology should be printed
|
|
# if not any([args.asic, args.bus, args.vbios, args.limit, args.driver, args.caps, args.ras, args.board]):
|
|
# args.asic = args.bus = args.vbios = args.limit = args.driver = args.caps = args.ras = args.board = True
|
|
|
|
topo_json = {}
|
|
topo_table = []
|
|
|
|
if args.topo_access:
|
|
pass
|
|
if args.topo_weight:
|
|
pass
|
|
if args.topo_hops:
|
|
pass
|
|
if args.topo_type:
|
|
pass
|
|
if args.topo_numa:
|
|
pass
|
|
|
|
|
|
def set_value(self, args, multiple_devices=False, gpu=None, clk=None, sclk=None, mclk=None,
|
|
pcie=None, slevel=None, mlevel=None, vc=None, srange=None, mrange=None,
|
|
fan=None, perflevel=None, overdrive=None, memoverdrive=None,
|
|
poweroverdrive=None, profile=None, perfdet=None, rasenable=None,
|
|
rasdisable=None):
|
|
pass
|
|
|
|
|
|
def reset(self, args, multiple_devices=False, gpu=None, gpureset=None,
|
|
resetclocks=None, resetfans=None, resetprofile=None,
|
|
resetpoweroverdrive=None, resetxgmierr=None, resetperfdet=None):
|
|
"""Issue reset commands to target gpu(s)
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
gpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
gpureset (bool, optional): Value over ride for args.gpureset. Defaults to None.
|
|
resetclocks (bool, optional): Value over ride for args.resetclocks. Defaults to None.
|
|
resetfans (bool, optional): Value over ride for args.resetfans. Defaults to None.
|
|
resetprofile (bool, optional): Value over ride for args.resetprofile. Defaults to None.
|
|
resetpoweroverdrive (bool, optional): Value over ride for args.resetpoweroverdrive. Defaults to None.
|
|
resetxgmierr (bool, optional): Value over ride for args.resetxgmierr. Defaults to None.
|
|
resetperfdet (bool, optional): Value over ride for args.resetperfdet. Defaults to None.
|
|
|
|
Raises:
|
|
ValueError: Value error if no gpu value is provided
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Return:
|
|
Nothing
|
|
"""
|
|
# Set args.* to passed in arguments
|
|
if gpu: args.gpu = gpu
|
|
if gpureset: args.gpureset = gpureset
|
|
if resetclocks: args.resetclocks = resetclocks
|
|
if resetfans: args.resetfans = resetfans
|
|
if resetprofile: args.resetprofile = resetprofile
|
|
if resetpoweroverdrive: args.resetpoweroverdrive = resetpoweroverdrive
|
|
if resetxgmierr: args.resetxgmierr = resetxgmierr
|
|
if resetperfdet: args.resetperfdet = resetperfdet
|
|
|
|
# Handle No GPU passed
|
|
if args.gpu is None:
|
|
raise ValueError('No GPU provided, specific GPU target(s) are needed')
|
|
|
|
# Handle multiple GPUs
|
|
if isinstance(args.gpu, list):
|
|
if len(args.gpu) > 1:
|
|
for device_handle in args.gpu:
|
|
# Handle multiple_devices to print all output at once
|
|
self.bad_pages(args, multiple_devices=True, gpu=device_handle)
|
|
self.logger.print_output(multiple_device_output=True)
|
|
return
|
|
if len(args.gpu) == 1:
|
|
args.gpu = args.gpu[0]
|
|
else:
|
|
raise IndexError("args.gpu should not be an empty list")
|
|
|
|
if args.gpureset:
|
|
if self.helpers.is_amd_device(args.gpu):
|
|
try:
|
|
amdsmi_interface.amdsmi_dev_reset_gpu(args.gpu)
|
|
result = 'Successfully reset GPU'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
result = err.get_error_info()
|
|
else:
|
|
result = 'Unable to reset non-amd GPU'
|
|
|
|
self.logger.store_output(args.gpu, 'gpu_reset', result)
|
|
if args.resetclocks:
|
|
# rsmi_string = ' Reset Clocks '
|
|
reset_clocks_results = {'overdrive' : '',
|
|
'clocks' : '',
|
|
'performance': ''}
|
|
try:
|
|
amdsmi_interface.amdsmi_dev_set_overdrive_level_v1(args.gpu, 0)
|
|
reset_clocks_results['overdrive'] = 'Overdrive set to 0'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
reset_clocks_results['overdrive'] = err.get_error_info()
|
|
|
|
try:
|
|
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
|
amdsmi_interface.amdsmi_dev_set_perf_level_v1(args.gpu, level_auto)
|
|
reset_clocks_results['clocks'] = 'Successfully reset clocks'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
reset_clocks_results['clocks'] = err.get_error_info()
|
|
|
|
try:
|
|
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
|
amdsmi_interface.amdsmi_dev_set_perf_level_v1(args.gpu, level_auto)
|
|
reset_clocks_results['performance'] = 'Performance level reset to auto'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
reset_clocks_results['performance'] = err.get_error_info()
|
|
|
|
self.logger.store_output(args.gpu, 'reset_clocks', reset_clocks_results)
|
|
if args.resetfans:
|
|
try:
|
|
amdsmi_interface.amdsmi_dev_reset_fan(args.gpu, 0)
|
|
result = 'Successfully reset fan speed to driver control'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
result = err.get_error_info()
|
|
|
|
self.logger.store_output(args.gpu, 'reset_fans', result)
|
|
if args.resetprofile:
|
|
reset_profile_results = {'power_profile' : '',
|
|
'performance_level': ''}
|
|
try:
|
|
power_profile_mask = amdsmi_interface.AmdSmiPowerProfilePresetMasks.BOOTUP_DEFAULT
|
|
amdsmi_interface.amdsmi_dev_set_power_profile(args.gpu, 0, power_profile_mask)
|
|
result = 'Successfully reset Power Profile'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
result = err.get_error_info()
|
|
|
|
try:
|
|
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
|
amdsmi_interface.amdsmi_dev_set_perf_level_v1(args.gpu, level_auto)
|
|
reset_clocks_results['performance'] = 'Successfully reset Performance Level'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
reset_clocks_results['performance'] = err.get_error_info()
|
|
|
|
self.logger.store_output(args.gpu, 'reset_profile', reset_profile_results)
|
|
if args.resetxgmierr:
|
|
try:
|
|
amdsmi_interface.amdsmi_dev_reset_xgmi_error(args.gpu)
|
|
result = 'Successfully reset XGMI Error count'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
result = err.get_error_info()
|
|
self.logger.store_output(args.gpu, 'reset_xgmi_err', result)
|
|
if args.resetprefdet:
|
|
try:
|
|
level_auto = amdsmi_interface.AmdSmiDevPerfLevel.AUTO
|
|
amdsmi_interface.amdsmi_dev_set_perf_level_v1(args.gpu, level_auto)
|
|
result = 'Successfully disabled performance determinism'
|
|
except amdsmi_interface.AmdSmiLibraryException as err:
|
|
result = err.get_error_info()
|
|
|
|
self.logger.store_output(args.gpu, 'reset_pref_det', result)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
|
|
self.logger.print_output()
|
|
|
|
|
|
def rocm_smi(self, args):
|
|
print("rocmsmi test")
|