Exemplo n.º 1
0
    def test_send_op_names_info(self):
        graph = Graph()
        graph.add_nodes_from(['node1'])
        graph.op_names_statistic = Counter(['a', 'a', 'a', 'b', 'b'])

        sub_graph1 = Graph()
        sub_graph1.add_nodes_from(['node2'])
        sub_graph1.op_names_statistic = Counter(['a', 'c', 'c'])

        sub_graph2 = Graph()
        sub_graph2.op_names_statistic = Counter(['a', 'd'])

        node1 = Node(graph, 'node1')
        node1['sub_graphs'] = ['sub_graph1']
        node1['sub_graph1'] = sub_graph1

        node2 = Node(sub_graph1, 'node2')
        node2['sub_graphs'] = ['sub_graph2']
        node2['sub_graph2'] = sub_graph2

        self.init_telemetry_mocks()

        send_op_names_info('framework', graph)
        tm.Telemetry.send_event.assert_any_call('mo', 'op_count',
                                                'framework_a', 5)
        tm.Telemetry.send_event.assert_any_call('mo', 'op_count',
                                                'framework_b', 2)
        tm.Telemetry.send_event.assert_any_call('mo', 'op_count',
                                                'framework_c', 2)
        tm.Telemetry.send_event.assert_any_call('mo', 'op_count',
                                                'framework_d', 1)
Exemplo n.º 2
0
def build_graph(graph_attrs, meta_data, nodes, edges):
    """ Build the Graph with specific nodes and edges.
     :param graph_attrs: dictionary with graph attributes
     :param nodes: list of nodes where each node is tuple (node_name, type, attrs)
                  nodes=[
                      ('input', 'Parameter',  {}),
                      ('weights', 'Const', {}),
                      ('conv', 'Convolution', {}),
                      ('output', 'Result', {})
                  ]
     :param edges: list of edges where each edge is tuple (node_out, node_in, attrs)
                  edges=[
                      ('input', 'conv', {'out': 0, 'in': 0}),
                      ('weights', 'conv', {'out': 0, 'in': 1}),
                      ('conv', 'output', {'out': 0, 'in': 0})
                  ]
     :return: generated graph.
    """
    graph = Graph()
    graph.graph = graph_attrs
    graph.meta_data = meta_data

    for node in nodes:
        create_node(graph, node[0], node[1], node[2])

    for edge in edges:
        out_port = edge[2].get('out', 0)
        in_port = edge[2].get('in', 0)
        connect_nodes_by_name(graph, edge[0], out_port, edge[1], in_port)

    graph.clean_up()

    return graph
Exemplo n.º 3
0
 def test_sub_graph_between_nodes_branches_included(self):
     """
     Check that the function works correctly for tree like structures.
     1 -> 2 -> 3 -> 4
          \
          5 -> 6
         / \
     9 ->   -> 7 -> 8
     """
     graph = Graph()
     node_names = list(range(1, 10))
     graph.add_nodes_from(node_names)
     graph.add_edges_from([(1, 2), (2, 3), (3, 4), (2, 5), (5, 6), (5, 7),
                           (7, 8), (9, 5)])
     self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [4])),
                          node_names)
     self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [6])),
                          node_names)
     self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [8])),
                          node_names)
     # all nodes except 4 because it is a child of end node
     self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [3])),
                          [n for n in node_names if n != 4])
     # all nodes except 1 because it is a parent node child of start node. The nodes 3 and 4 must be added because
     # after merging node 2 into sub-graph the node 2 will be removed and it is not known how to calculate the tensor
     # between node 2 and 3.
     self.assertListEqual(sorted(sub_graph_between_nodes(graph, [2], [8])),
                          [n for n in node_names if n != 1])
