Merge amd-dev into amd-master 20230418
Change-Id: I59dbdc309f230584ad89ce52d7124ed6f4668310 Signed-off-by: Galantsev, Dmitrii <dmitrii.galantsev@amd.com>
This commit is contained in:
@@ -19,6 +19,7 @@ add_custom_command(
|
||||
${PY_PACKAGE_DIR}/amdsmi_init.py
|
||||
${PY_PACKAGE_DIR}/amdsmi_logger.py
|
||||
${PY_PACKAGE_DIR}/amdsmi_parser.py
|
||||
${PY_PACKAGE_DIR}/amdsmi_cli_exceptions.py
|
||||
${PY_PACKAGE_DIR}/BDF.py
|
||||
DEPENDS amdsmi_cli
|
||||
COMMAND mkdir -p ${PY_PACKAGE_DIR}/
|
||||
@@ -30,6 +31,7 @@ add_custom_command(
|
||||
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_init.py ${PY_PACKAGE_DIR}/
|
||||
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_logger.py ${PY_PACKAGE_DIR}/
|
||||
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_parser.py ${PY_PACKAGE_DIR}/
|
||||
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/amdsmi_cli_exceptions.py ${PY_PACKAGE_DIR}/
|
||||
COMMAND ln -Pf ${CMAKE_CURRENT_SOURCE_DIR}/BDF.py ${PY_PACKAGE_DIR}/)
|
||||
|
||||
# The CLI requires the python amdsmi wrapper to be installed
|
||||
@@ -44,6 +46,7 @@ add_custom_target(
|
||||
${PY_PACKAGE_DIR}/amdsmi_init.py
|
||||
${PY_PACKAGE_DIR}/amdsmi_logger.py
|
||||
${PY_PACKAGE_DIR}/amdsmi_parser.py
|
||||
${PY_PACKAGE_DIR}/amdsmi_cli_exceptions.py
|
||||
${PY_PACKAGE_DIR}/BDF.py)
|
||||
|
||||
install(
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.0.2"
|
||||
__version__ = "0.0.3"
|
||||
|
||||
+37
-18
@@ -26,6 +26,20 @@ import sys
|
||||
from amdsmi_commands import AMDSMICommands
|
||||
from amdsmi_parser import AMDSMIParser
|
||||
from amdsmi_logger import AMDSMILogger
|
||||
import amdsmi_cli_exceptions
|
||||
from amdsmi import amdsmi_interface
|
||||
|
||||
def _print_error(e, destination):
|
||||
if destination == 'stdout':
|
||||
print(e)
|
||||
else:
|
||||
f = open(destination, "w")
|
||||
f.write(e)
|
||||
f.close()
|
||||
print("Error occured. Result written to " +
|
||||
str(destination) + " file")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Set compatability mode based on which cli mapping user selects
|
||||
@@ -50,23 +64,28 @@ if __name__ == "__main__":
|
||||
amd_smi_commands.set_value,
|
||||
amd_smi_commands.reset,
|
||||
amd_smi_commands.rocm_smi)
|
||||
try:
|
||||
args = amd_smi_parser.parse_args(args=None if sys.argv[1:] else ['--help'])
|
||||
|
||||
args = amd_smi_parser.parse_args(args=None if sys.argv[1:] else ['--help'])
|
||||
# Handle command modifiers before subcommand execution
|
||||
if args.json:
|
||||
amd_smi_commands.logger.format = amd_smi_commands.logger.LoggerFormat.json.value
|
||||
if args.csv:
|
||||
amd_smi_commands.logger.format = amd_smi_commands.logger.LoggerFormat.csv.value
|
||||
if args.file:
|
||||
amd_smi_commands.logger.destination = args.file
|
||||
if args.loglevel:
|
||||
logging_dict = {'DEBUG' : logging.DEBUG,
|
||||
'INFO' : logging.INFO,
|
||||
'WARNING': logging.WARNING,
|
||||
'ERROR': logging.ERROR,
|
||||
'CRITICAL': logging.CRITICAL}
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging_dict[args.loglevel])
|
||||
|
||||
# Handle command modifiers before subcommand execution
|
||||
if args.json:
|
||||
amd_smi_commands.logger.format = amd_smi_commands.logger.LoggerFormat.json.value
|
||||
if args.csv:
|
||||
amd_smi_commands.logger.format = amd_smi_commands.logger.LoggerFormat.csv.value
|
||||
if args.file:
|
||||
amd_smi_commands.logger.destination = args.file
|
||||
if args.loglevel:
|
||||
logging_dict = {'DEBUG' : logging.DEBUG,
|
||||
'INFO' : logging.INFO,
|
||||
'WARNING': logging.WARNING,
|
||||
'ERROR': logging.ERROR,
|
||||
'CRITICAL': logging.CRITICAL}
|
||||
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging_dict[args.loglevel])
|
||||
|
||||
# Execute subcommands
|
||||
args.func(args)
|
||||
# Execute subcommands
|
||||
args.func(args)
|
||||
except amdsmi_cli_exceptions.AmdSmiException as e:
|
||||
_print_error(str(e), amd_smi_commands.logger.destination)
|
||||
except amdsmi_interface.AmdSmiLibraryException as e:
|
||||
exc = amdsmi_cli_exceptions.AmdSmiAMDSMIErrorException(amd_smi_commands.logger.format, e.get_error_code())
|
||||
_print_error(str(exc), amd_smi_commands.logger.destination)
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
#!/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.
|
||||
#
|
||||
|
||||
import json
|
||||
|
||||
AMDSMI_ERROR_MESSAGES = {
|
||||
0: "Sucess",
|
||||
1: "Invalid parameters",
|
||||
2: "Command not supported",
|
||||
3: "Command not yet implemented",
|
||||
4: "Failed load module",
|
||||
5: "Failed load symbole",
|
||||
6: "Drm error",
|
||||
7: "API call failed",
|
||||
8: "Timeout in API call",
|
||||
9: "Retry operation",
|
||||
10: "Permission Denied",
|
||||
11: "Interrupt ocurred during execution",
|
||||
12: "I/O Error",
|
||||
13: "Address fault",
|
||||
14: "Error opening file",
|
||||
15: "Not enough memory",
|
||||
16: "Internal error",
|
||||
17: "Out of bounds",
|
||||
18: "Initialization error",
|
||||
19: "Internal reference counter exceeded",
|
||||
# Reserved for future error messages
|
||||
30: "Device busy",
|
||||
31: "Device Not found",
|
||||
32: "Device not initialized",
|
||||
33: "No more free slot",
|
||||
# Reserved for future error messages
|
||||
40: "No data was found for given input",
|
||||
41: "Insufficient size for operation",
|
||||
42: "Unexpected size of data was read",
|
||||
43: "The data read or provided was unexpected",
|
||||
}
|
||||
|
||||
def _get_error_message(error_code):
|
||||
if abs(error_code) in AMDSMI_ERROR_MESSAGES:
|
||||
return AMDSMI_ERROR_MESSAGES[abs(error_code)]
|
||||
return "Generic error"
|
||||
|
||||
class AmdSmiException(Exception):
|
||||
def __init__(self):
|
||||
self.json_message = {}
|
||||
self.csv_message = ''
|
||||
self.stdout_message = ''
|
||||
self.message = ''
|
||||
self.output_format = ''
|
||||
|
||||
def __str__(self):
|
||||
# Return message according to the current output format
|
||||
if self.output_format == 'json':
|
||||
self.message = json.dumps(self.json_message)
|
||||
elif self.output_format == 'csv':
|
||||
self.message = self.csv_message
|
||||
else:
|
||||
self.message = self.stdout_message
|
||||
|
||||
return self.message
|
||||
|
||||
|
||||
class AmdSmiInvalidCommandException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -1
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"Command '{self.command}' is invalid. Run '--help' for more info."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
|
||||
class AmdSmiInvalidParameterException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -2
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"Parameter '{self.command}' is invalid. Run '--help' for more info."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
|
||||
class AmdSmiDeviceNotFoundException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -3
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"GPU Device with GPU_INDEX '{self.command}' cannot be found on the system."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
class AmdSmiInvalidFilePathException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -4
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"Path '{self.command}' cannot be found."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
|
||||
class AmdSmiInvalidParameterValueException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -5
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"Value '{self.command}' is not of valid type or format. Run '--help' for more info."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
|
||||
class AmdSmiMissingParameterValueException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -6
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"Parameter '{self.command}' requires a value. Run '--help' for more info."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
|
||||
class AmdSmiParameterNotSupportedException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -8
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"Parameter '{self.command}' is not supported on the system. Run '--help' for more info."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
class AmdSmiUnknownErrorException(AmdSmiException):
|
||||
def __init__(self, command, outputformat):
|
||||
super().__init__()
|
||||
self.value = -100
|
||||
self.command = command
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = "An unknown error has occurred. Run 'help' for more info."
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
|
||||
class AmdSmiAMDSMIErrorException(AmdSmiException):
|
||||
def __init__(self, outputformat, error_code):
|
||||
super().__init__()
|
||||
self.value = -1000 - abs(error_code)
|
||||
self.smilibcode = error_code
|
||||
self.output_format = outputformat
|
||||
|
||||
common_message = f"AMDSMI has returned error '{self.value}' - '{AMDSMI_ERROR_MESSAGES[abs(self.smilibcode)]}'"
|
||||
|
||||
self.json_message["error"] = common_message
|
||||
self.json_message["code"] = self.value
|
||||
self.csv_message = f"error,code\n{common_message}, {self.value}"
|
||||
self.stdout_message = f"{common_message} Error code: {self.value}"
|
||||
+490
-432
Filskillnaden har hållits tillbaka eftersom den är för stor
Load Diff
+43
-17
@@ -22,6 +22,7 @@
|
||||
|
||||
import logging
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
|
||||
from pathlib import Path
|
||||
@@ -118,6 +119,20 @@ class AMDSMIHelpers():
|
||||
return self._is_windows
|
||||
|
||||
|
||||
def get_output_format(self):
|
||||
"""Returns the output format read from sys.argv
|
||||
Returns:
|
||||
str: outputformat
|
||||
"""
|
||||
args = sys.argv[1:]
|
||||
outputformat = "human"
|
||||
if "--json" in args or "--j" in args:
|
||||
outputformat = "json"
|
||||
elif "--csv" in args or "--c" in args:
|
||||
outputformat = "csv"
|
||||
return outputformat
|
||||
|
||||
|
||||
def get_gpu_choices(self):
|
||||
"""Return dictionary of possible GPU choices and string of the output:
|
||||
Dictionary will be in format: gpus[ID] : (BDF, UUID, Device Handle)
|
||||
@@ -307,11 +322,34 @@ class AMDSMIHelpers():
|
||||
return asic_info['vendor_id'] == AMD_VENDOR_ID
|
||||
|
||||
|
||||
def is_valid_clock_type(self, clock_type):
|
||||
if clock_type in amdsmi_interface.amdsmi_wrapper.amdsmi_clk_type_t__enumvalues:
|
||||
return True, amdsmi_interface.amdsmi_wrapper.amdsmi_clk_type_t__enumvalues.keys()
|
||||
else:
|
||||
return False, amdsmi_interface.amdsmi_wrapper.amdsmi_clk_type_t__enumvalues.keys()
|
||||
def get_perf_levels(self):
|
||||
perf_levels_str = [clock.name for clock in amdsmi_interface.AmdSmiDevPerfLevel]
|
||||
perf_levels_int = list(set(clock.value for clock in amdsmi_interface.AmdSmiDevPerfLevel))
|
||||
return perf_levels_str, perf_levels_int
|
||||
|
||||
|
||||
def get_clock_types(self):
|
||||
clock_types_str = [clock.name for clock in amdsmi_interface.AmdSmiClkType]
|
||||
clock_types_int = list(set(clock.value for clock in amdsmi_interface.AmdSmiClkType))
|
||||
return clock_types_str, clock_types_int
|
||||
|
||||
|
||||
def validate_clock_type(self, input_clock_type):
|
||||
valid_clock_types_str, valid_clock_types_int = self.get_clock_types()
|
||||
|
||||
valid_clock_input = False
|
||||
if isinstance(input_clock_type, str):
|
||||
for clock_type in valid_clock_types_str:
|
||||
if input_clock_type.lower() == clock_type.lower():
|
||||
input_clock_type = clock_type # Set input_clock_type to enum value in AmdSmiClkType
|
||||
valid_clock_input = True
|
||||
break
|
||||
elif isinstance(input_clock_type, int):
|
||||
if input_clock_type in valid_clock_types_int:
|
||||
input_clock_type = amdsmi_interface.AmdSmiClkType(input_clock_type)
|
||||
valid_clock_input = True
|
||||
|
||||
return valid_clock_input, input_clock_type
|
||||
|
||||
|
||||
def confirm_out_of_spec_warning(self, auto_respond=False):
|
||||
@@ -348,15 +386,3 @@ class AMDSMIHelpers():
|
||||
return True, profile_presets[profile]
|
||||
else:
|
||||
return False, profile_presets.values()
|
||||
|
||||
|
||||
def get_perf_level(self, device_handle):
|
||||
""" Return the current performance level of a given device
|
||||
|
||||
@param device_handle: DRM device identifier
|
||||
"""
|
||||
|
||||
try:
|
||||
ret = amdsmi_interface.amdsmi_dev_get_perf_level(device_handle)
|
||||
except amdsmi_exception.AmdSmiLibraryException as e:
|
||||
raise ValueError(self, f"Unable to get performance level of {device_handle}")
|
||||
|
||||
+127
-95
@@ -26,22 +26,31 @@ import errno
|
||||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
from _version import __version__
|
||||
from amdsmi_helpers import AMDSMIHelpers
|
||||
import amdsmi_cli_exceptions
|
||||
|
||||
|
||||
class AMDSMIParser(argparse.ArgumentParser):
|
||||
"""Unified Parser for AMDSMI CLI.
|
||||
This parser doesn't access amdsmi's lib directly,but via AMDSMIHelpers,
|
||||
this allows for us to use this parser with future OS & Platform integration.
|
||||
|
||||
Args:
|
||||
argparse (ArgumentParser): argparse.ArgumentParser
|
||||
"""
|
||||
def __init__(self, version, discovery, static, firmware, bad_pages, metric,
|
||||
process, profile, event, topology, set_value, reset, rocmsmi):
|
||||
|
||||
# Helper variables
|
||||
self.amdsmi_helpers = AMDSMIHelpers()
|
||||
self.gpu_choices, self.gpu_choices_str = self.amdsmi_helpers.get_gpu_choices()
|
||||
self.helpers = AMDSMIHelpers()
|
||||
self.gpu_choices, self.gpu_choices_str = self.helpers.get_gpu_choices()
|
||||
self.vf_choices = ['3', '2', '1']
|
||||
|
||||
version_string = f"Version: {__version__}"
|
||||
platform_string = f"Platform: {self.amdsmi_helpers.os_info()}"
|
||||
platform_string = f"Platform: {self.helpers.os_info()}"
|
||||
|
||||
# Adjust argument parser options
|
||||
super().__init__(
|
||||
@@ -80,8 +89,8 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
if int_value.isdigit(): # Is digit works only on positive numbers
|
||||
return int(int_value)
|
||||
else:
|
||||
raise argparse.ArgumentTypeError(
|
||||
f"invalid input:{int_value} integer provided must be positive")
|
||||
outputformat = self.helpers.get_output_format()
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidParameterValueException(int_value, outputformat)
|
||||
|
||||
|
||||
def _check_output_file_path(self):
|
||||
@@ -92,6 +101,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
If the path is a file and it doesn't exist create and return the file path
|
||||
"""
|
||||
class CheckOutputFilePath(argparse.Action):
|
||||
outputformat = self.helpers.get_output_format()
|
||||
# Checks the values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
path = Path(values)
|
||||
@@ -99,8 +109,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
if path.parent.is_dir():
|
||||
path.touch()
|
||||
else:
|
||||
raise argparse.ArgumentTypeError(
|
||||
f"Invalid path:{path} Could not find parent directory of given path")
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidFilePathException(path, CheckOutputFilePath.outputformat)
|
||||
|
||||
if path.is_dir():
|
||||
path = path / f"{int(time.time())}-amdsmi-output.txt"
|
||||
@@ -109,8 +118,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
elif path.is_file():
|
||||
setattr(args, self.dest, path)
|
||||
else:
|
||||
raise argparse.ArgumentTypeError(
|
||||
f"Invalid path:{path} Could not determine if value given is a valid path")
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidFilePathException(path, CheckOutputFilePath.outputformat)
|
||||
return CheckOutputFilePath
|
||||
|
||||
|
||||
@@ -142,28 +150,27 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
|
||||
def _check_watch_selected(self):
|
||||
""" Argument action validator:
|
||||
Validate that the -w/--watch argument was selected
|
||||
""" Validate that the -w/--watch argument was selected
|
||||
This is because -W/--watch_time and -i/--iterations are dependent on watch
|
||||
"""
|
||||
class _WatchSelectedAction(argparse.Action):
|
||||
class WatchSelectedAction(argparse.Action):
|
||||
# Checks the values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
if args.watch is None:
|
||||
raise argparse.ArgumentError(self,
|
||||
f"Invalid argument: '{self.dest}' needs to be paired with -w/--watch")
|
||||
setattr(args, self.dest, values)
|
||||
return _WatchSelectedAction
|
||||
|
||||
raise argparse.ArgumentError(self, f"invalid argument: '{self.dest}' needs to be paired with -w/--watch")
|
||||
else:
|
||||
setattr(args, self.dest, values)
|
||||
return WatchSelectedAction
|
||||
|
||||
def _gpu_select(self, gpu_choices):
|
||||
""" Argument action validator:
|
||||
Custom argparse action to return the device handle(s) for the gpu(s) selected
|
||||
""" Custom argparse action to return the device handle(s) for the gpu(s) selected
|
||||
This will set the destination (args.gpu) to a list of 1 or more device handles
|
||||
If 1 or more device handles are not found then raise an ArgumentError for the first invalid gpu seen
|
||||
"""
|
||||
amdsmi_helpers = self.amdsmi_helpers
|
||||
|
||||
amdsmi_helpers = self.helpers
|
||||
class _GPUSelectAction(argparse.Action):
|
||||
ouputformat=self.helpers.get_output_format()
|
||||
# Checks the values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
status, selected_device_handles = amdsmi_helpers.get_device_handles_from_gpu_selections(gpu_selections=values,
|
||||
@@ -171,8 +178,11 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
if status:
|
||||
setattr(args, self.dest, selected_device_handles)
|
||||
else:
|
||||
invalid_selection = selected_device_handles
|
||||
raise argparse.ArgumentError(self, f"invalid choice: '{invalid_selection}' (see available choices with -h)")
|
||||
if selected_device_handles == '':
|
||||
raise amdsmi_cli_exceptions.AmdSmiMissingParameterValueException("--gpu", _GPUSelectAction.ouputformat)
|
||||
else:
|
||||
raise amdsmi_cli_exceptions.AmdSmiDeviceNotFoundException(selected_device_handles, _GPUSelectAction.ouputformat)
|
||||
|
||||
return _GPUSelectAction
|
||||
|
||||
|
||||
@@ -195,6 +205,21 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"])
|
||||
|
||||
|
||||
def _add_watch_arguments(self, subcommand_parser):
|
||||
# Device arguments help text
|
||||
watch_help = "Reprint the command in a loop of Interval seconds"
|
||||
watch_time_help = "The total time to watch the given command"
|
||||
iterations_help = "Total number of iterations to loop on the given command"
|
||||
|
||||
# Mutually Exclusive Args within the subparser
|
||||
subcommand_parser.add_argument('-w', '--watch', action='store', metavar='loop_time',
|
||||
type=self._positive_int, required=False, help=watch_help)
|
||||
subcommand_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='total_loop_time',
|
||||
type=self._positive_int, required=False, help=watch_time_help)
|
||||
subcommand_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='number_of_iterations',
|
||||
type=self._positive_int, required=False, help=iterations_help)
|
||||
|
||||
|
||||
def _add_device_arguments(self, subcommand_parser, required=False):
|
||||
# Device arguments help text
|
||||
gpu_help = f"Select a GPU ID, BDF, or UUID from the possible choices:\n{self.gpu_choices_str}"
|
||||
@@ -206,7 +231,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
device_args.add_argument('-g', '--gpu', action=self._gpu_select(self.gpu_choices),
|
||||
nargs='+', help=gpu_help)
|
||||
|
||||
if self.amdsmi_helpers.is_hypervisor():
|
||||
if self.helpers.is_hypervisor():
|
||||
device_args.add_argument('-v', '--vf', action='store', nargs='+',
|
||||
help=vf_help, choices=self.vf_choices)
|
||||
|
||||
@@ -287,13 +312,13 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
static_parser.add_argument('-c', '--caps', action='store_true', required=False, help=caps_help)
|
||||
|
||||
# Options to display on Hypervisors and Baremetal
|
||||
if self.amdsmi_helpers.is_hypervisor() or self.amdsmi_helpers.is_baremetal():
|
||||
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
|
||||
static_parser.add_argument('-r', '--ras', action='store_true', required=False, help=ras_help)
|
||||
if self.amdsmi_helpers.is_linux():
|
||||
if self.helpers.is_linux():
|
||||
static_parser.add_argument('-B', '--board', action='store_true', required=False, help=board_help)
|
||||
|
||||
# Options to only display on a Hypervisor
|
||||
if self.amdsmi_helpers.is_hypervisor():
|
||||
if self.helpers.is_hypervisor():
|
||||
static_parser.add_argument('-d', '--dfc-ucode', action='store_true', required=False, help=dfc_help)
|
||||
static_parser.add_argument('-f', '--fb-info', action='store_true', required=False, help=fb_help)
|
||||
static_parser.add_argument('-n', '--num-vf', action='store_true', required=False, help=num_vf_help)
|
||||
@@ -323,12 +348,12 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
firmware_parser.add_argument('-f', '--ucode-list', '--fw-list', dest='fw_list', action='store_true', required=False, help=fw_list_help, default=True)
|
||||
|
||||
# Options to only display on a Hypervisor
|
||||
if self.amdsmi_helpers.is_hypervisor():
|
||||
if self.helpers.is_hypervisor():
|
||||
firmware_parser.add_argument('-e', '--error-records', action='store_true', required=False, help=err_records_help)
|
||||
|
||||
|
||||
def _add_bad_pages_parser(self, subparsers, func):
|
||||
if not (self.amdsmi_helpers.is_baremetal() and self.amdsmi_helpers.is_linux()):
|
||||
if not (self.helpers.is_baremetal() and self.helpers.is_linux()):
|
||||
# The bad_pages subcommand is only applicable to Linux Baremetal systems
|
||||
return
|
||||
|
||||
@@ -343,7 +368,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
un_res_help = "Displays unreservable pages"
|
||||
|
||||
# Create bad_pages subparser
|
||||
bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help, aliases=['bad_pages'])
|
||||
bad_pages_parser = subparsers.add_parser('bad-pages', help=bad_pages_help, description=bad_pages_subcommand_help)
|
||||
bad_pages_parser._optionals.title = bad_pages_optionals_title
|
||||
bad_pages_parser.formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=80, width=90)
|
||||
bad_pages_parser.set_defaults(func=func)
|
||||
@@ -367,9 +392,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
# Optional arguments help text
|
||||
usage_help = "Displays engine usage information"
|
||||
watch_help = "Reprint the command in a loop of Interval seconds"
|
||||
watch_time_help = "The total time to watch the given command"
|
||||
iterations_help = "Total number of iterations to loop on the given command"
|
||||
|
||||
# Help text for Arguments only Available on Virtual OS and Baremetal platforms
|
||||
fb_usage_help = "Total and used framebuffer"
|
||||
@@ -384,7 +406,6 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
# Help text for Arguments only on Linux Baremetal platforms
|
||||
fan_help = "Current fan speed"
|
||||
pcie_usage_help = "Estimated PCIe link usage"
|
||||
vc_help = "Display voltage curve"
|
||||
overdrive_help = "Current GPU clock overdrive level"
|
||||
mo_help = "Current memory clock overdrive level"
|
||||
@@ -409,21 +430,18 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
# Add Device args
|
||||
self._add_device_arguments(metric_parser, required=False)
|
||||
|
||||
# Add Watch args
|
||||
self._add_watch_arguments(metric_parser)
|
||||
|
||||
# Optional Args
|
||||
metric_parser.add_argument('-u', '--usage', action='store_true', required=False, help=usage_help)
|
||||
metric_parser.add_argument('-w', '--watch', action='store', metavar='Interval',
|
||||
type=self._positive_int, required=False, help=watch_help)
|
||||
metric_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='Duration',
|
||||
type=self._positive_int, required=False, help=watch_time_help)
|
||||
metric_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='Iterations',
|
||||
type=self._positive_int, required=False, help=iterations_help)
|
||||
|
||||
# Optional Args for Virtual OS and Baremetal systems
|
||||
if self.amdsmi_helpers.is_virtual_os() or self.amdsmi_helpers.is_baremetal():
|
||||
if self.helpers.is_virtual_os() or self.helpers.is_baremetal():
|
||||
metric_parser.add_argument('-b', '--fb-usage', action='store_true', required=False, help=fb_usage_help)
|
||||
|
||||
# Optional Args for Hypervisors and Baremetal systems
|
||||
if self.amdsmi_helpers.is_hypervisor() or self.amdsmi_helpers.is_baremetal():
|
||||
if self.helpers.is_hypervisor() or self.helpers.is_baremetal():
|
||||
metric_parser.add_argument('-p', '--power', action='store_true', required=False, help=power_help)
|
||||
metric_parser.add_argument('-c', '--clock', action='store_true', required=False, help=clock_help)
|
||||
metric_parser.add_argument('-t', '--temperature', action='store_true', required=False, help=temperature_help)
|
||||
@@ -432,9 +450,8 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
metric_parser.add_argument('-V', '--voltage', action='store_true', required=False, help=voltage_help)
|
||||
|
||||
# Optional Args for Linux Baremetal Systems
|
||||
if self.amdsmi_helpers.is_baremetal() and self.amdsmi_helpers.is_linux():
|
||||
if self.helpers.is_baremetal() and self.helpers.is_linux():
|
||||
metric_parser.add_argument('-f', '--fan', action='store_true', required=False, help=fan_help)
|
||||
metric_parser.add_argument('-s', '--pcie-usage', action='store_true', required=False, help=pcie_usage_help)
|
||||
metric_parser.add_argument('-C', '--voltage-curve', action='store_true', required=False, help=vc_help)
|
||||
metric_parser.add_argument('-o', '--overdrive', action='store_true', required=False, help=overdrive_help)
|
||||
metric_parser.add_argument('-M', '--mem-overdrive', action='store_true', required=False, help=mo_help)
|
||||
@@ -445,14 +462,14 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
metric_parser.add_argument('-m', '--mem-usage', action='store_true', required=False, help=mem_usage_help)
|
||||
|
||||
# Options to only display to Hypervisors
|
||||
if self.amdsmi_helpers.is_hypervisor():
|
||||
if self.helpers.is_hypervisor():
|
||||
metric_parser.add_argument('-s', '--schedule', action='store_true', required=False, help=schedule_help)
|
||||
metric_parser.add_argument('-G', '--guard', action='store_true', required=False, help=guard_help)
|
||||
metric_parser.add_argument('-u', '--guest', action='store_true', required=False, help=guest_help)
|
||||
|
||||
|
||||
def _add_process_parser(self, subparsers, func):
|
||||
if self.amdsmi_helpers.is_hypervisor():
|
||||
if self.helpers.is_hypervisor():
|
||||
# Don't add this subparser on Hypervisors
|
||||
# This subparser is only available to Guest and Baremetal systems
|
||||
return
|
||||
@@ -469,9 +486,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
pid_help = "Gets all process information about the specified process based on Process ID"
|
||||
name_help = "Gets all process information about the specified process based on Process Name.\
|
||||
\nIf multiple processes have the same name information is returned for all of them."
|
||||
watch_help = "Reprint the command in a loop of Interval seconds"
|
||||
watch_time_help = "The total time to watch the given command"
|
||||
iterations_help = "Total number of iterations to loop on the given command"
|
||||
|
||||
|
||||
# Create process subparser
|
||||
process_parser = subparsers.add_parser('process', help=process_help, description=process_subcommand_help)
|
||||
@@ -483,21 +498,18 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
# Add Device args
|
||||
self._add_device_arguments(process_parser, required=False)
|
||||
|
||||
# Add Watch args
|
||||
self._add_watch_arguments(process_parser)
|
||||
|
||||
# Optional Args
|
||||
process_parser.add_argument('-G', '--general', action='store_true', required=False, help=general_help)
|
||||
process_parser.add_argument('-e', '--engine', action='store_true', required=False, help=engine_help)
|
||||
process_parser.add_argument('-p', '--pid', action='store', type=self._positive_int, required=False, help=pid_help)
|
||||
process_parser.add_argument('-n', '--name', action='store', required=False, help=name_help)
|
||||
process_parser.add_argument('-w', '--watch', action='store', metavar='Interval',
|
||||
type=self._positive_int, required=False, help=watch_help)
|
||||
process_parser.add_argument('-W', '--watch_time', action=self._check_watch_selected(), metavar='Duration',
|
||||
type=self._positive_int, required=False, help=watch_time_help)
|
||||
process_parser.add_argument('-i', '--iterations', action=self._check_watch_selected(), metavar='Iterations',
|
||||
type=self._positive_int, required=False, help=iterations_help)
|
||||
|
||||
|
||||
def _add_profile_parser(self, subparsers, func):
|
||||
if not (self.amdsmi_helpers.is_windows() and self.amdsmi_helpers.is_hypervisor()):
|
||||
if not (self.helpers.is_windows() and self.helpers.is_hypervisor()):
|
||||
# This subparser only applies to Hypervisors
|
||||
return
|
||||
|
||||
@@ -518,7 +530,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
|
||||
def _add_event_parser(self, subparsers, func):
|
||||
if self.amdsmi_helpers.is_linux() and not self.amdsmi_helpers.is_virtual_os():
|
||||
if self.helpers.is_linux() and not self.helpers.is_virtual_os():
|
||||
# This subparser only applies to Linux BareMetal & Linux Hypervisors, NOT Linux Guest
|
||||
return
|
||||
|
||||
@@ -540,7 +552,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
def _add_topology_parser(self, subparsers, func):
|
||||
return
|
||||
if not(self.amdsmi_helpers.is_baremetal() and self.amdsmi_helpers.is_linux()):
|
||||
if not(self.helpers.is_baremetal() and self.helpers.is_linux()):
|
||||
# This subparser is only applicable to Baremetal Linux
|
||||
return
|
||||
|
||||
@@ -573,11 +585,11 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
topology_parser.add_argument('-o', '--hops', action='store_true', required=False, help=hops_help)
|
||||
topology_parser.add_argument('-t', '--type', action='store_true', required=False, help=type_help)
|
||||
topology_parser.add_argument('-n', '--numa', action='store_true', required=False, help=numa_help)
|
||||
topology_parser.add_argument('-b', '--numa_bw', action='store_true', required=False, help=numa_bw_help)
|
||||
topology_parser.add_argument('-b', '--numa-bw', action='store_true', required=False, help=numa_bw_help)
|
||||
|
||||
|
||||
def _add_set_value_parser(self, subparsers, func):
|
||||
if not(self.amdsmi_helpers.is_baremetal() and self.amdsmi_helpers.is_linux()):
|
||||
if not(self.helpers.is_baremetal() and self.helpers.is_linux()):
|
||||
# This subparser is only applicable to Baremetal Linux
|
||||
return
|
||||
|
||||
@@ -602,7 +614,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
set_mem_overdrive_help = "Set memory overclock overdrive level ***DEPRECATED IN NEWER KERNEL VERSIONS (use --mlevel instead)***"
|
||||
set_power_overdrive_help = "Set the maximum GPU power using power overdrive in Watts"
|
||||
set_profile_help = "Set power profile level (#) or a quoted string of custom profile attributes"
|
||||
set_perf_det_help = "Set GPU clock frequency limit to get minimal performance variation"
|
||||
set_perf_det_help = "Sets GPU clock frequency limit and performance level to determinism to get minimal performance variation"
|
||||
|
||||
# Create set_value subparser
|
||||
set_value_parser = subparsers.add_parser('set', help=set_value_help, description=set_value_subcommand_help)
|
||||
@@ -615,7 +627,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
self._add_device_arguments(set_value_parser, required=True)
|
||||
|
||||
# Optional Args
|
||||
set_value_parser.add_argument('-c', '--clock', action=self._validate_set_clock(True), nargs='+', type=self._positive_int, required=False, help=set_clock_help, metavar=('CLK_TYPE', 'CLK_LEVELS'))
|
||||
set_value_parser.add_argument('-c', '--clock', action=self._validate_set_clock(True), nargs='+', required=False, help=set_clock_help, metavar=('CLK_TYPE', 'CLK_LEVELS'))
|
||||
set_value_parser.add_argument('-s', '--sclk', action=self._validate_set_clock(False), nargs='+', type=self._positive_int, required=False, help=set_sclk_help, metavar='CLK_LEVELS')
|
||||
set_value_parser.add_argument('-m', '--mclk', action=self._validate_set_clock(False), nargs='+', type=self._positive_int, required=False, help=set_mclk_help, metavar='CLK_LEVELS')
|
||||
set_value_parser.add_argument('-p', '--pcie', action=self._validate_set_clock(False), nargs='+', type=self._positive_int, required=False, help=set_pcie_help, metavar='CLK_LEVELS')
|
||||
@@ -625,7 +637,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
set_value_parser.add_argument('-r', '--srange', action=self._prompt_spec_warning(), nargs=2, type=self._positive_int, required=False, help=set_srange_help, metavar=('SCLKMIN', 'SCLKMAX'))
|
||||
set_value_parser.add_argument('-R', '--mrange', action=self._prompt_spec_warning(), nargs=2, type=self._positive_int, required=False, help=set_mrange_help, metavar=('MCLKMIN', 'MCLKMAX'))
|
||||
set_value_parser.add_argument('-f', '--fan', action=self._validate_fan_speed(), required=False, help=set_fan_help, metavar='%')
|
||||
set_value_parser.add_argument('-l', '--perflevel', action='store', choices=['auto', 'low', 'high', 'manual'], required=False, help=set_perf_level_help, metavar='LEVEL')
|
||||
set_value_parser.add_argument('-l', '--perflevel', action='store', choices=self.helpers.get_perf_levels()[0], type=str.upper, required=False, help=set_perf_level_help, metavar='LEVEL')
|
||||
set_value_parser.add_argument('-o', '--overdrive', action=self._validate_overdrive_percent(), required=False, help=set_overdrive_help, metavar='%')
|
||||
set_value_parser.add_argument('-O', '--memoverdrive', action=self._validate_overdrive_percent(), required=False, help=set_mem_overdrive_help, metavar='%')
|
||||
set_value_parser.add_argument('-w', '--poweroverdrive', action=self._prompt_spec_warning(), type=self._positive_int, required=False, help=set_power_overdrive_help, metavar="WATTS")
|
||||
@@ -635,13 +647,14 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
def _validate_set_clock(self, validate_clock_type=True):
|
||||
""" Validate Clock input"""
|
||||
amdsmi_helpers = self.amdsmi_helpers
|
||||
amdsmi_helpers = self.helpers
|
||||
class _ValidateClockType(argparse.Action):
|
||||
# Checks the values
|
||||
# Checks the clock type and clock values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
if validate_clock_type:
|
||||
clock_type = values[0]
|
||||
valid_clock_type, clock_types = amdsmi_helpers.is_valid_clock_type(clock_type=clock_type)
|
||||
clock_types = amdsmi_helpers.get_clock_types()[0]
|
||||
valid_clock_type, amdsmi_clock_type = amdsmi_helpers.validate_clock_type(input_clock_type=clock_type)
|
||||
if not valid_clock_type:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{clock_type}' needs to be a valid clock type:{clock_types}")
|
||||
|
||||
@@ -656,7 +669,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
freq_bitmask |= (1 << level)
|
||||
|
||||
if validate_clock_type:
|
||||
setattr(args, self.dest, (clock_type, freq_bitmask))
|
||||
setattr(args, self.dest, (amdsmi_clock_type, freq_bitmask))
|
||||
else:
|
||||
setattr(args, self.dest, freq_bitmask)
|
||||
return _ValidateClockType
|
||||
@@ -664,7 +677,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
def _prompt_spec_warning(self):
|
||||
""" Prompt out of spec warning"""
|
||||
amdsmi_helpers = self.amdsmi_helpers
|
||||
amdsmi_helpers = self.helpers
|
||||
class _PromptSpecWarning(argparse.Action):
|
||||
# Checks the values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
@@ -675,56 +688,58 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
|
||||
def _validate_fan_speed(self):
|
||||
""" Validate fan speed input"""
|
||||
amdsmi_helpers = self.amdsmi_helpers
|
||||
amdsmi_helpers = self.helpers
|
||||
class _ValidateFanSpeed(argparse.Action):
|
||||
# Checks the values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
# Convert percentage to fan level
|
||||
if isinstance(values, str):
|
||||
try:
|
||||
values = int(values[:-1]) // 100 * 255
|
||||
except ValueError as e:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-255 or 0-100%")
|
||||
|
||||
# Store the fan level as fan_speed
|
||||
if isinstance(values, int):
|
||||
if 0 <= values <= 255:
|
||||
amdsmi_helpers.confirm_out_of_spec_warning()
|
||||
setattr(args, self.dest, values)
|
||||
else:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-255 or 0-100%")
|
||||
|
||||
# Convert percentage to fan level
|
||||
if '%' in values:
|
||||
try:
|
||||
amdsmi_helpers.confirm_out_of_spec_warning()
|
||||
values = int(int(values[:-1]) / 100 * 255)
|
||||
setattr(args, self.dest, values)
|
||||
except ValueError as e:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-100%")
|
||||
else: # Store the fan level as fan_speed
|
||||
values = int(values)
|
||||
if 0 <= values <= 255:
|
||||
amdsmi_helpers.confirm_out_of_spec_warning()
|
||||
setattr(args, self.dest, values)
|
||||
else:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-255")
|
||||
else:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-255 or 0-100%")
|
||||
return _ValidateFanSpeed
|
||||
|
||||
|
||||
def _validate_overdrive_percent(self):
|
||||
""" Validate overdrive percentage input"""
|
||||
amdsmi_helpers = self.amdsmi_helpers
|
||||
amdsmi_helpers = self.helpers
|
||||
class _ValidateOverdrivePercent(argparse.Action):
|
||||
# Checks the values
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
if isinstance(values, str):
|
||||
try:
|
||||
if values[-1] == '%':
|
||||
values = int(values[:-1])
|
||||
over_drive_percent = int(values[:-1])
|
||||
else:
|
||||
values = int(values)
|
||||
except ValueError as e:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-20 or 0-20%")
|
||||
over_drive_percent = int(values)
|
||||
|
||||
if isinstance(values, int):
|
||||
if 0 <= values <= 20:
|
||||
over_drive_percent = values
|
||||
else:
|
||||
if 0 <= over_drive_percent <= 20:
|
||||
amdsmi_helpers.confirm_out_of_spec_warning()
|
||||
setattr(args, self.dest, over_drive_percent)
|
||||
else:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be within range 0-20 or 0-20%")
|
||||
except ValueError:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-20 or 0-20%")
|
||||
|
||||
amdsmi_helpers.confirm_out_of_spec_warning()
|
||||
setattr(args, self.dest, over_drive_percent)
|
||||
else:
|
||||
raise argparse.ArgumentError(self, f"Invalid argument: '{values}' needs to be 0-20 or 0-20%")
|
||||
return _ValidateOverdrivePercent
|
||||
|
||||
|
||||
def _add_reset_parser(self, subparsers, func):
|
||||
if not(self.amdsmi_helpers.is_baremetal() and self.amdsmi_helpers.is_linux()):
|
||||
if not(self.helpers.is_baremetal() and self.helpers.is_linux()):
|
||||
# This subparser is only applicable to Baremetal Linux
|
||||
return
|
||||
|
||||
@@ -796,6 +811,7 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
rocm_smi_parser.add_argument('-l', '--load', action=self._check_input_file_path(), type=str, required=False, help=load_help)
|
||||
rocm_smi_parser.add_argument('-s', '--save', action=self._check_output_file_path(), type=str, required=False, help=save_help)
|
||||
|
||||
rocm_smi_parser.add_argument('-b', '--showbw', action='store_true', required=False, help=showbw_help)
|
||||
rocm_smi_parser.add_argument('-t', '--showtempgraph', action='store_true', required=False, help=showtempgraph_help)
|
||||
rocm_smi_parser.add_argument('-m', '--showmclkrange', action='store_true', required=False, help=showmclkrange_help)
|
||||
rocm_smi_parser.add_argument('-c', '--showsclkrange', action='store_true', required=False, help=showsclkrange_help)
|
||||
@@ -804,3 +820,19 @@ class AMDSMIParser(argparse.ArgumentParser):
|
||||
rocm_smi_parser.add_argument('-p', '--showproductname', action='store_true', required=False, help=showproductname_help)
|
||||
rocm_smi_parser.add_argument('-v', '--showclkvolt', action='store_true', required=False, help=showclkvolt_help)
|
||||
rocm_smi_parser.add_argument('-f', '--showclkfrq', action='store_true', required=False, help=showclkfrq_help)
|
||||
|
||||
|
||||
def error(self, message):
|
||||
outputformat = self.helpers.get_output_format()
|
||||
|
||||
if "argument : invalid choice: " in message:
|
||||
l = len("argument : invalid choice: ") + 1
|
||||
message = message[l:]
|
||||
message = message.split("'")[0]
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidCommandException(message, outputformat)
|
||||
elif "unrecognized arguments: " in message:
|
||||
l = len("unrecognized arguments: ")
|
||||
message = message[l:]
|
||||
raise amdsmi_cli_exceptions.AmdSmiInvalidParameterException(message, outputformat)
|
||||
else:
|
||||
print(message)
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.0.2"
|
||||
__version__ = "0.0.3"
|
||||
@@ -2437,7 +2437,7 @@ def amdsmi_dev_get_ecc_count(
|
||||
|
||||
ec = amdsmi_wrapper.amdsmi_error_count_t()
|
||||
_check_res(
|
||||
amdsmi_wrapper. amdsmi_dev_get_ecc_count(
|
||||
amdsmi_wrapper.amdsmi_dev_get_ecc_count(
|
||||
device_handle, block, ctypes.byref(ec))
|
||||
)
|
||||
|
||||
|
||||
@@ -168,17 +168,17 @@ def char_pointer_cast(string, encoding='utf-8'):
|
||||
|
||||
_libraries = {}
|
||||
from pathlib import Path
|
||||
libamd_smi_optrocm = Path(__file__).parents[3] / "/lib/libamd_smi.so"
|
||||
libamd_smi_cpack = Path("@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/libamd_smi.so")
|
||||
libamd_smi_optrocm = Path("/opt/rocm/lib/libamd_smi.so")
|
||||
libamd_smi_parent_dir = Path(__file__).resolve().parent / "libamd_smi.so"
|
||||
libamd_smi_cwd = Path.cwd()
|
||||
libamd_smi_cwd = Path.cwd() / "libamd_smi.so"
|
||||
|
||||
if libamd_smi_cpack.is_file():
|
||||
# try to find library in install directory provided by CMake
|
||||
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_cpack)
|
||||
elif libamd_smi_optrocm.is_file():
|
||||
if libamd_smi_optrocm.is_file():
|
||||
# try /opt/rocm/lib as a fallback
|
||||
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_optrocm)
|
||||
elif libamd_smi_cpack.is_file():
|
||||
# try to find library in install directory provided by CMake
|
||||
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_cpack)
|
||||
elif libamd_smi_parent_dir.is_file():
|
||||
# try to fall back to parent directory
|
||||
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_parent_dir)
|
||||
@@ -187,7 +187,6 @@ else:
|
||||
_libraries['libamd_smi.so'] = ctypes.CDLL(libamd_smi_cwd)
|
||||
|
||||
|
||||
|
||||
# values for enumeration 'c__EA_amdsmi_init_flags_t'
|
||||
c__EA_amdsmi_init_flags_t__enumvalues = {
|
||||
0: 'AMDSMI_INIT_ALL_DEVICES',
|
||||
|
||||
@@ -10,7 +10,7 @@ name = "amdsmi"
|
||||
authors = [
|
||||
{name = "AMD", email = "amd-smi.support@amd.com"},
|
||||
]
|
||||
version = '0.1'
|
||||
version = '0.3'
|
||||
license = {file = "amdsmi/LICENSE"}
|
||||
readme = {file = "amdsmi/README.md", content-type = "text/markdown"}
|
||||
description = "SMI LIB - AMD GPU Monitoring Library"
|
||||
|
||||
+6
-6
@@ -106,17 +106,17 @@ def main():
|
||||
library_path = os.path.join(os.path.dirname(__file__), library)
|
||||
line_to_replace = "_libraries['{}'] = ctypes.CDLL('{}')".format(library_name, library_path)
|
||||
new_line = f"""from pathlib import Path
|
||||
libamd_smi_optrocm = Path(__file__).parents[3] / "/lib/{library_name}"
|
||||
libamd_smi_cpack = Path("@CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/{library_name}")
|
||||
libamd_smi_optrocm = Path("/opt/rocm/lib/{library_name}")
|
||||
libamd_smi_parent_dir = Path(__file__).resolve().parent / "{library_name}"
|
||||
libamd_smi_cwd = Path.cwd()
|
||||
libamd_smi_cwd = Path.cwd() / "{library_name}"
|
||||
|
||||
if libamd_smi_cpack.is_file():
|
||||
# try to find library in install directory provided by CMake
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cpack)
|
||||
elif libamd_smi_optrocm.is_file():
|
||||
if libamd_smi_optrocm.is_file():
|
||||
# try /opt/rocm/lib as a fallback
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_optrocm)
|
||||
elif libamd_smi_cpack.is_file():
|
||||
# try to find library in install directory provided by CMake
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_cpack)
|
||||
elif libamd_smi_parent_dir.is_file():
|
||||
# try to fall back to parent directory
|
||||
_libraries['{library_name}'] = ctypes.CDLL(libamd_smi_parent_dir)
|
||||
|
||||
Referens i nytt ärende
Block a user