From: @liangyongxiong1024 Reviewed-by: Signed-off-by:pull/1318/MERGE
| @@ -0,0 +1,14 @@ | |||
| # Copyright 2021 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. | |||
| # ============================================================================ | |||
| @@ -0,0 +1,14 @@ | |||
| # Copyright 2021 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. | |||
| # ============================================================================ | |||
| @@ -0,0 +1,525 @@ | |||
| # Copyright 2021 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. | |||
| # ============================================================================ | |||
| """Base module.""" | |||
| import os | |||
| import re | |||
| import enum | |||
| import collections | |||
| import numpy as np | |||
| from mindinsight.domain.graph.exceptions import UnknownTensorError | |||
| class MindSporeType(enum.Enum): | |||
| """MindSpore Type.""" | |||
| INT = 'int32' | |||
| UINT = 'uint' | |||
| FLOAT = 'float16' | |||
| TENSOR = 'tensor' | |||
| class DeviceType(enum.Enum): | |||
| """Device Type.""" | |||
| ASCEND = 'ascend' | |||
| GPU = 'gpu' | |||
| class DumpType(enum.Enum): | |||
| """Dump Type.""" | |||
| E2E = 'e2e' | |||
| ASYNC = 'async' | |||
| class Tensor: | |||
| """ | |||
| Tensor object of dump file. | |||
| Args: | |||
| op_id (str): Operator ID. | |||
| index (int): Index of operator inputs/outputs. | |||
| file_path (str): Absolute file path of tensor file. | |||
| """ | |||
| FEATURE = collections.namedtuple('Feature', ['type', 'id', 'io']) | |||
| VALUE = collections.namedtuple('Value', ['index', 'shape', 'dtype', 'path']) | |||
| @classmethod | |||
| def extract_shape_from_str(cls, shape_str): | |||
| """ | |||
| Extract shape from tensor file. | |||
| Args: | |||
| shape_str (str): Shape string. | |||
| Returns: | |||
| tuple, shape of tensor file. | |||
| """ | |||
| shape = tuple([int(dim.strip()) for dim in shape_str.strip('_').split('_')]) | |||
| # The shape info in dump file name is (0,) which is inconsistent with the actual tensor shape. | |||
| # The shape needs to be converted to (1,). | |||
| if shape == (0,): | |||
| shape = (1,) | |||
| return shape | |||
| @classmethod | |||
| def parse_tensor_file_name(cls, file_name): | |||
| """ | |||
| Parse tensor file name. | |||
| Args: | |||
| file_name (str): Tensor file name. | |||
| Returns: | |||
| bool, indicating if node is operator. | |||
| dict, tensor file info. | |||
| Raises: | |||
| UnknownTensorError: If tensor file name can not be recognized. | |||
| """ | |||
| is_op = False | |||
| is_npy = file_name.endswith('.npy') | |||
| if re.search(r'-op\d+(_|(\.\d+\.\d+\.))(input|output)(_|\.)', file_name): | |||
| is_op = True | |||
| dump_type = DumpType.E2E | |||
| if re.search(r'-op(?P<op_id>\d+)\.(?P<stream_id>\d+)\.(?P<task_id>\d+)', file_name): | |||
| dump_type = DumpType.ASYNC | |||
| if dump_type == DumpType.ASYNC: | |||
| file_name = file_name[file_name.find('.')+1:] | |||
| if is_npy: | |||
| regex = r'_(?P<op_name>[A-Za-z0-9]+)-op(?P<op_id>\d+)' \ | |||
| r'\.(?P<stream_id>\d+)\.(?P<task_id>\d+)' \ | |||
| r'\.(?P<io>input|output)' \ | |||
| r'\.(?P<index>\d+)' \ | |||
| r'\.npy$' | |||
| else: | |||
| regex = r'_(?P<op_name>[A-Za-z0-9]+)-op(?P<op_id>\d+)' \ | |||
| r'\.(?P<stream_id>\d+)\.(?P<task_id>\d+)' \ | |||
| r'\.(?P<io>input|output)' \ | |||
| r'\.(?P<index>\d+)' \ | |||
| r'\.(?P<shape>[0-9\_]+)' \ | |||
| r'\.(?P<dtype>bool|((uint|int|float)\d+))' \ | |||
| r'\.(?P<format>[A-Za-z0-9\_]+)\.bin$' | |||
| else: | |||
| regex = r'--(?P<op_name>[A-Za-z0-9\_]+)-op(?P<op_id>\d+)' \ | |||
| r'_(?P<io>input|output)' \ | |||
| r'_(?P<index>\d+)' \ | |||
| r'_shape_(?P<shape>[0-9\_]+)' \ | |||
| r'_.*(?P<dtype>Bool|((UInt|Int|Float)\d+))' \ | |||
| r'_(?P<format>[A-Za-z0-9\_]+)\.bin$' | |||
| else: | |||
| regex = r'^(?P<node_name>[A-Za-z0-9\.\_]+)' \ | |||
| r'_(?P<io>input|output)' \ | |||
| r'_(?P<index>\d+)' \ | |||
| r'_shape_(?P<shape>[0-9\_]+)' \ | |||
| r'_.*(?P<dtype>Bool|((UInt|Int|Float)\d+))' \ | |||
| r'_(?P<format>[A-Za-z0-9\_]+)\.bin$' | |||
| pattern = re.search(regex, file_name) | |||
| if pattern is None: | |||
| raise UnknownTensorError(is_op, file_name) | |||
| info = pattern.groupdict() | |||
| info['index'] = int(info['index']) | |||
| info['shape'] = None if is_npy else cls.extract_shape_from_str(info['shape']) | |||
| info['dtype'] = None if is_npy else info['dtype'].lower() | |||
| return is_op, info | |||
| @classmethod | |||
| def scan_tensors(cls, tensor_dir): | |||
| """ | |||
| Scan tensors. | |||
| Args: | |||
| tensor_dir (str): Directory path where holds the tensor files. | |||
| check (lambda): Function to check tensor values. | |||
| Returns: | |||
| dict, tensor file mapping. | |||
| """ | |||
| tensor_mapping = {} | |||
| if not tensor_dir: | |||
| return tensor_mapping | |||
| file_names = os.listdir(tensor_dir) | |||
| for file_name in file_names: | |||
| full_path = os.path.join(tensor_dir, file_name) | |||
| if not re.search(r'\.(bin|npy)$', file_name) or os.path.isdir(full_path): | |||
| continue | |||
| try: | |||
| is_op, info = cls.parse_tensor_file_name(file_name) | |||
| except UnknownTensorError: | |||
| continue | |||
| if is_op: | |||
| feature = cls.FEATURE(type=info['op_name'], id=info['op_id'], io=info['io']) | |||
| else: | |||
| feature = cls.FEATURE(type='', id=info['node_name'], io=info['io']) | |||
| value = cls.VALUE(index=info['index'], shape=info['shape'], dtype=info['dtype'], path=full_path) | |||
| tensors = tensor_mapping.get(feature) | |||
| if tensors: | |||
| tensor_mapping[feature].append(value) | |||
| tensor_mapping[feature].sort(key=lambda x: x[0]) | |||
| else: | |||
| tensor_mapping[feature] = [value] | |||
| return tensor_mapping | |||
| def __init__(self, op_id, index, file_path): | |||
| self.op_id = op_id | |||
| self.index = index | |||
| self.file_path = file_path | |||
| def load(self): | |||
| """ | |||
| Load tensor file. | |||
| Returns: | |||
| ndarray, tensor data. | |||
| """ | |||
| if self.file_path.endswith('.npy'): | |||
| tensor = np.load(self.file_path) | |||
| return tensor | |||
| metas = self.metas | |||
| if metas is None: | |||
| return None | |||
| dtype = getattr(np, metas['dtype']) | |||
| tensor = np.fromfile(self.file_path, dtype=dtype) | |||
| try: | |||
| tensor = tensor.reshape(metas['shape']) | |||
| except ValueError: | |||
| pass | |||
| return tensor | |||
| @property | |||
| def metas(self): | |||
| """ | |||
| Metas property. | |||
| Returns: | |||
| dict, metas extracted from tensor file name. | |||
| """ | |||
| file_name = os.path.basename(self.file_path) | |||
| try: | |||
| is_op, info = self.parse_tensor_file_name(file_name) | |||
| except UnknownTensorError: | |||
| return None | |||
| if is_op: | |||
| info.pop('op_name') | |||
| info.pop('op_id') | |||
| else: | |||
| info.pop('node_name') | |||
| if file_name.endswith('.npy'): | |||
| info.pop('dtype') | |||
| info.pop('shape') | |||
| return info | |||
| @property | |||
| def full_name(self): | |||
| """ | |||
| Full name property. | |||
| Returns: | |||
| str, full name. | |||
| """ | |||
| full_name_str, _ = os.path.basename(self.file_path).split('_output_') | |||
| return full_name_str.replace('--', '/') | |||
| @property | |||
| def scope(self): | |||
| """ | |||
| Scope property. | |||
| Returns: | |||
| str, scope. | |||
| """ | |||
| return os.path.dirname(self.full_name) | |||
| def __repr__(self): | |||
| return str({ | |||
| 'op_id': self.op_id, | |||
| 'index': self.index, | |||
| 'file_path': self.file_path, | |||
| }) | |||
| class NodeType(enum.Enum): | |||
| """Node Type.""" | |||
| OPERATOR = 'operator' | |||
| PARAMETER = 'parameter' | |||
| CONSTANT = 'constant' | |||
| class InputType(enum.Enum): | |||
| """Input Type.""" | |||
| OPERATOR = 'operator' | |||
| PARAMETER = 'parameter' | |||
| CONSTANT = 'constant' | |||
| TENSOR = 'tensor' | |||
| SCALAR = 'scalar' | |||
| REFERENCE = 'reference' | |||
| NONE = 'none' | |||
| class OutputType(enum.Enum): | |||
| """Output Type.""" | |||
| NONE = 'none' | |||
| BOOL = 'bool' | |||
| INT8 = 'int8' | |||
| INT16 = 'int16' | |||
| INT32 = 'int32' | |||
| INT64 = 'int64' | |||
| UINT8 = 'uint8' | |||
| UINT16 = 'uint16' | |||
| UINT32 = 'uint32' | |||
| UINT64 = 'uint64' | |||
| FLOAT16 = 'float16' | |||
| FLOAT32 = 'float32' | |||
| FLOAT64 = 'float64' | |||
| TENSOR = 'tensor' | |||
| TUPLE = 'tuple' | |||
| class Input: | |||
| """ | |||
| Graph node input. | |||
| Args: | |||
| input_type (InputType): Input type. | |||
| input_name (str): Input name. | |||
| """ | |||
| def __init__(self, input_type, input_name): | |||
| self.type = input_type | |||
| self.name = input_name | |||
| self.op_id = '' | |||
| self.info = None | |||
| def __repr__(self): | |||
| return str({ | |||
| 'type': self.type, | |||
| 'name': self.name, | |||
| 'op_id': self.op_id, | |||
| 'info': self.info, | |||
| }) | |||
| class Output: | |||
| """ | |||
| Graph node output. | |||
| Args: | |||
| output_type (OutputType): Output type. | |||
| """ | |||
| SCALAR_TYPES = ( | |||
| OutputType.INT8, | |||
| OutputType.INT16, | |||
| OutputType.INT32, | |||
| OutputType.INT64, | |||
| OutputType.UINT8, | |||
| OutputType.UINT16, | |||
| OutputType.UINT32, | |||
| OutputType.UINT64, | |||
| OutputType.FLOAT16, | |||
| OutputType.FLOAT32, | |||
| ) | |||
| def __init__(self, output_type): | |||
| self.type = output_type | |||
| if output_type == OutputType.NONE: | |||
| self.info = None | |||
| elif output_type == OutputType.BOOL: | |||
| self.info = dict(value=None) | |||
| elif output_type in self.SCALAR_TYPES: | |||
| self.info = dict(value=None) | |||
| elif output_type == OutputType.TENSOR: | |||
| self.info = dict(dtype='', shape=(), tensor=None) | |||
| elif output_type == OutputType.TUPLE: | |||
| self.info = dict(dtypes=[], shapes=[], tensors=[]) | |||
| def __repr__(self): | |||
| return str({ | |||
| 'type': self.type, | |||
| 'info': self.info, | |||
| }) | |||
| class Source: | |||
| """ | |||
| Source address info. | |||
| Args: | |||
| file_path (str): Absolute path of source file. | |||
| line_no (int): Line number of code line in source file. | |||
| code_line (int): Code line content. | |||
| """ | |||
| def __init__(self, file_path, line_no, code_line): | |||
| self.file_path = file_path | |||
| self.line_no = line_no | |||
| self.code_line = code_line | |||
| def to_dict(self): | |||
| """Parse to dict.""" | |||
| return { | |||
| 'file_path': self.file_path, | |||
| 'line_no': self.line_no, | |||
| 'code_line': self.code_line, | |||
| } | |||
| def __repr__(self): | |||
| return str(self.to_dict()) | |||
| @classmethod | |||
| def build_stack_from_source_address(cls, source_address): | |||
| """ | |||
| Build stack from source address. | |||
| Args: | |||
| source_address (str): Source address content. | |||
| Returns: | |||
| list, list of Source objects. | |||
| """ | |||
| stack = [] | |||
| for line in source_address.strip().split('\n'): | |||
| regex = r'#\sIn\sfile\s(?P<file_path>.+)\((?P<line_no>\d+)\)/(?P<code_line>.+)/' | |||
| pattern = re.search(regex, line.strip()) | |||
| source = pattern.groupdict() | |||
| source['line_no'] = int(source['line_no']) | |||
| source['code_line'] = source['code_line'].strip() | |||
| stack.append(cls(**source)) | |||
| return stack | |||
| class Node: | |||
| """ | |||
| Graph node. | |||
| Args: | |||
| name (str): Node name. | |||
| """ | |||
| def __init__(self, name): | |||
| self.name = name | |||
| self.output = None | |||
| self.downstream = [] | |||
| self.raw = '' | |||
| class Constant(Node): | |||
| """Constant node within graph.""" | |||
| def __repr__(self): | |||
| return str({ | |||
| 'name': self.name, | |||
| 'output': self.output, | |||
| 'downstream': self.downstream, | |||
| }) | |||
| class Parameter(Node): | |||
| """Parameter node within graph.""" | |||
| def __repr__(self): | |||
| return str({ | |||
| 'name': self.name, | |||
| 'output': self.output, | |||
| 'downstream': self.downstream, | |||
| }) | |||
| class Operator(Node): | |||
| """ | |||
| Operator node within graph. | |||
| Args: | |||
| op_name (str): Operator name. | |||
| op_type (str): Operator type. | |||
| """ | |||
| def __init__(self, op_name, op_type): | |||
| super().__init__(op_name) | |||
| self.type = op_type | |||
| self.inputs = [] | |||
| self.attrs = {} | |||
| self.full_name = '' | |||
| self.stack = [] | |||
| @property | |||
| def scope(self): | |||
| """ | |||
| Scope property. | |||
| Returns: | |||
| str, scope. | |||
| """ | |||
| return os.path.dirname(self.full_name) | |||
| @property | |||
| def op_id(self): | |||
| """ | |||
| Op ID property. | |||
| Returns: | |||
| str, op ID. | |||
| """ | |||
| pattern = re.search(r'-op(?P<op_id>\d+)$', self.full_name) | |||
| if not pattern: | |||
| return self.full_name | |||
| info = pattern.groupdict() | |||
| return info['op_id'] | |||
| def __repr__(self): | |||
| return str({ | |||
| 'name': self.name, | |||
| 'type': self.type, | |||
| 'inputs': self.inputs, | |||
| 'output': self.output, | |||
| 'downstream': self.downstream, | |||
| 'attrs': self.attrs, | |||
| 'full_name': self.full_name, | |||
| 'op_id': self.op_id, | |||
| }) | |||
| class Parser: | |||
| """Graph file parser.""" | |||
| def __init__(self, graph_data=None, tensor_dir=''): | |||
| self.graph_data = graph_data | |||
| self.tensor_dir = os.path.realpath(tensor_dir) if tensor_dir else '' | |||
| self.constants = [] | |||
| self.parameters = [] | |||
| self.operators = [] | |||
| self.tensor_mapping = {} | |||
| def parse(self): | |||
| """Parse.""" | |||
| raise NotImplementedError | |||
| @@ -0,0 +1,45 @@ | |||
| # Copyright 2021 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. | |||
| # ============================================================================ | |||
| """Parse exceptions module.""" | |||
| from mindinsight.utils.exceptions import MindInsightException | |||
| from mindinsight.utils.constant import GraphDomainErrors | |||
| class UnknownDataTypeError(MindInsightException): | |||
| """Unknwn data type error.""" | |||
| def __init__(self, proto_type): | |||
| super().__init__( | |||
| error=GraphDomainErrors.UNKNOWN_DATA_TYPE_ERROR, | |||
| message=str(proto_type)) | |||
| class TupleGetitemIndexError(MindInsightException): | |||
| """Tuple getitem index error.""" | |||
| def __init__(self, op_name, index_name): | |||
| super().__init__( | |||
| error=GraphDomainErrors.TUPLE_GETITEM_INDEX_ERROR, | |||
| message=f'op : {op_name}, index: {index_name}') | |||
| class UnknownTensorError(MindInsightException): | |||
| """Unknwn tensor error.""" | |||
| def __init__(self, is_op, file_name): | |||
| super().__init__( | |||
| error=GraphDomainErrors.UNKNOWN_TENSOR_ERROR, | |||
| message=f'is_op : {is_op}, file_name: {file_name}') | |||
| @@ -0,0 +1,325 @@ | |||
| /** | |||
| * Copyright 2021 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. | |||
| */ | |||
| syntax = "proto2"; | |||
| package mindinsight.domain.graph; | |||
| // Versioning | |||
| enum Version { | |||
| // unknown version | |||
| UNKNOWWN_VERSION = 0; | |||
| // Initial version (IR VERSION 1), published on Sep 23, 2019 | |||
| IR_VERSION = 0x0000000000000001; | |||
| } | |||
| // Data type definition | |||
| enum DataType { | |||
| DT_UNDEFINED = 0; | |||
| // Basic types. | |||
| DT_BOOL = 1; // bool | |||
| DT_INT8 = 2; // int8_t | |||
| DT_INT16 = 3; // int16_t | |||
| DT_INT32 = 4; // int32_t | |||
| DT_INT64 = 5; // int64_t | |||
| DT_UINT8 = 6; // uint8_t | |||
| DT_UINT16 = 7; // uint16_t | |||
| DT_UINT32 = 8; // uint32_t | |||
| DT_UINT64 = 9; // uint64_t | |||
| DT_FLOAT16 = 10; // float 16 | |||
| DT_FLOAT32 = 11; // float 32 | |||
| DT_FLOAT64 = 12; // float 64 | |||
| DT_STRING = 13; // string | |||
| DT_TENSOR = 14; // tensor | |||
| DT_GRAPH = 15; // graph | |||
| // list type | |||
| DT_BOOLS = 16; // list of bool | |||
| DT_INTS8 = 17; // list of int8_t | |||
| DT_INTS16 = 18; // list of int16_t | |||
| DT_INTS32 = 19; // list of int32_t | |||
| DT_INTS64 = 20; // list of int64_t | |||
| DT_UINTS8 = 21; // list of uint8_t | |||
| DT_UINTS16 = 22; // list of uint16_t | |||
| DT_UINTS32 = 23; // list of uint32_t | |||
| DT_UINTS64 = 24; // list of uint64_t | |||
| DT_FLOATS16 = 25; // list of float16 | |||
| DT_FLOATS32 = 26; // list of float32 | |||
| DT_FLOATS64 = 27; // list of float64 | |||
| DT_STRINGS = 28; // list of string | |||
| DT_TENSORS = 29; // list of tensor | |||
| DT_GRAPHS = 30; // list of graph | |||
| DT_TUPLE = 31; // tuple | |||
| DT_LIST = 32; // list | |||
| DT_DICT = 33; // dictionary | |||
| // other types | |||
| DT_NONE = 34; // None | |||
| DT_SYM_INST = 35; // Symbolic Key Instance | |||
| // type related type | |||
| DT_BASE_INT = 36; // type generic int | |||
| DT_BASE_UINT = 37; // type generate unsigned int | |||
| DT_BASE_FLOAT = 38; // type generate float | |||
| DT_TYPE = 39; // type type | |||
| DT_ANYTHING = 40; // type anything | |||
| DT_REFKEY = 41; // type refkey | |||
| DT_REF = 42; // type ref | |||
| } | |||
| // Value definition for attribute value or parameter default value | |||
| message ValueProto { | |||
| // data type of value | |||
| optional DataType dtype = 1; // discriminator that indicates which field below is in use | |||
| // Exactly ONE of the following fields must be present for this version of the IR | |||
| optional bool bool_val = 2; // bool | |||
| optional int64 int_val = 3; // int | |||
| optional uint64 uint_val = 4; // uint | |||
| optional float float_val = 5; // float | |||
| optional double double_val = 6; // double | |||
| optional string str_val = 7; // string | |||
| optional TensorProto tensor_val = 8; // tensor value | |||
| optional GraphProto graph = 9; // graph | |||
| repeated bool bool_vals = 10; // list of bool | |||
| repeated int64 int_vals = 11; // list of int | |||
| repeated uint64 uint_vals = 12; // list of uint | |||
| repeated float float_vals = 13; // list of float | |||
| repeated double double_vals = 14; // list of double | |||
| repeated string str_vals = 15; // list of string | |||
| repeated TensorProto tensor_vals = 16; // list of tensor value | |||
| repeated GraphProto graphs = 17; // list of graph | |||
| // tuple or list | |||
| repeated ValueProto values = 18; // tuple, list of value | |||
| // dictionary | |||
| repeated NamedValueProto dict_val = 19; // dictionary info | |||
| // filed for type type | |||
| optional TypeProto type_val = 20; // type type info | |||
| } | |||
| message AttributeProto { | |||
| optional string name = 1; // attribute name | |||
| optional ValueProto value = 2; // attribute value | |||
| } | |||
| message NamedValueProto { | |||
| optional string key = 1; // attribute name | |||
| optional ValueProto value = 2; // attribute value | |||
| } | |||
| // Defines a tensor shape. | |||
| message TensorShapeProto { | |||
| // One dimension of the tensor. | |||
| message Dimension { | |||
| // Size of the tensor in that dimension. | |||
| // This value must be >= -1, but values of -1 are reserved for "unknown" | |||
| // shapes (values of -1 mean "unknown" dimension). | |||
| optional int64 size = 1; | |||
| // Optional name of the tensor dimension. | |||
| optional string name = 2; | |||
| }; | |||
| repeated Dimension dim = 1; | |||
| } | |||
| // Types for graph input(parameter) and output | |||
| message TypeProto { | |||
| message Tensor { | |||
| // This field MUST have a valid DataType value except DT_TENSOR | |||
| optional DataType elem_type = 1; | |||
| optional TensorShapeProto shape = 2; // for scalar, this field is not set | |||
| } | |||
| // tuple type | |||
| message Sequence { | |||
| // The type and optional shape of elements of the tuple. | |||
| repeated TypeProto elem_types = 1; | |||
| }; | |||
| // data type | |||
| optional DataType data_type = 1; | |||
| oneof value { | |||
| // The type of a tensor. | |||
| Tensor tensor_type = 2; | |||
| // The type of a tuple. | |||
| Sequence sequence_type = 3; | |||
| } | |||
| } | |||
| // Defines information on graph parameters, including the name, the type, and | |||
| // the default value of parameter if exists. | |||
| message ParameterProto { | |||
| optional string name = 1; // parameter name | |||
| optional TypeProto type = 2; // parameter type | |||
| optional ValueProto default_val = 3; // default value of parameter if exists | |||
| } | |||
| // Defines graph output information | |||
| message OutputProto { | |||
| optional string name = 1; // output node name | |||
| optional TypeProto type = 2; // output node type | |||
| } | |||
| // Define node input information | |||
| message InputProto { | |||
| enum EdgeType { | |||
| DATA_EDGE = 0; // data edge | |||
| CONTROL_EDGE = 1; // control edge | |||
| } | |||
| optional string name = 1; | |||
| optional EdgeType type = 2; | |||
| } | |||
| // Nodes | |||
| // | |||
| // Computation graphs are made up of a DAG of nodes, which represent what is | |||
| // commonly called a "layer" or "pipeline stage" in machine learning frameworks. | |||
| // | |||
| // For example, it can be a node of type "Conv" that takes in an image, a filter | |||
| // tensor and a bias tensor, and produces the convolved output. | |||
| message NodeProto { | |||
| repeated InputProto input = 1; // namespace Value | |||
| optional string name = 2; // namespace Value | |||
| // The symbolic identifier of the Operator to execute. | |||
| optional string op_type = 3; // namespace Operator | |||
| // The domain of the OperatorSet that specifies the operator named by op_type. | |||
| optional string scope = 4; // namespace Domain | |||
| // Additional named attributes. | |||
| repeated AttributeProto attribute = 5; | |||
| // Optional type info of this node | |||
| optional TypeProto output_type = 6; | |||
| // other fields for debug | |||
| optional uint64 output_i = 7; | |||
| // full name with scope | |||
| optional string full_name = 8; | |||
| // The corresponding source code for this node. | |||
| optional string source_address = 9; | |||
| } | |||
| // Models | |||
| // | |||
| // ModelProto is a top-level file/container format for bundling a ML model and | |||
| // associating its computation graph with metadata. | |||
| // | |||
| // The semantics of the model are described by the associated GraphProto. | |||
| message ModelProto { | |||
| // ir version | |||
| optional int64 ir_version = 1; | |||
| // Domain name of the model. | |||
| // We use reverse domain names as name space indicators. For example: | |||
| // `com.facebook.fair` or `com.microsoft.cognitiveservices` | |||
| // | |||
| // Together with `model_version` and GraphProto.name, this forms the unique identity of | |||
| // the graph. | |||
| optional string domain = 2; | |||
| // The version of the graph encoded. See Version enum below. | |||
| optional int64 model_version = 3; | |||
| // The parameterized graph that is evaluated to execute the model. | |||
| optional GraphProto graph = 4; | |||
| // metadata info of operators | |||
| optional OperatorSetProto metadata_operators = 5; | |||
| }; | |||
| message OperatorProto { | |||
| optional string name = 1; // used as key, must be distinct | |||
| optional bytes config = 2; // operator config info | |||
| optional bytes obj_info = 3; // operator related object info, e.g. content of operator binary or name | |||
| }; | |||
| message OperatorSetProto { | |||
| repeated OperatorProto operators = 1; | |||
| optional string summary = 2; // summary info of operators, e.g. file position of operators file | |||
| } | |||
| // Graphs | |||
| // | |||
| // A graph defines the computational logic of a model and is comprised of a parameterized | |||
| // list of nodes that form a directed acyclic graph based on their inputs and outputs. | |||
| // This is the equivalent of the "network" or "graph" in many deep learning | |||
| // frameworks. | |||
| message GraphProto { | |||
| // The nodes in the graph, sorted topologically. | |||
| repeated NodeProto node = 1; | |||
| // The name of the graph. | |||
| optional string name = 2; // namespace Graph | |||
| // The parameters(inputs) and outputs of the graph. | |||
| repeated ParameterProto parameters = 3; | |||
| repeated OutputProto outputs = 4; | |||
| // Constants used in this graph | |||
| repeated NamedValueProto const_vals = 5; | |||
| } | |||
| // Tensors | |||
| // | |||
| // A serialized tensor value. | |||
| message TensorProto { | |||
| // The node name of the tensor. | |||
| optional string node_name = 1; | |||
| // The slot of the tensor in its node. | |||
| optional string slot = 2; | |||
| // The serialized tensor content. | |||
| optional bytes tensor_content = 3; | |||
| // The shape of the tensor. | |||
| repeated int64 dims = 4; | |||
| // The data type of the tensor. | |||
| // This field MUST have a valid DataType value except DT_TENSOR | |||
| optional DataType data_type = 5; | |||
| // If the tensor content transferring is finished. | |||
| optional bool finished = 6; | |||
| // The iteration of the tensor. Supported: "prev" or leave empty. | |||
| optional string iter = 7; | |||
| // If the tensor name should be truncated. | |||
| optional bool truncate = 8; | |||
| } | |||
| @@ -102,3 +102,10 @@ class OptimizerErrors(Enum): | |||
| OPTIMIZER_TERMINATE = 4 | |||
| CONFIG_PARAM_ERROR = 5 | |||
| HYPER_CONFIG_ENV_ERROR = 6 | |||
| class GraphDomainErrors(Enum): | |||
| """Enum definition for graph domain errors.""" | |||
| UNKNOWN_DATA_TYPE_ERROR = 1 | |||
| TUPLE_GETITEM_INDEX_ERROR = 2 | |||
| UNKNOWN_TENSOR_ERROR = 3 | |||