Merge pull request !104 from ougongchang/optimize_graphtags/v0.3.0-alpha
| @@ -102,12 +102,11 @@ def graph_nodes(): | |||||
| """ | """ | ||||
| name = request.args.get('name', default=None) | name = request.args.get('name', default=None) | ||||
| node_type = request.args.get('type', default='name_scope') | |||||
| tag = request.args.get("tag", default=None) | tag = request.args.get("tag", default=None) | ||||
| train_id = get_train_id(request) | train_id = get_train_id(request) | ||||
| graph_process = GraphProcessor(train_id, DATA_MANAGER, tag) | graph_process = GraphProcessor(train_id, DATA_MANAGER, tag) | ||||
| response = graph_process.get_nodes(name=name, node_type=node_type) | |||||
| response = graph_process.list_nodes(scope=name) | |||||
| return jsonify(response) | return jsonify(response) | ||||
| @@ -15,13 +15,13 @@ | |||||
| """ | """ | ||||
| This file is used to define the basic graph. | This file is used to define the basic graph. | ||||
| """ | """ | ||||
| import copy | |||||
| import time | |||||
| from enum import Enum | from enum import Enum | ||||
| from collections import defaultdict | |||||
| from mindinsight.datavisual.common.log import logger | |||||
| from mindinsight.datavisual.common.exceptions import NodeNotInGraphError | from mindinsight.datavisual.common.exceptions import NodeNotInGraphError | ||||
| from mindinsight.datavisual.common.log import logger | |||||
| from mindinsight.utils.exceptions import ParamMissError | |||||
| from mindinsight.utils.exceptions import ParamValueError | |||||
| from .node import NodeTypeEnum | from .node import NodeTypeEnum | ||||
| from .node import Node | from .node import Node | ||||
| @@ -32,27 +32,38 @@ class EdgeTypeEnum(Enum): | |||||
| DATA = 'data' | DATA = 'data' | ||||
| class DataTypeEnum(Enum): | |||||
| """Data type enum.""" | |||||
| DT_TENSOR = 13 | |||||
| class Graph: | class Graph: | ||||
| """The `Graph` object is used to describe a graph file.""" | """The `Graph` object is used to describe a graph file.""" | ||||
| MIN_POLYMERIC_NODE_COUNT = 5 | |||||
| # Limit the size of a single attribute value per node to avoid storing too much data | |||||
| MAX_NODE_ATTRIBUTE_VALUE_BYTES = 1024 | |||||
| def __init__(self): | |||||
| # Store nodes contain leaf nodes, name scope node, except polymeric nodes | |||||
| self._normal_nodes = {} | |||||
| # In the same scope, the number of children of the same type exceeds this threshold, and we will combine them. | |||||
| MIN_GROUP_NODE_COUNT = 5 | |||||
| # Store polymeric nodes. | |||||
| self._polymeric_nodes = {} | |||||
| # Store all nodes resolved from the file. | |||||
| self._leaf_nodes = {} | |||||
| # The format of node groups is {'group_name': {'node_name': <Node>}} | |||||
| self._node_groups = {} | |||||
| def __init__(self): | |||||
| # Used to cache all nodes, and the key is node name, value is `Node` object. | |||||
| self._normal_node_map = {} | |||||
| self._node_id_map_name = {} | |||||
| # The additional caching of Const and Parameter is to handle the Const | |||||
| # and Parameter nodes separately later. | |||||
| self._const_node_temp_cache = {} | |||||
| self._parameter_node_temp_cache = {} | |||||
| def build_graph(self, proto_data): | |||||
| """This method is used to build the graph.""" | |||||
| # Notice: | |||||
| # The following methods are interdependent and cannot be switched at will. | |||||
| self._parse_data(proto_data) | |||||
| self._add_variable_nodes(NodeTypeEnum.PARAMETER.value) | |||||
| self._build_aggregation_scope_nodes() | |||||
| self._process_independent_layout() | |||||
| self._build_name_scope_nodes() | |||||
| # Since const nodes are not aggregated, adding them at the end can save a lot of computation. | |||||
| self._add_variable_nodes(NodeTypeEnum.CONST.value) | |||||
| self._calc_subnode_count() | |||||
| def exist_node(self, name): | def exist_node(self, name): | ||||
| """ | """ | ||||
| @@ -62,52 +73,27 @@ class Graph: | |||||
| name (str): The node name. | name (str): The node name. | ||||
| Returns: | Returns: | ||||
| bool, if node is exist will return True. | |||||
| bool, if node exists, will return True. | |||||
| """ | """ | ||||
| if self._normal_nodes.get(name) is None: | |||||
| if name is None: | |||||
| return False | return False | ||||
| return True | |||||
| return self._is_node_exist(node_name=name) | |||||
| def get_normal_nodes(self, namescope=None): | |||||
| def list_node_by_scope(self, scope=None): | |||||
| """ | """ | ||||
| Get nodes by namescope. | |||||
| List nodes by the scope of nodes. The scope of a node is the same as its parent node name. | |||||
| Args: | Args: | ||||
| namescope (str): A namescope of nodes. | |||||
| scope (str): A scope of nodes. | |||||
| Returns: | Returns: | ||||
| list[dict], a list object contain `Node` object. | list[dict], a list object contain `Node` object. | ||||
| """ | """ | ||||
| scope = "" if scope is None else scope | |||||
| nodes = [] | nodes = [] | ||||
| if namescope is None: | |||||
| for name, node in self._normal_nodes.items(): | |||||
| if '/' not in name: | |||||
| # Get first layer nodes | |||||
| nodes.append(node.to_dict()) | |||||
| return nodes | |||||
| namescope = namescope + '/' | |||||
| for name, node in self._normal_nodes.items(): | |||||
| if name.startswith(namescope) and '/' not in name.split(namescope)[1]: | |||||
| nodes.append(node.to_dict()) | |||||
| return nodes | |||||
| def get_polymeric_nodes(self, polymeric_scope): | |||||
| """ | |||||
| Get polymeric nodes by polymeric scope. | |||||
| Args: | |||||
| polymeric_scope (str): The polymeric scope name of nodes. | |||||
| Returns: | |||||
| list[dict], a list object contain `Node` object. | |||||
| """ | |||||
| nodes = [] | |||||
| for node in self._polymeric_nodes.values(): | |||||
| if node.polymeric_scope_name == polymeric_scope: | |||||
| for node in self._normal_node_map.values(): | |||||
| if node.scope == scope: | |||||
| nodes.append(node.to_dict()) | nodes.append(node.to_dict()) | ||||
| return nodes | return nodes | ||||
| @@ -117,21 +103,18 @@ class Graph: | |||||
| Args: | Args: | ||||
| content (Union[str, None]): This content can be the key content of the node to search, | content (Union[str, None]): This content can be the key content of the node to search, | ||||
| if None, will get all node names. | |||||
| if None, will get all node names. | |||||
| offset (int): An offset for page. Ex, offset is 0, mean current page is 1. | offset (int): An offset for page. Ex, offset is 0, mean current page is 1. | ||||
| limit (int): An offset for page. Ex, offset is 0, mean current page is 1. | limit (int): An offset for page. Ex, offset is 0, mean current page is 1. | ||||
| Returns: | Returns: | ||||
| list[str], a list of node names. | list[str], a list of node names. | ||||
| """ | """ | ||||
| all_names = [] | |||||
| all_names.extend(list(self._normal_nodes.keys())) | |||||
| all_names.extend(list(self._polymeric_nodes.keys())) | |||||
| if content is not None: | if content is not None: | ||||
| content = content.lower() | content = content.lower() | ||||
| catch_names = [name for name in all_names if content in name.lower()] | |||||
| catch_names = [name for name in self._normal_node_map if content in name.lower()] | |||||
| else: | else: | ||||
| catch_names = all_names | |||||
| catch_names = list(self._normal_node_map) | |||||
| catch_names = sorted(catch_names) | catch_names = sorted(catch_names) | ||||
| real_offset = offset * limit | real_offset = offset * limit | ||||
| return catch_names[real_offset:real_offset+limit] | return catch_names[real_offset:real_offset+limit] | ||||
| @@ -149,304 +132,419 @@ class Graph: | |||||
| 'scope_name': '<Node scope>', | 'scope_name': '<Node scope>', | ||||
| 'children': {<item_object>}} | 'children': {<item_object>}} | ||||
| """ | """ | ||||
| if node_name and self._polymeric_nodes.get(node_name) is None \ | |||||
| and self._normal_nodes.get(node_name) is None: | |||||
| if node_name and not self.exist_node(name=node_name): | |||||
| raise NodeNotInGraphError(node_name=node_name) | raise NodeNotInGraphError(node_name=node_name) | ||||
| response = {} | response = {} | ||||
| nodes = self.get_normal_nodes() | |||||
| nodes = self.list_node_by_scope() | |||||
| response.update({ | response.update({ | ||||
| 'nodes': nodes, | 'nodes': nodes, | ||||
| 'scope_name': '', | 'scope_name': '', | ||||
| 'children': {} | 'children': {} | ||||
| }) | }) | ||||
| names = node_name.split('/') | |||||
| children = response['children'] | children = response['children'] | ||||
| for i in range(1, len(names)+1): | |||||
| if i == len(names): | |||||
| polymeric_node = self._polymeric_nodes.get(node_name) | |||||
| if polymeric_node: | |||||
| polymeric_scope = polymeric_node.polymeric_scope_name | |||||
| nodes = self.get_polymeric_nodes(polymeric_scope) | |||||
| children.update({'nodes': nodes, | |||||
| 'scope_name': polymeric_scope, | |||||
| 'children': {}}) | |||||
| break | |||||
| name_scope = '/'.join(names[:i]) | |||||
| nodes = self.get_normal_nodes(name_scope) | |||||
| index = node_name.find('/') | |||||
| while index != -1: | |||||
| scope = node_name[:index] | |||||
| nodes = self.list_node_by_scope(scope) | |||||
| children.update({ | children.update({ | ||||
| 'nodes': nodes, | 'nodes': nodes, | ||||
| 'scope_name': name_scope, | |||||
| 'scope_name': scope, | |||||
| 'children': {} | 'children': {} | ||||
| }) | }) | ||||
| children = children['children'] | children = children['children'] | ||||
| index = node_name.find('/', index+1) | |||||
| return response | return response | ||||
| def _build_polymeric_nodes(self): | |||||
| """Build polymeric node.""" | |||||
| logger.debug("Start to build polymeric nodes") | |||||
| self._find_polymeric_nodes() | |||||
| group_count_map = {} | |||||
| for group_name, group in self._node_groups.items(): | |||||
| name = group_name.split('/')[-1] | |||||
| count = group_count_map.get(name, 0) | |||||
| count += 1 | |||||
| group_count_map[name] = count | |||||
| polymeric_node_name = group_name + '_{}_[{}]'.format(count, len(group)) | |||||
| polymeric_node = Node(polymeric_node_name, node_id=polymeric_node_name) | |||||
| polymeric_node.node_type = NodeTypeEnum.POLYMERIC_SCOPE.value | |||||
| polymeric_node.name_scope = '/'.join(group_name.split('/')[:-1]) | |||||
| polymeric_node.subnode_count = len(group) | |||||
| for name_tmp, node_tmp in group.items(): | |||||
| node_tmp.polymeric_scope_name = polymeric_node_name | |||||
| self._polymeric_nodes.update({name_tmp: node_tmp}) | |||||
| polymeric_node.update_input(node_tmp.inputs) | |||||
| polymeric_node.update_output(node_tmp.outputs) | |||||
| self._normal_nodes.update({polymeric_node_name: polymeric_node}) | |||||
| self._update_input_output() | |||||
| def _find_polymeric_nodes(self): | |||||
| """Find polymeric nodes from node groups.""" | |||||
| node_groups = copy.deepcopy(self._node_groups) | |||||
| for group_name, group in node_groups.items(): | |||||
| if len(group) < self.MIN_POLYMERIC_NODE_COUNT: | |||||
| self._normal_nodes.update(group) | |||||
| self._node_groups.pop(group_name) | |||||
| continue | |||||
| def _parse_data(self, proto_data): | |||||
| """ | |||||
| This method will parse the data and create basic nodes to store in the cache. | |||||
| move_node_names = [] | |||||
| is_move_group = False | |||||
| for node_name, group_node in group.items(): | |||||
| node_list = [] | |||||
| is_in_group = False | |||||
| for dst_name in group_node.outputs: | |||||
| node_tmp = self._leaf_nodes[dst_name] | |||||
| node_list.append(node_tmp) | |||||
| start = time.time() | |||||
| run_count = 0 | |||||
| visit_nodes = {} | |||||
| while node_list: | |||||
| # Iterate to find if the output of the node in the group causes a loop | |||||
| # example: there is a group A, and node_a is a Node in group. | |||||
| # if there is a loop in node_a, like A/node_a -> B/node_b -> A/node_b | |||||
| # we will remove the node_a from group A. | |||||
| node_tmp = node_list[0] | |||||
| node_list = node_list[1:] | |||||
| visit_nodes.update({node_tmp.name: True}) | |||||
| if node_tmp in group.values(): | |||||
| is_in_group = True | |||||
| break | |||||
| for dst_name_tmp in node_tmp.outputs: | |||||
| run_count += 1 | |||||
| node_tmp = self._leaf_nodes[dst_name_tmp] | |||||
| if visit_nodes.get(dst_name_tmp): | |||||
| The graph is then built based on the cache. | |||||
| """ | |||||
| raise NotImplementedError("Before you can build a graph, you need to parse the data.") | |||||
| def _build_name_scope_nodes(self): | |||||
| """ | |||||
| Build name scope node by every node name. | |||||
| We create the name scope node by the slash('/') in the node name. | |||||
| For example, if a node name is "Default/add", we generate a scope named 'Default' based on slash('/') and | |||||
| create a name scope node named 'Default'. | |||||
| """ | |||||
| logger.info("Start to build name scope nodes.") | |||||
| scope_node_map = {} | |||||
| for name, node in self._normal_node_map.items(): | |||||
| index = name.find('/') | |||||
| pre_index = None | |||||
| while index > 0: | |||||
| scope = name[:index] | |||||
| scope_node = scope_node_map.get(scope) | |||||
| if scope_node is None: | |||||
| if self._is_node_exist(node_name=scope): | |||||
| exist_node = self._get_normal_node(node_name=scope) | |||||
| if exist_node.type == NodeTypeEnum.AGGREGATION_SCOPE.value: | |||||
| # This scope is aggregation scope, so we don't have to do anything. | |||||
| pre_index = index | |||||
| index = name.find('/', pre_index + 1) | |||||
| continue | continue | ||||
| node_list.append(node_tmp) | |||||
| logger.debug("Find group %s node end, is_in_group: %s, use time: %s, " | |||||
| "run count: %s.", group_name, is_in_group, | |||||
| time.time() - start, run_count) | |||||
| if is_in_group: | |||||
| move_node_names.append(node_name) | |||||
| # We find a node name that conflicts with the current scope and rename the node | |||||
| self._update_conflict_node(conflict_name=scope) | |||||
| if (len(group) - len(move_node_names)) < self.MIN_POLYMERIC_NODE_COUNT: | |||||
| is_move_group = True | |||||
| break | |||||
| # We create a node for current scope. | |||||
| scope_node = Node(scope, node_id=scope) | |||||
| scope_node.type = NodeTypeEnum.NAME_SCOPE.value | |||||
| scope_node.scope = '' if pre_index is None else name[:pre_index] | |||||
| scope_node_map.update({scope_node.name: scope_node}) | |||||
| if is_move_group: | |||||
| self._normal_nodes.update(group) | |||||
| self._node_groups.pop(group_name) | |||||
| else: | |||||
| for name_tmp in move_node_names: | |||||
| node_tmp = self._node_groups[group_name].pop(name_tmp) | |||||
| self._normal_nodes.update({name_tmp: node_tmp}) | |||||
| def _update_input_output(self): | |||||
| """We need to update input and output attribute after build polymeric node.""" | |||||
| for node in self._normal_nodes.values(): | |||||
| for src_name, input_attr in node.inputs.items(): | |||||
| if self._polymeric_nodes.get(src_name): | |||||
| input_attr['scope'] = NodeTypeEnum.POLYMERIC_SCOPE.value | |||||
| node.update_input({src_name: input_attr}) | |||||
| for dst_name, output_attr in node.outputs.items(): | |||||
| if self._polymeric_nodes.get(dst_name): | |||||
| output_attr['scope'] = NodeTypeEnum.POLYMERIC_SCOPE.value | |||||
| node.update_output({dst_name: output_attr}) | |||||
| for node in self._polymeric_nodes.values(): | |||||
| for src_name, input_attr in node.inputs.items(): | |||||
| if self._polymeric_nodes.get(src_name): | |||||
| input_attr['scope'] = NodeTypeEnum.POLYMERIC_SCOPE.value | |||||
| node.update_input({src_name: input_attr}) | |||||
| for dst_name, output_attr in node.outputs.items(): | |||||
| if self._polymeric_nodes.get(dst_name): | |||||
| output_attr['scope'] = NodeTypeEnum.POLYMERIC_SCOPE.value | |||||
| node.update_output({dst_name: output_attr}) | |||||
| def _update_polymeric_input_output(self): | |||||
| """Calc polymeric input and output after build polymeric node.""" | |||||
| for node in self._normal_nodes.values(): | |||||
| polymeric_input = self._calc_polymeric_attr(node, 'inputs') | |||||
| node.update_polymeric_input(polymeric_input) | |||||
| polymeric_output = self._calc_polymeric_attr(node, 'outputs') | |||||
| node.update_polymeric_output(polymeric_output) | |||||
| for name, node in self._polymeric_nodes.items(): | |||||
| polymeric_input = {} | |||||
| for src_name in node.inputs: | |||||
| output_name = self._calc_dummy_node_name(name, src_name) | |||||
| polymeric_input.update({output_name: {'edge_type': EdgeTypeEnum.DATA.value}}) | |||||
| node.update_polymeric_input(polymeric_input) | |||||
| polymeric_output = {} | |||||
| for dst_name in node.outputs: | |||||
| polymeric_output = {} | |||||
| output_name = self._calc_dummy_node_name(name, dst_name) | |||||
| polymeric_output.update({output_name: {'edge_type': EdgeTypeEnum.DATA.value}}) | |||||
| node.update_polymeric_output(polymeric_output) | |||||
| def _calc_polymeric_attr(self, node, attr): | |||||
| # Inherit input and output from sub nodes. | |||||
| self._inherit_input_output_from_subnode(scope_node, subnode_list=[node]) | |||||
| pre_index = index | |||||
| index = name.find('/', pre_index+1) | |||||
| # Cache all the scope node to normal node dict | |||||
| for node in scope_node_map.values(): | |||||
| self._cache_node(node) | |||||
| def _update_conflict_node(self, conflict_name): | |||||
| conflict_node = self._get_normal_node(node_name=conflict_name) | |||||
| base_name = conflict_name.split('/')[-1] | |||||
| new_name = Node.create_node_name(scope=conflict_node.scope, base_name=base_name) | |||||
| self._update_node_name_of_cache(conflict_node, new_name, update_parent=True) | |||||
| def _inherit_input_output_from_subnode(self, parent_node, subnode_list, filtered_type=None): | |||||
| """ | """ | ||||
| Calc polymeric input or polymeric output after build polymeric node. | |||||
| Adds the input and output of all direct child nodes to the current node. | |||||
| Args: | Args: | ||||
| node (Node): Computes the polymeric input for a given node. | |||||
| attr (str): The polymeric attr, optional value is `input` or `output`. | |||||
| parent_node (Node): The nodes that inherit the input and output of the child nodes. | |||||
| subnode_list (list[Node]): A list of child nodes that are inherited from the input and output. | |||||
| filtered_type (set(str)): Filter some input and output that do not require inheritance | |||||
| based on the node type. Default is filter const node. | |||||
| Note: | |||||
| - Only the inputs and outputs of the external scope are inherited. | |||||
| - Before add_const_node method, if the input is a const, | |||||
| the scope of the const node is not startswith the name of parent node. | |||||
| So in this scenario, we need to filter the const nodes. | |||||
| """ | |||||
| filtered_type = {NodeTypeEnum.CONST.value} if filtered_type is None else filtered_type | |||||
| for method in ['input', 'output', 'proxy_input', 'proxy_output']: | |||||
| for node in subnode_list: | |||||
| for item_name, item_attr in getattr(node, method).items(): | |||||
| target_node = self._get_normal_node(node_name=item_name) | |||||
| if item_name.startswith(f'{parent_node.name}/'): | |||||
| # Own scope, ignore | |||||
| continue | |||||
| Returns: | |||||
| dict, return polymeric input or polymeric output of the given node. | |||||
| if target_node.type in filtered_type: | |||||
| continue | |||||
| getattr(parent_node, f'add_{method}')(item_name, item_attr) | |||||
| def _build_aggregation_scope_nodes(self): | |||||
| """ | """ | ||||
| polymeric_attr = {} | |||||
| for node_name in getattr(node, attr): | |||||
| polymeric_node = self._polymeric_nodes.get(node_name) | |||||
| if node.node_type == NodeTypeEnum.POLYMERIC_SCOPE.value: | |||||
| node_name = node_name if not polymeric_node else polymeric_node.polymeric_scope_name | |||||
| dummy_node_name = self._calc_dummy_node_name(node.name, node_name) | |||||
| polymeric_attr.update({dummy_node_name: {'edge_type': EdgeTypeEnum.DATA.value}}) | |||||
| continue | |||||
| Under the same scope, the number of nodes of the same type will be aggregated after exceeding the set threshold. | |||||
| if not polymeric_node: | |||||
| continue | |||||
| Note: | |||||
| The threshold value refers to the `MIN_GROUP_NODE_COUNT`. | |||||
| """ | |||||
| logger.info("Start to build aggregation scope nodes.") | |||||
| group_node_map, filtered_group_names = self._find_group_nodes() | |||||
| # create merge scope nodes | |||||
| aggregation_scope_node_map = {} | |||||
| for i, group_name in enumerate(filtered_group_names): | |||||
| slash_index = group_name.rfind('/') | |||||
| if slash_index != -1: | |||||
| scope, op_type = group_name[:slash_index], group_name[slash_index+1:] | |||||
| else: | |||||
| scope, op_type = '', group_name | |||||
| count = len(group_node_map.get(group_name)) | |||||
| aggregation_node_name = Node.create_node_name(scope=scope, base_name=f'{op_type}[{count}]_{i}') | |||||
| aggregation_scope_node = Node(name=aggregation_node_name, node_id=aggregation_node_name) | |||||
| aggregation_scope_node.subnode_count = count | |||||
| aggregation_scope_node.scope = scope | |||||
| aggregation_scope_node.type = NodeTypeEnum.AGGREGATION_SCOPE.value | |||||
| # Update the name and scope of all children nodes | |||||
| for node in group_node_map[group_name]: | |||||
| base_name = node.name.split('/')[-1] | |||||
| new_name = Node.create_node_name(scope=aggregation_node_name, base_name=base_name) | |||||
| node.scope = aggregation_node_name | |||||
| # Since the name scope has not been created, there is no need to update the parent node. | |||||
| self._update_node_name_of_cache(node, new_name, update_parent=False) | |||||
| # Cache this node | |||||
| self._cache_node(aggregation_scope_node) | |||||
| aggregation_scope_node_map.update({group_name: aggregation_scope_node}) | |||||
| # Adds the input and output of all direct child nodes to the current node. | |||||
| for group_name, node in aggregation_scope_node_map.items(): | |||||
| self._inherit_input_output_from_subnode(node, group_node_map[group_name]) | |||||
| def _find_group_nodes(self): | |||||
| """ | |||||
| Find nodes that can be grouped into a group. | |||||
| if not node.name_scope and polymeric_node.name_scope: | |||||
| # If current node is in top-level layer, and the polymeric_node node is not in | |||||
| # the top-level layer, the polymeric node will not be the polymeric input | |||||
| # or polymeric output of current node. | |||||
| For direct child nodes in a scope, we divide them into multiple groups by node type. | |||||
| However, we will exclude several types of child nodes, | |||||
| because these types of nodes are not operational nodes. | |||||
| """ | |||||
| exclude_types = { | |||||
| NodeTypeEnum.CONST.value, | |||||
| NodeTypeEnum.NAME_SCOPE.value, | |||||
| } | |||||
| group_node_map = defaultdict(list) | |||||
| for node in self._normal_node_map.values(): | |||||
| if node.type in exclude_types: | |||||
| continue | continue | ||||
| group_name = Node.create_node_name(scope=node.scope, base_name=node.type) | |||||
| group_node_map[group_name].append(node) | |||||
| if node.name_scope == polymeric_node.name_scope \ | |||||
| or node.name_scope.startswith(polymeric_node.name_scope + '/'): | |||||
| polymeric_attr.update( | |||||
| {polymeric_node.polymeric_scope_name: {'edge_type': EdgeTypeEnum.DATA.value}}) | |||||
| # filter can group scope. | |||||
| filtered_group_names = [] | |||||
| for name, nodes in group_node_map.items(): | |||||
| if len(nodes) < self.MIN_GROUP_NODE_COUNT: | |||||
| continue | |||||
| filtered_group_names.append(name) | |||||
| return polymeric_attr | |||||
| return group_node_map, filtered_group_names | |||||
| def _calc_dummy_node_name(self, current_node_name, other_node_name): | |||||
| def _add_variable_nodes(self, node_type): | |||||
| """ | """ | ||||
| Calc dummy node name. | |||||
| We create the Const nodes or Parameter nodes in this method. | |||||
| Args: | Args: | ||||
| current_node_name (str): The name of current node. | |||||
| other_node_name (str): The target dummy node name. | |||||
| node_type (str): Decide which type of node to add. | |||||
| Optional is `NodeTypeEnum.CONST.value` and `NodeTypeEnum.PARAMETER.value`. | |||||
| Returns: | |||||
| str, the dummy node name. | |||||
| Note: | |||||
| This method relies on the presence of data in the const cache or parameter cache. | |||||
| """ | """ | ||||
| name_tmp = other_node_name | |||||
| if self._polymeric_nodes.get(other_node_name): | |||||
| name_tmp = self._polymeric_nodes[other_node_name].polymeric_scope_name | |||||
| name_tmp_list = name_tmp.split('/') | |||||
| current_name_list = current_node_name.split('/') | |||||
| index = 0 | |||||
| min_len = min(len(name_tmp_list), len(current_name_list)) | |||||
| for i in range(min_len): | |||||
| index = i | |||||
| if name_tmp_list[index] != current_name_list[index]: | |||||
| break | |||||
| dummy_node_name = '/'.join(name_tmp_list[:index+1]) | |||||
| return dummy_node_name | |||||
| logger.info("Start to add %s nodes to each scope in graph.", node_type) | |||||
| node_map = {} | |||||
| for node in self._normal_node_map.values(): | |||||
| for src_name, input_attr in dict(node.input).items(): | |||||
| if node_type == NodeTypeEnum.CONST.value and not self._const_node_temp_cache.get(src_name): | |||||
| continue | |||||
| if node_type == NodeTypeEnum.PARAMETER.value and not self._parameter_node_temp_cache.get(src_name): | |||||
| continue | |||||
| variable_name = Node.create_node_name(scope=node.scope, base_name=src_name) | |||||
| if node_map.get(variable_name): | |||||
| # There is no need to create the node repeatedly | |||||
| variable_node = node_map.get(variable_name) | |||||
| else: | |||||
| cache_node = self._get_normal_node(node_name=src_name) | |||||
| variable_node = Node(name=variable_name, node_id=variable_name) | |||||
| Node.copy_node_without_input_output(cache_node, variable_node) | |||||
| variable_node.scope = node.scope | |||||
| variable_node.add_output(dst_name=node.name, output_attr=input_attr) | |||||
| node_map.update({variable_name: variable_node}) | |||||
| node.delete_input(src_name) | |||||
| node.add_input(variable_name, input_attr) | |||||
| for node in node_map.values(): | |||||
| self._cache_node(node) | |||||
| # Remove nodes that are not used in the cache. | |||||
| if node_type == NodeTypeEnum.CONST.value: | |||||
| unused_names = set(self._const_node_temp_cache) - set(node_map) | |||||
| elif node_type == NodeTypeEnum.PARAMETER.value: | |||||
| unused_names = set(self._parameter_node_temp_cache) - set(node_map) | |||||
| else: | |||||
| raise ParamValueError("The node type should be const or parameter.") | |||||
| def _build_name_scope_nodes(self): | |||||
| """Build name scope node by every node name.""" | |||||
| normal_nodes = dict(self._normal_nodes) | |||||
| rename_node_names = {} | |||||
| for name, node in normal_nodes.items(): | |||||
| name_list = name.split('/') | |||||
| for i in range(1, len(name_list)): | |||||
| name_scope = '/'.join(name_list[:i]) | |||||
| name_scope_node = self._normal_nodes.get(name_scope) | |||||
| if name_scope_node is None: | |||||
| name_scope_node = Node(name_scope, node_id=name_scope) | |||||
| name_scope_node.node_type = NodeTypeEnum.NAME_SCOPE.value | |||||
| name_scope_node.name_scope = '/'.join(name_list[:i-1]) | |||||
| elif name_scope_node.node_type != NodeTypeEnum.NAME_SCOPE.value: | |||||
| # The name of this node conflicts with namescope, so rename this node | |||||
| old_name = name_scope_node.name | |||||
| old_names = name_scope_node.name.split('/') | |||||
| old_names[-1] = f'({old_names[-1]})' | |||||
| new_name = '/'.join(old_names) | |||||
| name_scope_node.name = new_name | |||||
| self._normal_nodes.pop(old_name) | |||||
| self._normal_nodes.update({new_name: name_scope_node}) | |||||
| rename_node_names.update({old_name: new_name}) | |||||
| # create new namescope | |||||
| name_scope_node = Node(name_scope, node_id=name_scope) | |||||
| name_scope_node.node_type = NodeTypeEnum.NAME_SCOPE.value | |||||
| name_scope_node.name_scope = '/'.join(name_list[:i-1]) | |||||
| # update the input and output of this to namescope node | |||||
| name_scope_with_slash = name_scope + '/' | |||||
| for src_name, input_attr in node.inputs.items(): | |||||
| if src_name.startswith(name_scope_with_slash): | |||||
| continue | |||||
| name_scope_node.update_input({src_name: input_attr}) | |||||
| self._delete_nodes_of_cache(unused_names) | |||||
| for dst_name, output_attr in node.outputs.items(): | |||||
| if dst_name.startswith(name_scope_with_slash): | |||||
| continue | |||||
| name_scope_node.update_output({dst_name: output_attr}) | |||||
| self._normal_nodes.update({name_scope: name_scope_node}) | |||||
| if rename_node_names: | |||||
| # If existing nodes are renamed, the inputs and outputs of all nodes need to be refreshed | |||||
| nodes = [] | |||||
| nodes.extend(self._normal_nodes.values()) | |||||
| nodes.extend(self._polymeric_nodes.values()) | |||||
| for node in nodes: | |||||
| attrs = ['inputs', 'outputs', 'polymeric_inputs', 'polymeric_outputs'] | |||||
| for item in attrs: | |||||
| tmp_dict = dict(getattr(node, item)) | |||||
| for name, value in tmp_dict.items(): | |||||
| new_name = rename_node_names.get(name, False) | |||||
| if new_name: | |||||
| getattr(node, item).pop(name) | |||||
| getattr(node, f'update_{item}')({new_name: value}) | |||||
| def _calc_subnode_count(self): | |||||
| """Calc all the direct sub node count.""" | |||||
| subnode_count_map = defaultdict(int) | |||||
| for node in self._normal_node_map.values(): | |||||
| if not node.scope: | |||||
| continue | |||||
| self._calc_subnode_count() | |||||
| if not self._is_node_exist(node_name=node.scope): | |||||
| logger.warning("Can not find a scope node by the given name(%s), " | |||||
| "the name scope nodes may not have been created.", node.scope) | |||||
| continue | |||||
| subnode_count_map[node.scope] = subnode_count_map[node.scope] + 1 | |||||
| def _calc_subnode_count(self): | |||||
| """Calc the sub node count of scope node.""" | |||||
| name_scope_mapping = {} | |||||
| for node in self._normal_nodes.values(): | |||||
| if node.name_scope: | |||||
| count = name_scope_mapping.get(node.name_scope, 0) | |||||
| name_scope_mapping[node.name_scope] = count + 1 | |||||
| for name_scope, count in name_scope_mapping.items(): | |||||
| node = self._normal_nodes[name_scope] | |||||
| for name, count in subnode_count_map.items(): | |||||
| node = self._get_normal_node(node_name=name) | |||||
| node.subnode_count = count | node.subnode_count = count | ||||
| def _get_normal_node(self, node_id=None, node_name=None): | |||||
| """Query node by node id or node name.""" | |||||
| if node_id is not None: | |||||
| name = self._node_id_map_name.get(node_id) | |||||
| node = self._normal_node_map.get(name) | |||||
| return node | |||||
| if node_name is not None: | |||||
| return self._normal_node_map.get(node_name) | |||||
| raise ParamMissError('Method requires an argument that is not None.') | |||||
| def _is_node_exist(self, node_id=None, node_name=None): | |||||
| """Check node is exist.""" | |||||
| if node_id is not None: | |||||
| return bool(self._node_id_map_name.get(node_id)) | |||||
| if node_name is not None: | |||||
| return bool(self._normal_node_map.get(node_name)) | |||||
| raise ParamMissError('Method requires an argument that is not None.') | |||||
| @property | |||||
| def normal_node_count(self): | |||||
| """Get the normal node count.""" | |||||
| return len(self._normal_node_map) | |||||
| def _cache_node(self, node): | |||||
| """Store the node in the cache.""" | |||||
| # Notice: | |||||
| # The additional caching of Const and Parameter is to handle the Const and Parameter nodes separately later. | |||||
| if node.type == NodeTypeEnum.CONST.value: | |||||
| self._const_node_temp_cache.update({node.name: node}) | |||||
| if node.type == NodeTypeEnum.PARAMETER.value: | |||||
| self._parameter_node_temp_cache.update({node.name: node}) | |||||
| self._normal_node_map.update({node.name: node}) | |||||
| self._node_id_map_name.update({node.node_id: node.name}) | |||||
| def _delete_nodes_of_cache(self, node_names): | |||||
| """Delete node from cache.""" | |||||
| logger.debug("These nodes will be removed from the cache, node names: %s.", str(node_names)) | |||||
| for name in node_names: | |||||
| if self._parameter_node_temp_cache.get(name): | |||||
| self._parameter_node_temp_cache.pop(name) | |||||
| if self._const_node_temp_cache.get(name): | |||||
| self._const_node_temp_cache.pop(name) | |||||
| node = self._get_normal_node(node_name=name) | |||||
| self._normal_node_map.pop(name) | |||||
| self._node_id_map_name.pop(node.node_id) | |||||
| def _update_node_name_of_cache(self, node, new_name, update_parent=False): | |||||
| """ | |||||
| Update a node name which is stored in cache. | |||||
| Args: | |||||
| node (Node): The node that will be renamed. | |||||
| new_name (str): The new name. | |||||
| update_parent (bool): Determines whether the input and output of the parent node need to be updated. | |||||
| """ | |||||
| logger.debug('Update node name of cache, node(%s), new name is %s.', str(node), new_name) | |||||
| origin_name = node.name | |||||
| node.name = new_name | |||||
| # Find all nodes that need to modify the input and input | |||||
| update_node_map = {} | |||||
| for method in ['input', 'output', 'proxy_input', 'proxy_output']: | |||||
| for target_name in getattr(node, method): | |||||
| target_node = self._get_normal_node(node_name=target_name) | |||||
| if target_node is None: | |||||
| message = f"Node should not be None, name: {target_name}, {method}: {list(getattr(node, method))}." | |||||
| logger.error(message) | |||||
| continue | |||||
| update_node_map.update({target_name: target_node}) | |||||
| if not update_parent: | |||||
| continue | |||||
| slash_index = target_name.find('/') | |||||
| while slash_index != -1: | |||||
| scope_name = target_name[:slash_index] | |||||
| slash_index = target_name.find('/', slash_index+1) | |||||
| if update_node_map.get(scope_name): | |||||
| continue | |||||
| scope_node = self._get_normal_node(node_name=scope_name) | |||||
| update_node_map.update({scope_name: scope_node}) | |||||
| # Update the input and output of the nodes | |||||
| for target_node in update_node_map.values(): | |||||
| for method in ['input', 'output', 'proxy_input', 'proxy_output']: | |||||
| attr_temp = getattr(target_node, method).get(origin_name) | |||||
| if attr_temp is None: | |||||
| # This method does not have this node, so it is skipped | |||||
| continue | |||||
| # Delete the old attribute and update new name to source node or destination node. | |||||
| getattr(target_node, f'delete_{method}')(origin_name) | |||||
| getattr(target_node, f'add_{method}')(new_name, attr_temp) | |||||
| # Delete the origin node in cache. | |||||
| self._delete_nodes_of_cache(node_names=[origin_name]) | |||||
| self._cache_node(node) | |||||
| def _process_independent_layout(self): | |||||
| """Handle separate layout nodes.""" | |||||
| independent_layout_node_map = {} | |||||
| for node in self._normal_node_map.values(): | |||||
| base_name = node.name.split('/')[-1] | |||||
| if node.type == NodeTypeEnum.AGGREGATION_SCOPE.value and NodeTypeEnum.PARAMETER.value in base_name: | |||||
| independent_layout_node_map[node.name] = node | |||||
| # Find all sub nodes | |||||
| subnode_map = defaultdict(list) | |||||
| for node in self._normal_node_map.values(): | |||||
| if independent_layout_node_map.get(node.scope): | |||||
| subnode_map[node.scope].append(node) | |||||
| # Notice: | |||||
| # The following processing is only done for the parameter node, other types of nodes are not processed. | |||||
| # Later, when you need to extend to other nodes, the code needs to be adjusted. | |||||
| for scope_node in independent_layout_node_map.values(): | |||||
| scope_node.independent_layout = True | |||||
| method = 'output' | |||||
| for target_name, target_attr in dict(getattr(scope_node, method)).items(): | |||||
| proxy_attr = dict(edge_type=target_attr['edge_type']) | |||||
| target_node = self._get_normal_node(node_name=target_name) | |||||
| getattr(target_node, 'add_proxy_input')(scope_node.name, proxy_attr) | |||||
| # Note: | |||||
| # If the source node and the destination node are not in the same scope, | |||||
| # the proxy node is presented as scope in order to simplify the flow of the display data. | |||||
| # For example, the data flow is parameter[5]_1 -> add[5]_1/add1 | |||||
| # we create a scope proxy node(add[5]_1) for parameter[5]_1, | |||||
| # so there is a proxy data flow parameter[5]_1 -> add[5]_1 instead of parameter[5]_1 -> add[5]_1/add1. | |||||
| if target_node.scope == scope_node.scope: | |||||
| getattr(scope_node, f'add_proxy_{method}')(target_name, proxy_attr) | |||||
| else: | |||||
| target_scope_node = self._get_normal_node(node_name=target_node.scope) | |||||
| getattr(scope_node, f'add_proxy_{method}')(target_node.scope, proxy_attr) | |||||
| getattr(target_scope_node, 'add_proxy_input')(scope_node.name, proxy_attr) | |||||
| for subnode in subnode_map[scope_node.name]: | |||||
| for target_name, target_attr in dict(getattr(subnode, method)).items(): | |||||
| proxy_attr = dict(edge_type=target_attr['edge_type']) | |||||
| target_node = self._get_normal_node(node_name=target_name) | |||||
| if target_node.scope == scope_node.scope: | |||||
| getattr(subnode, f'add_proxy_{method}')(target_name, proxy_attr) | |||||
| else: | |||||
| getattr(subnode, f'add_proxy_{method}')(target_node.scope, proxy_attr) | |||||
| input_attr = getattr(target_node, 'input')[subnode.name] | |||||
| input_attr['independent_layout'] = True | |||||
| target_node.add_input(subnode.name, input_attr) | |||||
| @@ -13,236 +13,135 @@ | |||||
| # limitations under the License. | # limitations under the License. | ||||
| # ============================================================================ | # ============================================================================ | ||||
| """This file is used to define the MindSpore graph.""" | """This file is used to define the MindSpore graph.""" | ||||
| import re | |||||
| import copy | |||||
| import time | |||||
| from mindinsight.datavisual.common.log import logger | from mindinsight.datavisual.common.log import logger | ||||
| from mindinsight.datavisual.proto_files.mindinsight_anf_ir_pb2 import DataType | |||||
| from .node import Node | from .node import Node | ||||
| from .node import NodeTypeEnum | from .node import NodeTypeEnum | ||||
| from .graph import Graph | from .graph import Graph | ||||
| from .graph import EdgeTypeEnum | from .graph import EdgeTypeEnum | ||||
| from .graph import DataTypeEnum | |||||
| class MSGraph(Graph): | class MSGraph(Graph): | ||||
| """The object describes the MindSpore graph, and it is defined in the anf_if proto file.""" | |||||
| """The object describes the MindSpore graph, and it is defined in the anf_ir proto file.""" | |||||
| def build_graph(self, graph_proto): | |||||
| def build_graph(self, proto_data): | |||||
| """ | """ | ||||
| Build graph by graph proto which refer to `anf_ir_pb2.GraphProto`, and set status to loading. | |||||
| Build graph by graph proto which refer to `anf_ir_pb2.GraphProto`. | |||||
| Args: | Args: | ||||
| graph_proto (anf_ir_pb2.GraphProto): Refer to `anf_ir_pb2.GraphProto`. | |||||
| proto_data (anf_ir_pb2.GraphProto): Refer to `anf_ir_pb2.GraphProto`. | |||||
| """ | """ | ||||
| logger.info("Start to build graph.") | |||||
| logger.info("Start to build graph, graph name: %s.", proto_data.name) | |||||
| start_time = time.time() | |||||
| self._build_leaf_nodes(graph_proto) | |||||
| self._build_polymeric_nodes() | |||||
| self._build_name_scope_nodes() | |||||
| self._update_polymeric_input_output() | |||||
| logger.info("Build graph end, normal node count: %s, polymeric node " | |||||
| "count: %s.", len(self._normal_nodes), len(self._polymeric_nodes)) | |||||
| super(MSGraph, self).build_graph(proto_data) | |||||
| def _build_leaf_nodes(self, graph_proto): | |||||
| """ | |||||
| Build leaf node from graph proto. | |||||
| precision = 6 | |||||
| time_consuming = round(time.time()-start_time, precision) | |||||
| logger.info("Build graph end, all node count: %s, const count: %s, parameter count: %s, time-consuming: %s s.", | |||||
| self.normal_node_count, len(self._const_node_temp_cache), | |||||
| len(self._parameter_node_temp_cache), time_consuming) | |||||
| Left node will contain operation node, parameter node, const node. | |||||
| def _parse_data(self, proto_data): | |||||
| """ | |||||
| The proto data is parsed and all nodes are stored in the specified structure. | |||||
| Args: | Args: | ||||
| graph_proto (anf_ir_pb2.model_proto.graph): Refer to anf_ir_pb2.model_proto.graph. | |||||
| proto_data (anf_ir_pb2.GraphProto): Refer to anf_ir_pb2.GraphProto object. | |||||
| """ | """ | ||||
| logger.info("Start to build leaf nodes.") | |||||
| leaf_node_id_map_name = {} | |||||
| const_nodes_map = {} | |||||
| logger.info("Start to parse graph proto data.") | |||||
| for node_def in graph_proto.node: | |||||
| if not node_def.name: | |||||
| logger.warning("Finding a node with an empty name will not save it.") | |||||
| continue | |||||
| node = self._parse_graph_proto_node(node_def) | |||||
| leaf_node_id_map_name.update({node.node_id: node.name}) | |||||
| self._parse_op_nodes(proto_data.node) | |||||
| self._parse_parameters(proto_data.parameters) | |||||
| self._parse_consts(proto_data.const_vals) | |||||
| for parameter in graph_proto.parameters: | |||||
| if not parameter.name: | |||||
| logger.warning("Finding a parameter with an empty name will not save it.") | |||||
| continue | |||||
| node = self._parse_graph_proto_parameter(parameter) | |||||
| const_nodes_map.update({node.name: node}) | |||||
| self._update_input_after_create_node() | |||||
| self._update_output_after_create_node() | |||||
| for i, const in enumerate(graph_proto.const_vals): | |||||
| if not const.key: | |||||
| logger.warning("Finding a const with an empty key will not save it.") | |||||
| continue | |||||
| node_id = 'const_{}'.format(i) | |||||
| node = self._parse_graph_proto_const(const, node_id) | |||||
| const_nodes_map.update({const.key: node}) | |||||
| logger.info("Parse proto data end, normal node count(only contain op node, " | |||||
| "parameter, const): %s.", self.normal_node_count) | |||||
| self._calc_input(leaf_node_id_map_name, graph_proto, const_nodes_map) | |||||
| self._calc_output() | |||||
| logger.info("Build leaf nodes end, normal nodes count: %s, group count: %s, " | |||||
| "leaf nodes count: %s.", len(self._normal_nodes), len(self._node_groups), | |||||
| len(self._leaf_nodes)) | |||||
| def _calc_input(self, leaf_node_id_map_name, graph_proto, const_nodes_map): | |||||
| def _parse_op_nodes(self, node_protos): | |||||
| """ | """ | ||||
| Calc input for every leaf node. | |||||
| Parse `anf_ir_pb2.NodeProto` object, and create a normal node. | |||||
| Args: | Args: | ||||
| leaf_node_id_map_name (dict[str, str]): Format is {'node_id': 'node_name'}. | |||||
| graph_proto (anf_ir_pb2.model_proto.graph): See anf_ir_pb2.model_proto.graph. | |||||
| const_nodes_map (dict[str, Node]): Format is {'node name': <Const node>}. | |||||
| node_protos (list[anf_ir_pb2.NodeProto]): Refer to anf_ir_pb2.NodeProto. | |||||
| """ | """ | ||||
| logger.debug("Start to calc input.") | |||||
| for node_def in graph_proto.node: | |||||
| if not node_def.name: | |||||
| logger.debug("The node name is empty, ignore it.") | |||||
| logger.debug("Start to parse op nodes from proto.") | |||||
| for node_proto in node_protos: | |||||
| if not node_proto.name: | |||||
| logger.warning("Finding a node with an empty name will not save it.") | |||||
| continue | continue | ||||
| node_name = leaf_node_id_map_name[node_def.name] | |||||
| node = self._leaf_nodes[node_name] | |||||
| for input_def in node_def.input: | |||||
| if not input_def.name: | |||||
| logger.warning("The input node name is empty, ignore it. node name: %s.", node_name) | |||||
| continue | |||||
| edge_type = EdgeTypeEnum.DATA.value | |||||
| if input_def.type == "CONTROL_EDGE": | |||||
| edge_type = EdgeTypeEnum.CONTROL.value | |||||
| if const_nodes_map.get(input_def.name): | |||||
| const_node = copy.deepcopy(const_nodes_map[input_def.name]) | |||||
| src_name = '{}/{}'.format(node.name_scope, input_def.name) | |||||
| if not self._normal_nodes.get(src_name): | |||||
| const_node.name = src_name | |||||
| const_node.name_scope = node.name_scope | |||||
| self._normal_nodes.update({src_name: const_node}) | |||||
| self._leaf_nodes.update({src_name: const_node}) | |||||
| src_node = self._leaf_nodes.get(src_name) | |||||
| else: | |||||
| src_name = leaf_node_id_map_name.get(input_def.name) | |||||
| if not src_name: | |||||
| logger.warning("The input_def name '%s' in node '%s' is invalid, " | |||||
| "will be ignore.", input_def.name, node_name) | |||||
| continue | |||||
| src_node = self._leaf_nodes.get(src_name) | |||||
| if src_node is None: | |||||
| logger.warning("The input '%s' in node '%s' is not in " | |||||
| "leaf nodes.", src_name, node_name) | |||||
| continue | |||||
| input_item = { | |||||
| src_name: { | |||||
| "shape": src_node.shape, | |||||
| "edge_type": edge_type, | |||||
| "scope": NodeTypeEnum.NAME_SCOPE.value | |||||
| } | |||||
| } | |||||
| node.update_input(input_item) | |||||
| if self._normal_nodes.get(node_name): | |||||
| self._normal_nodes[node_name] = node | |||||
| else: | |||||
| group_name = self._create_group_name(node.name_scope, node.node_type, node.name) | |||||
| self._node_groups[group_name][node.name] = node | |||||
| def _calc_output(self): | |||||
| """Calc output of every node.""" | |||||
| logger.debug("Start to calc output.") | |||||
| for name, node in self._leaf_nodes.items(): | |||||
| if node.node_type == NodeTypeEnum.CONST.value: | |||||
| continue | |||||
| for src_name, input_attr in node.inputs.items(): | |||||
| src_node = self._leaf_nodes[src_name] | |||||
| if src_node.node_type == NodeTypeEnum.CONST.value: | |||||
| continue | |||||
| node_name = Node.create_node_name(scope=node_proto.scope, | |||||
| base_name=f'{node_proto.op_type}{node_proto.name}') | |||||
| node = Node(name=node_name, node_id=node_proto.name) | |||||
| node.type = node_proto.op_type | |||||
| logger.debug("Foreach graph proto nodes, node id: %s, node name: %s, node def name: %s, " | |||||
| "input count: %s", node.node_id, node.name, node_proto.name, len(node_proto.input)) | |||||
| if self._normal_nodes.get(src_name): | |||||
| self._normal_nodes[src_name].update_output({name: input_attr}) | |||||
| else: | |||||
| group_name = self._create_group_name(src_node.name_scope, | |||||
| src_node.node_type, src_node.name) | |||||
| self._node_groups[group_name][src_name].update_output({name: input_attr}) | |||||
| self._parse_attributes(node_proto.attribute, node) | |||||
| self._parse_inputs(node_proto.input, node) | |||||
| def _parse_graph_proto_node(self, node_def): | |||||
| """ | |||||
| Parse `anf_ir_pb2.model_proto.graph.node_def`, and create a a node. | |||||
| node.output_i = node_proto.output_i | |||||
| node.scope = node_proto.scope | |||||
| node.output_shape = self._get_shape_by_parse_type_proto(node_proto.output_type) | |||||
| node.output_data_type = self._get_data_type_by_parse_type_proto(node_proto.output_type) | |||||
| Args: | |||||
| node_def (anf_ir_pb2.model_proto.graph.node_def): Refer to anf_ir_pb2.model_proto.graph.node_def. | |||||
| self._cache_node(node) | |||||
| Returns: | |||||
| Node, a `Node` object. | |||||
| """ | |||||
| node_name = '/'.join([node_def.scope, node_def.op_type]) + node_def.name \ | |||||
| if node_def.scope else node_def.op_type + node_def.name | |||||
| node = Node(name=node_name, node_id=node_def.name) | |||||
| node.node_type = node_def.op_type | |||||
| logger.debug("Foreach graph proto nodes, node id: %s, node name: %s, node def name: %s, " | |||||
| "input count: %s", node.node_id, node.name, node_def.name, len(node_def.input)) | |||||
| for attr in node_def.attribute: | |||||
| node.update_attr({attr.name: str(attr.value)}) | |||||
| node.output_i = node_def.output_i | |||||
| node.name_scope = node_def.scope | |||||
| output_type = node_def.output_type | |||||
| shape = self._parse_type_proto(output_type) | |||||
| node.shape = shape | |||||
| self._leaf_nodes.update({node.name: node}) | |||||
| group_name = self._create_group_name(node.name_scope, node.node_type, node.name) | |||||
| if group_name is not None: | |||||
| node_dict = self._node_groups.get(group_name, {}) | |||||
| node_dict.update({node.name: node}) | |||||
| self._node_groups.update({group_name: node_dict}) | |||||
| else: | |||||
| self._normal_nodes.update({node.name: node}) | |||||
| return node | |||||
| def _parse_graph_proto_parameter(self, parameter): | |||||
| def _parse_parameters(self, parameter_protos): | |||||
| """ | """ | ||||
| Parse anf_ir_pb2.model_proto.graph.parameter, and create a parameter node. | |||||
| Parse `anf_ir_pb2.ParameterProto` object, and create a parameter node. | |||||
| Args: | Args: | ||||
| parameter (anf_ir_pb2.model_proto.graph.parameter): Refer to anf_ir_pb2.model_proto.graph.parameter. | |||||
| Returns: | |||||
| Node, a `Node` object. | |||||
| parameter_protos (list[anf_ir_pb2.ParameterProto]): Refer to anf_ir_pb2.ParameterProto. | |||||
| """ | """ | ||||
| node = Node(name=parameter.name, node_id=parameter.name) | |||||
| node.node_type = NodeTypeEnum.PARAMETER.value | |||||
| node.shape = self._parse_type_proto(parameter.type) | |||||
| logger.debug("Foreach graph proto parameters, node id: %s, node name: %s, " | |||||
| "node def name: %s", node.node_id, node.name, parameter.name) | |||||
| return node | |||||
| def _parse_graph_proto_const(self, const, const_node_id): | |||||
| logger.debug("Start to parse parameters from proto.") | |||||
| for parameter in parameter_protos: | |||||
| if not parameter.name: | |||||
| logger.warning("Finding a parameter with an empty name will not save it.") | |||||
| continue | |||||
| node = Node(name=parameter.name, node_id=parameter.name) | |||||
| node.type = NodeTypeEnum.PARAMETER.value | |||||
| node.output_shape = self._get_shape_by_parse_type_proto(parameter.type) | |||||
| attr = dict( | |||||
| type=self._get_data_type_by_parse_type_proto(parameter.type), | |||||
| shape=str(self._get_shape_by_parse_type_proto(parameter.type)) | |||||
| ) | |||||
| node.add_attr(attr) | |||||
| self._cache_node(node) | |||||
| logger.debug("Foreach graph proto parameters, node id: %s, node name: %s, " | |||||
| "node def name: %s", node.node_id, node.name, parameter.name) | |||||
| def _parse_consts(self, consts): | |||||
| """ | """ | ||||
| Parse anf_ir_pb2.model_proto.graph.const, and create a const node. | |||||
| Parse `anf_ir_pb2.NameValueProto` object, and create a const node. | |||||
| Args: | Args: | ||||
| const (anf_ir_pb2.model_proto.graph.const): Refer to anf_ir_pb2.model_proto.graph.const | |||||
| const_node_id (str): The id of the new const node, it should be unique in graph. | |||||
| Returns: | |||||
| Node, a `Node` object. | |||||
| consts (list[anf_ir_pb2.NameValueProto]): Refer to `anf_ir_pb2.NameValueProto` object. | |||||
| """ | """ | ||||
| node = Node(name=const.key, node_id=const_node_id) | |||||
| node.node_type = NodeTypeEnum.CONST.value | |||||
| node.update_attr({const.key: str(const.value)}) | |||||
| if const.value.dtype == DataTypeEnum.DT_TENSOR.value: | |||||
| shape = [] | |||||
| for dim in const.value.tensor_val.dims: | |||||
| shape.append(dim) | |||||
| node.shape = shape | |||||
| return node | |||||
| def _parse_type_proto(self, type_proto): | |||||
| logger.debug("Start to parse consts from proto.") | |||||
| for const in consts: | |||||
| if not const.key: | |||||
| logger.warning("Finding a const with an empty key will not save it.") | |||||
| continue | |||||
| node = Node(name=const.key, node_id=const.key) | |||||
| node.type = NodeTypeEnum.CONST.value | |||||
| node.add_attr({const.key: str(const.value)}) | |||||
| if const.value.dtype == DataType.DT_TENSOR: | |||||
| shape = [] | |||||
| for dim in const.value.tensor_val.dims: | |||||
| shape.append(dim) | |||||
| node.output_shape = shape | |||||
| self._cache_node(node) | |||||
| def _get_shape_by_parse_type_proto(self, type_proto): | |||||
| """ | """ | ||||
| Parse proto's `message TypeProto` to get shape information. | Parse proto's `message TypeProto` to get shape information. | ||||
| @@ -260,32 +159,113 @@ class MSGraph(Graph): | |||||
| shapes.append(dim.size) | shapes.append(dim.size) | ||||
| if type_proto.HasField('sequence_type'): | if type_proto.HasField('sequence_type'): | ||||
| for elem_type in type_proto.sequence_type.elem_types: | for elem_type in type_proto.sequence_type.elem_types: | ||||
| shapes.append(self._parse_type_proto(elem_type)) | |||||
| shapes.append(self._get_shape_by_parse_type_proto(elem_type)) | |||||
| return shapes | return shapes | ||||
| def _create_group_name(self, name_scope, node_type, node_name): | |||||
| def _get_data_type_by_parse_type_proto(self, type_proto): | |||||
| """ | """ | ||||
| Create group name by node name, name scope, node type. | |||||
| Get data type by parse type proto object. | |||||
| Only nodes that conform to the rules are aggregated. | |||||
| The name of the DataType, refer to `anf_ir_pb2.DataType` object. | |||||
| If data type is tensor or tuple, the data name we return is `data_type[element_type, element_type]`. | |||||
| Args: | Args: | ||||
| name_scope (str): The node name scope. | |||||
| node_type (str): The node type. | |||||
| node_name (str): The node name. | |||||
| type_proto (anf_ir_pb2.TypeProto): Refer to anf_ir_pb2.TypeProto. | |||||
| Returns: | Returns: | ||||
| Optional[str], if match the rules will return a group name, else return None. | |||||
| str, the data type. | |||||
| """ | |||||
| data_type_name = self._get_data_type_name_by_value(type_proto, type_proto.data_type, field_name='data_type') | |||||
| if type_proto.data_type == DataType.DT_TENSOR: | |||||
| tensor_type_proto = type_proto.tensor_type | |||||
| value = type_proto.tensor_type.elem_type | |||||
| elem_type_name = self._get_data_type_name_by_value(tensor_type_proto, value, field_name='elem_type') | |||||
| return f'{data_type_name}[{elem_type_name}]' | |||||
| if type_proto.data_type == DataType.DT_TUPLE: | |||||
| data_types = [] | |||||
| for elem_type in type_proto.sequence_type.elem_types: | |||||
| data_types.append(self._get_data_type_by_parse_type_proto(elem_type)) | |||||
| return f'{data_type_name}{str(data_types)}' | |||||
| return data_type_name | |||||
| def _parse_inputs(self, input_protos, node): | |||||
| """ | |||||
| Parse `anf_ir_pb2.InputProto` object. | |||||
| Args: | |||||
| input_protos (list[anf_ir_pb2.InputProto]): Refer to `anf_ir_pb2.InputProto` object. | |||||
| node (Node): Refer to `Node` object, it is used to log message and update input. | |||||
| """ | """ | ||||
| group_types = ['Reshape', 'Variable'] | |||||
| pattern_names = r'.*?/Cast-op\d+' | |||||
| for input_proto in input_protos: | |||||
| if not input_proto.name: | |||||
| logger.warning("The name in input proto of node(%s) is empty, will ignore.", node.name) | |||||
| continue | |||||
| edge_type = EdgeTypeEnum.DATA.value if not input_proto.type else EdgeTypeEnum.CONTROL.value | |||||
| # Notice: | |||||
| # 1. The name in the input proto is the node id of the Node object. | |||||
| # 2. In the current step, the shape of source node cannot be obtained, | |||||
| # so it is set to empty list by default, and the next step will update it. | |||||
| # 3. Same with scope, set the default value first. | |||||
| input_attr = { | |||||
| "shape": [], | |||||
| "edge_type": edge_type, | |||||
| "independent_layout": False, | |||||
| 'data_type': '' | |||||
| } | |||||
| node.add_input(src_name=input_proto.name, input_attr=input_attr) | |||||
| if node_type in group_types: | |||||
| group_name = name_scope + '/' + node_type if name_scope else node_type | |||||
| return group_name | |||||
| def _parse_attributes(self, attributes, node): | |||||
| """ | |||||
| Parse `anf_ir_pb2.AttributeProto` object., and Filters large attribute values. | |||||
| Args: | |||||
| attributes (list[anf_ir_pb2.AttributeProto]): Refer to `anf_ir_pb2.AttributeProto` object. | |||||
| node (Node): Refer to `Node` object, it is used to log message and update attr. | |||||
| """ | |||||
| for attr in attributes: | |||||
| if attr.value.ByteSize() > self.MAX_NODE_ATTRIBUTE_VALUE_BYTES: | |||||
| message = f"The attribute value of node({node.name}) " \ | |||||
| f"is over {self.MAX_NODE_ATTRIBUTE_VALUE_BYTES} Bytes, will ignore." | |||||
| logger.info(message) | |||||
| continue | |||||
| node.add_attr({attr.name: str(attr.value)}) | |||||
| def _update_input_after_create_node(self): | |||||
| """Update the input of node after create node.""" | |||||
| for node in self._normal_node_map.values(): | |||||
| for src_node_id, input_attr in dict(node.input).items(): | |||||
| node.delete_input(src_node_id) | |||||
| if not self._is_node_exist(node_id=src_node_id): | |||||
| message = f"The input node could not be found by node id({src_node_id}) " \ | |||||
| f"while updating the input of the node({node})" | |||||
| logger.warning(message) | |||||
| continue | |||||
| src_node = self._get_normal_node(node_id=src_node_id) | |||||
| input_attr['shape'] = src_node.output_shape | |||||
| input_attr['data_type'] = src_node.output_data_type | |||||
| node.add_input(src_name=src_node.name, input_attr=input_attr) | |||||
| def _update_output_after_create_node(self): | |||||
| """Update the output of node after create node.""" | |||||
| # Constants and parameter should not exist for input and output. | |||||
| filtered_node = {NodeTypeEnum.CONST.value, NodeTypeEnum.PARAMETER.value} | |||||
| for node in self._normal_node_map.values(): | |||||
| for src_name, input_attr in node.input.items(): | |||||
| src_node = self._get_normal_node(node_name=src_name) | |||||
| if src_node.type in filtered_node: | |||||
| continue | |||||
| if node_type == 'FrameworkOp' and re.search(pattern_names, node_name): | |||||
| group_name = name_scope + '/' + 'Cast-op' if name_scope else 'Cast-op' | |||||
| return group_name | |||||
| src_node.add_output(node.name, input_attr) | |||||
| return None | |||||
| @staticmethod | |||||
| def _get_data_type_name_by_value(data_type, value, field_name='data_type'): | |||||
| """Get the data type name by the enum value, data_type refer to `DataType` object.""" | |||||
| return data_type.DESCRIPTOR.fields_by_name[field_name].enum_type.values_by_number[value].name | |||||
| @@ -17,10 +17,11 @@ This file is used to define the node of graph and associated base types. | |||||
| """ | """ | ||||
| from enum import Enum | from enum import Enum | ||||
| class NodeTypeEnum(Enum): | class NodeTypeEnum(Enum): | ||||
| """Node type enum. The following types are new to our custom.""" | """Node type enum. The following types are new to our custom.""" | ||||
| NAME_SCOPE = 'name_scope' | NAME_SCOPE = 'name_scope' | ||||
| POLYMERIC_SCOPE = 'polymeric_scope' | |||||
| AGGREGATION_SCOPE = 'aggregation_scope' | |||||
| PARAMETER = 'Parameter' | PARAMETER = 'Parameter' | ||||
| CONST = 'Const' | CONST = 'Const' | ||||
| @@ -36,32 +37,33 @@ class Node: | |||||
| def __init__(self, name, node_id): | def __init__(self, name, node_id): | ||||
| self._node_id = node_id | self._node_id = node_id | ||||
| self._name = name | |||||
| self._type = "" | |||||
| self.name = name | |||||
| self.type = "" | |||||
| self._attr = dict() | self._attr = dict() | ||||
| self._inputs = dict() | |||||
| self._output_i = -1 | |||||
| self._outputs = {} | |||||
| self._polymeric_inputs = {} | |||||
| self._polymeric_outputs = {} | |||||
| self._polymeric_scope_name = "" | |||||
| self._subnode_count = 0 | |||||
| self._name_scope = "" | |||||
| self.shape = [] | |||||
| self._input = dict() | |||||
| self.output_i = 0 | |||||
| self._output = {} | |||||
| self._proxy_input = {} | |||||
| self._proxy_output = {} | |||||
| self.subnode_count = 0 | |||||
| self.scope = "" | |||||
| self.independent_layout = False | |||||
| self.output_shape = [] | |||||
| self.output_data_type = "" | |||||
| def to_dict(self): | def to_dict(self): | ||||
| """Converts the node object to dictionary format.""" | """Converts the node object to dictionary format.""" | ||||
| return { | return { | ||||
| 'name': self._name, | |||||
| 'type': self._type, | |||||
| 'name': self.name, | |||||
| 'type': self.type, | |||||
| 'attr': self._attr, | 'attr': self._attr, | ||||
| 'input': self._inputs, | |||||
| 'output_i': self._output_i, | |||||
| 'output': self._outputs, | |||||
| 'polymeric_input': self._polymeric_inputs, | |||||
| 'polymeric_output': self._polymeric_outputs, | |||||
| 'subnode_count': self._subnode_count, | |||||
| 'polymeric_scope_name': self._polymeric_scope_name | |||||
| 'input': self._input, | |||||
| 'output': self._output, | |||||
| 'output_i': self.output_i, | |||||
| 'proxy_input': self._proxy_input, | |||||
| 'proxy_output': self._proxy_output, | |||||
| 'subnode_count': self.subnode_count, | |||||
| 'independent_layout': self.independent_layout | |||||
| } | } | ||||
| @property | @property | ||||
| @@ -69,32 +71,26 @@ class Node: | |||||
| """The id of this node, and id is unique in graph.""" | """The id of this node, and id is unique in graph.""" | ||||
| return self._node_id | return self._node_id | ||||
| @property | |||||
| def name(self): | |||||
| """Get node name.""" | |||||
| return self._name | |||||
| @name.setter | |||||
| def name(self, name): | |||||
| """Set node name.""" | |||||
| self._name = name | |||||
| @staticmethod | |||||
| def create_node_name(scope, base_name): | |||||
| """ | |||||
| The name of the node consists of the scope and the basic name. | |||||
| @property | |||||
| def node_type(self): | |||||
| """Get node type.""" | |||||
| return self._type | |||||
| Args: | |||||
| scope (str): The scope of node, such as 'Default/Conv2D' | |||||
| base_name (str): The base name of node, such as 'Add11'. | |||||
| @node_type.setter | |||||
| def node_type(self, node_type): | |||||
| """Set node type.""" | |||||
| self._type = node_type | |||||
| Returns: | |||||
| str, a node name. | |||||
| """ | |||||
| return f'{scope}/{base_name}' if scope else base_name | |||||
| @property | @property | ||||
| def attr(self): | def attr(self): | ||||
| """Get node attr.""" | """Get node attr.""" | ||||
| return self._attr | return self._attr | ||||
| def update_attr(self, attr_dict): | |||||
| def add_attr(self, attr_dict): | |||||
| """ | """ | ||||
| Update node attr. | Update node attr. | ||||
| @@ -104,114 +100,122 @@ class Node: | |||||
| self._attr.update(attr_dict) | self._attr.update(attr_dict) | ||||
| @property | @property | ||||
| def inputs(self): | |||||
| def input(self): | |||||
| """ | """ | ||||
| Get all input of current node. | Get all input of current node. | ||||
| Returns: | Returns: | ||||
| dict[str, dict], format is {'<src_name>': {'shape': [], 'edge_type', 'scope'}}. | |||||
| dict[str, dict], refer to the input attr. | |||||
| """ | """ | ||||
| return self._inputs | |||||
| return self._input | |||||
| def update_input(self, input_dict): | |||||
| def add_input(self, src_name, input_attr): | |||||
| """ | """ | ||||
| Update input. | Update input. | ||||
| Args: | Args: | ||||
| input_dict (dict[str, dict]): Key is a source node name, and the value is a dict. | |||||
| src_name (stc): The source node name. | |||||
| input_attr (dict): The attribute of the input. | |||||
| - shape (list): The shape of input tensor. | - shape (list): The shape of input tensor. | ||||
| - edge_type (str): The type of edge, optional value refer to `EdgeTypeEnum`. | - edge_type (str): The type of edge, optional value refer to `EdgeTypeEnum`. | ||||
| - scope (str): The scope of this source node. | |||||
| - data_type (str): The data type of the input. | |||||
| - independent_layout (bool): Indicates whether the source nodes are laid out independently. | |||||
| """ | """ | ||||
| self._inputs.update(input_dict) | |||||
| self._input.update({src_name: input_attr}) | |||||
| @property | |||||
| def output_i(self): | |||||
| """The memory address of this node when it is in run time.""" | |||||
| return self._output_i | |||||
| @output_i.setter | |||||
| def output_i(self, output_i): | |||||
| """Set memory address.""" | |||||
| self._output_i = output_i | |||||
| @property | |||||
| def polymeric_inputs(self): | |||||
| def delete_input(self, src_name): | |||||
| """ | """ | ||||
| The polymeric input is the input of the polymeric nodes. | |||||
| Delete input attribute by the given source name. | |||||
| Returns: | |||||
| dict[str, dict], format is {'<src_name>': {'edge_type': '<value>'}}. | |||||
| Args: | |||||
| src_name (str): The source node name. | |||||
| """ | """ | ||||
| return self._polymeric_inputs | |||||
| def update_polymeric_input(self, polymeric_input): | |||||
| """The polymeric input is the input of the polymeric nodes.""" | |||||
| self._polymeric_inputs.update(polymeric_input) | |||||
| self._input.pop(src_name) | |||||
| @property | @property | ||||
| def outputs(self): | |||||
| def output(self): | |||||
| """The output node of this node.""" | """The output node of this node.""" | ||||
| return self._outputs | |||||
| return self._output | |||||
| def update_output(self, output): | |||||
| def add_output(self, dst_name, output_attr): | |||||
| """ | """ | ||||
| Update output node. | |||||
| Add a output node to this node. | |||||
| Args: | Args: | ||||
| output (dict[str, TypedDict('NodeType', {'type': str})]): Key is a dst node name, and value is a dict. | |||||
| dst_name (str): The name of the output node. | |||||
| output_attr (dict: Same as the input attribute. | |||||
| """ | |||||
| self._output.update({dst_name: output_attr}) | |||||
| def delete_output(self, dst_name): | |||||
| """ | |||||
| Delete a output node. | |||||
| - type (str): The type of the dst node. | |||||
| Args: | |||||
| dst_name (str): The name of the node to be deleted. | |||||
| """ | """ | ||||
| self._outputs.update(output) | |||||
| self._output.pop(dst_name) | |||||
| @property | @property | ||||
| def polymeric_outputs(self): | |||||
| """Get polymeric output.""" | |||||
| return self._polymeric_outputs | |||||
| def proxy_input(self): | |||||
| """Return proxy input, type is dict.""" | |||||
| return self._proxy_input | |||||
| def update_polymeric_output(self, polymeric_output): | |||||
| def add_proxy_input(self, src_name, attr): | |||||
| """ | """ | ||||
| Update polymeric output. | |||||
| Add a proxy input to node. | |||||
| Args: | Args: | ||||
| polymeric_output (dict[str, dict): Key is the polymeric scope name of dst name, and value is dict. | |||||
| - edge_type (str): The edge type of the dst node. | |||||
| src_name (str): The name of the input node. | |||||
| attr (dict): The attr of the input. | |||||
| - edge_type (str): The edge type, refer to `EdgeTypeEnum`. | |||||
| """ | """ | ||||
| self._polymeric_outputs.update(polymeric_output) | |||||
| self._proxy_input.update({src_name: attr}) | |||||
| def delete_proxy_input(self, src_name): | |||||
| """Delete a proxy input by the src name.""" | |||||
| self._proxy_input.pop(src_name) | |||||
| @property | @property | ||||
| def polymeric_scope_name(self): | |||||
| """Get polymeric scope name.""" | |||||
| return self._polymeric_scope_name | |||||
| def proxy_output(self): | |||||
| """Get proxy output, data type is dict.""" | |||||
| return self._proxy_output | |||||
| @polymeric_scope_name.setter | |||||
| def polymeric_scope_name(self, name): | |||||
| """Set polymeric scope name.""" | |||||
| self._polymeric_scope_name = name | |||||
| def add_proxy_output(self, dst_name, attr): | |||||
| """ | |||||
| Add a proxy output to node. | |||||
| @property | |||||
| def subnode_count(self): | |||||
| """The sub node count of this node, if this node is a scope node, this count will not be zero.""" | |||||
| return self._subnode_count | |||||
| Args: | |||||
| dst_name (str): The name of the output node. | |||||
| attr (dict): The attr of the output. | |||||
| @subnode_count.setter | |||||
| def subnode_count(self, count): | |||||
| """Set sub node count.""" | |||||
| self._subnode_count = count | |||||
| - edge_type (str): The edge type, refer to `EdgeTypeEnum`. | |||||
| """ | |||||
| self._proxy_output.update({dst_name: attr}) | |||||
| @property | |||||
| def name_scope(self): | |||||
| """Get name scope of this node.""" | |||||
| return self._name_scope | |||||
| def delete_proxy_output(self, dst_name): | |||||
| """Delete a proxy output by dst name.""" | |||||
| self._proxy_output.pop(dst_name) | |||||
| @name_scope.setter | |||||
| def name_scope(self, name_scope): | |||||
| """Set name scope.""" | |||||
| self._name_scope = name_scope | |||||
| @staticmethod | |||||
| def copy_node_without_input_output(src_node, dst_node): | |||||
| """ | |||||
| Copy a source node attribute to a new node, but not input and output. | |||||
| Args: | |||||
| src_node (Node): The copied node. | |||||
| dst_node (Node): The destination node. | |||||
| """ | |||||
| dst_node.type = src_node.type | |||||
| dst_node.output_i = src_node.output_i | |||||
| dst_node.subnode_count = src_node.subnode_count | |||||
| dst_node.scope = src_node.scope | |||||
| dst_node.independent_layout = src_node.independent_layout | |||||
| dst_node.output_shape = src_node.output_shape | |||||
| dst_node.output_data_type = src_node.output_data_type | |||||
| dst_node.add_attr(src_node.attr) | |||||
| def __str__(self): | def __str__(self): | ||||
| return f'<Node, name: {self._name}, type: {self._type}>' | |||||
| return f'<Node, name: {self.name}, type: {self.type}>' | |||||
| @@ -20,9 +20,7 @@ and the status of graph will be checked before calling `Graph` object. | |||||
| from mindinsight.datavisual.common import exceptions | from mindinsight.datavisual.common import exceptions | ||||
| from mindinsight.datavisual.common.enums import PluginNameEnum | from mindinsight.datavisual.common.enums import PluginNameEnum | ||||
| from mindinsight.datavisual.common.validation import Validation | from mindinsight.datavisual.common.validation import Validation | ||||
| from mindinsight.datavisual.data_transform.graph import NodeTypeEnum | |||||
| from mindinsight.datavisual.processors.base_processor import BaseProcessor | from mindinsight.datavisual.processors.base_processor import BaseProcessor | ||||
| from mindinsight.utils.exceptions import ParamValueError | |||||
| from mindinsight.datavisual.common.exceptions import NodeNotInGraphError | from mindinsight.datavisual.common.exceptions import NodeNotInGraphError | ||||
| @@ -51,13 +49,12 @@ class GraphProcessor(BaseProcessor): | |||||
| tensors = self._data_manager.list_tensors(train_id, tag=tag) | tensors = self._data_manager.list_tensors(train_id, tag=tag) | ||||
| self._graph = tensors[0].value | self._graph = tensors[0].value | ||||
| def get_nodes(self, name, node_type): | |||||
| def list_nodes(self, scope): | |||||
| """ | """ | ||||
| Get the nodes of every layer in graph. | Get the nodes of every layer in graph. | ||||
| Args: | Args: | ||||
| name (str): The name of a node. | |||||
| node_type (Any): The type of node, either 'name_scope' or 'polymeric'. | |||||
| scope (str): The name of a scope. | |||||
| Returns: | Returns: | ||||
| TypedDict('Nodes', {'nodes': list[Node]}), format is {'nodes': [<Node object>]}. | TypedDict('Nodes', {'nodes': list[Node]}), format is {'nodes': [<Node object>]}. | ||||
| @@ -81,33 +78,19 @@ class GraphProcessor(BaseProcessor): | |||||
| } | } | ||||
| }, | }, | ||||
| "output_i" : -1, | "output_i" : -1, | ||||
| "polymeric_input" : {}, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "", | |||||
| "proxy_input" : {}, | |||||
| "proxy_output" : {}, | |||||
| "independent_layout" : False, | |||||
| "subnode_count" : 0, | "subnode_count" : 0, | ||||
| "type" : "Data" | "type" : "Data" | ||||
| } | } | ||||
| ] | ] | ||||
| } | } | ||||
| """ | """ | ||||
| if node_type not in [NodeTypeEnum.NAME_SCOPE.value, NodeTypeEnum.POLYMERIC_SCOPE.value]: | |||||
| raise ParamValueError( | |||||
| 'The node type is not support, only either %s or %s.' | |||||
| '' % (NodeTypeEnum.NAME_SCOPE.value, NodeTypeEnum.POLYMERIC_SCOPE.value)) | |||||
| if name and not self._graph.exist_node(name): | |||||
| raise NodeNotInGraphError(node_name=name, node_type=node_type) | |||||
| nodes = [] | |||||
| if node_type == NodeTypeEnum.NAME_SCOPE.value: | |||||
| nodes = self._graph.get_normal_nodes(name) | |||||
| if node_type == NodeTypeEnum.POLYMERIC_SCOPE.value: | |||||
| if not name: | |||||
| raise NodeNotInGraphError(node_name=name, node_type=node_type) | |||||
| polymeric_scope_name = name | |||||
| nodes = self._graph.get_polymeric_nodes(polymeric_scope_name) | |||||
| if scope and not self._graph.exist_node(scope): | |||||
| raise NodeNotInGraphError(node_name=scope) | |||||
| nodes = self._graph.list_node_by_scope(scope=scope) | |||||
| return {'nodes': nodes} | return {'nodes': nodes} | ||||
| def search_node_names(self, search_content, offset, limit): | def search_node_names(self, search_content, offset, limit): | ||||
| @@ -1 +1 @@ | |||||
| {"nodes":[{"attr":{},"input":{},"name":"Default/conv1-Conv2d","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":1,"type":"name_scope"},{"attr":{},"input":{},"name":"Default/bn1-BatchNorm2d","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":14,"type":"name_scope"},{"attr":{},"input":{},"name":"Default/bn1","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":20,"type":"name_scope"}]} | |||||
| {"nodes":[{"attr":{},"independent_layout":false,"input":{},"name":"Default","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":3,"type":"name_scope"}]} | |||||
| @@ -1 +1 @@ | |||||
| {"nodes":[{"attr":{},"input":{},"name":"Default","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":3,"type":"name_scope"}]} | |||||
| {"nodes":[{"attr":{},"independent_layout":false,"input":{},"name":"Default/conv1-Conv2d","output":{"Default/bn1/Reshape[12]_1/Reshape6":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,64,112,112]}},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":2,"type":"name_scope"},{"attr":{},"independent_layout":false,"input":{},"name":"Default/bn1-BatchNorm2d","output":{"Default/bn1/Add[5]_0/Add53":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,128,28,28]}},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":5,"type":"name_scope"},{"attr":{},"independent_layout":false,"input":{"Default/bn1-BatchNorm2d/tuple_getitem56":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,128,28,28]},"Default/conv1-Conv2d/Conv2D55":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,64,112,112]}},"name":"Default/bn1","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":4,"type":"name_scope"}]} | |||||
| @@ -1 +1 @@ | |||||
| {"names":["Default/bn1/Reshape1","Default/bn1/Reshape10","Default/bn1/Reshape11","Default/bn1/Reshape12","Default/bn1/Reshape2","Default/bn1/Reshape3","Default/bn1/Reshape4","Default/bn1/Reshape5","Default/bn1/Reshape6","Default/bn1/Reshape7","Default/bn1/Reshape8","Default/bn1/Reshape9","Default/bn1/Reshape_1_[12]"]} | |||||
| {"names":["Default/bn1","Default/bn1-BatchNorm2d","Default/bn1-BatchNorm2d/Parameter[22]_3","Default/bn1-BatchNorm2d/Parameter[22]_3/conv1.weight","Default/bn1-BatchNorm2d/Parameter[22]_3/x","Default/bn1-BatchNorm2d/Parameter[22]_3/x1","Default/bn1-BatchNorm2d/Parameter[22]_3/x10","Default/bn1-BatchNorm2d/Parameter[22]_3/x11","Default/bn1-BatchNorm2d/Parameter[22]_3/x12","Default/bn1-BatchNorm2d/Parameter[22]_3/x13","Default/bn1-BatchNorm2d/Parameter[22]_3/x14","Default/bn1-BatchNorm2d/Parameter[22]_3/x15","Default/bn1-BatchNorm2d/Parameter[22]_3/x16","Default/bn1-BatchNorm2d/Parameter[22]_3/x17","Default/bn1-BatchNorm2d/Parameter[22]_3/x18","Default/bn1-BatchNorm2d/Parameter[22]_3/x19","Default/bn1-BatchNorm2d/Parameter[22]_3/x2","Default/bn1-BatchNorm2d/Parameter[22]_3/x20","Default/bn1-BatchNorm2d/Parameter[22]_3/x3","Default/bn1-BatchNorm2d/Parameter[22]_3/x4","Default/bn1-BatchNorm2d/Parameter[22]_3/x5","Default/bn1-BatchNorm2d/Parameter[22]_3/x6","Default/bn1-BatchNorm2d/Parameter[22]_3/x7","Default/bn1-BatchNorm2d/Parameter[22]_3/x8","Default/bn1-BatchNorm2d/Parameter[22]_3/x9","Default/bn1-BatchNorm2d/cst13","Default/bn1-BatchNorm2d/cst25","Default/bn1-BatchNorm2d/tuple_getitem105","Default/bn1-BatchNorm2d/tuple_getitem56","Default/bn1/Add[5]_0","Default/bn1/Add[5]_0/Add50","Default/bn1/Add[5]_0/Add51","Default/bn1/Add[5]_0/Add52","Default/bn1/Add[5]_0/Add53","Default/bn1/Add[5]_0/Add54","Default/bn1/Reshape[12]_1","Default/bn1/Reshape[12]_1/Reshape1","Default/bn1/Reshape[12]_1/Reshape10","Default/bn1/Reshape[12]_1/Reshape11","Default/bn1/Reshape[12]_1/Reshape12","Default/bn1/Reshape[12]_1/Reshape2","Default/bn1/Reshape[12]_1/Reshape3","Default/bn1/Reshape[12]_1/Reshape4","Default/bn1/Reshape[12]_1/Reshape5","Default/bn1/Reshape[12]_1/Reshape6","Default/bn1/Reshape[12]_1/Reshape7","Default/bn1/Reshape[12]_1/Reshape8","Default/bn1/Reshape[12]_1/Reshape9","Default/bn1/x","Default/bn1/x11"]} | |||||
| @@ -40,22 +40,17 @@ class TestQueryNodes: | |||||
| @pytest.mark.platform_x86_gpu_training | @pytest.mark.platform_x86_gpu_training | ||||
| @pytest.mark.platform_x86_ascend_training | @pytest.mark.platform_x86_ascend_training | ||||
| @pytest.mark.usefixtures("init_summary_logs") | @pytest.mark.usefixtures("init_summary_logs") | ||||
| @pytest.mark.parametrize("node_name, node_type, result_file", [ | |||||
| ('', "name_scope", "test_query_nodes_success_result2.json"), | |||||
| ("Default", "name_scope", "test_query_nodes_success_result1.json"), | |||||
| ("Default/bn1/Reshape_1_[12]", "polymeric_scope", "test_query_nodes_success_result3.json") | |||||
| @pytest.mark.parametrize("node_name, result_file", [ | |||||
| ('', "test_query_nodes_success_result1.json"), | |||||
| ("Default", "test_query_nodes_success_result2.json"), | |||||
| ("Default/bn1/Reshape[12]_1", "test_query_nodes_success_result3.json") | |||||
| ]) | ]) | ||||
| def test_query_namescope_success(self, client, node_name, node_type, result_file): | |||||
| def test_list_node_success(self, client, node_name, result_file): | |||||
| """Query the name scope node.""" | """Query the name scope node.""" | ||||
| train_id = gbl.get_train_ids()[0] | train_id = gbl.get_train_ids()[0] | ||||
| if node_name: | |||||
| params = dict(train_id=train_id, | |||||
| type=node_type, | |||||
| name=node_name) | |||||
| else: | |||||
| params = dict(train_id=train_id, | |||||
| type=node_type) | |||||
| params = dict(train_id=train_id, | |||||
| name=node_name) | |||||
| url = get_url(BASE_URL, params) | url = get_url(BASE_URL, params) | ||||
| response = client.get(url) | response = client.get(url) | ||||
| assert response.status_code == 200 | assert response.status_code == 200 | ||||
| @@ -41,7 +41,7 @@ class TestQuerySingleNode: | |||||
| @pytest.mark.platform_x86_ascend_training | @pytest.mark.platform_x86_ascend_training | ||||
| @pytest.mark.usefixtures("init_summary_logs") | @pytest.mark.usefixtures("init_summary_logs") | ||||
| @pytest.mark.parametrize("node_name, result_file", [ | @pytest.mark.parametrize("node_name, result_file", [ | ||||
| ('Default/bn1/Reshape1', "test_query_single_node_success_result1.json") | |||||
| ('Default/bn1', "test_query_single_node_success_result1.json") | |||||
| ]) | ]) | ||||
| def test_query_single_node_success(self, client, node_name, result_file): | def test_query_single_node_success(self, client, node_name, result_file): | ||||
| """Query single node.""" | """Query single node.""" | ||||
| @@ -41,7 +41,7 @@ class TestSearchNodes: | |||||
| @pytest.mark.platform_x86_ascend_training | @pytest.mark.platform_x86_ascend_training | ||||
| @pytest.mark.usefixtures("init_summary_logs") | @pytest.mark.usefixtures("init_summary_logs") | ||||
| @pytest.mark.parametrize("search_content, offset, limit, result_file", [ | @pytest.mark.parametrize("search_content, offset, limit, result_file", [ | ||||
| ('Default/bn1/Reshape', 0, 1000, "test_search_nodes_success_result1.json") | |||||
| ('Default/bn1', 0, 1000, "test_search_nodes_success_result1.json") | |||||
| ]) | ]) | ||||
| def test_search_nodes_success(self, client, search_content, offset, limit, result_file): | def test_search_nodes_success(self, client, search_content, offset, limit, result_file): | ||||
| """Search node with parameters: offset is 0, limit is 1000.""" | """Search node with parameters: offset is 0, limit is 1000.""" | ||||
| @@ -22,7 +22,6 @@ from unittest.mock import Mock, patch | |||||
| import pytest | import pytest | ||||
| from mindinsight.datavisual.data_transform.graph import NodeTypeEnum | |||||
| from mindinsight.datavisual.processors.graph_processor import GraphProcessor | from mindinsight.datavisual.processors.graph_processor import GraphProcessor | ||||
| from mindinsight.datavisual.processors.images_processor import ImageProcessor | from mindinsight.datavisual.processors.images_processor import ImageProcessor | ||||
| from mindinsight.datavisual.processors.scalars_processor import ScalarsProcessor | from mindinsight.datavisual.processors.scalars_processor import ScalarsProcessor | ||||
| @@ -227,47 +226,27 @@ class TestTrainVisual: | |||||
| assert results['error_msg'] == "Param missing. 'train_id' is required." | assert results['error_msg'] == "Param missing. 'train_id' is required." | ||||
| @patch.object(GraphProcessor, '__init__') | @patch.object(GraphProcessor, '__init__') | ||||
| def test_graph_nodes_with_type_is_invalid(self, mock_graph_processor, client): | |||||
| """Test getting graph nodes with invalid type.""" | |||||
| mock_init = Mock(return_value=None) | |||||
| mock_graph_processor.side_effect = mock_init | |||||
| node_type = "invalid_node_type" | |||||
| params = dict(train_id='aaa', type=node_type) | |||||
| url = get_url(TRAIN_ROUTES['graph_nodes'], params) | |||||
| response = client.get(url) | |||||
| results = response.get_json() | |||||
| assert response.status_code == 400 | |||||
| assert results['error_code'] == '50540002' | |||||
| assert results['error_msg'] == "Invalid parameter value. The node type " \ | |||||
| "is not support, only either %s or %s." \ | |||||
| "" % (NodeTypeEnum.NAME_SCOPE.value, | |||||
| NodeTypeEnum.POLYMERIC_SCOPE.value) | |||||
| @patch.object(GraphProcessor, '__init__') | |||||
| @patch.object(GraphProcessor, 'get_nodes') | |||||
| def test_graph_nodes_success(self, mock_graph_processor, mock_graph_processor_1, client): | |||||
| @patch.object(GraphProcessor, 'list_nodes') | |||||
| def test_graph_nodes_success(self, mock_list_nodes_func, mock_init_func, client): | |||||
| """Test getting graph nodes successfully.""" | """Test getting graph nodes successfully.""" | ||||
| def mock_get_nodes(name, node_type): | |||||
| return dict(name=name, node_type=node_type) | |||||
| def mock_list_nodes(scope): | |||||
| return dict(scope=scope) | |||||
| mock_graph_processor.side_effect = mock_get_nodes | |||||
| mock_list_nodes_func.side_effect = mock_list_nodes | |||||
| mock_init = Mock(return_value=None) | mock_init = Mock(return_value=None) | ||||
| mock_graph_processor_1.side_effect = mock_init | |||||
| mock_init_func.side_effect = mock_init | |||||
| test_train_id = 'aaa' | test_train_id = 'aaa' | ||||
| test_node_name = 'bbb' | test_node_name = 'bbb' | ||||
| test_node_type = NodeTypeEnum.NAME_SCOPE.value | |||||
| params = dict(train_id=test_train_id, name=test_node_name, type=test_node_type) | |||||
| params = dict(train_id=test_train_id, name=test_node_name) | |||||
| url = get_url(TRAIN_ROUTES['graph_nodes'], params) | url = get_url(TRAIN_ROUTES['graph_nodes'], params) | ||||
| response = client.get(url) | response = client.get(url) | ||||
| assert response.status_code == 200 | assert response.status_code == 200 | ||||
| results = response.get_json() | results = response.get_json() | ||||
| assert results == dict(name=test_node_name, node_type=test_node_type) | |||||
| assert results == dict(scope=test_node_name) | |||||
| def test_graph_node_names_with_train_id_is_none(self, client): | def test_graph_node_names_with_train_id_is_none(self, client): | ||||
| """Test getting graph node names with train id is none.""" | """Test getting graph node names with train id is none.""" | ||||
| @@ -1,16 +1 @@ | |||||
| { | |||||
| "nodes" : [ | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : {}, | |||||
| "name" : "Default", | |||||
| "output" : {}, | |||||
| "output_i" : -1, | |||||
| "polymeric_input" : {}, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "", | |||||
| "subnode_count" : 3, | |||||
| "type" : "name_scope" | |||||
| } | |||||
| ] | |||||
| } | |||||
| {"nodes":[{"attr":{},"independent_layout":false,"input":{},"name":"Default","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":3,"type":"name_scope"}]} | |||||
| @@ -1,20 +1 @@ | |||||
| { | |||||
| "nodes" : [ | |||||
| { | |||||
| "attr" : | |||||
| { | |||||
| "output_names" : "dtype: DT_GRAPHS\nvalues {\n dtype: DT_FLOAT64\n str_val: \"output\"\n}\n", | |||||
| "pad_mode" : "dtype: DT_FLOAT64\nstr_val: \"same\"\n" | |||||
| }, | |||||
| "input" : {}, | |||||
| "name" : "Default/conv1-Conv2d/Conv2D1", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : {}, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Conv2D" | |||||
| } | |||||
| ] | |||||
| } | |||||
| {"nodes":[{"attr":{"output_names":"dtype: DT_GRAPHS\nvalues {\n dtype: DT_FLOAT64\n str_val: \"output\"\n}\n","pad_mode":"dtype: DT_FLOAT64\nstr_val: \"same\"\n"},"independent_layout":false,"input":{"Default/conv1-Conv2d/Parameter[12]_2/conv1.weight":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[64,3,7,7]},"Default/conv1-Conv2d/Parameter[12]_2/x":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x1":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x10":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x2":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x3":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x4":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x5":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x6":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x7":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x8":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/conv1-Conv2d/Parameter[12]_2/x9":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]}},"name":"Default/conv1-Conv2d/Conv2D55","output":{"Default/bn1/Reshape[12]_1/Reshape6":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,64,112,112]}},"output_i":0,"proxy_input":{"Default/conv1-Conv2d/Parameter[12]_2":{"edge_type":"data"}},"proxy_output":{},"subnode_count":0,"type":"Conv2D"},{"attr":{},"independent_layout":true,"input":{},"name":"Default/conv1-Conv2d/Parameter[12]_2","output":{"Default/conv1-Conv2d/Conv2D55":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[64,3,7,7]}},"output_i":0,"proxy_input":{},"proxy_output":{"Default/conv1-Conv2d/Conv2D55":{"edge_type":"data"}},"subnode_count":12,"type":"aggregation_scope"}]} | |||||
| @@ -1,437 +1 @@ | |||||
| { | |||||
| "nodes" : [ | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/Add50" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 1024, 14, 14] | |||||
| }, | |||||
| "Default/bn1/conv1.weight" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [64, 3, 7, 7] | |||||
| }, | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x1" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x10" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x2" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x3" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x4" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x5" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x6" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x7" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x8" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| }, | |||||
| "Default/bn1/x9" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape1", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/Add50" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/conv1.weight" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x1" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x10" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x2" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x3" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x4" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x5" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x6" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x7" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x8" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| }, | |||||
| "Default/bn1/x9" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/Add51" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 1024, 14, 14] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape2", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/Add51" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/Add52" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 1024, 14, 14] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape3", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/Add52" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/Add53" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 1024, 14, 14] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape4", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/Add53" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/Add54" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 1024, 14, 14] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape5", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/Add54" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape6", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape7", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape8", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape9", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape10", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape11", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| }, | |||||
| { | |||||
| "attr" : {}, | |||||
| "input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data", | |||||
| "scope" : "polymeric_scope", | |||||
| "shape" : [1, 3, 224, 224] | |||||
| } | |||||
| }, | |||||
| "name" : "Default/bn1/Reshape12", | |||||
| "output" : {}, | |||||
| "output_i" : 0, | |||||
| "polymeric_input" : | |||||
| { | |||||
| "Default/bn1/x" : | |||||
| { | |||||
| "edge_type" : "data" | |||||
| } | |||||
| }, | |||||
| "polymeric_output" : {}, | |||||
| "polymeric_scope_name" : "Default/bn1/Reshape_1_[12]", | |||||
| "subnode_count" : 0, | |||||
| "type" : "Reshape" | |||||
| } | |||||
| ] | |||||
| } | |||||
| {"nodes":[{"attr":{},"independent_layout":false,"input":{"Default/bn1/Add[5]_0/Add50":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,1024,14,14]}},"name":"Default/bn1/Reshape[12]_1/Reshape1","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/Add[5]_0/Add51":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,1024,14,14]}},"name":"Default/bn1/Reshape[12]_1/Reshape2","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/Add[5]_0/Add52":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,1024,14,14]}},"name":"Default/bn1/Reshape[12]_1/Reshape3","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/Add[5]_0/Add53":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,1024,14,14]}},"name":"Default/bn1/Reshape[12]_1/Reshape4","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/Add[5]_0/Add54":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,1024,14,14]}},"name":"Default/bn1/Reshape[12]_1/Reshape5","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/conv1-Conv2d/Conv2D55":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,64,112,112]}},"name":"Default/bn1/Reshape[12]_1/Reshape6","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/x":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[1,3,224,224]}},"name":"Default/bn1/Reshape[12]_1/Reshape7","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/x":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[1,3,224,224]}},"name":"Default/bn1/Reshape[12]_1/Reshape8","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/x":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[1,3,224,224]}},"name":"Default/bn1/Reshape[12]_1/Reshape9","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/x":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[1,3,224,224]}},"name":"Default/bn1/Reshape[12]_1/Reshape10","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/x":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[1,3,224,224]}},"name":"Default/bn1/Reshape[12]_1/Reshape11","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"},{"attr":{},"independent_layout":false,"input":{"Default/bn1/x":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[1,3,224,224]}},"name":"Default/bn1/Reshape[12]_1/Reshape12","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Reshape"}]} | |||||
| @@ -0,0 +1 @@ | |||||
| {"nodes":[{"attr":{},"independent_layout":false,"input":{"Default/bn1-BatchNorm2d/Parameter[22]_3/x":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x1":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x10":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x2":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x3":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x4":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x5":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x6":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x7":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x8":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x9":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/cst13":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[]}},"name":"Default/bn1-BatchNorm2d/tuple_getitem56","output":{"Default/bn1/Add[5]_0/Add53":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,128,28,28]}},"output_i":0,"proxy_input":{"Default/bn1-BatchNorm2d/Parameter[22]_3":{"edge_type":"data"}},"proxy_output":{},"subnode_count":0,"type":"tuple_getitem"},{"attr":{},"independent_layout":false,"input":{"Default/bn1-BatchNorm2d/Parameter[22]_3/conv1.weight":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[64,3,7,7]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x11":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x12":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x13":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x14":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x15":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x16":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x17":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x18":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x19":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/Parameter[22]_3/x20":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]},"Default/bn1-BatchNorm2d/cst25":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[]}},"name":"Default/bn1-BatchNorm2d/tuple_getitem105","output":{},"output_i":0,"proxy_input":{"Default/bn1-BatchNorm2d/Parameter[22]_3":{"edge_type":"data"}},"proxy_output":{},"subnode_count":0,"type":"tuple_getitem"},{"attr":{},"independent_layout":true,"input":{},"name":"Default/bn1-BatchNorm2d/Parameter[22]_3","output":{"Default/bn1-BatchNorm2d/tuple_getitem105":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[64,3,7,7]},"Default/bn1-BatchNorm2d/tuple_getitem56":{"data_type":"","edge_type":"data","independent_layout":true,"shape":[1,3,224,224]}},"output_i":0,"proxy_input":{},"proxy_output":{"Default/bn1-BatchNorm2d/tuple_getitem105":{"edge_type":"data"},"Default/bn1-BatchNorm2d/tuple_getitem56":{"edge_type":"data"}},"subnode_count":22,"type":"aggregation_scope"},{"attr":{"cst13":"dtype: DT_INT32\nint_val: 0\n"},"independent_layout":false,"input":{},"name":"Default/bn1-BatchNorm2d/cst13","output":{"Default/bn1-BatchNorm2d/tuple_getitem56":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[]}},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Const"},{"attr":{"cst25":"dtype: DT_INT32\nint_val: 0\n"},"independent_layout":false,"input":{},"name":"Default/bn1-BatchNorm2d/cst25","output":{"Default/bn1-BatchNorm2d/tuple_getitem105":{"data_type":"","edge_type":"data","independent_layout":false,"shape":[]}},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":0,"type":"Const"}]} | |||||
| @@ -1 +1 @@ | |||||
| {"names":["Default/bn1-BatchNorm2d/cst25","Default/bn1-BatchNorm2d/tuple_getitem105","Default/bn1-BatchNorm2d/tuple_getitem53"]} | |||||
| {"names":["Default/bn1-BatchNorm2d/Parameter[22]_3/conv1.weight","Default/bn1-BatchNorm2d/Parameter[22]_3/x","Default/bn1-BatchNorm2d/Parameter[22]_3/x1"]} | |||||
| @@ -1,4 +1 @@ | |||||
| { | |||||
| "names" : ["Default", "Default/bn1", "Default/bn1-BatchNorm2d", "Default/bn1-BatchNorm2d/conv1.weight", "Default/bn1-BatchNorm2d/cst25", "Default/bn1-BatchNorm2d/tuple_getitem105", "Default/bn1-BatchNorm2d/tuple_getitem53", "Default/bn1-BatchNorm2d/x11", "Default/bn1-BatchNorm2d/x12", "Default/bn1-BatchNorm2d/x13", "Default/bn1-BatchNorm2d/x14", "Default/bn1-BatchNorm2d/x15", "Default/bn1-BatchNorm2d/x16", "Default/bn1-BatchNorm2d/x17", "Default/bn1-BatchNorm2d/x18", "Default/bn1-BatchNorm2d/x19", "Default/bn1-BatchNorm2d/x20", "Default/bn1/Add50", "Default/bn1/Add51", "Default/bn1/Add52", "Default/bn1/Add53", "Default/bn1/Add54", "Default/bn1/Reshape1", "Default/bn1/Reshape10", "Default/bn1/Reshape11", "Default/bn1/Reshape12", "Default/bn1/Reshape2", "Default/bn1/Reshape3", "Default/bn1/Reshape4", "Default/bn1/Reshape5", "Default/bn1/Reshape6", "Default/bn1/Reshape7", "Default/bn1/Reshape8", "Default/bn1/Reshape9", "Default/bn1/Reshape_1_[12]", "Default/bn1/conv1.weight", "Default/bn1/cst13", "Default/bn1/x", "Default/bn1/x1", "Default/bn1/x10", "Default/bn1/x11", "Default/bn1/x2", "Default/bn1/x3", "Default/bn1/x4", "Default/bn1/x5", "Default/bn1/x6", "Default/bn1/x7", "Default/bn1/x8", "Default/bn1/x9", "Default/conv1-Conv2d", "Default/conv1-Conv2d/Conv2D1"] | |||||
| } | |||||
| {"names":["Default","Default/bn1","Default/bn1-BatchNorm2d","Default/bn1-BatchNorm2d/Parameter[22]_3","Default/bn1-BatchNorm2d/Parameter[22]_3/conv1.weight","Default/bn1-BatchNorm2d/Parameter[22]_3/x","Default/bn1-BatchNorm2d/Parameter[22]_3/x1","Default/bn1-BatchNorm2d/Parameter[22]_3/x10","Default/bn1-BatchNorm2d/Parameter[22]_3/x11","Default/bn1-BatchNorm2d/Parameter[22]_3/x12","Default/bn1-BatchNorm2d/Parameter[22]_3/x13","Default/bn1-BatchNorm2d/Parameter[22]_3/x14","Default/bn1-BatchNorm2d/Parameter[22]_3/x15","Default/bn1-BatchNorm2d/Parameter[22]_3/x16","Default/bn1-BatchNorm2d/Parameter[22]_3/x17","Default/bn1-BatchNorm2d/Parameter[22]_3/x18","Default/bn1-BatchNorm2d/Parameter[22]_3/x19","Default/bn1-BatchNorm2d/Parameter[22]_3/x2","Default/bn1-BatchNorm2d/Parameter[22]_3/x20","Default/bn1-BatchNorm2d/Parameter[22]_3/x3","Default/bn1-BatchNorm2d/Parameter[22]_3/x4","Default/bn1-BatchNorm2d/Parameter[22]_3/x5","Default/bn1-BatchNorm2d/Parameter[22]_3/x6","Default/bn1-BatchNorm2d/Parameter[22]_3/x7","Default/bn1-BatchNorm2d/Parameter[22]_3/x8","Default/bn1-BatchNorm2d/Parameter[22]_3/x9","Default/bn1-BatchNorm2d/cst13","Default/bn1-BatchNorm2d/cst25","Default/bn1-BatchNorm2d/tuple_getitem105","Default/bn1-BatchNorm2d/tuple_getitem56","Default/bn1/Add[5]_0","Default/bn1/Add[5]_0/Add50","Default/bn1/Add[5]_0/Add51","Default/bn1/Add[5]_0/Add52","Default/bn1/Add[5]_0/Add53","Default/bn1/Add[5]_0/Add54","Default/bn1/Reshape[12]_1","Default/bn1/Reshape[12]_1/Reshape1","Default/bn1/Reshape[12]_1/Reshape10","Default/bn1/Reshape[12]_1/Reshape11","Default/bn1/Reshape[12]_1/Reshape12","Default/bn1/Reshape[12]_1/Reshape2","Default/bn1/Reshape[12]_1/Reshape3","Default/bn1/Reshape[12]_1/Reshape4","Default/bn1/Reshape[12]_1/Reshape5","Default/bn1/Reshape[12]_1/Reshape6","Default/bn1/Reshape[12]_1/Reshape7","Default/bn1/Reshape[12]_1/Reshape8","Default/bn1/Reshape[12]_1/Reshape9","Default/bn1/x","Default/bn1/x11","Default/conv1-Conv2d","Default/conv1-Conv2d/Conv2D55","Default/conv1-Conv2d/Parameter[12]_2","Default/conv1-Conv2d/Parameter[12]_2/conv1.weight","Default/conv1-Conv2d/Parameter[12]_2/x","Default/conv1-Conv2d/Parameter[12]_2/x1","Default/conv1-Conv2d/Parameter[12]_2/x10","Default/conv1-Conv2d/Parameter[12]_2/x2","Default/conv1-Conv2d/Parameter[12]_2/x3","Default/conv1-Conv2d/Parameter[12]_2/x4","Default/conv1-Conv2d/Parameter[12]_2/x5","Default/conv1-Conv2d/Parameter[12]_2/x6","Default/conv1-Conv2d/Parameter[12]_2/x7","Default/conv1-Conv2d/Parameter[12]_2/x8","Default/conv1-Conv2d/Parameter[12]_2/x9"]} | |||||
| @@ -1 +1 @@ | |||||
| {"names":["Default/bn1","Default/bn1-BatchNorm2d","Default/bn1-BatchNorm2d/conv1.weight","Default/bn1-BatchNorm2d/cst25","Default/bn1-BatchNorm2d/tuple_getitem105","Default/bn1-BatchNorm2d/tuple_getitem53","Default/bn1-BatchNorm2d/x11","Default/bn1-BatchNorm2d/x12","Default/bn1-BatchNorm2d/x13","Default/bn1-BatchNorm2d/x14","Default/bn1-BatchNorm2d/x15","Default/bn1-BatchNorm2d/x16","Default/bn1-BatchNorm2d/x17","Default/bn1-BatchNorm2d/x18","Default/bn1-BatchNorm2d/x19","Default/bn1-BatchNorm2d/x20","Default/bn1/Add50","Default/bn1/Add51","Default/bn1/Add52","Default/bn1/Add53","Default/bn1/Add54","Default/bn1/Reshape1","Default/bn1/Reshape10","Default/bn1/Reshape11","Default/bn1/Reshape12","Default/bn1/Reshape2","Default/bn1/Reshape3","Default/bn1/Reshape4","Default/bn1/Reshape5","Default/bn1/Reshape6","Default/bn1/Reshape7","Default/bn1/Reshape8","Default/bn1/Reshape9","Default/bn1/Reshape_1_[12]","Default/bn1/conv1.weight","Default/bn1/cst13","Default/bn1/x","Default/bn1/x1","Default/bn1/x10","Default/bn1/x11","Default/bn1/x2","Default/bn1/x3","Default/bn1/x4","Default/bn1/x5","Default/bn1/x6","Default/bn1/x7","Default/bn1/x8","Default/bn1/x9"]} | |||||
| {"names":["Default/bn1","Default/bn1-BatchNorm2d","Default/bn1-BatchNorm2d/Parameter[22]_3","Default/bn1-BatchNorm2d/Parameter[22]_3/conv1.weight","Default/bn1-BatchNorm2d/Parameter[22]_3/x","Default/bn1-BatchNorm2d/Parameter[22]_3/x1","Default/bn1-BatchNorm2d/Parameter[22]_3/x10","Default/bn1-BatchNorm2d/Parameter[22]_3/x11","Default/bn1-BatchNorm2d/Parameter[22]_3/x12","Default/bn1-BatchNorm2d/Parameter[22]_3/x13","Default/bn1-BatchNorm2d/Parameter[22]_3/x14","Default/bn1-BatchNorm2d/Parameter[22]_3/x15","Default/bn1-BatchNorm2d/Parameter[22]_3/x16","Default/bn1-BatchNorm2d/Parameter[22]_3/x17","Default/bn1-BatchNorm2d/Parameter[22]_3/x18","Default/bn1-BatchNorm2d/Parameter[22]_3/x19","Default/bn1-BatchNorm2d/Parameter[22]_3/x2","Default/bn1-BatchNorm2d/Parameter[22]_3/x20","Default/bn1-BatchNorm2d/Parameter[22]_3/x3","Default/bn1-BatchNorm2d/Parameter[22]_3/x4","Default/bn1-BatchNorm2d/Parameter[22]_3/x5","Default/bn1-BatchNorm2d/Parameter[22]_3/x6","Default/bn1-BatchNorm2d/Parameter[22]_3/x7","Default/bn1-BatchNorm2d/Parameter[22]_3/x8","Default/bn1-BatchNorm2d/Parameter[22]_3/x9","Default/bn1-BatchNorm2d/cst13","Default/bn1-BatchNorm2d/cst25","Default/bn1-BatchNorm2d/tuple_getitem105","Default/bn1-BatchNorm2d/tuple_getitem56","Default/bn1/Add[5]_0","Default/bn1/Add[5]_0/Add50","Default/bn1/Add[5]_0/Add51","Default/bn1/Add[5]_0/Add52","Default/bn1/Add[5]_0/Add53","Default/bn1/Add[5]_0/Add54","Default/bn1/Reshape[12]_1","Default/bn1/Reshape[12]_1/Reshape1","Default/bn1/Reshape[12]_1/Reshape10","Default/bn1/Reshape[12]_1/Reshape11","Default/bn1/Reshape[12]_1/Reshape12","Default/bn1/Reshape[12]_1/Reshape2","Default/bn1/Reshape[12]_1/Reshape3","Default/bn1/Reshape[12]_1/Reshape4","Default/bn1/Reshape[12]_1/Reshape5","Default/bn1/Reshape[12]_1/Reshape6","Default/bn1/Reshape[12]_1/Reshape7","Default/bn1/Reshape[12]_1/Reshape8","Default/bn1/Reshape[12]_1/Reshape9","Default/bn1/x","Default/bn1/x11"]} | |||||
| @@ -1 +1 @@ | |||||
| {"children":{"children":{},"nodes":[{"attr":{},"input":{},"name":"Default/conv1-Conv2d","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":1,"type":"name_scope"},{"attr":{},"input":{},"name":"Default/bn1-BatchNorm2d","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":14,"type":"name_scope"},{"attr":{},"input":{},"name":"Default/bn1","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":20,"type":"name_scope"}],"scope_name":"Default"},"nodes":[{"attr":{},"input":{},"name":"Default","output":{},"output_i":-1,"polymeric_input":{},"polymeric_output":{},"polymeric_scope_name":"","subnode_count":3,"type":"name_scope"}],"scope_name":""} | |||||
| {"children":{"children":{},"nodes":[{"attr":{},"independent_layout":false,"input":{},"name":"Default/conv1-Conv2d","output":{"Default/bn1/Reshape[12]_1/Reshape6":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,64,112,112]}},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":2,"type":"name_scope"},{"attr":{},"independent_layout":false,"input":{},"name":"Default/bn1-BatchNorm2d","output":{"Default/bn1/Add[5]_0/Add53":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,128,28,28]}},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":5,"type":"name_scope"},{"attr":{},"independent_layout":false,"input":{"Default/bn1-BatchNorm2d/tuple_getitem56":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,128,28,28]},"Default/conv1-Conv2d/Conv2D55":{"data_type":"DT_STRING","edge_type":"data","independent_layout":false,"shape":[1,64,112,112]}},"name":"Default/bn1","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":4,"type":"name_scope"}],"scope_name":"Default"},"nodes":[{"attr":{},"independent_layout":false,"input":{},"name":"Default","output":{},"output_i":0,"proxy_input":{},"proxy_output":{},"subnode_count":3,"type":"name_scope"}],"scope_name":""} | |||||
| @@ -118,26 +118,27 @@ class TestGraphProcessor: | |||||
| assert mock_get_train_job_by_plugin.called | assert mock_get_train_job_by_plugin.called | ||||
| @pytest.mark.usefixtures('load_graph_record') | @pytest.mark.usefixtures('load_graph_record') | ||||
| @pytest.mark.parametrize("name, node_type", [("not_exist_name", "name_scope"), ("", "polymeric_scope")]) | |||||
| def test_get_nodes_with_not_exist_name(self, name, node_type): | |||||
| @pytest.mark.parametrize("name", ["not_exist_name"]) | |||||
| def test_get_nodes_with_not_exist_name(self, name): | |||||
| """Test getting nodes with not exist name.""" | """Test getting nodes with not exist name.""" | ||||
| with pytest.raises(NodeNotInGraphError) as exc_info: | with pytest.raises(NodeNotInGraphError) as exc_info: | ||||
| graph_processor = GraphProcessor(self._train_id, self._mock_data_manager) | graph_processor = GraphProcessor(self._train_id, self._mock_data_manager) | ||||
| graph_processor.get_nodes(name, node_type) | |||||
| graph_processor.list_nodes(name) | |||||
| assert 'Can not find node in graph by the given node name' in exc_info.value.message | assert 'Can not find node in graph by the given node name' in exc_info.value.message | ||||
| @pytest.mark.usefixtures('load_graph_record') | @pytest.mark.usefixtures('load_graph_record') | ||||
| @pytest.mark.parametrize( | @pytest.mark.parametrize( | ||||
| "name, node_type, result_file", | |||||
| [(None, 'name_scope', 'test_get_nodes_success_expected_results1.json'), | |||||
| ('Default/conv1-Conv2d', 'name_scope', 'test_get_nodes_success_expected_results2.json'), | |||||
| ('Default/bn1/Reshape_1_[12]', 'polymeric_scope', 'test_get_nodes_success_expected_results3.json')]) | |||||
| def test_get_nodes_success(self, name, node_type, result_file): | |||||
| "name, result_file", | |||||
| [(None, 'test_get_nodes_success_expected_results1.json'), | |||||
| ('Default/conv1-Conv2d', 'test_get_nodes_success_expected_results2.json'), | |||||
| ('Default/bn1/Reshape[12]_1', 'test_get_nodes_success_expected_results3.json'), | |||||
| ('Default/bn1-BatchNorm2d', 'test_get_nodes_success_expected_results4.json'), | |||||
| ]) | |||||
| def test_get_nodes_success(self, name, result_file): | |||||
| """Test getting nodes successfully.""" | """Test getting nodes successfully.""" | ||||
| graph_processor = GraphProcessor(self._train_id, self._mock_data_manager) | graph_processor = GraphProcessor(self._train_id, self._mock_data_manager) | ||||
| results = graph_processor.get_nodes(name, node_type) | |||||
| results = graph_processor.list_nodes(name) | |||||
| expected_file_path = os.path.join(self.graph_results_dir, result_file) | expected_file_path = os.path.join(self.graph_results_dir, result_file) | ||||
| compare_result_with_file(results, expected_file_path) | compare_result_with_file(results, expected_file_path) | ||||
| @@ -0,0 +1,640 @@ | |||||
| { | |||||
| "node": [ | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "1", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "1", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "2", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "2", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "3", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "3", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "4", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "4", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "5", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "5", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "6", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "6", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "7", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "7", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "8", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "8", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "9", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "10", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "11", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "12", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "13", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "14", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "14", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "15", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "15", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "16", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ], | |||||
| "name": "849_848_847_424_1_construct", | |||||
| "parameters": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| }, | |||||
| { | |||||
| "size": "3" | |||||
| }, | |||||
| { | |||||
| "size": "224" | |||||
| }, | |||||
| { | |||||
| "size": "224" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -51,7 +51,7 @@ | |||||
| "type": "DATA_EDGE" | "type": "DATA_EDGE" | ||||
| } | } | ||||
| ], | ], | ||||
| "name": "1", | |||||
| "name": "55", | |||||
| "opType": "Conv2D", | "opType": "Conv2D", | ||||
| "scope": "Default/conv1-Conv2d", | "scope": "Default/conv1-Conv2d", | ||||
| "attribute": [ | "attribute": [ | ||||
| @@ -149,7 +149,7 @@ | |||||
| "type": "DATA_EDGE" | "type": "DATA_EDGE" | ||||
| } | } | ||||
| ], | ], | ||||
| "name": "53", | |||||
| "name": "56", | |||||
| "opType": "tuple_getitem", | "opType": "tuple_getitem", | ||||
| "scope": "Default/bn1-BatchNorm2d", | "scope": "Default/bn1-BatchNorm2d", | ||||
| "outputType": { | "outputType": { | ||||
| @@ -354,7 +354,7 @@ | |||||
| { | { | ||||
| "input": [ | "input": [ | ||||
| { | { | ||||
| "name": "x11", | |||||
| "name": "56", | |||||
| "type": "DATA_EDGE" | "type": "DATA_EDGE" | ||||
| } | } | ||||
| ], | ], | ||||
| @@ -585,7 +585,7 @@ | |||||
| { | { | ||||
| "input": [ | "input": [ | ||||
| { | { | ||||
| "name": "x", | |||||
| "name": "55", | |||||
| "type": "DATA_EDGE" | "type": "DATA_EDGE" | ||||
| } | } | ||||
| ], | ], | ||||
| @@ -0,0 +1,559 @@ | |||||
| { | |||||
| "node": [ | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "6", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "1", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "7", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "2", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "8", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "3", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "14", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "4", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "10", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "5", | |||||
| "opType": "Conv2D", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "6", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "7", | |||||
| "opType": "Sub", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "8", | |||||
| "opType": "Sqrt", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "5", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "9", | |||||
| "opType": "Reshape", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "10", | |||||
| "opType": "Mul", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "11", | |||||
| "opType": "Add", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "12", | |||||
| "opType": "Relu", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [ | |||||
| { | |||||
| "name": "9", | |||||
| "type": "DATA_EDGE" | |||||
| } | |||||
| ], | |||||
| "name": "13", | |||||
| "opType": "Dense", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| { | |||||
| "input": [], | |||||
| "name": "14", | |||||
| "opType": "Reshape", | |||||
| "scope": "Default", | |||||
| "attribute": [ | |||||
| { | |||||
| "name": "output_names", | |||||
| "value": { | |||||
| "dtype": "DT_GRAPHS", | |||||
| "values": [ | |||||
| { | |||||
| "dtype": "DT_FLOAT64", | |||||
| "strVal": "output" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| ], | |||||
| "outputType": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ], | |||||
| "name": "849_848_847_424_1_construct", | |||||
| "parameters": [ | |||||
| { | |||||
| "name": "data", | |||||
| "type": { | |||||
| "dataType": "DT_STRING", | |||||
| "tensorType": { | |||||
| "elemType": "DT_FLOAT16", | |||||
| "shape": { | |||||
| "dim": [ | |||||
| { | |||||
| "size": "1" | |||||
| }, | |||||
| { | |||||
| "size": "3" | |||||
| }, | |||||
| { | |||||
| "size": "224" | |||||
| }, | |||||
| { | |||||
| "size": "224" | |||||
| } | |||||
| ] | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ] | |||||
| } | |||||