Exemplo n.º 4
0
def add_initializers_and_inputs_to_graph(graph: Graph, graph_pb, data_nodes_map: dict):
    """
    The function adds nodes specified in the 'initializer' attribute of the pb and input nodes.
    :param graph: the Graph to add nodes to
    :param graph_pb: the graph protobuf message
    :param data_nodes_map: the dictionary with mapping of tensor names to node id and port
    :return: the list of Parameter nodes
    """
    initializers = Graph()
    fill_graph_with_nodes(initializers, graph_pb.initializer, get_id=lambda pb: pb.name, get_attrs=protobuf_attrs)

    parameters = []
    # first go through all inputs and separate constant from placeholders
    for inp in graph_pb.input:
        name = str(inp.name)
        if graph.has_node(name):
            raise Error('Name {} of input node already exists, input names are duplicated.', name)
        elif initializers.has_node(name):
            graph.add_node(name, kind='op', op='Const', pb=inp, pb_init=initializers.node[name]['pb'])
        else:
            graph.add_node(name, kind='op', op='Parameter', pb=inp)
            parameters.append(Node(graph, name))

        assert name not in data_nodes_map, 'Inconsistency between data_nodes_map and graph.nodes'
        data_nodes_map[name] = (name, 0)

    # go over all initializers and make sure that all of them are added to the graph
    for initializer in initializers.nodes():
        initializer_id = initializer
        if not graph.has_node(initializer_id):
            graph.add_node(initializer_id, kind='op', op='Const', pb=initializers.node[initializer]['pb'],
                           pb_init=initializers.node[initializer]['pb'])
            data_nodes_map[initializer] = (initializer_id, 0)
    return parameters
 def setUp(self):
     self.graph = Graph()
     self.graph.graph['user_shapes'] = None
     self.replacement_desc = CustomReplacementDescriptor('dummy_id', {})
     self.match = SubgraphMatch(self.graph, self.replacement_desc, [], [],
                                [], '')
     self.pipeline_config = FakePipelineConfig({})
Exemplo n.º 6
0
    def test_component_map_loading_swap(self):
        test_map = "input-node name=input dim=16 \n" + \
                   "component-node name=lda component=lda input=input \n" + \
                   "component-node name=tdnn1.batchnorm component=tdnn1.batchnorm input=tdnn1.relu \n" + \
                   "component-node name=tdnn1.relu component=tdnn1.relu input=tdnn1.affine \n" + \
                   "component-node name=tdnn1.affine component=tdnn1.affine input=lda \n" + \
                   "\n"
        graph = Graph(name="test_graph_component_map_loading_swap")

        test_top_map = load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)

        ref_map = {b"lda": ["lda"],
                   b"tdnn1.affine": ["tdnn1.affine"],
                   b"tdnn1.relu": ["tdnn1.relu"],
                   b"tdnn1.batchnorm": ["tdnn1.batchnorm"]}
        self.assertEqual(test_top_map, ref_map)
        self.assertTrue("input" in graph.nodes())
        self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])

        ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
                                 'lda': {'kind': 'op'},
                                 'tdnn1.affine': {'kind': 'op'},
                                 'tdnn1.relu': {'kind': 'op'},
                                 'tdnn1.batchnorm': {'kind': 'op'},
                                 },
                                [
                                    ('input', 'lda'),
                                    ('lda', 'tdnn1.affine'),
                                    ('tdnn1.affine', 'tdnn1.relu'),
                                    ('tdnn1.relu', 'tdnn1.batchnorm'),
                                ]
                                )
        (flag, resp) = compare_graphs(graph, ref_graph, 'tdnn1.batchnorm')
        self.assertTrue(flag, resp)
Exemplo n.º 7
0
    def test_component_map_loading_scale(self):
        test_map = "input-node name=input dim=16\n" + \
                   "component-node name=lda component=lda input=Scale(0.1, input)\n" + \
                   "\n"
        graph = Graph(name="test_graph_component_map_loading_scale")

        test_top_map = load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)

        ref_map = {b"lda": ["lda"]}
        self.assertEqual(test_top_map, ref_map)
        self.assertTrue("input" in graph.nodes())
        self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])

        ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
                                 'lda': {'kind': 'op'},
                                 'mul': {'kind': 'op'},
                                 'scale_const': {'kind': 'op', 'op': 'Const'},
                                 },
                                [
                                    ('input', 'mul', {'in': 0}),
                                    ('scale_const', 'mul', {'in': 1}),
                                    ('mul', 'lda', {'out': 0}),
                                ]
                                )

        (flag, resp) = compare_graphs(graph, ref_graph, 'lda')
        self.assertTrue(flag, resp)
Exemplo n.º 8
0
 def test_caffe_same_name_layer(self):
     proto = caffe_pb2.NetParameter()
     text_format.Merge(proto_str_multi_input + proto_same_name_layers, proto)
     graph = Graph()
     caffe_pb_to_nx(graph, proto, None)
     # 6 nodes because: 2 inputs + 2 convolutions + 2 identity nodes used as fake outputs
     np.testing.assert_equal(len(graph.nodes()), 6)
