Ejemplo n.º 1
0
    def test_backward_bfs_simple(self):
        # Placeholder->ScaleShift->Mul->Add
        graph = build_graph(nodes_attributes,
                            [('placeholder_1', 'placeholder_1_data'),
                             ('placeholder_1_data', 'scaleshift_1'),
                             ('scaleshift_1_w', 'scaleshift_1'),
                             ('scaleshift_1', 'scaleshift_1_data'),
                             ('scaleshift_1_data', 'mul_1'),
                             ('mul_1', 'mul_1_data'), ('mul_1_data', 'add_1'),
                             ('add_1', 'add_1_data'),
                             ('add_1_data', 'op_output')])

        res = backward_bfs(Node(graph, 'add_1_data'),
                           ['Add', 'ScaleShift', 'Mul'], ['Parameter'])
        self.assertTrue(
            len(res) == 1 and res[0].id == 'placeholder_1',
            'Placeholder operation was not found by bfs')

        res = backward_bfs(Node(graph, 'add_1'), [], ['Parameter'],
                           allowed_all=True)
        self.assertTrue(
            len(res) == 1 and res[0].id == 'placeholder_1',
            'Placeholder operation was not found by bfs')

        res = backward_bfs(Node(graph, 'add_1_data'), ['Add'], ['ScaleShift'])
        self.assertTrue(
            len(res) == 0,
            'No one node should be found! But bfs found {} nodes'.format(
                len(res)))

        res = backward_bfs(Node(graph, 'add_1_data'), ['Add', 'Mul'],
                           ['Parameter', 'ScaleShift'])
        self.assertTrue(
            len(res) == 1 and res[0].id == 'scaleshift_1',
            'BFS should find only one ScaleShift operation')
def fuse_linear_ops(graph: Graph):
    """
    This function makes fusing of linear operations (Mul,Add) to Convolution/FC.
    """
    fuse_count = 0

    # Fusion in backward direction
    nodes = graph.pseudo_topological_sort()
    for node in nodes:
        is_fused = False

        # Fuse Mul to Convolution/FC
        if node.soft_get('op') == 'Mul' and get_value_in_port(
                node) is not None and node.soft_get('can_be_fused') is True:
            fuse_nodes = backward_bfs(
                node, [],
                ['Convolution', 'Deconvolution', 'FullyConnected', 'MatMul'])
            is_fused = _fuse_mul(graph, node, fuse_nodes)

        if hasattr(graph, 'graph') and 'cmd_params' in graph.graph and \
            not graph.graph['cmd_params'].generate_experimental_IR_V10:
            # Fuse Add to Convolution/FC
            if node.soft_get('op') == 'Add'\
                    and get_value_in_port(node) is not None\
                    and node.soft_get('can_be_fused') is True:
                fuse_nodes = backward_bfs(node, [], [
                    'Convolution', 'Deconvolution', 'FullyConnected', 'MatMul'
                ])
                is_fused = _fuse_add(graph, node, fuse_nodes)

        fuse_count += is_fused

    # Fusion in forward direction
    nodes = graph.pseudo_topological_sort(reverse=True)
    for node in nodes:
        is_fused = False

        # Fuse Mul to Convolution/FC
        if node.soft_get('op') == 'Mul' and get_value_in_port(
                node) is not None and node.soft_get('can_be_fused') is True:
            fuse_nodes = forward_bfs(
                node, [],
                ['Convolution', 'Deconvolution', 'FullyConnected', 'MatMul'])
            is_fused = _fuse_mul(graph, node, fuse_nodes, False)

        # Fuse Add to Convolution/FC
        if hasattr(graph, 'graph') and 'cmd_params' in graph.graph and \
                not graph.graph['cmd_params'].generate_experimental_IR_V10:
            if node.soft_get('op') == 'Add' and \
                    get_value_in_port(node) is not None and \
                    node.soft_get('can_be_fused') is True:
                fuse_nodes = forward_bfs(node, [],
                                         ['FullyConnected', 'MatMul'])
                is_fused = _fuse_add(graph, node, fuse_nodes, False)

        fuse_count += is_fused

    log.debug("Fused {} nodes".format(fuse_count))
Ejemplo n.º 3
0
def fuse_linear_ops(graph: nx.MultiDiGraph):
    """
    This function makes fusing of linear operations (Mul,Add) to Convolution/FC.
    """
    fuse_count = 0

    # Fusion in backward direction
    nodes = pseudo_topological_sort(graph)
    for idx in nodes:
        node = Node(graph, idx)
        is_fused = False

        # Fuse Mul to Convolution/FC
        if node.soft_get('op') == 'Mul' and get_value_id(
                node) is not None and node.soft_get('can_be_fused') == True:
            fuse_nodes = backward_bfs(
                node, [], ['Convolution', 'Deconvolution', 'FullyConnected'])
            is_fused = _fuse_mul(graph, node, fuse_nodes)

        # Fuse Add to Convolution/FC
        if node.soft_get('op') == 'Add' and get_value_id(
                node) is not None and node.soft_get('can_be_fused') == True:
            fuse_nodes = backward_bfs(
                node, [], ['Convolution', 'Deconvolution', 'FullyConnected'])
            is_fused = _fuse_add(graph, node, fuse_nodes)

        fuse_count += is_fused

    # Fusion in forward direction
    nodes = pseudo_topological_sort(graph, reverse=True)
    for idx in nodes:
        node = Node(graph, idx)
        is_fused = False

        # Fuse Mul to Convolution/FC
        if node.soft_get('op') == 'Mul' and get_value_id(
                node) is not None and node.soft_get('can_be_fused') == True:
            fuse_nodes = forward_bfs(
                node, [], ['Convolution', 'Deconvolution', 'FullyConnected'])
            is_fused = _fuse_mul(graph, node, fuse_nodes, False)

        # Fuse Add to Convolution/FC
        if node.soft_get('op') == 'Add' and get_value_id(
                node) is not None and node.soft_get('can_be_fused') == True:
            fuse_nodes = forward_bfs(node, [], ['FullyConnected'])
            is_fused = _fuse_add(graph, node, fuse_nodes, False)

        fuse_count += is_fused

    log.debug("Fused {} nodes".format(fuse_count))
