Fix pad op with int input 2021.4 (#5772)

* Added operation ConvertLike to the MO

* Fixed transformations with Pad which insert Const with pad value of incorrect type

* Added constant folding to ConvertLike operation

* Fixed unit tests for Pad transformations to include ConverLike operations

* Update copyright year

* nGraph code style fix
This commit is contained in:
Evgeny Lazarev
2021-05-25 11:55:27 +03:00
committed by GitHub
parent 7a31e29517
commit 43bdf6b3c1
4 changed files with 21 additions and 6 deletions

View File

@@ -1,7 +1,9 @@
# Copyright (C) 2018-2021 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from extensions.ops.ConvertLike import ConvertLike
from mo.front.common.replacement import FrontReplacementPattern
from mo.front.tf.graph_utils import create_op_with_const_inputs
from mo.graph.graph import Graph, rename_nodes
from mo.ops.const import Const
from mo.ops.pad import Pad
@@ -26,7 +28,11 @@ class AttributedPadToPad(FrontReplacementPattern):
new_pad.in_port(1).connect(Const(graph, {'value': attr_pad.pads[:, 0]}).create_node().out_port(0))
new_pad.in_port(2).connect(Const(graph, {'value': attr_pad.pads[:, 1]}).create_node().out_port(0))
if attr_pad.soft_get('mode') == 'constant':
new_pad.in_port(3).connect(Const(graph, {'value': attr_pad.fill_value}).create_node().out_port(0))
# create Constant node of proper data type (equal to the data type of the Pad first input)
convert_pad_value = create_op_with_const_inputs(graph, ConvertLike, {0: attr_pad.fill_value},
{'name': original_name + '/pad_value_convert'})
convert_pad_value.in_port(1).connect(new_pad.in_port(0).get_source())
new_pad.in_port(3).connect(convert_pad_value.out_port(0))
attr_pad.out_port(0).get_connection().set_source(new_pad.out_port(0))
graph.remove_node(attr_pad.id)

View File

@@ -1,13 +1,13 @@
# Copyright (C) 2018-2021 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
from extensions.ops.ConvertLike import ConvertLike
from extensions.ops.split import Split
from extensions.ops.transpose import Transpose
from mo.front.common.partial_infer.utils import int64_array
from mo.front.common.replacement import FrontReplacementPattern
from mo.front.tf.graph_utils import create_op_with_const_inputs
from mo.graph.graph import Graph, rename_node
from mo.ops.const import Const
from mo.ops.pad import Pad
from mo.ops.squeeze import Squeeze
@@ -35,8 +35,11 @@ class PadTFToPad(FrontReplacementPattern):
if not tfpad.in_port(2).disconnected():
tfpad.in_port(2).get_connection().set_destination(new_pad.in_port(3))
else:
new_pad.in_port(3).connect(Const(graph, {'value': 0.0, 'name': new_pad.name + '/value'}
).create_node().out_port(0))
# create Constant node of proper data type (equal to the data type of the Pad first input)
convert_pad_value = create_op_with_const_inputs(graph, ConvertLike, {0: 0.0},
{'name': original_name + '/pad_value_convert'})
convert_pad_value.in_port(1).connect(new_pad.in_port(0).get_source())
new_pad.in_port(3).connect(convert_pad_value.out_port(0))
# convert TF representation of the pads as [N, 2] to MO representation: [N] and [N]
transposed_pads = create_op_with_const_inputs(graph, Transpose, {1: int64_array([1, 0])})

View File

@@ -18,6 +18,7 @@ nodes_attributes = {
# new Pad layer and inputs
'pad': {'type': 'Pad', 'kind': 'op', 'op': 'Pad', 'mode': 'constant'},
'convert_like': {'type': 'ConvertLike', 'kind': 'op', 'op': 'ConvertLike'},
**const('pad_begin', int64_array([1, 3, 5])),
**const('pad_end', int64_array([2, 4, 6])),
**const('pad_fill', np.array(0.75)),
@@ -36,7 +37,9 @@ class AttributedPadToPadTest(unittest.TestCase):
[('placeholder', 'pad', {'in': 0, 'out': 0}),
('pad_begin', 'pad', {'in': 1, 'out': 0}),
('pad_end', 'pad', {'in': 2, 'out': 0}),
('pad_fill', 'pad', {'in': 3, 'out': 0}),
('pad_fill', 'convert_like', {'in': 0, 'out': 0}),
('placeholder', 'convert_like', {'in': 1, 'out': 0}),
('convert_like', 'pad', {'in': 3, 'out': 0}),
('pad', 'result')
],
{}, nodes_with_edges_only=True)

View File

@@ -27,6 +27,7 @@ nodes_attributes = {
**const('squeeze_1_axis', int64_array([0])),
'squeeze_2': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
**const('squeeze_2_axis', int64_array([0])),
'convert_like': {'type': 'ConvertLike', 'kind': 'op', 'op': 'ConvertLike'},
**const('pad_fill', np.array(0.0)),
}
@@ -73,7 +74,9 @@ class PadTFToPadTest(unittest.TestCase):
{}, nodes_with_edges_only=True)
graph.get_op_nodes(op='TFPad')[0].add_input_port(2)
graph_ref = build_graph(nodes_attributes, common_edges + [('pad_fill', 'pad', {'in': 3, 'out': 0})],
graph_ref = build_graph(nodes_attributes, common_edges + [('pad_fill', 'convert_like', {'in': 0, 'out': 0}),
('placeholder', 'convert_like', {'in': 1, 'out': 0}),
('convert_like', 'pad', {'in': 3, 'out': 0})],
{}, nodes_with_edges_only=True)
self._run_test(graph, graph_ref)