Exemplo n.º 9
0
    def test_simple_dfs(self):
        graph = Graph()
        graph.add_nodes_from(list(range(1, 5)))
        graph.add_edges_from([(1, 2), (1, 3), (3, 4)])

        visited = set()
        order = graph.dfs(1, visited)
        self.assertTrue(order == [4, 3, 2, 1] or order == [2, 4, 3, 1])
Exemplo n.º 10
0
    def test_caffe_pb_to_nx_one_input(self):
        proto = caffe_pb2.NetParameter()
        text_format.Merge(proto_str_one_input, proto)
        input_shapes = caffe_pb_to_nx(Graph(), proto, None)
        expected_input_shapes = {'Input0': np.array([1, 3, 224, 224])}

        for i in expected_input_shapes:
            np.testing.assert_array_equal(input_shapes[i],
                                          expected_input_shapes[i])
Exemplo n.º 11
0
 def test_is_connected_component_connected(self):
     """
     Check that if the sub-graph is connected.
     """
     graph = Graph()
     node_names = list(range(1, 8))
     graph.add_nodes_from(node_names)
     graph.add_edges_from([(1, 2), (2, 3), (4, 5), (5, 6), (1, 7), (7, 4)])
     self.assertTrue(is_connected_component(graph, list(range(1, 8))))
Exemplo n.º 12
0
    def test_bfs_search_specific_start_nodes(self):
        """
        Check that BFS stars from the user defined nodes and doesn't go in backward edge direction.
        """
        graph = Graph()
        graph.add_nodes_from(list(range(1, 7)))
        graph.add_edges_from([(1, 3), (2, 3), (3, 4), (4, 5), (6, 1)])

        order = bfs_search(graph, [1])
        self.assertTrue(order == [1, 3, 4, 5])
Exemplo n.º 13
0
    def test_bfs_search_default_start_nodes(self):
        """
        Check that BFS automatically determines input nodes and start searching from them.
        """
        graph = Graph()
        graph.add_nodes_from(list(range(1, 6)))
        graph.add_edges_from([(1, 3), (2, 3), (3, 4), (4, 5)])

        order = bfs_search(graph)
        self.assertTrue(order == [1, 2, 3, 4, 5] or order == [2, 1, 3, 4, 5])
Exemplo n.º 14
0
 def test_is_connected_component_two_separate_sub_graphs(self):
     """
     Check that if there are two separate sub-graphs the function returns False.
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 7)))
     graph.add_edges_from([(1, 2), (2, 3), (4, 5), (5, 6)])
     self.assertFalse(is_connected_component(graph, list(range(1, 7))))
     self.assertFalse(is_connected_component(graph, [1, 3]))
     self.assertFalse(is_connected_component(graph, [6, 4]))
     self.assertFalse(is_connected_component(graph, [2, 5]))
Exemplo n.º 15
0
 def test_is_connected_component_two_separate_sub_graphs_divided_by_ignored_node(
         self):
     """
     Check that if there are two separate sub-graphs the function connected by an edge going through the ignored node
     then the function returns False.
     """
     graph = Graph()
     node_names = list(range(1, 8))
     graph.add_nodes_from(node_names)
     graph.add_edges_from([(1, 2), (2, 3), (4, 5), (5, 6), (1, 7), (7, 4)])
     self.assertFalse(is_connected_component(graph, list(range(1, 7))))
Exemplo n.º 16
0
def create_internal_graph(external_graph: Graph):
    internal_graph = Graph()
    # fill the body graph
    for attr_key in external_graph.graph.keys():
        if attr_key != 'library':
            internal_graph.graph[attr_key] = copy.deepcopy(
                external_graph.graph[attr_key])
        else:
            # it is sufficient to have a link to the library
            internal_graph.graph['library'] = external_graph.graph['library']
    return internal_graph
Exemplo n.º 17
0
 def test_is_connected_component_edges_direction_is_ignored(self):
     """
     Check that edges direction is ignored when checking for the connectivity.
     """
     graph = Graph()
     node_names = list(range(1, 5))
     graph.add_nodes_from(node_names)
     graph.add_edges_from([(2, 1), (2, 3), (4, 3)])
     self.assertTrue(is_connected_component(graph, node_names))
     self.assertTrue(is_connected_component(graph, [2, 1]))
     self.assertTrue(is_connected_component(graph, [4, 2, 3]))
Exemplo n.º 18
0
    def test_caffe_pb_to_multi_input(self):
        proto = caffe_pb2.NetParameter()
        text_format.Merge(proto_str_multi_input + layer_proto_str, proto)
        input_shapes = caffe_pb_to_nx(Graph(), proto, None)
        expected_input_shapes = {
            'data': np.array([1, 3, 224, 224]),
            'data1': np.array([1, 3])
        }

        for i in expected_input_shapes:
            np.testing.assert_array_equal(input_shapes[i], expected_input_shapes[i])
Exemplo n.º 19
0
def unified_pipeline(argv: argparse.Namespace):
    graph = Graph(cmd_params=argv,
                  name=argv.model_name,
                  ir_version=get_ir_version(argv))
    class_registration.apply_replacements(graph, [
        class_registration.ClassType.LOADER,
        class_registration.ClassType.FRONT_REPLACER,
        class_registration.ClassType.MIDDLE_REPLACER,
        class_registration.ClassType.BACK_REPLACER
    ])
    return graph
Exemplo n.º 20
0
 def test_sub_graph_between_nodes_placeholder_included(self):
     """
     Check that the function doesn't allow to add Placeholders to the sub-graph. 5 is the Placeholder op.
       5->
          \
     1 -> 2 -> 3 -> 4
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 6)))
     graph.node[5]['op'] = 'Parameter'
     graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
     self.assertRaises(Error, sub_graph_between_nodes, graph, [1], [4])
