#!/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"Can not find a device with the corresponding identifier: '{self.command}'" 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 AmdSmiRequiredCommandException(AmdSmiException): def __init__(self, command, outputformat): super().__init__() self.value = -9 self.command = command self.output_format = outputformat common_message = f"Command '{self.command}' requires a target argument. 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}"