CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
1772 lines
79 KiB
Python
1772 lines
79 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 functools
|
|
import logging
|
|
import os
|
|
|
|
from amdsmi_cli_exceptions import AmdSmiInvalidParameterException
|
|
from amdsmi_helpers import AMDSMIHelpers
|
|
|
|
from amdsmi import amdsmi_exception, amdsmi_interface
|
|
|
|
|
|
# Canonical human-readable AMD vendor string, matching `lspci` / pci.ids (vendor 0x1002).
|
|
# The board manufacturer name is reported as the raw AMD PCI vendor ID ("0x1002") when
|
|
# the host pci.ids lookup is unavailable; the CLI translates it to this string for display
|
|
# while the C/Python APIs continue to return the raw value unchanged.
|
|
AMD_VENDOR_DISPLAY_NAME = "Advanced Micro Devices, Inc. [AMD/ATI]"
|
|
|
|
|
|
class StaticCommands:
|
|
def static_cpu(self, args, multiple_devices=False, cpu=None, interface_ver=None):
|
|
"""Get Static information for target cpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
cpu (device_handle, optional): device_handle for target device. Defaults to None.
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
|
|
if cpu:
|
|
args.cpu = cpu
|
|
if interface_ver:
|
|
args.interface_ver = interface_ver
|
|
|
|
# Store cpu args that are applicable to the current platform
|
|
curr_platform_cpu_args = ["smu", "interface_ver"]
|
|
curr_platform_cpu_values = [args.smu, args.interface_ver]
|
|
|
|
# If no cpu options are passed, return all available args
|
|
if not any(curr_platform_cpu_values):
|
|
for arg in curr_platform_cpu_args:
|
|
setattr(args, arg, True)
|
|
|
|
# Handle multiple CPUs
|
|
handled_multiple_cpus, device_handle = self.helpers.handle_cpus(
|
|
args, self.logger, self.static_cpu
|
|
)
|
|
if handled_multiple_cpus:
|
|
return # This function is recursive
|
|
args.cpu = device_handle
|
|
|
|
# Get cpu id for logging
|
|
cpu_id = self.helpers.get_cpu_id_from_device_handle(args.cpu)
|
|
logging.debug(f"Static Arg information for CPU {cpu_id} on {self.helpers.os_info()}")
|
|
|
|
static_dict = {}
|
|
if self.logger.is_json_format():
|
|
static_dict["cpu"] = int(cpu_id)
|
|
|
|
if args.smu:
|
|
try:
|
|
smu = amdsmi_interface.amdsmi_get_cpu_smu_fw_version(args.cpu)
|
|
static_dict["smu"] = {
|
|
"FW_VERSION": f"{smu['smu_fw_major_ver_num']}."
|
|
f"{smu['smu_fw_minor_ver_num']}.{smu['smu_fw_debug_ver_num']}"
|
|
}
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
static_dict["smu"] = "N/A"
|
|
logging.debug("Failed to get SMU FW for cpu %s | %s", cpu_id, e.get_error_info())
|
|
|
|
if args.interface_ver:
|
|
static_dict["interface_version"] = {}
|
|
try:
|
|
intf_ver = amdsmi_interface.amdsmi_get_cpu_hsmp_proto_ver(args.cpu)
|
|
static_dict["interface_version"]["proto version"] = intf_ver
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
static_dict["interface_version"]["proto version"] = "N/A"
|
|
logging.debug(
|
|
"Failed to get proto version for cpu %s | %s", cpu_id, e.get_error_info()
|
|
)
|
|
|
|
multiple_devices_csv_override = False
|
|
if not self.logger.is_json_format():
|
|
self.logger.store_cpu_output(args.cpu, "values", static_dict)
|
|
else:
|
|
self.logger.store_cpu_json_output.append(static_dict)
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
if not self.logger.is_json_format():
|
|
self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override)
|
|
|
|
def static_gpu(
|
|
self,
|
|
args,
|
|
multiple_devices=False,
|
|
gpu=None,
|
|
asic=None,
|
|
bus=None,
|
|
vbios=None,
|
|
limit=None,
|
|
driver=None,
|
|
ras=None,
|
|
board=None,
|
|
numa=None,
|
|
vram=None,
|
|
cache=None,
|
|
partition=None,
|
|
dfc_ucode=None,
|
|
fb_info=None,
|
|
num_vf=None,
|
|
soc_pstate=None,
|
|
xgmi_plpd=None,
|
|
process_isolation=None,
|
|
clock=None,
|
|
profile=None,
|
|
mem_carveout=None,
|
|
):
|
|
"""Get Static information for target gpu
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
current_platform_args (list): gpu supported platform arguments
|
|
current_platform_values (list): gpu supported platform values for each argument
|
|
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.
|
|
ras (bool, optional): Value override for args.ras. Defaults to None.
|
|
board (bool, optional): Value override for args.board. Defaults to None.
|
|
numa (bool, optional): Value override for args.numa. Defaults to None.
|
|
vram (bool, optional): Value override for args.vram. Defaults to None.
|
|
cache (bool, optional): Value override for args.cache. Defaults to None.
|
|
partition (bool, optional): Value override for args.partition. Defaults to None.
|
|
dfc_ucode (bool, optional): Value override for args.dfc_ucode. Defaults to None.
|
|
fb_info (bool, optional): Value override for args.fb_info. Defaults to None.
|
|
num_vf (bool, optional): Value override for args.num_vf. Defaults to None.
|
|
soc_pstate (bool, optional): Value override for args.soc_pstate. Defaults to None.
|
|
xgmi_plpd (bool, optional): Value override for args.xgmi_plpd. Defaults to None.
|
|
process_isolation (bool, optional): Value override for args.process_isolation. Defaults to None.
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if asic:
|
|
args.asic = asic
|
|
if bus:
|
|
args.bus = bus
|
|
if vbios:
|
|
args.vbios = vbios
|
|
if board:
|
|
args.board = board
|
|
if driver:
|
|
args.driver = driver
|
|
if ras:
|
|
args.ras = ras
|
|
if vram:
|
|
args.vram = vram
|
|
if cache:
|
|
args.cache = cache
|
|
if process_isolation:
|
|
args.process_isolation = process_isolation
|
|
if partition:
|
|
args.partition = partition
|
|
if clock:
|
|
args.clock = clock
|
|
if mem_carveout:
|
|
args.mem_carveout = mem_carveout
|
|
|
|
# args.clock defaults to False so if it was overwritten to empty list, that indicates that it was given as an arguments but with an empty list
|
|
if args.clock == []:
|
|
args.clock = True
|
|
|
|
# Store args that are applicable to the current platform (default arguments)
|
|
current_platform_args = [
|
|
"asic",
|
|
"bus",
|
|
"vbios",
|
|
"driver",
|
|
"ras",
|
|
"vram",
|
|
"cache",
|
|
"board",
|
|
"process_isolation",
|
|
"clock",
|
|
"mem_carveout",
|
|
]
|
|
current_platform_values = [
|
|
args.asic,
|
|
args.bus,
|
|
args.vbios,
|
|
args.driver,
|
|
args.ras,
|
|
args.vram,
|
|
args.cache,
|
|
args.board,
|
|
args.process_isolation,
|
|
args.clock,
|
|
args.mem_carveout,
|
|
]
|
|
|
|
# amd-smi static default arguments:
|
|
# Exclude args that are not applicable to the current platform,
|
|
# but allow output if argument is passed.
|
|
#
|
|
# Note: Partition is a special case, it is no longer an amd-smi static
|
|
# default argument.
|
|
# Reason: Reading current_compute_partition may momentarily wake the
|
|
# GPU up. This is due to reading XCD registers, which is expected
|
|
# behavior. Changing partitions is not a trivial operation,
|
|
# current_compute_partition SYSFS controls this action.
|
|
if args.partition:
|
|
current_platform_args += ["partition"]
|
|
current_platform_values += [args.partition]
|
|
|
|
if not self.group_check_printed:
|
|
self.helpers.check_required_groups()
|
|
self.group_check_printed = True
|
|
|
|
if self.helpers.is_linux() and self.helpers.is_baremetal():
|
|
if limit:
|
|
args.limit = limit
|
|
if soc_pstate:
|
|
args.soc_pstate = soc_pstate
|
|
if xgmi_plpd:
|
|
args.xgmi_plpd = xgmi_plpd
|
|
if profile:
|
|
args.profile = profile
|
|
current_platform_args += ["ras", "limit", "soc_pstate", "xgmi_plpd", "profile"]
|
|
current_platform_values += [
|
|
args.ras,
|
|
args.limit,
|
|
args.soc_pstate,
|
|
args.xgmi_plpd,
|
|
args.profile,
|
|
]
|
|
|
|
if self.helpers.is_linux() and not self.helpers.is_virtual_os():
|
|
if numa:
|
|
args.numa = numa
|
|
current_platform_args += ["numa"]
|
|
current_platform_values += [args.numa]
|
|
|
|
if self.helpers.is_hypervisor():
|
|
if dfc_ucode:
|
|
args.dfc_ucode = dfc_ucode
|
|
if fb_info:
|
|
args.fb_info = fb_info
|
|
if num_vf:
|
|
args.num_vf = num_vf
|
|
current_platform_args += ["dfc_ucode", "fb_info", "num_vf"]
|
|
current_platform_values += [args.dfc_ucode, args.fb_info, args.num_vf]
|
|
|
|
if not any(current_platform_values):
|
|
for arg in current_platform_args:
|
|
setattr(args, arg, True)
|
|
|
|
handled_multiple_gpus, device_handle = self.helpers.handle_gpus(
|
|
args, self.logger, self.static_gpu
|
|
)
|
|
if handled_multiple_gpus:
|
|
return # This function is recursive
|
|
args.gpu = device_handle
|
|
# Get gpu_id for logging
|
|
gpu_id = self.helpers.get_gpu_id_from_device_handle(args.gpu)
|
|
|
|
logging.debug("=====================================================================")
|
|
logging.debug(f"Static Arg information for GPU {gpu_id} on {self.helpers.os_info()}")
|
|
logging.debug(f"Function args: {args}")
|
|
logging.debug(f"Current platform args: {current_platform_args}")
|
|
logging.debug(f"Current platform values: {current_platform_values}")
|
|
logging.debug("=====================================================================")
|
|
|
|
# Populate static dictionary for each enabled argument
|
|
static_dict = {}
|
|
if self.logger.is_json_format():
|
|
static_dict["gpu"] = int(gpu_id)
|
|
if args.asic:
|
|
asic_dict = {
|
|
"market_name": "N/A",
|
|
"vendor_id": "N/A",
|
|
"vendor_name": "N/A",
|
|
"subvendor_id": "N/A",
|
|
"device_id": "N/A",
|
|
"subsystem_id": "N/A",
|
|
"rev_id": "N/A",
|
|
"asic_serial": "N/A",
|
|
"oam_id": "N/A",
|
|
"num_compute_units": "N/A",
|
|
"target_graphics_version": "N/A",
|
|
}
|
|
|
|
try:
|
|
asic_info = amdsmi_interface.amdsmi_get_gpu_asic_info(args.gpu)
|
|
for key, value in asic_info.items():
|
|
asic_dict[key] = value
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug("Failed to get asic info for gpu %s | %s", gpu_id, e.get_error_info())
|
|
|
|
static_dict["asic"] = asic_dict
|
|
if args.bus:
|
|
bus_info = {
|
|
"bdf": "N/A",
|
|
"max_pcie_width": "N/A",
|
|
"max_pcie_speed": "N/A",
|
|
"pcie_levels": "N/A",
|
|
"pcie_interface_version": "N/A",
|
|
"slot_type": "N/A",
|
|
}
|
|
|
|
try:
|
|
bus_info["bdf"] = amdsmi_interface.amdsmi_get_gpu_device_bdf(args.gpu)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
bus_info["bdf"] = "N/A"
|
|
logging.debug("Failed to get bdf for gpu %s | %s", gpu_id, e.get_error_info())
|
|
|
|
try:
|
|
pcie_static = amdsmi_interface.amdsmi_get_pcie_info(args.gpu)["pcie_static"]
|
|
bus_info["max_pcie_width"] = pcie_static["max_pcie_width"]
|
|
bus_info["max_pcie_speed"] = pcie_static["max_pcie_speed"]
|
|
bus_info["pcie_interface_version"] = pcie_static["pcie_interface_version"]
|
|
bus_info["slot_type"] = pcie_static["slot_type"]
|
|
if bus_info["max_pcie_speed"] % 1000 != 0:
|
|
pcie_speed_GTs_value = round(bus_info["max_pcie_speed"] / 1000, 1)
|
|
else:
|
|
pcie_speed_GTs_value = round(bus_info["max_pcie_speed"] / 1000)
|
|
|
|
bus_info["max_pcie_speed"] = pcie_speed_GTs_value
|
|
|
|
if bus_info["pcie_interface_version"] > 0:
|
|
bus_info["pcie_interface_version"] = f"Gen {bus_info['pcie_interface_version']}"
|
|
|
|
# Set the unit for pcie_speed
|
|
pcie_speed_unit = "GT/s"
|
|
if self.logger.is_human_readable_format():
|
|
bus_info["max_pcie_speed"] = f"{bus_info['max_pcie_speed']} {pcie_speed_unit}"
|
|
|
|
if self.logger.is_json_format():
|
|
bus_info["max_pcie_speed"] = {
|
|
"value": bus_info["max_pcie_speed"],
|
|
"unit": pcie_speed_unit,
|
|
}
|
|
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug("Failed to get bus info for gpu %s | %s", gpu_id, e.get_error_info())
|
|
|
|
try:
|
|
pcie_info = amdsmi_interface.amdsmi_get_gpu_pci_bandwidth(args.gpu)
|
|
num_supported = pcie_info["transfer_rate"]["num_supported"]
|
|
if num_supported != 0:
|
|
bus_info["pcie_levels"] = {}
|
|
for level in range(0, num_supported):
|
|
speed = (
|
|
str(
|
|
self.helpers.convert_SI_unit(
|
|
float(pcie_info["transfer_rate"]["frequency"][level]),
|
|
AMDSMIHelpers.SI_Unit.NANO,
|
|
)
|
|
)
|
|
+ " GT/s"
|
|
)
|
|
width = str(pcie_info["lanes"][level])
|
|
level_values = (speed, width)
|
|
bus_info["pcie_levels"].update({str(level): level_values})
|
|
else:
|
|
bus_info["pcie_levels"] = "N/A"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get pci bandwidth info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
static_dict["bus"] = bus_info
|
|
if args.vbios:
|
|
try:
|
|
vbios_info = amdsmi_interface.amdsmi_get_gpu_vbios_info(args.gpu)
|
|
for key, value in vbios_info.items():
|
|
if isinstance(value, str):
|
|
if value.strip() == "":
|
|
vbios_info[key] = "N/A"
|
|
static_dict["ifwi"] = vbios_info
|
|
# Remove boot_firmware since it's not used
|
|
del static_dict["ifwi"]["boot_firmware"]
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
static_dict["ifwi"] = "N/A"
|
|
logging.debug(
|
|
"Failed to get vbios/ifwi info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
if "limit" in current_platform_args:
|
|
if args.limit:
|
|
# Power limits
|
|
|
|
power_limit_types = {}
|
|
for power_type in amdsmi_interface.AmdSmiPowerCapType:
|
|
# Strip 'AMDSMI_POWER_CAP_TYPE_' prefix and convert to lowercase
|
|
key = power_type.name.replace("AMDSMI_POWER_CAP_TYPE_", "").lower()
|
|
power_limit_types[key] = {
|
|
"max_power_limit": "N/A",
|
|
"min_power_limit": "N/A",
|
|
"socket_power_limit": "N/A",
|
|
}
|
|
|
|
try:
|
|
power_cap_types = amdsmi_interface.amdsmi_get_supported_power_cap(args.gpu)
|
|
for sensor in power_cap_types["sensor_inds"]:
|
|
power_cap_info = amdsmi_interface.amdsmi_get_power_cap_info(
|
|
args.gpu, sensor
|
|
)
|
|
max_power_limit = power_cap_info["max_power_cap"]
|
|
max_power_limit = self.helpers.convert_SI_unit(
|
|
max_power_limit, AMDSMIHelpers.SI_Unit.MICRO
|
|
)
|
|
min_power_limit = power_cap_info["min_power_cap"]
|
|
min_power_limit = self.helpers.convert_SI_unit(
|
|
min_power_limit, AMDSMIHelpers.SI_Unit.MICRO
|
|
)
|
|
socket_power_limit = power_cap_info["power_cap"]
|
|
socket_power_limit = self.helpers.convert_SI_unit(
|
|
socket_power_limit, AMDSMIHelpers.SI_Unit.MICRO
|
|
)
|
|
ppt = {
|
|
"max_power_limit": self.helpers.unit_format(
|
|
self.logger, max_power_limit, "W"
|
|
),
|
|
"min_power_limit": self.helpers.unit_format(
|
|
self.logger, min_power_limit, "W"
|
|
),
|
|
"socket_power_limit": self.helpers.unit_format(
|
|
self.logger, socket_power_limit, "W"
|
|
),
|
|
}
|
|
|
|
sensor_name = power_cap_types["sensor_types"][sensor]
|
|
# Strip 'AMDSMI_POWER_CAP_TYPE_' prefix and convert to lowercase
|
|
sensor_key = sensor_name.name.replace("AMDSMI_POWER_CAP_TYPE_", "").lower()
|
|
power_limit_types[sensor_key] = ppt
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get power cap info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
# Edge temperature limits
|
|
try:
|
|
slowdown_temp_edge_limit_error = False
|
|
slowdown_temp_edge_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
|
args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.EDGE,
|
|
amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL,
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
slowdown_temp_edge_limit_error = True
|
|
slowdown_temp_edge_limit = "N/A"
|
|
logging.debug(
|
|
"Failed to get edge temperature slowdown metric for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
if slowdown_temp_edge_limit == 0:
|
|
slowdown_temp_edge_limit_error = True
|
|
slowdown_temp_edge_limit = "N/A"
|
|
|
|
try:
|
|
shutdown_temp_edge_limit_error = False
|
|
shutdown_temp_edge_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
|
args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.EDGE,
|
|
amdsmi_interface.AmdSmiTemperatureMetric.EMERGENCY,
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
shutdown_temp_edge_limit_error = True
|
|
shutdown_temp_edge_limit = "N/A"
|
|
logging.debug(
|
|
"Failed to get edge temperature shutdown metrics for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
if shutdown_temp_edge_limit == 0:
|
|
shutdown_temp_edge_limit_error = True
|
|
shutdown_temp_edge_limit = "N/A"
|
|
|
|
# Hotspot/Junction temperature limits
|
|
try:
|
|
slowdown_temp_hotspot_limit_error = False
|
|
slowdown_temp_hotspot_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
|
args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.HOTSPOT,
|
|
amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL,
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
slowdown_temp_hotspot_limit_error = True
|
|
slowdown_temp_hotspot_limit = "N/A"
|
|
logging.debug(
|
|
"Failed to get hotspot temperature slowdown metrics for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
try:
|
|
shutdown_temp_hotspot_limit_error = False
|
|
shutdown_temp_hotspot_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
|
args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.HOTSPOT,
|
|
amdsmi_interface.AmdSmiTemperatureMetric.EMERGENCY,
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
shutdown_temp_hotspot_limit_error = True
|
|
shutdown_temp_hotspot_limit = "N/A"
|
|
logging.debug(
|
|
"Failed to get hotspot temperature shutdown metrics for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
# VRAM temperature limits
|
|
try:
|
|
slowdown_temp_vram_limit_error = False
|
|
slowdown_temp_vram_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
|
args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.VRAM,
|
|
amdsmi_interface.AmdSmiTemperatureMetric.CRITICAL,
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
slowdown_temp_vram_limit_error = True
|
|
slowdown_temp_vram_limit = "N/A"
|
|
logging.debug(
|
|
"Failed to get vram temperature slowdown metrics for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
try:
|
|
shutdown_temp_vram_limit_error = False
|
|
shutdown_temp_vram_limit = amdsmi_interface.amdsmi_get_temp_metric(
|
|
args.gpu,
|
|
amdsmi_interface.AmdSmiTemperatureType.VRAM,
|
|
amdsmi_interface.AmdSmiTemperatureMetric.EMERGENCY,
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
shutdown_temp_vram_limit_error = True
|
|
shutdown_temp_vram_limit = "N/A"
|
|
logging.debug(
|
|
"Failed to get vram temperature shutdown metrics for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
# PTL
|
|
try:
|
|
ptl_state = amdsmi_interface.amdsmi_get_gpu_ptl_state(args.gpu)
|
|
ptl_state = "Enabled" if ptl_state else "Disabled"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
ptl_state = "N/A"
|
|
logging.debug(
|
|
"Failed to get PTL state for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
try:
|
|
ptl_format1, ptl_format2 = amdsmi_interface.amdsmi_get_gpu_ptl_formats(args.gpu)
|
|
fmt1_name = (
|
|
amdsmi_interface.amdsmi_wrapper.amdsmi_ptl_data_format_t__enumvalues.get(
|
|
ptl_format1
|
|
)
|
|
)
|
|
fmt2_name = (
|
|
amdsmi_interface.amdsmi_wrapper.amdsmi_ptl_data_format_t__enumvalues.get(
|
|
ptl_format2
|
|
)
|
|
)
|
|
|
|
fmt1_short = (
|
|
fmt1_name.replace("AMDSMI_PTL_DATA_FORMAT_", "") if fmt1_name else "UNKNOWN"
|
|
)
|
|
fmt2_short = (
|
|
fmt2_name.replace("AMDSMI_PTL_DATA_FORMAT_", "") if fmt2_name else "UNKNOWN"
|
|
)
|
|
|
|
ptl_format = f"{fmt1_short},{fmt2_short}"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
ptl_format = "N/A"
|
|
logging.debug(
|
|
"Failed to get PTL state for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
# Assign units
|
|
power_unit = "W"
|
|
temp_unit_human_readable = "\N{DEGREE SIGN}C"
|
|
temp_unit_json = "C"
|
|
|
|
if self.logger.is_human_readable_format():
|
|
if not slowdown_temp_edge_limit_error:
|
|
slowdown_temp_edge_limit = (
|
|
f"{slowdown_temp_edge_limit} {temp_unit_human_readable}"
|
|
)
|
|
if not slowdown_temp_hotspot_limit_error:
|
|
slowdown_temp_hotspot_limit = (
|
|
f"{slowdown_temp_hotspot_limit} {temp_unit_human_readable}"
|
|
)
|
|
if not slowdown_temp_vram_limit_error:
|
|
slowdown_temp_vram_limit = (
|
|
f"{slowdown_temp_vram_limit} {temp_unit_human_readable}"
|
|
)
|
|
if not shutdown_temp_edge_limit_error:
|
|
shutdown_temp_edge_limit = (
|
|
f"{shutdown_temp_edge_limit} {temp_unit_human_readable}"
|
|
)
|
|
if not shutdown_temp_hotspot_limit_error:
|
|
shutdown_temp_hotspot_limit = (
|
|
f"{shutdown_temp_hotspot_limit} {temp_unit_human_readable}"
|
|
)
|
|
if not shutdown_temp_vram_limit_error:
|
|
shutdown_temp_vram_limit = (
|
|
f"{shutdown_temp_vram_limit} {temp_unit_human_readable}"
|
|
)
|
|
|
|
if self.logger.is_json_format():
|
|
if not slowdown_temp_edge_limit_error:
|
|
slowdown_temp_edge_limit = {
|
|
"value": slowdown_temp_edge_limit,
|
|
"unit": temp_unit_json,
|
|
}
|
|
if not slowdown_temp_hotspot_limit_error:
|
|
slowdown_temp_hotspot_limit = {
|
|
"value": slowdown_temp_hotspot_limit,
|
|
"unit": temp_unit_json,
|
|
}
|
|
if not slowdown_temp_vram_limit_error:
|
|
slowdown_temp_vram_limit = {
|
|
"value": slowdown_temp_vram_limit,
|
|
"unit": temp_unit_json,
|
|
}
|
|
if not shutdown_temp_edge_limit_error:
|
|
shutdown_temp_edge_limit = {
|
|
"value": shutdown_temp_edge_limit,
|
|
"unit": temp_unit_json,
|
|
}
|
|
if not shutdown_temp_hotspot_limit_error:
|
|
shutdown_temp_hotspot_limit = {
|
|
"value": shutdown_temp_hotspot_limit,
|
|
"unit": temp_unit_json,
|
|
}
|
|
if not shutdown_temp_vram_limit_error:
|
|
shutdown_temp_vram_limit = {
|
|
"value": shutdown_temp_vram_limit,
|
|
"unit": temp_unit_json,
|
|
}
|
|
|
|
limit_info = {}
|
|
# Power limits
|
|
limit_info["ppt0"] = power_limit_types["ppt0"]
|
|
limit_info["ppt1"] = power_limit_types["ppt1"]
|
|
|
|
# Shutdown limits
|
|
limit_info["slowdown_edge_temperature"] = slowdown_temp_edge_limit
|
|
limit_info["slowdown_hotspot_temperature"] = slowdown_temp_hotspot_limit
|
|
limit_info["slowdown_vram_temperature"] = slowdown_temp_vram_limit
|
|
limit_info["shutdown_edge_temperature"] = shutdown_temp_edge_limit
|
|
limit_info["shutdown_hotspot_temperature"] = shutdown_temp_hotspot_limit
|
|
limit_info["shutdown_vram_temperature"] = shutdown_temp_vram_limit
|
|
|
|
# PTL
|
|
limit_info["ptl_state"] = ptl_state
|
|
limit_info["ptl_format"] = ptl_format
|
|
|
|
static_dict["limit"] = limit_info
|
|
if args.driver:
|
|
driver_info_dict = {"name": "N/A", "version": "N/A", "os_kernel_version": "N/A"}
|
|
|
|
try:
|
|
driver_info = amdsmi_interface.amdsmi_get_gpu_driver_info(args.gpu)
|
|
driver_info_dict["name"] = driver_info["driver_name"]
|
|
driver_info_dict["version"] = driver_info["driver_version"]
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get driver info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
try:
|
|
driver_info_dict["os_kernel_version"] = os.uname().release
|
|
except (AttributeError, OSError) as e:
|
|
logging.debug("Failed to get os kernel version for gpu %s | %s", gpu_id, e)
|
|
|
|
static_dict["driver"] = driver_info_dict
|
|
if args.board:
|
|
static_dict["board"] = {
|
|
"model_number": "N/A",
|
|
"product_serial": "N/A",
|
|
"fru_id": "N/A",
|
|
"product_name": "N/A",
|
|
"manufacturer_name": "N/A",
|
|
}
|
|
try:
|
|
board_info = amdsmi_interface.amdsmi_get_gpu_board_info(args.gpu)
|
|
for key, value in board_info.items():
|
|
if isinstance(value, str):
|
|
if value.strip() == "":
|
|
board_info[key] = "N/A"
|
|
# manufacturer_name falls back to the raw AMD PCI vendor ID ("0x1002")
|
|
# when the host pci.ids lookup is unavailable. Translate it to the
|
|
# canonical vendor string for display, matching `lspci` / pci.ids.
|
|
manufacturer_name = board_info.get("manufacturer_name")
|
|
if isinstance(manufacturer_name, str) and manufacturer_name.strip() == "0x1002":
|
|
board_info["manufacturer_name"] = AMD_VENDOR_DISPLAY_NAME
|
|
static_dict["board"] = board_info
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get board info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
if "ras" in current_platform_args:
|
|
if args.ras:
|
|
ras_dict = {
|
|
"eeprom_version": "N/A",
|
|
"bad_page_threshold": "N/A",
|
|
"bad_page_threshold_exceeded": "N/A",
|
|
"parity_schema": "N/A",
|
|
"single_bit_schema": "N/A",
|
|
"double_bit_schema": "N/A",
|
|
"poison_schema": "N/A",
|
|
"ecc_block_state": "N/A",
|
|
}
|
|
|
|
try:
|
|
ras_info = amdsmi_interface.amdsmi_get_gpu_ras_feature_info(args.gpu)
|
|
for key, value in ras_info.items():
|
|
if isinstance(value, int):
|
|
if value == 65535:
|
|
logging.debug(f"Failed to get ras {key} for gpu {gpu_id}")
|
|
ras_info[key] = "N/A"
|
|
continue
|
|
if key != "eeprom_version":
|
|
if value:
|
|
ras_info[key] = "ENABLED"
|
|
else:
|
|
ras_info[key] = "DISABLED"
|
|
|
|
ras_dict.update(ras_info)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get ras info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
try:
|
|
ras_dict["bad_page_threshold"] = (
|
|
amdsmi_interface.amdsmi_get_gpu_bad_page_threshold(args.gpu)
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get bad page threshold count for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
try:
|
|
bad_page_info = amdsmi_interface.amdsmi_get_gpu_bad_page_info(args.gpu)
|
|
retired_pages = 0
|
|
if bad_page_info:
|
|
for bad_page in bad_page_info:
|
|
if (
|
|
bad_page["status"]
|
|
== amdsmi_interface.AmdSmiMemoryPageStatus.RESERVED
|
|
):
|
|
retired_pages += 1
|
|
# default to N/A
|
|
ras_dict["bad_page_threshold_exceeded"] = "N/A"
|
|
# If this is an int, then default to False
|
|
if isinstance(ras_dict["bad_page_threshold"], int):
|
|
ras_dict["bad_page_threshold_exceeded"] = "False"
|
|
if retired_pages > ras_dict["bad_page_threshold"]:
|
|
# If there are more retired pages then set to True
|
|
ras_dict["bad_page_threshold_exceeded"] = "True"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get retired pages count for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
try:
|
|
ras_states = amdsmi_interface.amdsmi_get_gpu_ras_block_features_enabled(
|
|
args.gpu
|
|
)
|
|
ecc_block_state_dict = {}
|
|
for state in ras_states:
|
|
ecc_block_state_dict[state["block"]] = state["status"]
|
|
ras_dict["ecc_block_state"] = ecc_block_state_dict
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug(
|
|
"Failed to get ras block features for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
static_dict["ras"] = ras_dict
|
|
if args.partition:
|
|
try:
|
|
compute_partition = amdsmi_interface.amdsmi_get_gpu_compute_partition(args.gpu)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
compute_partition = "N/A"
|
|
logging.debug(
|
|
"Failed to get compute partition info for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
try:
|
|
memory_partition = amdsmi_interface.amdsmi_get_gpu_memory_partition(args.gpu)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
memory_partition = "N/A"
|
|
logging.debug(
|
|
"Failed to get memory partition info for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
try:
|
|
mem_alloc_mode = (
|
|
amdsmi_interface.amdsmi_get_gpu_accelerator_partition_mem_alloc_mode(args.gpu)
|
|
)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
mem_alloc_mode = "N/A"
|
|
logging.debug(
|
|
"Failed to get accelerator partition mem alloc mode for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
try:
|
|
kfd_info = amdsmi_interface.amdsmi_get_gpu_kfd_info(args.gpu)
|
|
partition_id = kfd_info["current_partition_id"]
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
partition_id = "N/A"
|
|
logging.debug(
|
|
"Failed to get partition ID for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
static_dict["partition"] = {
|
|
"accelerator_partition": compute_partition,
|
|
"memory_partition": memory_partition,
|
|
"partition_id": partition_id,
|
|
"compute_partition_mem_alloc_mode": mem_alloc_mode,
|
|
}
|
|
if "soc_pstate" in current_platform_args:
|
|
if args.soc_pstate:
|
|
try:
|
|
policy_info = amdsmi_interface.amdsmi_get_soc_pstate(args.gpu)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
policy_info = "N/A"
|
|
logging.debug(
|
|
"Failed to get soc pstate policy info for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
|
|
# Format for CSV output - flatten completely to avoid extra columns
|
|
if self.logger.is_csv_format() and isinstance(policy_info, dict):
|
|
policies_str = (
|
|
", ".join(
|
|
f"{p['policy_id']}:{p['policy_description']}"
|
|
for p in policy_info.get("policies", [])
|
|
)
|
|
or "N/A"
|
|
)
|
|
|
|
static_dict["num_supported"] = policy_info.get("num_supported", "N/A")
|
|
static_dict["current_id"] = policy_info.get("current_id", "N/A")
|
|
static_dict["policies"] = policies_str
|
|
else:
|
|
static_dict["soc_pstate"] = policy_info
|
|
if "xgmi_plpd" in current_platform_args:
|
|
if args.xgmi_plpd:
|
|
try:
|
|
policy_info = amdsmi_interface.amdsmi_get_xgmi_plpd(args.gpu)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
policy_info = "N/A"
|
|
logging.debug(
|
|
"Failed to get xgmi_plpd info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
# Format for CSV output - flatten completely to avoid extra columns
|
|
if self.logger.is_csv_format() and isinstance(policy_info, dict):
|
|
policies_str = (
|
|
", ".join(
|
|
f"{p['policy_id']}:{p['policy_description']}"
|
|
for p in policy_info.get("policies", [])
|
|
)
|
|
or "N/A"
|
|
)
|
|
|
|
static_dict["num_supported"] = policy_info.get("num_supported", "N/A")
|
|
static_dict["current_id"] = policy_info.get("current_id", "N/A")
|
|
static_dict["policies"] = policies_str
|
|
else:
|
|
static_dict["xgmi_plpd"] = policy_info
|
|
if "profile" in current_platform_args:
|
|
if args.profile:
|
|
try:
|
|
profile_status = amdsmi_interface.amdsmi_get_gpu_power_profile_presets(
|
|
args.gpu, 0
|
|
)
|
|
|
|
# Parse available profiles from bitfield
|
|
available_profiles = self.helpers.parse_available_profiles(
|
|
profile_status["available_profiles"]
|
|
)
|
|
|
|
# Get current profile name
|
|
current_profile = self.helpers.get_profile_name_from_mask(
|
|
profile_status["current"]
|
|
)
|
|
|
|
# Store output
|
|
static_dict["profile"] = {
|
|
"available_profiles": available_profiles,
|
|
"current": current_profile,
|
|
"num_profiles": profile_status["num_profiles"],
|
|
}
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
static_dict["profile"] = e.get_error_info()
|
|
logging.debug(
|
|
"Failed to get power profile info for gpu %s | %s",
|
|
gpu_id,
|
|
e.get_error_info(),
|
|
)
|
|
if "process_isolation" in current_platform_args:
|
|
if args.process_isolation:
|
|
try:
|
|
status = amdsmi_interface.amdsmi_get_gpu_process_isolation(args.gpu)
|
|
status = "Enabled" if status else "Disabled"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
status = "N/A"
|
|
logging.debug(
|
|
"Failed to process isolation for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
static_dict["process_isolation"] = status
|
|
if "numa" in current_platform_args:
|
|
if args.numa:
|
|
try:
|
|
numa_node_number = amdsmi_interface.amdsmi_topo_get_numa_node_number(args.gpu)
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
numa_node_number = "N/A"
|
|
logging.debug(
|
|
"Failed to get numa node number for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
try:
|
|
numa_affinity = amdsmi_interface.amdsmi_get_gpu_topo_numa_affinity(args.gpu)
|
|
# -1 means No numa node is assigned to the GPU, so there is no numa affinity
|
|
if self.logger.is_human_readable_format() and numa_affinity == -1:
|
|
numa_affinity = "NONE"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
numa_affinity = "N/A"
|
|
logging.debug(
|
|
"Failed to get numa affinity for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
try:
|
|
cpu_set = amdsmi_interface.amdsmi_get_cpu_affinity_with_scope(
|
|
args.gpu, amdsmi_interface.AmdSmiAffinityScope.NUMA_SCOPE
|
|
)
|
|
cpu_set = [f"{cpus:016X}" for cpus in cpu_set]
|
|
cpu_set = {f"cpu_list_{i}": f"{cpus}" for i, cpus in enumerate(cpu_set)}
|
|
bitmask_ranges = self.helpers.get_bitmask_ranges(cpu_set)
|
|
cpu_affinity = {}
|
|
|
|
for key in cpu_set:
|
|
cpu_affinity[key] = {
|
|
"bitmask": cpu_set[key],
|
|
"cpu_cores_affinity": bitmask_ranges[key],
|
|
}
|
|
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
cpu_affinity = "N/A"
|
|
logging.debug(
|
|
"Failed to get cpu affinity for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
try:
|
|
socket_set = amdsmi_interface.amdsmi_get_cpu_affinity_with_scope(
|
|
args.gpu, amdsmi_interface.AmdSmiAffinityScope.SOCKET_SCOPE
|
|
)
|
|
socket_set = [f"{cpus:016X}" for cpus in socket_set]
|
|
socket_set = {f"cpu_list_{i}": f"{cpus}" for i, cpus in enumerate(socket_set)}
|
|
socket_bitmask_ranges = self.helpers.get_bitmask_ranges(socket_set)
|
|
socket_affinity = {}
|
|
for key in socket_set:
|
|
socket_affinity[key] = {
|
|
"bitmask": socket_set[key],
|
|
"cpu_cores_affinity": socket_bitmask_ranges.get(key, "N/A"),
|
|
}
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
socket_affinity = "N/A"
|
|
logging.debug(
|
|
"Failed to get socket affinity for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
static_dict["numa"] = {
|
|
"node": numa_node_number,
|
|
"affinity": numa_affinity,
|
|
"cpu_affinity": cpu_affinity,
|
|
"socket_affinity": socket_affinity,
|
|
}
|
|
if args.vram:
|
|
vram_info_dict = {
|
|
"type": "N/A",
|
|
"vendor": "N/A",
|
|
"size": "N/A",
|
|
"bit_width": "N/A",
|
|
"max_bandwidth": "N/A",
|
|
}
|
|
try:
|
|
vram_info = amdsmi_interface.amdsmi_get_gpu_vram_info(args.gpu)
|
|
|
|
# Get vram type string
|
|
vram_type_enum = vram_info["vram_type"]
|
|
if vram_type_enum == amdsmi_interface.amdsmi_wrapper.AMDSMI_VRAM_TYPE__MAX:
|
|
vram_type = "GDDR7"
|
|
else:
|
|
vram_type = amdsmi_interface.amdsmi_wrapper.amdsmi_vram_type_t__enumvalues[
|
|
vram_type_enum
|
|
]
|
|
# Remove amdsmi enum prefix
|
|
vram_type = vram_type.replace("AMDSMI_VRAM_TYPE_", "").replace("_", "")
|
|
|
|
# Get vram vendor string
|
|
vram_vendor = vram_info["vram_vendor"]
|
|
if "PLACEHOLDER" in vram_vendor:
|
|
vram_vendor = "N/A"
|
|
|
|
# Assign cleaned values to vram_info_dict
|
|
vram_info_dict["type"] = vram_type
|
|
vram_info_dict["vendor"] = vram_vendor
|
|
|
|
# Populate vram size with unit
|
|
vram_info_dict["size"] = vram_info["vram_size"]
|
|
vram_size_unit = "MB"
|
|
if self.logger.is_human_readable_format():
|
|
vram_info_dict["size"] = f"{vram_info['vram_size']} {vram_size_unit}"
|
|
|
|
if self.logger.is_json_format():
|
|
vram_info_dict["size"] = {
|
|
"value": vram_info["vram_size"],
|
|
"unit": vram_size_unit,
|
|
}
|
|
|
|
# Populate bit width
|
|
vram_info_dict["bit_width"] = vram_info["vram_bit_width"]
|
|
|
|
# Populate vram_max_bandwidth
|
|
vram_max_bw = vram_info["vram_max_bandwidth"]
|
|
vram_max_bw_unit = "GB/s"
|
|
if self.logger.is_human_readable_format():
|
|
vram_info_dict["max_bandwidth"] = (
|
|
f"{vram_max_bw} {vram_max_bw_unit if vram_max_bw != 'N/A' else ''}"
|
|
)
|
|
if self.logger.is_json_format():
|
|
vram_info_dict["max_bandwidth"] = {
|
|
"value": vram_max_bw,
|
|
"unit": vram_max_bw_unit,
|
|
}
|
|
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
logging.debug("Failed to get vram info for gpu %s | %s", gpu_id, e.get_error_info())
|
|
|
|
static_dict["vram"] = vram_info_dict
|
|
if args.cache:
|
|
try:
|
|
cache_info_list = amdsmi_interface.amdsmi_get_gpu_cache_info(args.gpu)["cache"]
|
|
logging.debug(f"cache_info dictionary = {cache_info_list}")
|
|
|
|
for index, cache_info in enumerate(cache_info_list):
|
|
new_cache_info = {"cache": index}
|
|
new_cache_info.update(cache_info)
|
|
cache_info_list[index] = new_cache_info
|
|
|
|
logging.debug(f"[after update] cache_info_list = {cache_info_list}")
|
|
|
|
cache_size_unit = "KB"
|
|
if self.logger.is_human_readable_format():
|
|
cache_info_dict_format = {}
|
|
for cache_dict in cache_info_list:
|
|
cache_index = "cache_" + str(cache_dict["cache"])
|
|
cache_info_dict_format[cache_index] = cache_dict
|
|
|
|
# Remove cache index from new dictionary
|
|
cache_info_dict_format[cache_index].pop("cache")
|
|
|
|
# Add cache_size unit
|
|
cache_size = (
|
|
f"{cache_info_dict_format[cache_index]['cache_size']} {cache_size_unit}"
|
|
)
|
|
cache_info_dict_format[cache_index]["cache_size"] = cache_size
|
|
|
|
# take cache_properties out of list -> display as string, removing brackets
|
|
cache_info_dict_format[cache_index]["cache_properties"] = ", ".join(
|
|
cache_info_dict_format[cache_index]["cache_properties"]
|
|
)
|
|
|
|
cache_info_list = cache_info_dict_format
|
|
logging.debug(f"[human readable] cache_info_list = {cache_info_list}")
|
|
|
|
# Add cache_size_unit to json output
|
|
if self.logger.is_json_format():
|
|
for cache_dict in cache_info_list:
|
|
cache_dict["cache_size"] = {
|
|
"value": cache_dict["cache_size"],
|
|
"unit": cache_size_unit,
|
|
}
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
cache_info_list = "N/A"
|
|
logging.debug(
|
|
"Failed to get cache info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
static_dict["cache_info"] = cache_info_list
|
|
|
|
if args.mem_carveout:
|
|
try:
|
|
uma_info = amdsmi_interface.amdsmi_get_gpu_uma_carveout_info(args.gpu)
|
|
logging.debug(f"UMA carveout info: {uma_info}")
|
|
|
|
if self.logger.is_json_format():
|
|
# JSON: show all options with current index
|
|
carveout_dict = {
|
|
"options": uma_info.get("options", []),
|
|
"current_index": uma_info.get("current_index", -1),
|
|
}
|
|
static_dict["mem_carveout"] = carveout_dict
|
|
elif self.logger.is_csv_format():
|
|
# CSV: show only current index
|
|
static_dict["mem_carveout_index"] = uma_info.get("current_index", -1)
|
|
else:
|
|
# Human readable: show all options with current marked
|
|
options = uma_info.get("options", [])
|
|
current_index = uma_info.get("current_index", -1)
|
|
if options:
|
|
formatted_options = []
|
|
for idx, option in enumerate(options):
|
|
marker = "*" if idx == current_index else " "
|
|
description = option.get("description", "N/A")
|
|
# Align indices: *[0] vs [1]
|
|
formatted_options.append(f" {marker}[{idx}] {description}")
|
|
static_dict["mem_carveout"] = "\n" + "\n".join(formatted_options)
|
|
else:
|
|
static_dict["mem_carveout"] = "N/A"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
# UMA carveout is only exposed by APU VBIOSes that support
|
|
# ATCS function 0xA. On dGPUs and Instinct parts (including
|
|
# MI300A) the sysfs attribute does not exist and the library
|
|
# returns NOT_SUPPORTED; surface a clearer reason than bare N/A.
|
|
not_supported = (
|
|
e.get_error_code()
|
|
== amdsmi_interface.amdsmi_wrapper.AMDSMI_STATUS_NOT_SUPPORTED
|
|
)
|
|
if not_supported and not (
|
|
self.logger.is_json_format() or self.logger.is_csv_format()
|
|
):
|
|
# Human-readable: give a descriptive reason. JSON/CSV
|
|
# consumers keep the legacy bare "N/A" for back-compat.
|
|
static_dict["mem_carveout"] = (
|
|
"N/A (UMA carveout is not supported on this ASIC/VBIOS)"
|
|
)
|
|
elif self.logger.is_csv_format():
|
|
static_dict["mem_carveout_index"] = "N/A"
|
|
else:
|
|
static_dict["mem_carveout"] = "N/A"
|
|
logging.debug(
|
|
"Failed to get mem carveout info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
|
|
# default to printing all clocks, if in current_platform_args; otherwise print specific clocks
|
|
if "clock" in current_platform_args and (
|
|
args.clock == True or isinstance(args.clock, list)
|
|
):
|
|
original_clock_args = (
|
|
args.clock
|
|
) # save original args.clock value, so we can reset for multiple devices
|
|
if isinstance(args.clock, bool):
|
|
args.clock = ["sys", "mem", "df", "soc", "dcef", "vclk0", "vclk1", "dclk0", "dclk1"]
|
|
|
|
if isinstance(args.clock, list):
|
|
# remove potential duplicates from list
|
|
args.clock = list(set(args.clock))
|
|
# check that clock is valid option
|
|
if "all" in args.clock or len(args.clock) == 0:
|
|
args.clock = [
|
|
"sys",
|
|
"mem",
|
|
"df",
|
|
"soc",
|
|
"dcef",
|
|
"vclk0",
|
|
"vclk1",
|
|
"dclk0",
|
|
"dclk1",
|
|
]
|
|
|
|
clk_dict = {
|
|
"sys": "N/A",
|
|
"mem": "N/A",
|
|
"df": "N/A",
|
|
"soc": "N/A",
|
|
"dcef": "N/A",
|
|
"vclk0": "N/A",
|
|
"vclk1": "N/A",
|
|
"dclk0": "N/A",
|
|
"dclk1": "N/A",
|
|
}
|
|
for clk in list(clk_dict.keys()):
|
|
if clk not in args.clock:
|
|
del clk_dict[clk]
|
|
for clk in args.clock:
|
|
if clk in self.helpers.convert_clock_type:
|
|
clk_type_conversion = self.helpers.convert_clock_type[clk]
|
|
else:
|
|
clk_type_conversion = "N/A"
|
|
output_format = self.helpers.get_output_format()
|
|
raise AmdSmiInvalidParameterException(
|
|
"static", clk_type, output_format
|
|
) # clk type given is bad
|
|
|
|
try:
|
|
frequencies = amdsmi_interface.amdsmi_get_clk_freq(
|
|
args.gpu, clk_type_conversion
|
|
)
|
|
# some clocks may have a sysfs file but no frequencies for whatever reason.
|
|
if len(frequencies["frequency"]) == 0:
|
|
freq_dict = "N/A"
|
|
continue
|
|
freq_dict = {}
|
|
current_level = frequencies["current"]
|
|
# The C library reports current = (uint32_t)-1 when the
|
|
# kernel exposes the pp_dpm_* table without a '*'
|
|
# current-level marker (e.g. SMU power-gated domains
|
|
# on gfx1151 APUs at idle). Surface that as N/A so
|
|
# the CLI doesn't show 4294967295 to users.
|
|
if current_level == 0xFFFFFFFF:
|
|
current_level = "N/A"
|
|
# Add current_level first for proper output ordering
|
|
freq_dict.update({"current_level": current_level})
|
|
# Add frequency_levels second
|
|
freq_dict.update({"frequency_levels": {}})
|
|
if frequencies["num_supported"] != 0:
|
|
for level in range(len(frequencies["frequency"])):
|
|
if frequencies["frequency"][level] != "N/A":
|
|
freq = str(
|
|
self.helpers.convert_SI_unit(
|
|
frequencies["frequency"][level],
|
|
AMDSMIHelpers.SI_Unit.MICRO,
|
|
)
|
|
)
|
|
if self.logger.is_json_format():
|
|
freq_dict["frequency_levels"].update(
|
|
{f"Level {level}": {"value": freq, "unit": "MHz"}}
|
|
)
|
|
else:
|
|
freq_dict["frequency_levels"].update(
|
|
{f"Level {level}": f"{freq} MHz"}
|
|
)
|
|
else:
|
|
freq_dict["frequency_levels"].update({f"Level {level}": "N/A"})
|
|
else:
|
|
freq_dict = "N/A"
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
freq_dict = "N/A"
|
|
logging.debug(
|
|
"Failed to get clock info for gpu %s | %s", gpu_id, e.get_error_info()
|
|
)
|
|
clk_dict[clk] = freq_dict
|
|
|
|
static_dict["clock"] = clk_dict
|
|
else:
|
|
raise amdsmi_exception.AmdSmiParameterException(args.clock, "list[str]")
|
|
# if original_clock_args is a boolean, set it back to the original value
|
|
if isinstance(original_clock_args, bool):
|
|
args.clock = original_clock_args
|
|
|
|
# Convert and store output by pid for csv format
|
|
multiple_devices_csv_override = False
|
|
if self.logger.is_csv_format():
|
|
# For NUMA data - flatten CPU affinity lists
|
|
if "numa" in static_dict and isinstance(static_dict["numa"], dict):
|
|
numa_data = static_dict.pop("numa")
|
|
multiple_devices_csv_override = True
|
|
|
|
# Get data
|
|
node = numa_data.get("node", "N/A")
|
|
affinity = numa_data.get("affinity", "N/A")
|
|
cpu_affinity = numa_data.get("cpu_affinity", {})
|
|
socket_affinity = numa_data.get("socket_affinity", {})
|
|
# Create a flattened row for list entry
|
|
row_dict = static_dict.copy()
|
|
|
|
if cpu_affinity and isinstance(cpu_affinity, dict):
|
|
for cpu_list_key in cpu_affinity.keys():
|
|
cpu_entry = cpu_affinity[cpu_list_key]
|
|
socket_entry = socket_affinity.get(
|
|
cpu_list_key, {"bitmask": "N/A", "cpu_cores_affinity": "N/A"}
|
|
)
|
|
row_dict.update(
|
|
{
|
|
"node": node,
|
|
"affinity": affinity,
|
|
"cpu_list": cpu_list_key,
|
|
"bitmask": cpu_entry.get("bitmask"),
|
|
"cpu_cores_affinity": cpu_entry.get("cpu_cores_affinity"),
|
|
"socket_bitmask": socket_entry.get("bitmask"),
|
|
"socket_cpu_cores_affinity": socket_entry.get("cpu_cores_affinity"),
|
|
}
|
|
)
|
|
self.logger.store_output(args.gpu, "values", row_dict)
|
|
self.logger.store_gpu_json_output.append(row_dict)
|
|
self.logger.store_multiple_device_output()
|
|
else:
|
|
row_dict.update(
|
|
{
|
|
"node": node,
|
|
"affinity": affinity,
|
|
"cpu_list": "N/A",
|
|
"bitmask": "N/A",
|
|
"cpu_cores_affinity": "N/A",
|
|
"socket_bitmask": "N/A",
|
|
"socket_cpu_cores_affinity": "N/A",
|
|
}
|
|
)
|
|
self.logger.store_output(args.gpu, "values", row_dict)
|
|
self.logger.store_gpu_json_output.append(row_dict)
|
|
self.logger.store_multiple_device_output()
|
|
# expand if ras blocks are populated
|
|
elif self.helpers.is_linux() and self.helpers.is_baremetal() and args.ras:
|
|
if isinstance(static_dict["ras"]["ecc_block_state"], list):
|
|
ecc_block_dicts = static_dict["ras"].pop("ecc_block_state")
|
|
multiple_devices_csv_override = True
|
|
for ecc_block_dict in ecc_block_dicts:
|
|
for key, value in ecc_block_dict.items():
|
|
self.logger.store_output(args.gpu, key, value)
|
|
self.logger.store_output(args.gpu, "values", static_dict)
|
|
self.logger.store_gpu_json_output.append(static_dict)
|
|
self.logger.store_multiple_device_output()
|
|
else:
|
|
# Store values if ras has an error
|
|
self.logger.store_output(args.gpu, "values", static_dict)
|
|
self.logger.store_gpu_json_output.append(static_dict)
|
|
else:
|
|
self.logger.store_output(args.gpu, "values", static_dict)
|
|
self.logger.store_gpu_json_output.append(static_dict)
|
|
elif self.logger.is_json_format():
|
|
self.logger.store_gpu_json_output.append(static_dict)
|
|
else:
|
|
# Store values in logger.output
|
|
self.logger.store_output(args.gpu, "values", static_dict)
|
|
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
if not self.logger.is_json_format():
|
|
self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override)
|
|
|
|
def _filter_nics_from_args(subcommand):
|
|
@functools.wraps(subcommand)
|
|
def wrapper(self, *args, **kwargs):
|
|
original_nic = None
|
|
if len(args) > 0:
|
|
original_nic = args[0].nic
|
|
nics, ainics = self._get_nics_from_args(args[0])
|
|
if len(nics) == 0:
|
|
args[0].nic = None
|
|
else:
|
|
args[0].nic = nics
|
|
result = subcommand(self, *args, **kwargs)
|
|
if len(args) > 0:
|
|
args[0].nic = original_nic
|
|
return result
|
|
|
|
return wrapper
|
|
|
|
@_filter_nics_from_args
|
|
def _static_brcm_nic(self, args, multiple_devices=False, nic=None):
|
|
"""Get Static information for target nic
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
nic (device_handle, optional): device_handle for target device. Defaults to None.
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
|
|
if nic:
|
|
args.nic = nic
|
|
|
|
# Handle multiple NICs
|
|
handled_multiple_nics, device_handle = self.helpers.handle_brcm_nics(
|
|
args, self.logger, self._static_brcm_nic
|
|
)
|
|
if handled_multiple_nics:
|
|
return # This function is recursive
|
|
args.nic = device_handle
|
|
if not args.nic:
|
|
return
|
|
|
|
# Get nic id for logging
|
|
nic_id = self.helpers.get_nic_id_from_device_handle(args.nic)
|
|
logging.debug(f"Static Arg information for NIC {nic_id} on {self.helpers.os_info()}")
|
|
|
|
static_dict = {}
|
|
if self.logger.is_json_format():
|
|
static_dict["ai_nic"] = int(nic_id)
|
|
|
|
if args.nic:
|
|
try:
|
|
nic_info = amdsmi_interface.amdsmi_get_nic_info(args.nic)
|
|
if nic_info:
|
|
static_dict["nic"] = {
|
|
"bdf": f"{nic_info['bdf']}",
|
|
"UUID": f"{nic_info['UUID']}",
|
|
"Device Name": f"{nic_info['Device Name']}",
|
|
"Part Number": f"{nic_info['Part Number']}",
|
|
"Firmware_Version": f"{nic_info['Firmware_Version']}",
|
|
}
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
static_dict["nic"] = "N/A"
|
|
logging.debug("Failed to get NIC %s | %s", nic_id, e.get_error_info())
|
|
|
|
multiple_devices_csv_override = False
|
|
if not self.logger.is_json_format():
|
|
self.logger.store_nic_output(args.nic, "values", static_dict)
|
|
else:
|
|
self.logger.store_nic_json_output.append(static_dict)
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
if not self.logger.is_json_format():
|
|
self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override)
|
|
|
|
def _filter_ainics_from_args(subcommand):
|
|
@functools.wraps(subcommand)
|
|
def wrapper(self, *args, **kwargs):
|
|
original_nic = None
|
|
if len(args) > 0:
|
|
original_nic = args[0].nic
|
|
nics, ainics = self._get_nics_from_args(args[0])
|
|
if len(ainics) == 0:
|
|
args[0].nic = None
|
|
else:
|
|
args[0].nic = ainics
|
|
result = subcommand(self, *args, **kwargs)
|
|
if len(args) > 0:
|
|
args[0].nic = original_nic
|
|
return result
|
|
|
|
return wrapper
|
|
|
|
@_filter_ainics_from_args
|
|
def _static_ainic(self, args, multiple_devices=False, nic=None):
|
|
"""Get Static information for target ainic
|
|
|
|
Args:
|
|
args (Namespace): Namespace containing the parsed CLI args
|
|
multiple_devices (bool, optional): True if checking for multiple devices. Defaults to False.
|
|
nic (device_handle, optional): device_handle for target device. Defaults to None.
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
|
|
if nic:
|
|
args.nic = nic
|
|
|
|
# Handle multiple NICs
|
|
handled_multiple_nics, device_handle = self.helpers.handle_ainics(
|
|
args, self.logger, self._static_ainic
|
|
)
|
|
if handled_multiple_nics:
|
|
return # This function is recursive
|
|
args.nic = device_handle
|
|
if not args.nic:
|
|
return
|
|
|
|
# Get nic id for logging
|
|
nic_id = self.helpers.get_ainic_id_from_device_handle(args.nic)
|
|
logging.debug(f"Static Arg information for NIC {nic_id} on {self.helpers.os_info()}")
|
|
|
|
static_dict = {}
|
|
if self.logger.is_json_format():
|
|
static_dict["ai_nic"] = int(nic_id)
|
|
|
|
if args.nic:
|
|
try:
|
|
nic_info = amdsmi_interface.amdsmi_get_ainic_info(args.nic, True)
|
|
info_filter = []
|
|
if hasattr(args, "asic") and getattr(args, "asic"):
|
|
info_filter.append("asic")
|
|
if hasattr(args, "bus") and getattr(args, "bus"):
|
|
info_filter.append("bus")
|
|
if hasattr(args, "driver") and getattr(args, "driver"):
|
|
info_filter.append("driver")
|
|
if hasattr(args, "numa") and getattr(args, "numa"):
|
|
info_filter.append("numa")
|
|
if len(info_filter) == 0 or len(info_filter) == 4:
|
|
static_dict["nic"] = nic_info
|
|
else:
|
|
nic_info_filtered = {}
|
|
for attr in info_filter: # remove all attributes except the one in info_filter:
|
|
nic_info_filtered = nic_info_filtered | {
|
|
key: value for key, value in nic_info.items() if key.lower() == attr
|
|
}
|
|
static_dict["nic"] = nic_info_filtered
|
|
except amdsmi_exception.AmdSmiLibraryException as e:
|
|
static_dict["nic"] = "N/A"
|
|
logging.debug("Failed to get NIC %s | %s", nic_id, e.get_error_info())
|
|
|
|
multiple_devices_csv_override = False
|
|
if not self.logger.is_json_format():
|
|
self.logger.store_ainic_output(args.nic, "values", static_dict)
|
|
else:
|
|
self.logger.store_nic_json_output.append(static_dict)
|
|
if multiple_devices:
|
|
self.logger.store_multiple_device_output()
|
|
return # Skip printing when there are multiple devices
|
|
if not self.logger.is_json_format():
|
|
self.logger.print_output(multiple_device_enabled=multiple_devices_csv_override)
|
|
|
|
def _static_nics(self, args, multiple_devices, nic):
|
|
if hasattr(args, "nic") and args.nic == None:
|
|
nic = None
|
|
if self.helpers.is_ainic_initialized():
|
|
nic = self.device_handles_ainics
|
|
if self.helpers.is_brcm_nic_initialized():
|
|
nic = self.device_handles_brcm_nics
|
|
args.nic = nic
|
|
return False
|
|
else:
|
|
if (
|
|
not self.helpers.is_ainic_initialized()
|
|
and not self.helpers.is_brcm_nic_initialized()
|
|
):
|
|
return False
|
|
self.logger.output = {}
|
|
self.logger.clear_multiple_devices_output()
|
|
if self.helpers.is_ainic_initialized():
|
|
self._static_ainic(args, multiple_devices, nic)
|
|
if self.helpers.is_brcm_nic_initialized():
|
|
self._static_brcm_nic(args, multiple_devices, nic)
|
|
return True
|
|
|
|
def static(
|
|
self,
|
|
args,
|
|
multiple_devices=False,
|
|
gpu=None,
|
|
asic=None,
|
|
bus=None,
|
|
vbios=None,
|
|
limit=None,
|
|
driver=None,
|
|
ras=None,
|
|
board=None,
|
|
numa=None,
|
|
vram=None,
|
|
cache=None,
|
|
partition=None,
|
|
dfc_ucode=None,
|
|
fb_info=None,
|
|
num_vf=None,
|
|
cpu=None,
|
|
nic=None,
|
|
interface_ver=None,
|
|
soc_pstate=None,
|
|
xgmi_plpd=None,
|
|
process_isolation=None,
|
|
clock=None,
|
|
profile=None,
|
|
mem_carveout=None,
|
|
):
|
|
"""Get Static information for target gpu and cpu
|
|
|
|
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.
|
|
ras (bool, optional): Value override for args.ras. Defaults to None.
|
|
board (bool, optional): Value override for args.board. Defaults to None.
|
|
numa (bool, optional): Value override for args.numa. Defaults to None.
|
|
vram (bool, optional): Value override for args.vram. Defaults to None.
|
|
cache (bool, optional): Value override for args.cache. Defaults to None.
|
|
partition (bool, optional): Value override for args.partition. Defaults to None.
|
|
dfc_ucode (bool, optional): Value override for args.dfc_ucode. Defaults to None.
|
|
fb_info (bool, optional): Value override for args.fb_info. Defaults to None.
|
|
num_vf (bool, optional): Value override for args.num_vf. Defaults to None.
|
|
cpu (cpu_handle, optional): cpu_handle for target device. Defaults to None.
|
|
nic (nic_handle, optional): nic_handle for target device. Defaults to None.
|
|
interface_ver (bool, optional): Value override for args.interface_ver. Defaults to None
|
|
soc_pstate (bool, optional): Value override for args.soc_pstate. Defaults to None.
|
|
xgmi_plpd (bool, optional): Value override for args.xgmi_plpd. Defaults to None.
|
|
process_isolation (bool, optional): Value override for args.process_isolation. Defaults to None.
|
|
Raises:
|
|
IndexError: Index error if gpu list is empty
|
|
|
|
Returns:
|
|
None: Print output via AMDSMILogger to destination
|
|
"""
|
|
# Mutually exclusive arguments
|
|
if cpu:
|
|
args.cpu = cpu
|
|
if gpu:
|
|
args.gpu = gpu
|
|
if nic:
|
|
args.nic = nic
|
|
|
|
if self._static_nics(args, multiple_devices, nic):
|
|
return True # we do not want to print cpu or gpu if user only wanted nic
|
|
|
|
if (hasattr(args, "cpu") and args.cpu) or (hasattr(args, "gpu") and args.gpu):
|
|
args.nic = None # we do not want to output nic at the end if user wants only cpu or gpu
|
|
|
|
# Check if a CPU argument has been set
|
|
cpu_args_enabled = False
|
|
cpu_attributes = ["smu", "interface_ver"]
|
|
for attr in cpu_attributes:
|
|
if hasattr(args, attr):
|
|
if getattr(args, attr):
|
|
cpu_args_enabled = True
|
|
break
|
|
|
|
# Check if a GPU argument has been set
|
|
gpu_args_enabled = False
|
|
gpu_attributes = [
|
|
"asic",
|
|
"bus",
|
|
"vbios",
|
|
"limit",
|
|
"driver",
|
|
"ras",
|
|
"board",
|
|
"numa",
|
|
"vram",
|
|
"cache",
|
|
"partition",
|
|
"dfc_ucode",
|
|
"fb_info",
|
|
"num_vf",
|
|
"soc_pstate",
|
|
"xgmi_plpd",
|
|
"process_isolation",
|
|
"clock",
|
|
"profile",
|
|
"mem_carveout",
|
|
]
|
|
for attr in gpu_attributes:
|
|
if hasattr(args, attr):
|
|
if getattr(args, attr):
|
|
gpu_args_enabled = True
|
|
break
|
|
|
|
# Handle CPU and GPU initialization cases
|
|
if self.helpers.is_amd_hsmp_initialized() and self.helpers.is_amdgpu_initialized():
|
|
# Print out all CPU and all GPU static info only if no device was specified.
|
|
# If a GPU or CPU argument is provided only print out the specified device.
|
|
if args.cpu == None and args.gpu == None:
|
|
if not cpu_args_enabled and not gpu_args_enabled:
|
|
args.cpu = self.cpu_handles
|
|
args.gpu = self.device_handles
|
|
|
|
# Handle cases where the user has only specified an argument and no specific device
|
|
if args.gpu == None and gpu_args_enabled:
|
|
args.gpu = self.device_handles
|
|
if args.cpu == None and cpu_args_enabled:
|
|
args.cpu = self.cpu_handles
|
|
|
|
if args.cpu:
|
|
self.static_cpu(args, multiple_devices, cpu, interface_ver)
|
|
if args.gpu:
|
|
self.logger.output = {}
|
|
self.logger.clear_multiple_devices_output()
|
|
self.static_gpu(
|
|
args,
|
|
multiple_devices,
|
|
gpu,
|
|
asic,
|
|
bus,
|
|
vbios,
|
|
limit,
|
|
driver,
|
|
ras,
|
|
board,
|
|
numa,
|
|
vram,
|
|
cache,
|
|
partition,
|
|
dfc_ucode,
|
|
fb_info,
|
|
num_vf,
|
|
soc_pstate,
|
|
xgmi_plpd,
|
|
process_isolation,
|
|
clock,
|
|
profile,
|
|
mem_carveout,
|
|
)
|
|
elif self.helpers.is_amd_hsmp_initialized(): # Only CPU is initialized
|
|
if args.cpu == None:
|
|
args.cpu = self.cpu_handles
|
|
|
|
self.static_cpu(args, multiple_devices, cpu, interface_ver)
|
|
elif self.helpers.is_amdgpu_initialized(): # Only GPU is initialized
|
|
if args.gpu == None:
|
|
args.gpu = self.device_handles
|
|
|
|
self.logger.clear_multiple_devices_output()
|
|
self.static_gpu(
|
|
args,
|
|
multiple_devices,
|
|
gpu,
|
|
asic,
|
|
bus,
|
|
vbios,
|
|
limit,
|
|
driver,
|
|
ras,
|
|
board,
|
|
numa,
|
|
vram,
|
|
cache,
|
|
partition,
|
|
dfc_ucode,
|
|
fb_info,
|
|
num_vf,
|
|
soc_pstate,
|
|
xgmi_plpd,
|
|
process_isolation,
|
|
clock,
|
|
profile,
|
|
mem_carveout,
|
|
)
|
|
|
|
if hasattr(args, "nic") and args.nic:
|
|
self.logger.output = {}
|
|
self.logger.clear_multiple_devices_output()
|
|
self._static_ainic(args, multiple_devices, nic)
|
|
self._static_brcm_nic(args, multiple_devices, nic)
|
|
|
|
if self.logger.is_json_format():
|
|
self.logger.combine_arrays_to_json()
|