Exemplo n.º 21
0
 def test_is_connected_component_edges_direction_is_ignored_not_connected(
         self):
     """
     Check that edges direction is ignored when checking for the connectivity. In this case the graph is not
     connected.
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 5)))
     graph.add_edges_from([(2, 1), (2, 3), (4, 3)])
     self.assertFalse(is_connected_component(graph, [1, 2, 4]))
     self.assertFalse(is_connected_component(graph, [1, 4]))
     self.assertFalse(is_connected_component(graph, [2, 4]))
     self.assertFalse(is_connected_component(graph, [3, 4, 1]))
Exemplo n.º 22
0
def build_matcher(graph: Graph, nodes: list, edges: list, node_attrs: list = None,
                  edge_attrs: list = None):
    if node_attrs is not None or edge_attrs is not None:
        log.warning('\'edge_attrs\' or `\'node_attrs\'` parameter was passed to function \'find_pattern_matches\', '
                    'but they are not used anymore. Pattern matching proceeds according to \'nodes\' and \'edges\' '
                    'parameters. Please avoid passing \'edge_attrs\' and \'node_attrs\' parameters to any pattern '
                    'matching function like \'find_pattern_matches\', \'apply_pattern\' and \'pattern\' because it '
                    'will be deprecated in the next release.')

    subgraph = Graph(name='pattern')
    subgraph.add_nodes_from(nodes)
    subgraph.add_edges_from(edges)
    return ism.MultiDiGraphMatcher(graph, subgraph, node_match, edge_match)
Exemplo n.º 23
0
 def test_sub_graph_between_nodes_multiple_inputs(self):
     """
     Check that the function works correctly when multiple inputs specified.
       5->
          \
     1 -> 2 -> 3 -> 4
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 6)))
     graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
     sub_graph_nodes = sub_graph_between_nodes(graph, [2, 5], [4])
     self.assertIsNotNone(sub_graph_nodes)
     self.assertListEqual(sorted(sub_graph_nodes), sorted([2, 3, 4, 5]))
Exemplo n.º 24
0
 def test_sub_graph_between_nodes_do_not_include_incoming_edges_for_input_nodes(
         self):
     """
     Check that the function doesn't add input nodes for the start nodes of the sub-graph. For example, we do not
     need to add node 5 in the case below if we find match from node 1 till node 4.
       5->
          \
     1 -> 2 -> 3 -> 4
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 6)))
     graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
     sub_graph_nodes = sub_graph_between_nodes(graph, [2], [4])
     self.assertIsNotNone(sub_graph_nodes)
     self.assertListEqual(sorted(sub_graph_nodes), [2, 3, 4])
Exemplo n.º 25
0
 def test_sub_graph_between_nodes_placeholder_excluded(self):
     """
     Check that the function do not check that node is Placeholders for the nodes not included into the sub-graph.
     For example, node 5 is Placeholder but it is not included into the sub-graph, so this attribute is ignored.
       5->
          \
     1 -> 2 -> 3 -> 4
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 6)))
     graph.node[5]['op'] = 'Parameter'
     graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
     sub_graph_nodes = sub_graph_between_nodes(graph, [2], [4])
     self.assertIsNotNone(sub_graph_nodes)
     self.assertListEqual(sorted(sub_graph_nodes), [2, 3, 4])
