# Copyright 2019 Huawei Technologies Co., Ltd # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ """Define custom exception.""" import sys from enum import unique from importlib import import_module from lib2to3.pgen2 import parse from treelib.exceptions import DuplicatedNodeIdError, MultipleRootError, NodeIDAbsentError from mindinsight.mindconverter.common.log import logger as log, logger_console as log_console from mindinsight.utils.constant import ScriptConverterErrors from mindinsight.utils.exceptions import MindInsightException, ParamMissError @unique class ConverterErrors(ScriptConverterErrors): """Converter error codes.""" SCRIPT_NOT_SUPPORT = 1 NODE_TYPE_NOT_SUPPORT = 2 CODE_SYNTAX_ERROR = 3 NODE_INPUT_TYPE_NOT_SUPPORT = 4 NODE_INPUT_MISSING = 5 TREE_NODE_INSERT_FAIL = 6 UNKNOWN_MODEL = 7 MODEL_NOT_SUPPORT = 8 SCRIPT_GENERATE_FAIL = 9 REPORT_GENERATE_FAIL = 10 BASE_CONVERTER_FAIL = 000 GRAPH_INIT_FAIL = 100 TREE_CREATE_FAIL = 200 SOURCE_FILES_SAVE_FAIL = 300 class ScriptNotSupport(MindInsightException): """The script can not support to process.""" def __init__(self, msg): super(ScriptNotSupport, self).__init__(ConverterErrors.SCRIPT_NOT_SUPPORT, msg, http_code=400) class NodeTypeNotSupport(MindInsightException): """The astNode can not support to process.""" def __init__(self, msg): super(NodeTypeNotSupport, self).__init__(ConverterErrors.NODE_TYPE_NOT_SUPPORT, msg, http_code=400) class CodeSyntaxError(MindInsightException): """The CodeSyntaxError class definition.""" def __init__(self, msg): super(CodeSyntaxError, self).__init__(ConverterErrors.CODE_SYNTAX_ERROR, msg, http_code=400) class MindConverterException(Exception): """MindConverter exception.""" def __init__(self, **kwargs): """Initialization of MindInsightException.""" error = kwargs.get('error', None) user_msg = kwargs.get('user_msg', '') debug_msg = kwargs.get('debug_msg', '') cls_code = kwargs.get('cls_code', 0) if isinstance(user_msg, str): user_msg = ' '.join(user_msg.split()) super(MindConverterException, self).__init__() self.error = error self.user_msg = user_msg self.debug_msg = debug_msg self.cls_code = cls_code def __str__(self): return '[{}] code: {}, msg: {}'.format(self.__class__.__name__, self.error_code(), self.user_msg) def error_code(self): """" Calculate error code. code compose(2bytes) error: 16bits. num = 0xFFFF & error error_cods Returns: str, Hex string representing the composed MindConverter error code. """ num = 0xFFFF & self.error.value error_code = ''.join((f'{self.cls_code}'.zfill(3), hex(num)[2:].zfill(4).upper())) return error_code @staticmethod def raise_from(): """Raise from below exceptions.""" return None @classmethod def check_except_with_print_pytorch(cls, msg): """Check except in pytorch.""" def decorator(func): def _f(graph_path, sample_shape, output_folder, report_folder): try: func(graph_path=graph_path, sample_shape=sample_shape, output_folder=output_folder, report_folder=report_folder) except cls.raise_from() as e: error = cls(msg=msg) detail_info = f"Error detail: {str(e)}" log_console.error(str(error)) log_console.error(detail_info) log.exception(e) sys.exit(-1) return _f return decorator @classmethod def check_except_with_print_tf(cls, msg): """Check except in tf.""" def decorator(func): def _f(graph_path, sample_shape, input_nodes, output_nodes, output_folder, report_folder): try: func(graph_path=graph_path, sample_shape=sample_shape, input_nodes=input_nodes, output_nodes=output_nodes, output_folder=output_folder, report_folder=report_folder) except cls.raise_from() as e: error = cls(msg=msg) detail_info = f"Error detail: {str(e)}" log_console.error(str(error)) log_console.error(detail_info) log.exception(e) sys.exit(-1) return _f return decorator class BaseConverterFail(MindConverterException): """Base converter failed.""" def __init__(self, msg): super(BaseConverterFail, self).__init__(error=ConverterErrors.BASE_CONVERTER_FAIL, user_msg=msg) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (UnknownModel, ParamMissError) return except_source @classmethod def check_except(cls, msg): """Check except.""" def decorator(func): def _f(file_config): try: func(file_config=file_config) except cls.raise_from() as e: error = cls(msg=msg) detail_info = f"Error detail: {str(e)}" log_console.error(str(error)) log_console.error(detail_info) log.exception(e) sys.exit(-1) return _f return decorator class UnknownModel(MindConverterException): """The unknown model error.""" def __init__(self, msg): super(UnknownModel, self).__init__(error=ConverterErrors.UNKNOWN_MODEL, user_msg=msg) class GraphInitFail(MindConverterException): """The graph init fail error.""" def __init__(self, **kwargs): super(GraphInitFail, self).__init__(error=ConverterErrors.GRAPH_INIT_FAIL, user_msg=kwargs.get('msg', '')) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (FileNotFoundError, ModuleNotFoundError, ModelNotSupport, TypeError, ZeroDivisionError, RuntimeError) return except_source @classmethod def check_except_pytorch(cls, msg): """Check except for pytorch.""" return super().check_except_with_print_pytorch(msg) @classmethod def check_except_tf(cls, msg): """Check except for tf.""" return super().check_except_with_print_tf(msg) class TreeCreateFail(MindConverterException): """The tree create fail.""" def __init__(self, msg): super(TreeCreateFail, self).__init__(error=ConverterErrors.TREE_CREATE_FAIL, user_msg=msg) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (NodeInputMissing, TreeNodeInsertFail) return except_source @classmethod def check_except_pytorch(cls, msg): """Check except.""" return super().check_except_with_print_pytorch(msg) @classmethod def check_except_tf(cls, msg): """Check except for tf.""" return super().check_except_with_print_tf(msg) class SourceFilesSaveFail(MindConverterException): """The source files save fail error.""" def __init__(self, msg): super(SourceFilesSaveFail, self).__init__(error=ConverterErrors.SOURCE_FILES_SAVE_FAIL, user_msg=msg) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (NodeInputTypeNotSupport, ScriptGenerateFail, ReportGenerateFail, IOError) return except_source @classmethod def check_except_pytorch(cls, msg): """Check except.""" return super().check_except_with_print_pytorch(msg) @classmethod def check_except_tf(cls, msg): """Check except for tf.""" return super().check_except_with_print_tf(msg) class ModelNotSupport(MindConverterException): """The model not support error.""" def __init__(self, msg): super(ModelNotSupport, self).__init__(error=ConverterErrors.MODEL_NOT_SUPPORT, user_msg=msg, cls_code=ConverterErrors.GRAPH_INIT_FAIL.value) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (RuntimeError, ValueError, TypeError, OSError, ZeroDivisionError) return except_source @classmethod def check_except_pytorch(cls, msg): """Check except.""" def decorator(func): def _f(arch, model_path, **kwargs): try: output = func(arch, model_path=model_path, **kwargs) except cls.raise_from() as e: error = cls(msg=msg) log.error(msg) log.exception(e) raise error from e return output return _f return decorator @classmethod def check_except_tf(cls, msg): """Check except.""" tf_error_module = import_module('tensorflow.python.framework.errors_impl') tf_error = getattr(tf_error_module, 'OpError') cls._error = cls.raise_from() + (tf_error,) def decorator(func): def _f(arch, model_path, **kwargs): try: output = func(arch, model_path=model_path, **kwargs) except cls._error as e: error = cls(msg=msg) log.error(msg) log.exception(e) raise error from e return output return _f return decorator class NodeInputMissing(MindConverterException): """The node input missing error.""" def __init__(self, msg): super(NodeInputMissing, self).__init__(error=ConverterErrors.NODE_INPUT_MISSING, user_msg=msg, cls_code=ConverterErrors.TREE_CREATE_FAIL.value) class TreeNodeInsertFail(MindConverterException): """The tree node create fail error.""" def __init__(self, msg): super(TreeNodeInsertFail, self).__init__(error=ConverterErrors.TREE_NODE_INSERT_FAIL, user_msg=msg, cls_code=ConverterErrors.TREE_CREATE_FAIL.value) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (OSError, DuplicatedNodeIdError, MultipleRootError, NodeIDAbsentError) return except_source @classmethod def check_except(cls, msg): """Check except.""" def decorator(func): def _f(arch, graph): try: output = func(arch, graph=graph) except cls.raise_from() as e: error = cls(msg=msg) log.error(msg) log.exception(e) raise error from e return output return _f return decorator class NodeInputTypeNotSupport(MindConverterException): """The node input type NOT support error.""" def __init__(self, msg): super(NodeInputTypeNotSupport, self).__init__(error=ConverterErrors.NODE_INPUT_TYPE_NOT_SUPPORT, user_msg=msg, cls_code=ConverterErrors.SOURCE_FILES_SAVE_FAIL.value) class ScriptGenerateFail(MindConverterException): """The script generate fail error.""" def __init__(self, msg): super(ScriptGenerateFail, self).__init__(error=ConverterErrors.SCRIPT_GENERATE_FAIL, user_msg=msg, cls_code=ConverterErrors.SOURCE_FILES_SAVE_FAIL.value) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = (RuntimeError, parse.ParseError, AttributeError) return except_source @classmethod def check_except(cls, msg): """Check except.""" def decorator(func): def _f(arch, mapper): try: output = func(arch, mapper=mapper) except cls.raise_from() as e: error = cls(msg=msg) log.error(msg) log.exception(e) raise error from e return output return _f return decorator class ReportGenerateFail(MindConverterException): """The report generate fail error.""" def __init__(self, msg): super(ReportGenerateFail, self).__init__(error=ConverterErrors.REPORT_GENERATE_FAIL, user_msg=msg, cls_code=ConverterErrors.SOURCE_FILES_SAVE_FAIL.value) @staticmethod def raise_from(): """Raise from exceptions below.""" except_source = ZeroDivisionError return except_source @classmethod def check_except(cls, msg): """Check except.""" def decorator(func): def _f(arch, mapper): try: output = func(arch, mapper=mapper) except cls.raise_from() as e: error = cls(msg=msg) log.error(msg) log.exception(e) raise error from e return output return _f return decorator