extensions/front/mxnet/fully_connected_ext.py
extensions/front/mxnet/gather.py
extensions/front/mxnet/gather_ext.py
+extensions/front/mxnet/gluoncv_ssd_anchors.py
extensions/front/mxnet/instance_norm_ext.py
extensions/front/mxnet/leaky_relu.py
extensions/front/mxnet/lrn_ext.py
extensions/middle/AddFakeQuantizeFuse.py
extensions/middle/AddIsCyclicAttribute.py
extensions/middle/AddMeanScaleValues.py
-extensions/middle/AnchorToPriorBox.py
extensions/middle/ApplyNHWCtoNCHWpermutation.py
extensions/middle/ApplyPermutations.py
extensions/middle/ArgMaxToTopK.py
extensions/middle/SliceLikeToStridedSlice.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
extensions/middle/TensorIteratorBackEdge.py
]
core_nodes = lambda weights_shape, limit_shape, reshape_shape: {
- **regular_op_with_shaped_data('input', None, {'type': 'Parameter'}),
+ **regular_op_with_shaped_data('input', None, {'type': 'Parameter', 'op': 'Parameter'}),
**valued_const_with_data('weights', np.ones(weights_shape)),
**const_with_data('dim', int64_array(reshape_shape)),
- **regular_op_with_shaped_data('reshape', reshape_shape, {'type': 'Reshape', 'infer': Reshape.infer}),
+ **regular_op_with_shaped_data('reshape', reshape_shape, {'type': 'Reshape', 'infer': Reshape.infer, 'op': 'Reshape'}),
**valued_const_with_data('il', np.ones(limit_shape)),
**valued_const_with_data('ih', np.ones(limit_shape)),
**valued_const_with_data('oh', np.ones(limit_shape)),
**regular_op_with_shaped_data('FQ', weights_shape, {'type': 'FakeQuantize', 'infer': FakeQuantize.infer,
- 'stop_value_propagation': True, 'levels': 2}),
+ 'stop_value_propagation': True, 'levels': 2, 'op': 'FakeQuantize'}),
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution'}),
+ **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'op': 'Convolution'}),
**result(),
}
'placeholder_1_data': {'name': 'placeholder_1_data', 'value': None, 'shape': None, 'kind': 'data',
'data_type': None},
# Transpose layers
- 'const_1': {'value': None, 'kind': 'op', 'type': 'Const'},
+ 'const_1': {'value': None, 'kind': 'op', 'type': 'Const', 'op': 'Const'},
'const_1_data': {'value': None, 'shape': None, 'kind': 'data'},
'permute_1': {'type': 'Transpose', 'value': None, 'kind': 'op', 'op': 'Transpose'},
'permute_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_2': {'value': None, 'kind': 'op', 'type': 'Const'},
+ 'const_2': {'value': None, 'kind': 'op', 'type': 'Const', 'op': 'Const'},
'const_2_data': {'value': None, 'shape': None, 'kind': 'data'},
'permute_2': {'type': 'Transpose', 'value': None, 'kind': 'op', 'op': 'Transpose'},
'permute_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_3': {'value': None, 'kind': 'op', 'type': 'Const'},
+ 'const_3': {'value': None, 'kind': 'op', 'type': 'Const', 'op': 'Const'},
'const_3_data': {'value': None, 'shape': None, 'kind': 'data'},
'permute_3': {'type': 'Transpose', 'value': None, 'kind': 'op', 'op': 'Transpose'},
'permute_3_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': { 'op': 'Result', 'kind': 'op'}
+ 'op_output': {'op': 'Result', 'kind': 'op'}
}
connect_data
nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 30, 40], {'type': 'Parameter'}),
+ **regular_op_with_shaped_data('placeholder', [1, 3, 30, 40], {'type': 'Parameter', 'op': 'Parameter'}),
**valued_const_with_data('out_shape', np.array([60, 160])),
- **regular_op_with_shaped_data('interpolate', [1, 3, 60, 160], {'type': 'Interpolate', 'axes': [2, 3]}),
+ **regular_op_with_shaped_data('interpolate', [1, 3, 60, 160], {'type': 'Interpolate', 'axes': [2, 3],
+ 'op': 'Interpolate'}),
- **regular_op_with_shaped_data('shape', [4], {'type': 'ShapeOf'}),
+ **regular_op_with_shaped_data('shape', [4], {'type': 'ShapeOf', 'op': 'ShapeOf'}),
**valued_const_with_data('indices', np.array([2, 3])),
**valued_const_with_data('axis', np.array(0)),
- **regular_op_with_shaped_data('gather', [2], {'type': 'Gather'}),
+ **regular_op_with_shaped_data('gather', [2], {'type': 'Gather', 'op': 'Gather'}),
**valued_const_with_data('multiplier', np.array([2, 4])),
- **regular_op_with_shaped_data('mul', [2], {'type': 'Multiply'}),
+ **regular_op_with_shaped_data('mul', [2], {'type': 'Multiply', 'op': 'Mul'}),
- **regular_op_with_shaped_data('placeholder_1', [1, 3, 60, 160], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('concat', [1, 7, 60, 160], {'type': 'Concat', 'axis': 1}),
+ **regular_op_with_shaped_data('placeholder_1', [1, 3, 60, 160], {'type': 'Parameter', 'op': 'Parameter'}),
+ **regular_op_with_shaped_data('concat', [1, 7, 60, 160], {'type': 'Concat', 'axis': 1, 'op': 'Concat'}),
**result(),
}
'placeholder_data': {'kind': 'data'},
# weights
- 'weights_const': {'type': 'Const', 'kind': 'op', 'value': np.array([], dtype=np.float32)},
+ 'weights_const': {'type': 'Const', 'kind': 'op', 'value': np.array([], dtype=np.float32), 'op': 'Const'},
'weights_data': {'kind': 'data'},
# quantize
- 'quantize1': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 5},
- 'quantize2': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 2},
- 'quantize3': {'type': 'FakeQuantize', 'kind': 'op', 'levels': None},
- 'quantize4': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 122},
- 'quantize5': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 202},
- 'quantize6': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 257},
+ 'quantize1': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 5, 'op': 'FakeQuantize'},
+ 'quantize2': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 2, 'op': 'FakeQuantize'},
+ 'quantize3': {'type': 'FakeQuantize', 'kind': 'op', 'levels': None, 'op': 'FakeQuantize'},
+ 'quantize4': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 122, 'op': 'FakeQuantize'},
+ 'quantize5': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 202, 'op': 'FakeQuantize'},
+ 'quantize6': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 257, 'op': 'FakeQuantize'},
'quantize_data': {'kind': 'data'},
- 'new_quantize1': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 5},
- 'new_quantize4': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 122},
- 'new_quantize5': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 202},
+ 'new_quantize1': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 5, 'op': 'FakeQuantize'},
+ 'new_quantize4': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 122, 'op': 'FakeQuantize'},
+ 'new_quantize5': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 202, 'op': 'FakeQuantize'},
'new_quantize_data': {'kind': 'data'},
# quantize input/output
- 'output_high_init': {'kind': 'op', 'type': 'Const'},
+ 'output_high_init': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
'output_high_init_data': {'kind': 'data', 'value': 3},
- 'output_low_init': {'kind': 'op', 'type': 'Const'},
+ 'output_low_init': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
'output_low_init_data': {'kind': 'data', 'value': -1.5},
- 'input_low': {'kind': 'op', 'type': 'Const'},
+ 'input_low': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
'input_low_data': {'kind': 'data'},
- 'input_high': {'kind': 'op', 'type': 'Const'},
+ 'input_high': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
'input_high_data': {'kind': 'data'},
- 'output_low': {'kind': 'op', 'type': 'Const'},
+ 'output_low': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
'output_low_data': {'kind': 'data'},
- 'output_high': {'kind': 'op', 'type': 'Const'},
+ 'output_high': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
'output_high_data': {'kind': 'data'},
'output_high_init_data1': {'kind': 'data', 'value': 256.1},
'mul': {'kind': 'op', 'op': 'Mul'},
'add': {'kind': 'op', 'op': 'Add'},
- 'scale': {'kind': 'op', 'type': 'Const', 'value': 1.125},
- 'shift': {'kind': 'op', 'type': 'Const', 'value': -1.5},
- 'scale1': {'kind': 'op', 'type': 'Const', 'value': 1.9735537190082646},
- 'shift1': {'kind': 'op', 'type': 'Const', 'value': 17.3},
- 'scale2': {'kind': 'op', 'type': 'Const', 'value': 0.010711442786069652},
- 'shift2': {'kind': 'op', 'type': 'Const', 'value': -2.573},
+ 'scale': {'kind': 'op', 'type': 'Const', 'value': 1.125, 'op': 'Const'},
+ 'shift': {'kind': 'op', 'type': 'Const', 'value': -1.5, 'op': 'Const'},
+ 'scale1': {'kind': 'op', 'type': 'Const', 'value': 1.9735537190082646, 'op': 'Const'},
+ 'shift1': {'kind': 'op', 'type': 'Const', 'value': 17.3, 'op': 'Const'},
+ 'scale2': {'kind': 'op', 'type': 'Const', 'value': 0.010711442786069652, 'op': 'Const'},
+ 'shift2': {'kind': 'op', 'type': 'Const', 'value': -2.573, 'op': 'Const'},
'shift_data': {'kind': 'data'},
'scale_data': {'kind': 'data'},
'mul_data': {'kind': 'data'},
'add_data': {'kind': 'data'},
- 'convolution': {'type': 'Convolution', 'kind': 'op'},
- 'convert': {'type': 'Convert', 'kind': 'op', 'dst_type': np.float32},
+ 'convolution': {'type': 'Convolution', 'kind': 'op', 'op': 'Convolution'},
+ 'convert': {'type': 'Convert', 'kind': 'op', 'dst_type': np.float32, 'op': 'Cast'},
'convert_data': {'kind': 'data'},
- 'result_data': {'kind':'data'},
+ 'result_data': {'kind': 'data'},
'result': {'kind': 'op', 'op': 'Result'},
# accuracy test
'ac_weights': {'kind': 'op', 'op': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
'ac_weights_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_input_low': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_input_low': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_input_low_data': {'kind': 'data', 'value': None, 'shape': None},
- 'ac_input_high': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_input_high': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_input_high_data': {'kind': 'data', 'value': None, 'shape': None},
- 'ac_output_low': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_output_low': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_output_low_data': {'kind': 'data', 'value': None, 'shape': None},
- 'ac_output_high': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_output_high': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_output_high_data': {'kind': 'data', 'value': None, 'shape': None},
- 'ac_fakeQuantize': {'kind': 'op', 'type': 'FakeQuantize', 'levels': None, 'infer': FakeQuantize.infer},
+ 'ac_fakeQuantize': {'kind': 'op', 'type': 'FakeQuantize', 'levels': None, 'infer': FakeQuantize.infer, 'op': 'FakeQuantize'},
'ac_fakeQuantize_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_quantize': {'kind': 'op', 'type': 'fakeQuantize', 'levels': None, 'infer': FakeQuantize.infer},
+ 'ac_quantize': {'kind': 'op', 'type': 'fakeQuantize', 'levels': None, 'infer': FakeQuantize.infer, 'op': 'FakeQuantize'},
'ac_quantize_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_convolution': {'kind': 'op', 'type': 'Convolution'},
+ 'ac_convolution': {'kind': 'op', 'type': 'Convolution', 'op': 'Convolution'},
'ac_mul': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
'ac_mul_data': {'kind': 'data', 'shape': None, 'value': None},
'ac_add': {'kind': 'op', 'op': 'Add', 'infer': lambda node: eltwise_infer(node, lambda a, b: a + b)},
'ac_add_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_scale': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_scale': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_scale_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_shift': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_shift': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_shift_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_output_low_ref': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_output_low_ref': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_output_low_ref_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ac_output_high_ref': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer},
+ 'ac_output_high_ref': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer, 'op': 'Const'},
'ac_output_high_ref_data': {'kind': 'data', 'shape': None, 'value': None}
}
**valued_const_with_data('weights', np.ones([1, 2, 3, 4], dtype=original)),
**valued_const_with_data('int_weights', np.ones([1, 2, 3, 4], dtype=np.uint8)),
- **regular_op_with_shaped_data('cast', [1, 2, 3, 4], {'type': 'Convert', 'dst_type': transformed}),
+ **regular_op_with_shaped_data('cast', [1, 2, 3, 4], {'type': 'Convert', 'dst_type': transformed,
+ 'op': 'Cast'}),
**valued_const_with_data('il', np.array([0])),
**valued_const_with_data('ih', np.array([254])),
**valued_const_with_data('oh', np.array([254])),
**regular_op_with_shaped_data('FQ', [1, 2, 3, 4], {'type': 'FakeQuantize', 'infer': FakeQuantize.infer,
- 'stop_value_propagation': True, 'levels': 255}),
+ 'stop_value_propagation': True, 'levels': 255,
+ 'op': 'FakeQuantize'}),
**result()
}
connect_data
nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 30, 40], {'type': 'Parameter'}),
+ **regular_op_with_shaped_data('placeholder', [1, 3, 30, 40], {'type': 'Parameter', 'op': 'Parameter'}),
**valued_const_with_data('out_shape', np.array([60, 160])),
**regular_op_with_shaped_data('interpolate', [1, 3, 60, 160],
- {'type': 'Interpolate', 'axes': int64_array([2, 3])}),
- **regular_op_with_shaped_data('identity_00', [1, 3, 60, 160], {'identity': True}),
- **regular_op_with_shaped_data('identity_01', [1, 3, 60, 160], {'identity': True}),
+ {'type': 'Interpolate', 'axes': int64_array([2, 3]), 'op': 'Interpolate'}),
+ **regular_op_with_shaped_data('identity_00', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
+ **regular_op_with_shaped_data('identity_01', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
- **regular_op_with_shaped_data('shape', [4], {'type': 'ShapeOf'}),
+ **regular_op_with_shaped_data('shape', [4], {'type': 'ShapeOf', 'op': 'ShapeOf'}),
**valued_const_with_data('indices', np.array([2, 3])),
**valued_const_with_data('axis', np.array(0)),
- **regular_op_with_shaped_data('gather', [2], {'type': 'Gather'}),
+ **regular_op_with_shaped_data('gather', [2], {'type': 'Gather', 'op': 'Gather'}),
- **regular_op_with_shaped_data('placeholder_1', [1, 3, 60, 160], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('identity_10', [1, 3, 60, 160], {'identity': True}),
- **regular_op_with_shaped_data('identity_11', [1, 3, 60, 160], {'identity': True}),
- **regular_op_with_shaped_data('concat', [1, 7, 60, 160], {'type': 'Concat', 'axis': 1}),
+ **regular_op_with_shaped_data('placeholder_1', [1, 3, 60, 160], {'type': 'Parameter', 'op': 'Parameter'}),
+ **regular_op_with_shaped_data('identity_10', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
+ **regular_op_with_shaped_data('identity_11', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
+ **regular_op_with_shaped_data('concat', [1, 7, 60, 160], {'type': 'Concat', 'axis': 1, 'op': 'Concat'}),
**result(),
}
--- /dev/null
+"""
+ Copyright (C) 2018-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 numpy as np
+
+from typing import Dict
+
+from extensions.front.mxnet.mx_reshape_to_reshape import MXReshapeToReshape
+from extensions.front.mxnet.ssd_detection_output_replacer import SsdPatternDetectionOutputReplacer
+from extensions.ops.elementwise import Div, Add, Sub
+from extensions.ops.split import Split
+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_node_with_second_input
+from mo.graph.graph import Graph, Node
+from mo.graph.port import Port
+from mo.middle.passes.convert_data_type import data_type_str_to_np
+from mo.ops.concat import Concat
+from mo.ops.reshape import Reshape
+
+
+def calculate_prior_box_value(value: Node, value_to_div: Port, value_to_add: Port):
+ """
+ :param value: Node with value. Here is supposed the node with op='Split'
+ :param value_to_div: Output port with values to be divided by 2
+ :param value_to_add: Output port with values to be added to values from value_to_div port
+ :return: Sub and Add nodes
+
+ The sub-graph can be described by formulas:
+ min = value[value_to_add] - (value[value_to_div] / 2)
+ max = value[value_to_add] + (value[value_to_div] / 2)
+ """
+ graph = value.graph
+ dtype = data_type_str_to_np(graph.graph['cmd_params'].data_type)
+ _min = Sub(graph, dict(name=value.name + '/Sub')).create_node()
+ div = create_op_node_with_second_input(graph, Div, np.array([2], dtype=dtype), op_attrs=dict(name=value.name + '/Div'))
+ div.in_port(0).connect(value_to_div)
+ _min.in_port(0).connect(value_to_add)
+ _min.in_port(1).connect(div.out_port(0))
+
+ _max = Add(graph, dict(name=value.name + '/Add')).create_node()
+ _max.in_port(0).connect(div.out_port(0))
+ _max.in_port(1).connect(value_to_add)
+
+ return _min, _max
+
+
+class SsdAnchorsReplacer(FrontReplacementPattern):
+ """
+ Replacing sub-graph with all anchors to sub-graph which calculates prior boxes values by formulas:
+
+ value[i] = xmin = value[i] - (value[i + 2] / 2)
+ value[i + 1] = ymin = value[i + 1] - (value[i + 3] / 2)
+ value[i + 2] = xmax = value[i] + (value[i + 2] / 2)
+ value[i + 3] = ymax = value[i + 1] + (value[i + 3] / 2)
+ """
+
+ enabled = True
+ graph_condition = [lambda graph: graph.graph['cmd_params'].enable_ssd_gluoncv]
+
+ def run_after(self):
+ return [SsdPatternDetectionOutputReplacer, MXReshapeToReshape]
+
+ def pattern(self):
+ return dict(
+ nodes=[
+ ('slice_like', dict(op='slice_like')),
+ ('reshape0', dict(op='Reshape')),
+ ('reshape1', dict(op='Reshape')),
+ ('reshape2', dict(op='Reshape')),
+ ('reshape3', dict(op='Reshape')),
+ ('concat', dict(op='Concat')),
+ ('detection_output', dict(op='DetectionOutput'))
+ ],
+ edges=[
+ ('slice_like', 'reshape0'),
+ ('reshape0', 'reshape1'),
+ ('reshape1', 'reshape2'),
+ ('reshape2', 'reshape3'),
+ ('reshape3', 'concat', {'in': 0}),
+ ('concat', 'detection_output', {'in': 2})
+ ])
+
+ def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
+ concat_node = match['concat']
+ concat_node['axis'] = 1
+ concat_name = concat_node.soft_get('name', concat_node.id)
+
+ concat_reshape = create_op_node_with_second_input(graph, Reshape, int64_array([1, 2, -1]), op_attrs=dict(
+ name=concat_name + '/Reshape'))
+ split_node = create_op_node_with_second_input(graph, Split, int64_array(1), op_attrs=dict(
+ name=concat_name + '/Split', num_splits=2), input_node=concat_reshape)
+ split_node_reshape = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 4]), op_attrs=dict(
+ name=split_node.name + '/Reshape'))
+ split_node.out_port(0).connect(split_node_reshape.in_port(0))
+ value = create_op_node_with_second_input(graph, Split, int64_array(1), op_attrs=dict(
+ name=split_node_reshape.name + '/Split', num_splits=4), input_node=split_node_reshape)
+
+ xmin, xmax = calculate_prior_box_value(value, value_to_div=value.out_port(2), value_to_add=value.out_port(0))
+ ymin, ymax = calculate_prior_box_value(value, value_to_div=value.out_port(3), value_to_add=value.out_port(1))
+
+ concat_slice_value = Concat(graph, dict(name=value.name + '/Concat', in_ports_count=4, axis=1)).create_node()
+ for ind, node in enumerate([xmin, ymin, xmax, ymax]):
+ concat_slice_value.in_port(ind).connect(node.out_port(0))
+
+ reshape_concat_values = create_op_node_with_second_input(graph, Reshape, int64_array([1, 1, -1]),
+ op_attrs=dict(name=concat_slice_value.name + '/Reshape'),
+ input_node=concat_slice_value)
+ concat = Concat(graph, dict(name=reshape_concat_values.name + '/Concat', in_ports_count=2, axis=1)).create_node()
+ concat.in_port(0).connect(reshape_concat_values.out_port(0))
+ concat.in_port(1).connect(split_node.out_port(1))
+
+ match['detection_output'].in_port(2).get_connection().set_source(concat.out_port(0))
+ concat_node.out_port(0).get_connection().set_destination(concat_reshape.in_port(0))
--- /dev/null
+"""
+ Copyright (C) 2018-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 numpy as np
+import unittest
+
+from extensions.front.mxnet.gluoncv_ssd_anchors import SsdAnchorsReplacer
+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
+
+nodes_attributes = {
+ 'slice_like': {'kind': 'op', 'op': 'slice_like'},
+ 'model_reshape0': {'kind': 'op', 'op': 'Reshape'},
+ 'model_reshape0_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([1, -1, 4])},
+ 'model_reshape1': {'kind': 'op', 'op': 'Reshape'},
+ 'model_reshape1_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([1, -1, 4])},
+ 'model_reshape2': {'kind': 'op', 'op': 'Reshape'},
+ 'model_reshape2_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([1, -1])},
+ 'reshape0': {'kind': 'op', 'op': 'Reshape'},
+ 'reshape0_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([1, -1])},
+ 'concat': {'kind': 'op', 'op': 'Concat'},
+ 'reshape1': {'kind': 'op', 'op': 'Reshape'},
+ 'reshape1_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([1, 2, -1])},
+ 'split': {'kind': 'op', 'op': 'Split', 'num_splits': 2},
+ 'split_const': {'kind': 'op', 'op': 'Const', 'value': int64_array(1)},
+ 'reshape2': {'kind': 'op', 'op': 'Reshape'},
+ 'reshape2_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([-1, 4])},
+ 'value': {'kind': 'op', 'op': 'Split', 'num_splits': 4},
+ 'value_const': {'kind': 'op', 'op': 'Const', 'value': int64_array(1)},
+ 'div_1': {'kind': 'op', 'op': 'Div'},
+ 'div_1_const': {'kind': 'op', 'op': 'Const', 'value': np.array([2], dtype=np.float32)},
+ 'div_2': {'kind': 'op', 'op': 'Div'},
+ 'div_2_const': {'kind': 'op', 'op': 'Const', 'value': np.array([2], dtype=np.float32)},
+ 'xmin': {'kind': 'op', 'op': 'Sub'},
+ 'ymin': {'kind': 'op', 'op': 'Sub'},
+ 'xmax': {'kind': 'op', 'op': 'Add'},
+ 'ymax': {'kind': 'op', 'op': 'Add'},
+ 'concat_value': {'kind': 'op', 'op': 'Concat', 'axis': 1},
+ 'reshape3': {'kind': 'op', 'op': 'Reshape'},
+ 'reshape3_const': {'kind': 'op', 'op': 'Const', 'value': int64_array([1, 1, -1])},
+ 'end_concat': {'kind': 'op', 'op': 'Concat'},
+ 'detection_output': {'kind': 'op', 'op': 'DetectionOutput'}
+}
+
+
+class SsdAnchorsReplacerTest(unittest.TestCase):
+
+ def test_replacer(self):
+ graph = build_graph(
+ nodes_attrs=nodes_attributes,
+ edges=[
+ ('slice_like', 'model_reshape0', {'in': 0}),
+ ('model_reshape0_const', 'model_reshape0', {'in': 1}),
+ ('model_reshape0', 'model_reshape1', {'in': 0}),
+ ('model_reshape1_const', 'model_reshape1', {'in': 1}),
+ ('model_reshape1', 'model_reshape2', {'in': 0}),
+ ('model_reshape2_const', 'model_reshape2', {'in': 1}),
+ ('model_reshape2', 'reshape0', {'in': 0}),
+ ('reshape0_const', 'reshape0', {'in': 1}),
+ ('reshape0', 'concat'),
+ ('concat', 'detection_output', {'in': 2})
+ ],
+ nodes_with_edges_only=True
+ )
+
+ ref_graph = build_graph(
+ nodes_attrs=nodes_attributes,
+ edges=[
+ ('slice_like', 'model_reshape0', {'in': 0}),
+ ('model_reshape0_const', 'model_reshape0', {'in': 1}),
+ ('model_reshape0', 'model_reshape1', {'in': 0}),
+ ('model_reshape1_const', 'model_reshape1', {'in': 1}),
+ ('model_reshape1', 'model_reshape2', {'in': 0}),
+ ('model_reshape2_const', 'model_reshape2', {'in': 1}),
+ ('model_reshape2', 'reshape0', {'in': 0}),
+ ('reshape0_const', 'reshape0', {'in': 1}),
+ ('reshape0', 'concat'),
+ ('concat', 'reshape1', {'in': 0}),
+ ('reshape1_const', 'reshape1', {'in': 1}),
+ ('reshape1', 'split', {'in': 0}),
+ ('split_const', 'split', {'in': 1}),
+ ('split', 'reshape2', {'out': 0, 'in': 0}),
+ ('reshape2_const', 'reshape2', {'in': 1}),
+ ('reshape2', 'value', {'in': 0}),
+ ('value_const', 'value', {'in': 1}),
+ ('value', 'xmin', {'out': 0, 'in': 0}),
+ ('value', 'ymin', {'out': 1, 'in': 0}),
+ ('value', 'xmax', {'out': 0, 'in': 1}),
+ ('value', 'ymax', {'out': 1, 'in': 1}),
+ ('value', 'div_1', {'out': 2, 'in': 0}),
+ ('value', 'div_2', {'out': 3, 'in': 0}),
+ ('div_1_const', 'div_1', {'in': 1}),
+ ('div_2_const', 'div_2', {'in': 1}),
+ ('div_1', 'xmin', {'in': 1, 'out': 0}),
+ ('div_1', 'xmax', {'in': 0, 'out': 0}),
+ ('div_2', 'ymin', {'in': 1, 'out': 0}),
+ ('div_2', 'ymax', {'in': 0, 'out': 0}),
+ ('xmin', 'concat_value', {'in': 0}),
+ ('ymin', 'concat_value', {'in': 1}),
+ ('xmax', 'concat_value', {'in': 2}),
+ ('ymax', 'concat_value', {'in': 3}),
+ ('concat_value', 'reshape3', {'in': 0}),
+ ('reshape3_const', 'reshape3', {'in': 1}),
+ ('reshape3', 'end_concat', {'in': 0}),
+ ('split', 'end_concat', {'in': 1}),
+ ('end_concat', 'detection_output', {'in': 2})
+ ],
+ update_attributes={
+ 'concat': {'axis': 1}
+ },
+ nodes_with_edges_only=True
+ )
+ graph.stage = 'front'
+ graph.graph['cmd_params'].data_type = 'FP32'
+ SsdAnchorsReplacer().find_and_replace_pattern(graph)
+ flag, resp = compare_graphs(graph, ref_graph, 'detection_output', check_op_attrs=True)
+ self.assertTrue(flag, resp)
from mo.graph.graph import Graph, Node
from mo.middle.pattern_match import find_pattern_matches
from mo.ops.const import Const
-from mo.ops.crop import Crop
class SsdPatternAnchorReshape(FrontReplacementSubgraph):
def reshape_priorboxes(self, concat):
for i, node in concat.in_nodes().items():
- reshape_node = create_op_node_with_second_input(concat.graph, Reshape, int64_array([0, 2, -1]),
+ reshape_node = create_op_node_with_second_input(concat.graph, Reshape, int64_array([1, -1]),
dict(name=concat.name + str(i) + '/PriorBoxReshape_'))
node.out_port(0).disconnect()
node.out_port(0).connect(reshape_node.in_port(0))
+++ /dev/null
-"""
- Copyright (C) 2018-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 numpy as np
-
-from extensions.middle.SliceLikeToStridedSlice import SliceLikeToStridedSlice
-from mo.graph.graph import Graph
-from mo.middle.replacement import MiddleReplacementPattern
-from mo.ops.const import Const
-
-
-class AnchorToPriorBoxes(MiddleReplacementPattern):
- """
- Crop anchors consts before replacing subgraph with all anchors
- """
- enabled = True
- force_clean_up = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'mxnet' and graph.graph['cmd_params'].enable_ssd_gluoncv]
-
- def run_after(self):
- from extensions.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def run_before(self):
- return [SliceLikeToStridedSlice]
-
- def pattern(self):
- return dict(
- nodes=[
- ('const', dict(op='Const')),
- ('const_data', dict(kind='data')),
- ('slice_like', dict(op='slice_like')),
- ('slice_like_out', dict(kind='data')),
- ('reshape', dict(op='Reshape')),
- ],
- edges=[
- ('const', 'const_data'),
- ('const_data', 'slice_like', {'in': 0}),
- ('slice_like', 'slice_like_out'),
- ('slice_like_out', 'reshape'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- slice_like = match['slice_like']
- anchor_node = slice_like.in_port(0).get_source().node
- reshape = slice_like.out_nodes()[0].out_node()
- slice_shape = slice_like.out_nodes()[0].shape
- anchor_node.value = np.copy(anchor_node.value[:slice_shape[0], :slice_shape[1],
- :slice_shape[2], :slice_shape[3], :slice_shape[4]])
- anchor_node.shape = slice_shape
-
- val_node = Const(graph, {'name': slice_like.name +'/croped_', 'value': anchor_node.value[:slice_shape[0], :slice_shape[1],
- :slice_shape[2], :slice_shape[3], :slice_shape[4]], 'shape': slice_shape}).create_node_with_data()
- slice_like.in_port(0).disconnect()
- slice_like.in_port(1).disconnect()
- slice_like.out_port(0).disconnect()
- reshape.in_port(0).connect(val_node.in_node().out_port(0))
'split_data_1': {'kind': 'data', 'value': None, 'shape': np.array([1, 227, 227, 1])},
'last_data': {'kind': 'data', 'value': None, 'shape': np.array([1, 227, 227, 3])},
- 'axis_const': {'kind': 'op'},
+ 'axis_const': {'kind': 'op', 'op': 'Const'},
'axis_const_data': {'value': np.int64(1), 'shape': None, 'kind': 'data'},
- 'split_dim_const': {'kind': 'op'},
+ 'split_dim_const': {'kind': 'op', 'op': 'Const'},
'split_dim_const_data': {'value': np.array([1, 2, 3]), 'shape': None, 'kind': 'data'},
}
+++ /dev/null
-"""
- Copyright (C) 2018-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 numpy as np
-
-from extensions.middle.AnchorToPriorBox import AnchorToPriorBoxes
-from extensions.middle.SliceLikeToStridedSlice import SliceLikeToStridedSlice
-from mo.graph.graph import Graph
-from mo.middle.replacement import MiddleReplacementPattern
-from mo.ops.const import Const
-
-
-class SsdAnchorsMiddleReplacer(MiddleReplacementPattern):
- """
- Replacing subgraph with all anchors constant to constant op with pre calculated prior boxes values.
- """
- enabled = True
- force_clean_up = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'mxnet' and graph.graph['cmd_params'].enable_ssd_gluoncv]
-
- def run_after(self):
- return [AnchorToPriorBoxes]
-
- def run_before(self):
- return [SliceLikeToStridedSlice]
-
-
- def pattern(self):
- return dict(
- nodes=[
- ('const', dict(op='Const')),
- ('const_data', dict(kind='data')),
- ('reshape0', dict(op='Reshape')),
- ('reshape0_data', dict(kind='data')),
- ('reshape1', dict(op='Reshape')),
- ('reshape1_data', dict(kind='data')),
- ('reshape2', dict(op='Reshape')),
- ('reshape2_data', dict(kind='data')),
- ('reshape3', dict(op='Reshape')),
- ('reshape3_data', dict(kind='data')),
- ('concat', dict(op='Concat')),
- ],
- edges=[
- ('const', 'const_data'),
- ('const_data', 'reshape0'),
- ('reshape0', 'reshape0_data'),
- ('reshape0_data', 'reshape1'),
- ('reshape1', 'reshape1_data'),
- ('reshape1_data', 'reshape2'),
- ('reshape2', 'reshape2_data'),
- ('reshape2_data', 'reshape3'),
- ('reshape3', 'reshape3_data'),
- ('reshape3_data', 'concat'),
- ])
-
- def replace_pattern(self, graph: Graph, match: dict):
- #self.pattern()['nodes']
- concat_node = match['concat']
- if len(concat_node.out_nodes()[0].out_nodes()) == 0:
- return
- const_values = []
- for in_node_index in concat_node.in_nodes():
- current_node = concat_node.in_port(in_node_index).get_source().node
- for k, v in reversed(self.pattern()['nodes'][:-1]):
- if 'op' in v:
- assert current_node.op == v['op']
- current_node = current_node.in_port(0).get_source().node
- if current_node.op == 'Const':
- crop_value = current_node.value
- crop_value = np.reshape(crop_value, (1, -1))
- const_values.append(crop_value)
- break
- concat_value = np.concatenate(tuple(const_values), axis=1)
- concat_value = np.reshape(concat_value, (1, 2, -1))
- slice_value = concat_value[0][0]
- for i in range(int(concat_value[0][0].size / 4)):
- index = i * 4
- xmin = slice_value[index] - (slice_value[index+2] / 2)
- ymin = slice_value[index + 1] - (slice_value[index + 3] / 2)
- xmax = slice_value[index] + (slice_value[index + 2] / 2)
- ymax = slice_value[index + 1] + (slice_value[index + 3] / 2)
- slice_value[index] = xmin
- slice_value[index + 1] = ymin
- slice_value[index + 2] = xmax
- slice_value[index + 3] = ymax
-
- val_node = Const(graph, {'name': concat_node.name + '/const_',
- 'value': concat_value}).create_node_with_data()
- out_node = concat_node.out_port(0).get_destination().node
- concat_node.out_port(0).disconnect()
- out_node.in_port(2).connect(val_node.in_node().out_port(0))
'Input shape ranks are inconsistent: {} and {}'.format(input_shape.size, shape_like.size)
node.axes = int64_array(range(shape_like.size))
new_shape = np.copy(shape_like)
-
node.out_port(0).data.set_shape(new_shape)
+
+ if node.in_port(0).get_connection().data.get_value() is not None:
+ out_value = np.copy(node.in_port(0).data.get_value())
+
+ slice_indexes = []
+ for s in out_value.shape:
+ slice_indexes.append(slice(0, s))
+
+ for axis in node.axes:
+ slice_indexes[axis] = slice(0, new_shape[axis])
+ out_value = out_value[tuple(slice_indexes)]
+ node.out_port(0).data.set_value(out_value)
from mo.utils.unittest.graph import build_graph
nodes_attributes = {
- 'input_data': {'kind': 'data', 'shape': int64_array([3, 4]), 'value': None},
+ 'input': {'kind': 'op', 'op': 'Const'},
+ 'input_data': {'kind': 'data', 'shape': int64_array([3, 4]), 'value': np.arange(1, 13).reshape([3, 4])},
+ 'shape_like': {'kind': 'op', 'op': 'Const', 'shape': int64_array([2, 3]), 'value': None},
'shape_like_data': {'kind': 'data', 'shape': int64_array([2, 3]), 'value': None},
'slice_like': {'kind': 'op', 'op': 'slice_data'},
'out_data': {'kind': 'data', 'shape': None, 'value': None}
}
edges = [
+ ('input', 'input_data'),
('input_data', 'slice_like', {'in': 0}),
+ ('shape_like', 'shape_like_data'),
('shape_like_data', 'slice_like', {'in': 1}),
('slice_like', 'out_data')
]
slice_like = Node(graph, 'slice_like')
SliceLike.infer(slice_like)
ref_shape = int64_array([2, 3])
+ ref_value = np.array([[1, 2, 3], [5, 6, 7]])
res_shape = graph.node['out_data']['shape']
+ res_value = graph.node['out_data']['value']
self.assertTrue(np.array_equal(res_shape, ref_shape))
+ self.assertTrue(np.array_equal(res_value, ref_value))
def test_2(self):
graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': (0, 1)}})
slice_like = Node(graph, 'slice_like')
SliceLike.infer(slice_like)
ref_shape = int64_array([2, 3])
+ ref_value = np.array([[1, 2, 3], [5, 6, 7]])
res_shape = graph.node['out_data']['shape']
+ res_value = graph.node['out_data']['value']
self.assertTrue(np.array_equal(res_shape, ref_shape))
+ self.assertTrue(np.array_equal(res_value, ref_value))
def test_3(self):
graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': (0,)}})
slice_like = Node(graph, 'slice_like')
SliceLike.infer(slice_like)
ref_shape = int64_array([2, 4])
+ ref_value = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
res_shape = graph.node['out_data']['shape']
+ res_value = graph.node['out_data']['value']
self.assertTrue(np.array_equal(res_shape, ref_shape))
+ self.assertTrue(np.array_equal(res_value, ref_value))
def test_4(self):
graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': (-1,)}})
slice_like = Node(graph, 'slice_like')
SliceLike.infer(slice_like)
ref_shape = int64_array([3, 3])
+ ref_value = np.array([[1, 2, 3], [5, 6, 7], [9, 10, 11]])
res_shape = graph.node['out_data']['shape']
+ res_value = graph.node['out_data']['value']
self.assertTrue(np.array_equal(res_shape, ref_shape))
+ self.assertTrue(np.array_equal(res_value, ref_value))
# {'embeddings': [{'port': None}]}
@generate({'C': [{'port': None}]}, {'C': [{'out': 0}]}, {'C': [{'out': 1}]})
def test_output_port_cut(self, output):
- nodes = {'A': {'type': 'Identity', 'kind': 'op'},
- 'B': {'type': 'Identity', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op'},
- 'D': {'type': 'Identity', 'kind': 'op'},
- 'E': {'type': 'Identity', 'kind': 'op'},
+ nodes = {'A': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
+ 'B': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
+ 'C': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
+ 'D': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
+ 'E': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
}
edges = [
('A', 'C', {'in': 0, 'out': 0}),
def test_output_port_cut(self, output):
nodes = {'A': {'op': 'Parameter', 'kind': 'op'},
'B': {'op': 'Parameter', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op'},
- 'D': {'type': 'Identity', 'kind': 'op'},
- 'E': {'type': 'Identity', 'kind': 'op'},
+ 'C': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
+ 'D': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
+ 'E': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
}
edges = [
('A', 'C', {'in': 0, 'out': 0}),
class TestUserDataRepack(unittest.TestCase):
nodes = {'A': {'name': 'Aa', 'op': 'Parameter', 'kind': 'op'},
'B': {'name': 'Bb', 'op': 'Parameter', 'kind': 'op'},
- 'C': {'name': 'Cc', 'type': 'Identity', 'value': None, 'kind': 'op'},
- 'D': {'name': 'Dd', 'type': 'Identity', 'value': None, 'kind': 'op'},
- 'E': {'name': 'Ee', 'type': 'Identity', 'value': None, 'kind': 'op'},
+ 'C': {'name': 'Cc', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'D': {'name': 'Dd', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'E': {'name': 'Ee', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
}
edges = [
('A', 'C', {'in': 0, 'out': 0}),
undead_node_types.append('TFCustomSubgraphCall')
if 'cmd_params' in self.graph and getattr(self.graph['cmd_params'], 'keep_shape_ops'):
- undead_node_types.extend(['ShapeOf', 'Shape'])
+ undead_node_types.extend(['ShapeOf', 'Shape', 'slice_like'])
mark_output_reachable_nodes(self)
shape_inference(self)
nx.set_node_attributes(G=graph, name='is_undead', values=False)
- # mark output nodes as undead
- outputs = graph.get_nodes_with_attributes(op='Result')
- nx.set_node_attributes(G=graph, name='is_undead', values={n: True for n in outputs})
-
- # mark specifically defined with node type set of nodes
- for type in undead_types:
- node_of_specific_type = graph.get_nodes_with_attributes(type=type)
- nx.set_node_attributes(G=graph, name='is_undead', values={n: True for n in node_of_specific_type})
-
- undead_nodes = graph.get_nodes_with_attributes(is_undead=True)
+ undead_types_with_result = undead_types + ['Result']
+ undead_nodes = []
+ for node in graph.get_op_nodes():
+ node_type = node.soft_get('type', node.op)
+ if node_type in undead_types_with_result:
+ undead_nodes.append(node.id)
+
+ nx.set_node_attributes(G=graph, name='is_undead', values={n: True for n in undead_nodes})
# propagate 'undead' attribute to children nodes of undead nodes if the node produces constant value
for node_name in bfs_search(graph, undead_nodes):
if graph.node[node_name]['is_undead']:
from mo.middle.passes.eliminate import mark_output_reachable_nodes, mark_const_producer_nodes
from mo.utils.unittest.graph import build_graph
-nodes_attributes = {'placeholder_1': {'type': 'Parameter', 'kind': 'op'},
- 'placeholder_2': {'type': 'Parameter', 'kind': 'op'},
- 'node_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_4': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_5': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_6': {'type': 'Identity', 'value': None, 'kind': 'op'},
+nodes_attributes = {'placeholder_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
+ 'placeholder_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
+ 'node_1': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'node_4': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'node_5': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
+ 'node_6': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
'placeholder_1_data_node': {'value': None, 'kind': 'data'},
'placeholder_2_data_node': {'value': None, 'kind': 'data'},
'data_node_1': {'value': None, 'kind': 'data'},
'data_node_4': {'value': None, 'kind': 'data'},
'data_node_5': {'value': None, 'shape': None, 'kind': 'data'},
'data_node_6': {'value': None, 'shape': None, 'kind': 'data'},
- 'tf_call_1': {'type': 'TFCustomSubgraphCall', 'kind': 'op'},
- 'tf_call_2': {'type': 'TFCustomSubgraphCall', 'kind': 'op'},
- 'tf_call_3': {'type': 'TFCustomSubgraphCall', 'kind': 'op'},
+ 'tf_call_1': {'type': 'TFCustomSubgraphCall', 'kind': 'op', 'op': 'TFCustomSubgraphCall'},
+ 'tf_call_2': {'type': 'TFCustomSubgraphCall', 'kind': 'op', 'op': 'TFCustomSubgraphCall'},
+ 'tf_call_3': {'type': 'TFCustomSubgraphCall', 'kind': 'op', 'op': 'TFCustomSubgraphCall'},
'op_output': {'kind': 'op', 'op': 'Result'},
'op_output_1': {'kind': 'op', 'op': 'Result'},
'op_output_2': {'kind': 'op', 'op': 'Result'}
'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# ScaleShift layer
'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift', 'axis': 0},
- 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Mul and Add operations
'mul_1': {'type': None, 'value': None, 'kind': 'op', 'op': 'Mul'},
- 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'},
'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'},
'add_1': {'type': None, 'kind': 'op', 'op': 'Add'},
- 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'add_1_w': {'value': None, 'shape': None, 'kind': 'data'},
'add_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Mul and Add operations
'mul_2': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'mul_2_w': {'value': None, 'shape': None, 'kind': 'data'},
'mul_2_data': {'value': None, 'shape': None, 'kind': 'data'},
'add_2': {'type': None, 'kind': 'op', 'op': 'Add'},
- 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'add_2_w': {'value': None, 'shape': None, 'kind': 'data'},
'add_2_data': {'value': None, 'shape': None, 'kind': 'data'},
# Reshape
'placeholder_2/Reshape_const_data': {'kind': 'data', 'value': None, 'shape': None},
# BatchNorm operation
'bn_op': {'type': None, 'kind': 'op', 'op': 'BatchNorm', 'can_be_fused': True},
- 'const_bn_const': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_bn_const': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'bn_const': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_bn_beta': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_bn_beta': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'bn_beta': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_bn_mean': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_bn_mean': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'bn_mean': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_bn_var': {'value': None, 'shape': None, 'kind': 'op'},
+ 'const_bn_var': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
'bn_var': {'value': None, 'shape': None, 'kind': 'data'},
'bn_data': {'value': None, 'shape': None, 'kind': 'data'},
# Concat1 operation
'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'},
'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
- 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
+ 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Mul and Add operations
'mul_1': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True,
'infer': lambda node: eltwise_infer(node, lambda a, b: a*b)},
'mul_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'mul_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_1': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
'add_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'add_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# Mul2 and Add2 operations
'mul_2': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
'mul_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'mul_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_2': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
'add_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'add_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# Concat1 operation
'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
'conv_1_w': {'value': None, 'shape': None, 'kind': 'data'},
'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
- 'const_conv_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_conv_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
+ 'const_conv_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
'conv_2_w': {'value': None, 'shape': None, 'kind': 'data'},
'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
- 'const_conv_2_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_conv_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
+ 'const_conv_2_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
# MatMul
- 'fc_1': {'type': 'MatMul', 'kind': 'op', 'layout': 'NHWC'},
+ 'fc_1': {'type': 'MatMul', 'kind': 'op', 'layout': 'NHWC', 'op': 'MatMul'},
'fc_1_w': {'value': None, 'shape': None, 'kind': 'data'},
'fc_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_fc_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
- 'const_fc_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_fc_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
+ 'const_fc_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'fc_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Placeholders
'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# ScaleShift layer
'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'},
- 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Mul and Add operations
'mul_1': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'mul_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'mul_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_1': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'add_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# Mul2 and Add2 operations
'mul_2': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'mul_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'mul_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_2': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'add_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# Mul3 and Add3 operations
'mul_3': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_3_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_mul_3_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'mul_3_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'mul_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_3': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_3_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_add_3_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'add_3_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# Mul4 and Add4 operations
'mul_4': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_4_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_mul_4_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'mul_4_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'mul_4_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_4': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_4_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_add_4_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'add_4_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'add_4_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
# Concat1 operation
'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Convolutions
'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'const_conv_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_conv_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'conv_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_conv_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'const_conv_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_conv_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'conv_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_2_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_conv_2_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
# FullyConnected
'fc_1': {'type': 'MatMul', 'kind': 'op', 'op': 'FullyConnected', 'layout': 'NHWC'},
- 'const_fc_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_fc_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'fc_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_fc_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None},
+ 'const_fc_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
'fc_1_b': {'value': None, 'shape': None, 'kind': 'data'},
'fc_1_data': {'value': None, 'shape': None, 'kind': 'data'},
# Placeholders
'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
'placeholder_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
+ 'op_output': {'kind': 'op', 'op': 'Result'}
}
# constants
const = lambda name, value: {name: {'kind': 'op', 'value': value, 'shape': int64_array(value.shape),
- 'type': 'Const', 'infer': Const.infer}}
+ 'type': 'Const', 'infer': Const.infer, 'op': 'Const'}}
fake_const = lambda name, shape: {name: {'kind': 'op', 'value': None, 'infer': Const.infer,
'shape': int64_array(shape) if shape is not None else None}}
shaped_const_with_data = lambda name, shape: {**fake_const(name, shape), **shaped_data(name + '_d', shape)}