Exemplo n.º 26
0
    def _create_node(pads=None, value=None, mode=None):
        if pads is None:
            pads = [1, 2, 3, 4]
        if value is None:
            value = 0.0
        if mode is None:
            mode = 'constant'
        pb = onnx.helper.make_node('Pad',
                                   pads=pads,
                                   mode=mode,
                                   value=value,
                                   inputs=['a'],
                                   outputs=['b'])
        graph = Graph()
        node = PB({'pb': pb, 'graph': graph})

        return node
Exemplo n.º 27
0
 def test_sub_graph_between_nodes_control_flow_not_included_forward(self):
     """
     Check that the function works correctly for case when control flow edges should not be traversed (edge 3 -> 5).
        1 -> 2 -> 3 -> 4
                   \
                    -> 5 -> 6
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 7)))
     graph.add_edges_from([(1, 2), (2, 3), (3, 4),
                           (3, 5, {
                               'control_flow_edge': True
                           }), (5, 6)])
     sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4],
                                               include_control_flow=False)
     self.assertIsNotNone(sub_graph_nodes)
     self.assertListEqual(sorted(sub_graph_nodes), sorted([1, 2, 3, 4]))
Exemplo n.º 28
0
 def test_sub_graph_between_nodes_control_flow_included(self):
     """
     Check that the function works correctly for case when control flow edges must be traversed (edge 5 -> 2).
     6 -> 5->
             \
        1 -> 2 -> 3 -> 4
     """
     graph = Graph()
     graph.add_nodes_from(list(range(1, 7)))
     graph.add_edges_from([(1, 2), (2, 3), (3, 4),
                           (5, 2, {
                               'control_flow_edge': True
                           }), (6, 5)])
     sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4],
                                               include_control_flow=True)
     self.assertIsNotNone(sub_graph_nodes)
     self.assertListEqual(sorted(sub_graph_nodes),
                          sorted([1, 2, 3, 4, 5, 6]))
Exemplo n.º 29
0
    def test_sub_graph_between_nodes_include_incoming_edges_for_internal_nodes(
            self):
        """
        Check that the function adds input nodes for the internal nodes of the graph. For example, we need to add node 5
        and 6 in the case below if we find match from node 1 till node 4.
        6 -> 5 ->
                 \
            1 -> 2 -> 3 -> 4
        :return:
        """
        graph = Graph()
        graph.add_nodes_from(list(range(1, 7)))
        graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2), (6, 5)])
        sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4])
        self.assertIsNotNone(sub_graph_nodes)
        self.assertListEqual(sorted(sub_graph_nodes), list(range(1, 7)))

        sub_graph_nodes = sub_graph_between_nodes(graph, [1], [2])
        self.assertIsNotNone(sub_graph_nodes)
        self.assertListEqual(sorted(sub_graph_nodes), [1, 2, 5, 6])
Exemplo n.º 30
0
def build_graph_with_edge_attrs(nodes_attrs: dict,
                                edges: list,
                                update_attributes: dict = None,
                                cli: Namespace = Namespace(static_shape=False,
                                                           data_type='FP32')):
    """
    Build the Graph with specific nodes and edges.
    :param nodes_attrs: dictionary where key is the node name and the value is the dictionary with node attributes.
    :param edges: list of pairs with start and end node names of the edge.
    :param update_attributes: optional dictionary which specifies nodes names and their attributes to be updated. The
    key is a node name to update attribute and the value is a dictionary with attribute name and its value.
    :param cli: Namespace with cli keys to associate with the graph
    :return: generated graph.
    """
    graph = Graph()
    for node_1, node_2, attr in edges:
        if node_1 not in graph.nodes():
            graph.add_node(node_1, **deepcopy(nodes_attrs[node_1]))
        if node_2 not in graph.nodes():
            graph.add_node(node_2, **deepcopy(nodes_attrs[node_2]))
        graph.add_edge(node_1, node_2, **attr)
    if update_attributes is not None:
        for node_name, new_attrs in update_attributes.items():
            assert (node_name in graph.nodes())
            for attr, value in new_attrs.items():
                graph.node[node_name][attr] = value

    for node in graph.get_op_nodes():
        # Add in_ports attribute
        in_edges = node.in_edges()
        for attr in in_edges.values():
            node.add_input_port(idx=attr['in'])

        # Add out_ports attribute
        out_edges = node.out_edges()
        for attr in out_edges.values():
            node.add_output_port(idx=attr['out'])

    graph.graph['cmd_params'] = cli
    return graph