SplitConcatPairToInterpolate inserts Interpolate when input is 2D (#596)

* SplitConcatPairToInterpolate transformation was moved to middle stage and is applied only for 4D and 5D inputs.
This commit is contained in:
Vladimir Gavrilov authored and GitHub committed 2020-05-28 18:08:24 +03:00
1 parent 77162bf8ee
commit 33aca7d2c4
4 files changed
+451 -427

No files matched your search

+1 -1
View File
@@ -436,7 +436,6 @@ extensions/front/tf/sparse_segment_sum_ext.py
extensions/front/tf/sparse_to_dense_ext.py
extensions/front/tf/sparse_weighted_sum.py
extensions/front/tf/split_ext.py
extensions/front/tf/SplitConcatPairToInterpolate.py
extensions/front/tf/ssd_support.json
extensions/front/tf/ssd_support_api_v1.14.json
extensions/front/tf/ssd_support_api_v1.15.json
@@ -568,6 +567,7 @@ extensions/middle/SliceConverter.py
extensions/middle/SliceLikeToStridedSlice.py
extensions/middle/space_to_depth.py
extensions/middle/sparse_reshape.py
extensions/middle/SplitConcatPairToInterpolate.py
extensions/middle/ssd_anchors_to_const.py
extensions/middle/SwapAxesMiddleReplacer.py
extensions/middle/TensorIterator_utils.py
@@ -1,412 +0,0 @@
"""
Copyright (c) 2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import unittest
import numpy as np
from extensions.front.tf.SplitConcatPairToInterpolate import SplitConcatPairToInterpolate
from mo.front.common.partial_infer.utils import int64_array
from mo.utils.ir_engine.compare_graphs import compare_graphs
from mo.utils.unittest.graph import build_graph
graph_node_attrs_for_2d_spatial_case = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(3, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(3, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 3},
'split_data_0': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
graph_node_attrs_for_3d_spatial_case = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 3, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(4, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(4, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 4},
'split_data_0': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
graph_edges = [
('placeholder', 'placeholder_data'),
('placeholder_data', 'split', {'in': 0}),
('split_axis_const', 'split_axis_const_data'),
('split_axis_const_data', 'split', {'in': 1}),
('split', 'split_data_0', {'out': 0}),
('split', 'split_data_1', {'out': 1}),
('split', 'split_data_2', {'out': 2}),
('split_data_0', 'concat', {'in': 0}),
('split_data_0', 'concat', {'in': 1}),
('split_data_1', 'concat', {'in': 2}),
('split_data_1', 'concat', {'in': 3}),
('split_data_2', 'concat', {'in': 4}),
('split_data_2', 'concat', {'in': 5}),
('concat', 'concat_data'),
('concat_data', 'abs'),
('abs', 'abs_data'),
('abs_data', 'output')
]
ref_graph_edges = [
('placeholder', 'placeholder_data'),
('placeholder_data', 'interpolate', {'in': 0}),
('placeholder_data', 'shape'),
('shape', 'sslice', {'in': 0}),
('slice_begin', 'sslice', {'in': 1}),
('slice_end', 'sslice', {'in': 2}),
('sslice', 'sslice_data'),
('scales', 'scales_data'),
('sslice_data', 'mul', {'in': 0}),
('scales_data', 'mul', {'in': 1}),
('mul', 'mul_data'),
('mul_data', 'interpolate', {'in': 1}),
('interpolate', 'interpolate_data'),
('interpolate_data', 'abs'),
('abs', 'abs_data'),
('abs_data', 'output'),
]
ref_graph_node_attrs_for_2d_spatial_case_1 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([3]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([3]),
'shape': int64_array([1])
},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([4])},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
ref_graph_node_attrs_for_2d_spatial_case_2 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([2]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([3])},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
ref_graph_node_attrs_for_3d_spatial_case_1 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 3, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([4]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([4]),
'shape': int64_array([1])
},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([5])},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
ref_graph_node_attrs_for_3d_spatial_case_2 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 3, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([3]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([4]),
'shape': int64_array([1])
},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([5])},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
class SplitConcatPairToInterpolateTest(unittest.TestCase):
def test_spatial_2d_split_concat_1(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_2d_spatial_case,
edges=graph_edges
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_2d_spatial_case_1,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
def test_spatial_2d_split_concat_2(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_2d_spatial_case,
edges=graph_edges,
update_attributes={
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(2, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(2, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 2},
'split_data_0': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
}
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_2d_spatial_case_2,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
def test_spatial_3d_split_concat_1(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_3d_spatial_case,
edges=graph_edges
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_3d_spatial_case_1,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
def test_spatial_3d_split_concat_2(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_3d_spatial_case,
edges=graph_edges,
update_attributes={
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(3, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(3, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 3},
'split_data_0': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
}
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_3d_spatial_case_2,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
@@ -20,8 +20,9 @@ from typing import Optional
from extensions.ops.elementwise import Mul
from extensions.ops.interpolate import Interpolate
from mo.front.common.partial_infer.utils import int64_array
from mo.front.common.replacement import FrontReplacementSubgraph
from mo.front.tf.graph_utils import create_op_with_const_inputs
from mo.graph.graph import Graph, Node
from mo.middle.replacement import MiddleReplacementPattern
from mo.ops.const import Const
from mo.ops.shape import Shape
from mo.ops.strided_slice import StridedSlice
@@ -53,6 +54,9 @@ def get_concat_after_split(split: Node) -> Optional[Node]:
def get_interpolate_pattern(split: Node) -> dict:
split_shape = split.in_port(0).data.get_shape()
if len(split_shape) not in {4, 5}:
return {}
concat = get_concat_after_split(split)
if concat is None:
return {}
@@ -79,19 +83,19 @@ def replace_interpolate_pattern(graph: Graph, match: dict):
mul_node = Mul(graph, dict(name=split_node_name + '/Mul_')).create_node()
scales_node.out_port(0).connect(mul_node.in_port(1))
slice_begin = Const(graph, dict(name=split_node_name + '/slice_begin_',
value=int64_array([axis]))).create_node()
slice_end = Const(graph, dict(name=split_node_name + '/slice_end_',
value=int64_array([axis + 1]))).create_node()
strided_slice_node = create_op_with_const_inputs(graph,
StridedSlice,
{1: int64_array([axis]), 2: int64_array([axis + 1])},
{
'name': split_node_name + '/StridedSlice_',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0])
})
shape_node.out_port(0).connect(strided_slice_node.in_port(0))
strided_slice_node = StridedSlice(graph,
{'name': split_node_name + '/StridedSlice_',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
}).create_node([shape_node, slice_begin, slice_end])
strided_slice_node.out_port(0).connect(mul_node.in_port(0))
interp_node = Interpolate(graph, dict(name=split_node_name + '/Interpolate_',
@@ -106,7 +110,7 @@ def replace_interpolate_pattern(graph: Graph, match: dict):
split_connection.get_source().connect(shape_node.in_port(0))
class SplitConcatPairToInterpolate(FrontReplacementSubgraph):
class SplitConcatPairToInterpolate(MiddleReplacementPattern):
"""
This transformation looks for Interpolation layer implemented using simple operations, i.e. Split and Concat,
and replaces found pattern with a sequence of Shape, StridedSlice, Const, Mul, Interpolate.
@@ -146,6 +150,11 @@ class SplitConcatPairToInterpolate(FrontReplacementSubgraph):
by number of output ports of 'split'.
"""
enabled = True
force_clean_up = True
def run_before(self):
from extensions.middle.InterpolateSequenceToInterpolate import InterpolateSequenceToInterpolate
return [InterpolateSequenceToInterpolate]
def find_and_replace_pattern(self, graph: Graph):
log.debug('Enabled replacement of a pair of Split and Concat with Interpolate.')
@@ -0,0 +1,427 @@
"""
Copyright (c) 2020 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import unittest
import numpy as np
from extensions.middle.SplitConcatPairToInterpolate import SplitConcatPairToInterpolate
from mo.front.common.partial_infer.utils import int64_array
from mo.utils.ir_engine.compare_graphs import compare_graphs
from mo.utils.unittest.graph import build_graph
graph_node_attrs_for_2d_spatial_case = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(3, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(3, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 3},
'split_data_0': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
graph_node_attrs_for_3d_spatial_case = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 3, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(4, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(4, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 4},
'split_data_0': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
graph_edges = [
('placeholder', 'placeholder_data'),
('placeholder_data', 'split', {'in': 0}),
('split_axis_const', 'split_axis_const_data'),
('split_axis_const_data', 'split', {'in': 1}),
('split', 'split_data_0', {'out': 0}),
('split', 'split_data_1', {'out': 1}),
('split', 'split_data_2', {'out': 2}),
('split_data_0', 'concat', {'in': 0}),
('split_data_0', 'concat', {'in': 1}),
('split_data_1', 'concat', {'in': 2}),
('split_data_1', 'concat', {'in': 3}),
('split_data_2', 'concat', {'in': 4}),
('split_data_2', 'concat', {'in': 5}),
('concat', 'concat_data'),
('concat_data', 'abs'),
('abs', 'abs_data'),
('abs_data', 'output')
]
ref_graph_edges = [
('placeholder', 'placeholder_data'),
('placeholder_data', 'interpolate', {'in': 0}),
('placeholder_data', 'shape'),
('shape', 'shape_data'),
('shape_data', 'sslice', {'in': 0}),
('slice_begin', 'slice_begin_data'),
('slice_begin_data', 'sslice', {'in': 1}),
('slice_end', 'slice_end_data'),
('slice_end_data', 'sslice', {'in': 2}),
('sslice', 'sslice_data'),
('scales', 'scales_data'),
('sslice_data', 'mul', {'in': 0}),
('scales_data', 'mul', {'in': 1}),
('mul', 'mul_data'),
('mul_data', 'interpolate', {'in': 1}),
('interpolate', 'interpolate_data'),
('interpolate_data', 'abs'),
('abs', 'abs_data'),
('abs_data', 'output'),
]
ref_graph_node_attrs_for_2d_spatial_case_1 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([3]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'shape_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([3]),
'shape': int64_array([1])
},
'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([4])},
'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
ref_graph_node_attrs_for_2d_spatial_case_2 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([2]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'shape_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([3])},
'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
ref_graph_node_attrs_for_3d_spatial_case_1 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 3, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([4]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'shape_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([4]),
'shape': int64_array([1])
},
'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([5])},
'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
ref_graph_node_attrs_for_3d_spatial_case_2 = {
'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_data': {
'value': None,
'shape': int64_array([1, 3, 100, 120, 150]),
'kind': 'data',
'data_type': None
},
'interpolate': {
'type': 'Interpolate',
'kind': 'op',
'op': 'Interpolate',
'axes': int64_array([3]),
'mode': 'nearest'
},
'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
'shape_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_begin': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([4]),
'shape': int64_array([1])
},
'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([5])},
'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
'sslice': {
'kind': 'op',
'type': 'StridedSlice',
'op': 'StridedSlice',
'begin_mask': int64_array([1]),
'end_mask': int64_array([1]),
'new_axis_mask': int64_array([0]),
'shrink_axis_mask': int64_array([0]),
'ellipsis_mask': int64_array([0]),
},
'sslice_data': {'kind': 'data', 'shape': None},
'scales': {
'type': 'Const',
'op': 'Const',
'kind': 'op',
'value': int64_array([2]),
'shape': int64_array([1])
},
'scales_data': {'kind': 'data', 'shape': None},
'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
'mul_data': {'kind': 'data', 'shape': None},
'interpolate_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
'output': {'kind': 'op', 'op': 'Result'},
}
class SplitConcatPairToInterpolateTest(unittest.TestCase):
def test_spatial_2d_split_concat_1(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_2d_spatial_case,
edges=graph_edges
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_2d_spatial_case_1,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
def test_spatial_2d_split_concat_2(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_2d_spatial_case,
edges=graph_edges,
update_attributes={
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(2, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(2, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 2},
'split_data_0': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
'abs_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
}
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_2d_spatial_case_2,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
def test_spatial_3d_split_concat_1(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_3d_spatial_case,
edges=graph_edges
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_3d_spatial_case_1,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)
def test_spatial_3d_split_concat_2(self):
graph = build_graph(
nodes_attrs=graph_node_attrs_for_3d_spatial_case,
edges=graph_edges,
update_attributes={
'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
'split_axis_const': {
'kind': 'op',
'value': np.array(3, dtype=np.int64),
'op': 'Const',
'type': 'Const'
},
'split_axis_const_data': {'value': None, 'shape': np.array(3, dtype=np.int64).shape, 'kind': 'data'},
'concat': {'type': 'Concat', 'kind': 'op', 'axis': 3},
'split_data_0': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
'split_data_1': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
'split_data_2': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
'concat_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
}
)
ref_graph = build_graph(
nodes_attrs=ref_graph_node_attrs_for_3d_spatial_case_2,
edges=ref_graph_edges
)
SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
(flag, resp) = compare_graphs(graph, ref_graph, 'output')
self.assertTrue(flag, resp)