def replace_pattern(graph: Graph, match: dict):
        node = match['op']
        if not node.has_port('in', 2) or node.in_port(2).disconnected() or not node.has_and_set('shape_input'):
            return

        if node.has_valid('layout') and not node.layout.startswith('NC') and graph.graph['layout'] == 'NCHW':
            input_shape_rank = len(node.in_port(0).data.get_shape())
            permutation = PermuteAttrs.get_nhwc_to_nchw_permutation(input_shape_rank)

            data_node = node.in_node(2)

            name = node.soft_get('name', node.id) + '/ShapeGather'
            const = Const(graph, {'value': permutation.perm, 'name': name + '/Const',
                                  'need_shape_inference': True}).create_node_with_data()
            axis_const = Const(graph, {'value': int64_array(0), 'name': name + '/Axis'}).create_node_with_data()
            gather = Gather(graph, {'name': name,
                                    'need_shape_inference': True}).create_node_with_data([data_node, const, axis_const])
            attrs = graph.get_edge_data(data_node.id, node.id, key=0).copy()

            graph.add_edge(gather.id, node.id, **attrs)
            graph.remove_edge(data_node.id, node.id)
Exemple #2
0
def strided_slice(op_node: Node, port_info: str, input_port: int):
    """
    StridedSLice must be permuted even if input or output tensors have rank lesser than 4
    e.g. input_shape = (1, 10, 10), out = input[:, 0:10, :, new_axis], input_rank < 4
    input_shape = (1, 10, 10, 3), out = input[:, 0:5, 0:4, 0], output_rank < 4
    in both examples slice_rank is >= 4
    slice_rank is defined by length of begin, end, strides (they all are of the same length)
    """
    permutation_data_node = get_node_with_permutation(op_node, port_info)
    assert permutation_data_node.has_and_set('permutation'), 'Data node "{}" does not have permutation for node {}, ' \
                                                             'port_info "{}".'.format(permutation_data_node.id,
                                                                                      op_node.id, port_info)
    permute_indices_for_gather = permutation_data_node.permutation.perm
    if len(permute_indices_for_gather) == 0:
        return
    from openvino.tools.mo.ops.op import PermuteAttrs

    slice_rank = op_node.in_port(input_port).data.get_shape()[
        0]  # length of begin, end or strides
    permute_indices_for_gather = PermuteAttrs.get_nhwc_to_nchw_permutation(
        slice_rank).perm
    reorder_inputs_for_shape_or_slice(op_node, input_port,
                                      permute_indices_for_gather)
Exemple #3
0
    def create_topK_net(shape, k, ir_version, use_new_frontend):
        """
            Tensorflow net:

                          |-> Values
            Input -> TopK |
                          |-> Indices


            IR net:

                          |-> Values
            Input -> TopK |
                          |-> Indices

        """

        #
        #   Create Tensorflow model
        #

        import tensorflow as tf

        tf.compat.v1.reset_default_graph()

        # Create the graph and model
        with tf.compat.v1.Session() as sess:
            shape_net = permute_nchw_to_nhwc(shape)

            input_tensor = tf.compat.v1.placeholder(tf.int32,
                                                    shape=shape_net,
                                                    name='Input')
            values, indices = tf.nn.top_k(input_tensor,
                                          k=k,
                                          sorted=True,
                                          name='Operation')

            tf.compat.v1.global_variables_initializer()
            tf_net = sess.graph_def

        #
        #   Create reference IR net
        #
        topk_output_shape = shape.copy()
        inverse_nhwc_nchw = PermuteAttrs.get_nhwc_to_nchw_permutation(
            len(topk_output_shape)).inv
        topk_axis = permute_axis(
            len(topk_output_shape) - 1,
            inverse_nhwc_nchw)  # we need to permute axis attribute
        topk_output_shape[topk_axis] = k

        ref_net = None

        if check_ir_version(10, None, ir_version) and not use_new_frontend:
            nodes_attributes = {
                'input': {
                    'kind': 'op',
                    'type': 'Parameter'
                },
                'input_data': {
                    'shape': shape,
                    'kind': 'data'
                },
                'Const_k_input_data': {
                    'shape': [],
                    'kind': 'data'
                },
                'Const_k': {
                    'kind': 'op',
                    'type': 'Const'
                },
                'Const_k_data': {
                    'shape': [],
                    'kind': 'data'
                },
                'TopK': {
                    'kind': 'op',
                    'type': 'TopK',
                    'axis': topk_axis,
                    'mode': 'max',
                    'sort': 'value'
                },
                'TopK_data_1': {
                    'shape': topk_output_shape,
                    'kind': 'data'
                },
                'TopK_data_2': {
                    'shape': topk_output_shape,
                    'kind': 'data'
                },
                'result_1': {
                    'kind': 'op',
                    'type': 'Result'
                },
                'result_2': {
                    'kind': 'op',
                    'type': 'Result'
                },
            }

            ref_net = build_graph(nodes_attributes, [
                ('input', 'input_data'),
                ('input_data', 'TopK', {
                    'in': 0
                }),
                ('Const_k_input_data', 'Const_k'),
                ('Const_k', 'Const_k_data'),
                ('Const_k_data', 'TopK', {
                    'in': 1
                }),
                ('TopK', 'TopK_data_1', {
                    'out': 0
                }),
                ('TopK', 'TopK_data_2', {
                    'out': 1
                }),
                ('TopK_data_1', 'result_1'),
                ('TopK_data_2', 'result_2'),
            ])

        return tf_net, ref_net
