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) | |||
| node_type = request.args.get('type', default='name_scope') | |||
| tag = request.args.get("tag", default=None) | |||
| train_id = get_train_id(request) | |||
| 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) | |||
| @@ -15,13 +15,13 @@ | |||
| """ | |||
| This file is used to define the basic graph. | |||
| """ | |||
| import copy | |||
| import time | |||
| 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.log import logger | |||
| from mindinsight.utils.exceptions import ParamMissError | |||
| from mindinsight.utils.exceptions import ParamValueError | |||
| from .node import NodeTypeEnum | |||
| from .node import Node | |||
| @@ -32,27 +32,38 @@ class EdgeTypeEnum(Enum): | |||
| DATA = 'data' | |||
| class DataTypeEnum(Enum): | |||
| """Data type enum.""" | |||
| DT_TENSOR = 13 | |||
| class Graph: | |||
| """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): | |||
| """ | |||
| @@ -62,52 +73,27 @@ class Graph: | |||
| name (str): The node name. | |||
| 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 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: | |||
| namescope (str): A namescope of nodes. | |||
| scope (str): A scope of nodes. | |||
| Returns: | |||
| list[dict], a list object contain `Node` object. | |||
| """ | |||
| scope = "" if scope is None else scope | |||
| 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()) | |||
| return nodes | |||
| @@ -117,21 +103,18 @@ class Graph: | |||
| Args: | |||
| 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. | |||
| limit (int): An offset for page. Ex, offset is 0, mean current page is 1. | |||
| Returns: | |||
| 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: | |||
| 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: | |||
| catch_names = all_names | |||
| catch_names = list(self._normal_node_map) | |||
| catch_names = sorted(catch_names) | |||
| real_offset = offset * limit | |||
| return catch_names[real_offset:real_offset+limit] | |||
| @@ -149,304 +132,419 @@ class Graph: | |||
| 'scope_name': '<Node scope>', | |||
| '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) | |||
| response = {} | |||
| nodes = self.get_normal_nodes() | |||
| nodes = self.list_node_by_scope() | |||
| response.update({ | |||
| 'nodes': nodes, | |||
| 'scope_name': '', | |||
| 'children': {} | |||
| }) | |||
| names = node_name.split('/') | |||
| 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({ | |||
| 'nodes': nodes, | |||
| 'scope_name': name_scope, | |||
| 'scope_name': scope, | |||
| 'children': {} | |||
| }) | |||
| children = children['children'] | |||
| index = node_name.find('/', index+1) | |||
| 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 | |||
| 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: | |||
| 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 | |||
| 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: | |||
| 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 | |||
| 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. | |||
| # ============================================================================ | |||
| """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.proto_files.mindinsight_anf_ir_pb2 import DataType | |||
| from .node import Node | |||
| from .node import NodeTypeEnum | |||
| from .graph import Graph | |||
| from .graph import EdgeTypeEnum | |||
| from .graph import DataTypeEnum | |||
| 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: | |||
| 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: | |||
| 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: | |||
| 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 | |||
| 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: | |||
| 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: | |||
| 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. | |||
| @@ -260,32 +159,113 @@ class MSGraph(Graph): | |||
| shapes.append(dim.size) | |||
| if type_proto.HasField('sequence_type'): | |||
| 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 | |||
| 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: | |||
| 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: | |||
| 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 | |||
| class NodeTypeEnum(Enum): | |||
| """Node type enum. The following types are new to our custom.""" | |||
| NAME_SCOPE = 'name_scope' | |||
| POLYMERIC_SCOPE = 'polymeric_scope' | |||
| AGGREGATION_SCOPE = 'aggregation_scope' | |||
| PARAMETER = 'Parameter' | |||
| CONST = 'Const' | |||
| @@ -36,32 +37,33 @@ class Node: | |||
| def __init__(self, name, node_id): | |||
| self._node_id = node_id | |||
| self._name = name | |||
| self._type = "" | |||
| self.name = name | |||
| self.type = "" | |||
| 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): | |||
| """Converts the node object to dictionary format.""" | |||
| return { | |||
| 'name': self._name, | |||
| 'type': self._type, | |||
| 'name': self.name, | |||
| 'type': self.type, | |||
| '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 | |||
| @@ -69,32 +71,26 @@ class Node: | |||
| """The id of this node, and id is unique in graph.""" | |||
| 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 | |||
| def attr(self): | |||
| """Get node attr.""" | |||
| return self._attr | |||
| def update_attr(self, attr_dict): | |||
| def add_attr(self, attr_dict): | |||
| """ | |||
| Update node attr. | |||
| @@ -104,114 +100,122 @@ class Node: | |||
| self._attr.update(attr_dict) | |||
| @property | |||
| def inputs(self): | |||
| def input(self): | |||
| """ | |||
| Get all input of current node. | |||
| 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. | |||
| 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. | |||
| - 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 | |||
| def outputs(self): | |||
| def output(self): | |||
| """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: | |||
| 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 | |||
| 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: | |||
| 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 | |||
| 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): | |||
| 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.enums import PluginNameEnum | |||
| 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.utils.exceptions import ParamValueError | |||
| from mindinsight.datavisual.common.exceptions import NodeNotInGraphError | |||
| @@ -51,13 +49,12 @@ class GraphProcessor(BaseProcessor): | |||
| tensors = self._data_manager.list_tensors(train_id, tag=tag) | |||
| 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. | |||
| 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: | |||
| TypedDict('Nodes', {'nodes': list[Node]}), format is {'nodes': [<Node object>]}. | |||
| @@ -81,33 +78,19 @@ class GraphProcessor(BaseProcessor): | |||
| } | |||
| }, | |||
| "output_i" : -1, | |||
| "polymeric_input" : {}, | |||
| "polymeric_output" : {}, | |||
| "polymeric_scope_name" : "", | |||
| "proxy_input" : {}, | |||
| "proxy_output" : {}, | |||
| "independent_layout" : False, | |||
| "subnode_count" : 0, | |||
| "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} | |||
| 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_ascend_training | |||
| @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.""" | |||
| 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) | |||
| response = client.get(url) | |||
| assert response.status_code == 200 | |||
| @@ -41,7 +41,7 @@ class TestQuerySingleNode: | |||
| @pytest.mark.platform_x86_ascend_training | |||
| @pytest.mark.usefixtures("init_summary_logs") | |||
| @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): | |||
| """Query single node.""" | |||
| @@ -41,7 +41,7 @@ class TestSearchNodes: | |||
| @pytest.mark.platform_x86_ascend_training | |||
| @pytest.mark.usefixtures("init_summary_logs") | |||
| @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): | |||
| """Search node with parameters: offset is 0, limit is 1000.""" | |||
| @@ -22,7 +22,6 @@ from unittest.mock import Mock, patch | |||
| import pytest | |||
| from mindinsight.datavisual.data_transform.graph import NodeTypeEnum | |||
| from mindinsight.datavisual.processors.graph_processor import GraphProcessor | |||
| from mindinsight.datavisual.processors.images_processor import ImageProcessor | |||
| from mindinsight.datavisual.processors.scalars_processor import ScalarsProcessor | |||
| @@ -227,47 +226,27 @@ class TestTrainVisual: | |||
| assert results['error_msg'] == "Param missing. 'train_id' is required." | |||
| @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.""" | |||
| 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_graph_processor_1.side_effect = mock_init | |||
| mock_init_func.side_effect = mock_init | |||
| test_train_id = 'aaa' | |||
| 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) | |||
| response = client.get(url) | |||
| assert response.status_code == 200 | |||
| 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): | |||
| """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 | |||
| @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.""" | |||
| with pytest.raises(NodeNotInGraphError) as exc_info: | |||
| 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 | |||
| @pytest.mark.usefixtures('load_graph_record') | |||
| @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.""" | |||
| 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) | |||
| 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" | |||
| } | |||
| ], | |||
| "name": "1", | |||
| "name": "55", | |||
| "opType": "Conv2D", | |||
| "scope": "Default/conv1-Conv2d", | |||
| "attribute": [ | |||
| @@ -149,7 +149,7 @@ | |||
| "type": "DATA_EDGE" | |||
| } | |||
| ], | |||
| "name": "53", | |||
| "name": "56", | |||
| "opType": "tuple_getitem", | |||
| "scope": "Default/bn1-BatchNorm2d", | |||
| "outputType": { | |||
| @@ -354,7 +354,7 @@ | |||
| { | |||
| "input": [ | |||
| { | |||
| "name": "x11", | |||
| "name": "56", | |||
| "type": "DATA_EDGE" | |||
| } | |||
| ], | |||
| @@ -585,7 +585,7 @@ | |||
| { | |||
| "input": [ | |||
| { | |||
| "name": "x", | |||
| "name": "55", | |||
| "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" | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ] | |||
| } | |||