Ejemplo n.º 4
0
    def test_backward_bfs_hard(self):
        # Placeholder->ScaleShift->Mul1->Add1---->Concat
        #             `----------->Add2->Mul2--'
        graph = build_graph(nodes_attributes,
                            [('placeholder_1', 'placeholder_1_data'),
                             ('placeholder_1_data', 'scaleshift_1'),
                             ('placeholder_1_data', 'add_2'),
                             ('scaleshift_1_w', 'scaleshift_1'),
                             ('scaleshift_1', 'scaleshift_1_data'),
                             ('scaleshift_1_data', 'mul_1'),
                             ('mul_1', 'mul_1_data'), ('mul_1_data', 'add_1'),
                             ('add_1', 'add_1_data'), ('add_2', 'add_2_data'),
                             ('add_2_data', 'mul_2'), ('mul_2', 'mul_2_data'),
                             ('add_1_data', 'concat_1'),
                             ('mul_2_data', 'concat_1'),
                             ('concat_1', 'concat_1_data')],
                            {'concat_1_data': {
                                'is_output': True
                            }})

        res = backward_bfs(Node(graph, 'concat_1'),
                           ['ScaleShift', 'Mul', 'Add'], ['Placeholder'])
        self.assertTrue(len(res) == 0, 'Smth went wrong with bfs')

        res = backward_bfs(Node(graph, 'concat_1'), ['Mul'], ['Add'])
        self.assertTrue(
            len(res) == 2
            and all([res[x].id in ['add_1', 'add_2']
                     for x in range(len(res))]),
            'Add operations was not found by bfs')

        res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['Add'])
        self.assertTrue(len(res) == 0, 'BFS shouldn\'t find any operations')

        res = backward_bfs(Node(graph, 'concat_1'), [], ['Add'],
                           allowed_all=True)
        self.assertTrue(
            len(res) == 2
            and all([res[x].id in ['add_1', 'add_2']
                     for x in range(len(res))]),
            'Add operations was not found by bfs')

        res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift'],
                           ['ScaleShift'])
        self.assertTrue(
            len(res) == 0,
            'No one node should be found! But bfs found {} nodes'.format(
                len(res)))
Ejemplo n.º 5
0
def fuse_linear_ops(graph: Graph):
    """
    This function makes fusing of linear operations (Mul,Add) to Convolution/FC.
    """
    fuse_count = 0

    # Fusion in backward direction
    nodes = graph.pseudo_topological_sort()
    for node in nodes:
        is_fused = False

        # Fuse Mul to Convolution/FC
        if node.soft_get('op') == 'Mul' and get_value_in_port(
                node) is not None and node.has_and_set('can_be_fused'):
            fuse_nodes = backward_bfs(
                node, [], ['Convolution', 'Deconvolution', 'MatMul'])
            is_fused = _fuse_mul(graph, node, fuse_nodes)

        fuse_count += is_fused

    # Fusion in forward direction
    nodes = graph.pseudo_topological_sort(reverse=True)
    for node in nodes:
        is_fused = False

        # Fuse Mul to Convolution/FC
        if node.soft_get('op') == 'Mul' and get_value_in_port(
                node) is not None and node.has_and_set('can_be_fused'):
            fuse_nodes = forward_bfs(
                node, [], ['Convolution', 'Deconvolution', 'MatMul'])
            is_fused = _fuse_mul(graph, node, fuse_nodes, False)

        fuse_count += is_fused

    log.debug("Fused {} nodes".format(fuse_count))
Ejemplo n.º 6
0
    def test_backward_bfs_cycle(self):
        # Placeholder->ScaleShift->Mul->Add
        graph = build_graph(nodes_attributes,
                            [('placeholder_1', 'placeholder_1_data'),
                             ('placeholder_1_data', 'scaleshift_1'),
                             ('scaleshift_1_w', 'scaleshift_1'),
                             ('scaleshift_1', 'scaleshift_1_data'),
                             ('scaleshift_1_data', 'mul_1'),
                             ('mul_1', 'mul_1_data'),
                             ('mul_1_data', 'add_1'),
                             ('add_1', 'add_1_data'),
                             ('add_1_data', 'placeholder_1'),
                             ('add_1_data', 'op_output')
                             ])

        res = backward_bfs(Node(graph, 'add_1_data'), ['Add', 'ScaleShift', 'Mul', 'Parameter'], ['Conv2D'])
        self.assertTrue(len(res) == 0, 'Sholdn\'t find any nodes due to cycle in graph')