Exemple #4
0
def permute_nhwc_to_nchw(shape, use_new_frontend=False):
    if use_new_frontend:
        return shape
    perm = PermuteAttrs.get_nhwc_to_nchw_permutation(len(shape)).perm
    new_shape = np.array(shape)[perm]
    return new_shape
Exemple #5
0
    def find_and_replace_pattern(self, graph: Graph):
        for node in list(graph.nodes()):
            node = Node(graph, node)
            node_name = node.soft_get('name', node.id)
            # Check that node layout mismatch with graph layout
            # For example: NHWC and NCHW or NCDHW and NDHWC
            if node.kind == 'op' and node.has_valid(
                    'layout') and node.layout != indices_mapping[len(
                        node.layout)][graph.graph['layout']]:
                input = node.in_node()
                output = node.out_node()

                # Calculate permutation for further Transpose operations
                if graph.graph['layout'] == 'NCHW':
                    # if Node has NCHW and graph has NHWC layout
                    permutation = PermuteAttrs.get_nhwc_to_nchw_permutation(
                        len(node.layout))
                else:
                    # if Node has NHWC and graph has NCHW layout
                    permutation = PermuteAttrs.get_nchw_to_nhwc_permutation(
                        len(node.layout))

                # Schematic representation of transformation below
                #
                #                                           \            NCHW                              NCHW
                #            NHWC                        --  \            |  permutation       permutation  |
                #   data-->Convolution(example)-->data   --  /            |      |       NCHW      |        |
                #                                           /   data->Transpose->data->Convolution->data->Transpose->data

                # 1. Insert input Transpose
                #    This Transpose will permute input from original input layout to operation layout
                edge_attrs = graph.get_edge_data(input.id, node.id)[0]
                graph.remove_edge(input.id, node.id)

                input_permute_name = node_name + '/input_transpose'
                input_order_const = Const(
                    graph, {
                        'name': input_permute_name + '/order',
                        'value': permutation.perm
                    }).create_node_with_data()
                input_permute_op = Transpose(graph,
                                             {'name': input_permute_name})
                input_permute_data_node = input_permute_op.create_node_with_data(
                    [input, input_order_const])

                graph.add_edge(input_permute_data_node.id, node.id,
                               **edge_attrs)

                # 2. Insert output Transpose
                #    This Transpose will permute output from operation layout to original input layout
                edge_attrs = graph.get_edge_data(node.id, output.id)[0]
                graph.remove_edge(node.id, output.id)

                input_data_node = Op.create_data_node(
                    graph, node, {'shape': output.shape[permutation.perm]},
                    edge_attrs)

                output_permute_name = node_name + '/output_transpose'
                output_order_const = Const(
                    graph, {
                        'name': output_permute_name + '/order',
                        'value': permutation.inv
                    }).create_node_with_data()
                output_permute_op = Transpose(graph, {
                    'name': output_permute_name
                }).create_node_with_data([input_data_node, output_order_const],
                                         data_nodes=output)

                # 3. Add permutations for Node
                #    Here we use permutation mechanism where data nodes takes permutation attribute.
                #    And then we call permute_attrs method that permutes node attributes according to permutations on
                #    data nodes.
                node.in_node()['permutation'] = permutation
                node.out_node()['permutation'] = permutation
                node.permute_attrs.permute_attrs(node)

                node.in_node()['permutation'] = None
                node.out_node()['permutation'] = None