diff --git a/inference-engine/thirdparty/clDNN/tests/module_tests/gpu_toolkit_test.cpp b/inference-engine/thirdparty/clDNN/tests/module_tests/gpu_toolkit_test.cpp index fae259ebba8..ce9b9732e6b 100644 --- a/inference-engine/thirdparty/clDNN/tests/module_tests/gpu_toolkit_test.cpp +++ b/inference-engine/thirdparty/clDNN/tests/module_tests/gpu_toolkit_test.cpp @@ -114,7 +114,7 @@ private: } }; -TEST(gpu_engine, user_context) +TEST(gpu_engine, DISABLED_user_context) { user_gpu_toolkit gpu_toolkit; cl_context user_context = gpu_toolkit.get_gpu_context(); diff --git a/model-optimizer/automation/package_BOM.txt b/model-optimizer/automation/package_BOM.txt index 93b6070c0eb..b3286fc15a6 100644 --- a/model-optimizer/automation/package_BOM.txt +++ b/model-optimizer/automation/package_BOM.txt @@ -8,7 +8,6 @@ extensions/analysis/tf_od_api.py extensions/analysis/tf_retinanet.py extensions/analysis/tf_yolo.py extensions/back/__init__.py -extensions/back/ActivationsNormalizer.py extensions/back/AvgPool.py extensions/back/blob_normalizer.py extensions/back/CellNormalizer.py @@ -19,36 +18,26 @@ extensions/back/CorrectName.py extensions/back/CropToStridedSlice.py extensions/back/CutMemory.py extensions/back/disable_unsupported_ND_operations.py -extensions/back/DumpFakeQuantStat.py -extensions/back/ElementwiseOpsToEltwiseOps.py extensions/back/EnableConstantStridedSlice.py extensions/back/ForceStrictPrecision.py extensions/back/fuse_sub_div_min.py extensions/back/FuseTransposesSequence.py extensions/back/GatherNormalizer.py extensions/back/GroupedConvWeightsNormalize.py -extensions/back/I64ToI32.py extensions/back/insert_compatibility_l2normalization.py extensions/back/InterpolateReshape.py -extensions/back/InterpolateToInterpOrResample.py extensions/back/kaldi_remove_memory_output.py extensions/back/LeakyReLUMutation.py -extensions/back/LeakyReluToReluWithNegativeSlope.py extensions/back/LRNToNorm.py extensions/back/MatMulNormalizer.py extensions/back/MaxPool.py -extensions/back/NonMaximumSuppressionNormalize.py extensions/back/NormalizeToNormalizeL2.py -extensions/back/OneHotNormalizer.py extensions/back/op_versioning.py extensions/back/OptimizeTransposeReshapeSequence.py extensions/back/PackBinaryWeights.py -extensions/back/PadToV7.py -extensions/back/ParameterToPlaceholder.py extensions/back/pass_separator.py extensions/back/priorbox_mutation.py extensions/back/ProposalMutation.py -extensions/back/ReadValueAssignToMemory.py extensions/back/ReduceToPooling.py extensions/back/ReduceTransposeDimensions.py extensions/back/remove_last_softmax_pattern.py @@ -60,16 +49,12 @@ extensions/back/ReverseInputChannels.py extensions/back/RNNSequenceTypeRename.py extensions/back/ScalarConstNormalize.py extensions/back/SelectBroadcast.py -extensions/back/ShapeOfToShape.py extensions/back/ShuffleChannelPatternOptimization.py extensions/back/ShufflenetReLUReorder.py extensions/back/SpecialNodesFinalization.py -extensions/back/split_normalizer.py extensions/back/StridedSliceMasksNormalizer.py -extensions/back/TileNormalizer.py extensions/back/TopKNormalizer.py extensions/back/TransposeReduceFusing.py -extensions/back/TransposeToPermute.py extensions/back/UselessConcatRemoval.py extensions/front/__init__.py extensions/front/ArgMaxSqueeze.py @@ -160,7 +145,6 @@ extensions/front/kaldi/split_memoryoffsets.py extensions/front/kaldi/tanh_component_ext.py extensions/front/Log1p.py extensions/front/LogSoftmax.py -extensions/front/LRNReplacer.py extensions/front/MatMul_normalizer.py extensions/front/MoveEmbeddedInputsToInputs.py extensions/front/mxnet/__init__.py @@ -338,7 +322,6 @@ extensions/front/softmax.py extensions/front/softplus.py extensions/front/softsign_replacer.py extensions/front/split_normalizer.py -extensions/front/squared_difference.py extensions/front/SqueezeNormalize.py extensions/front/standalone_const_eraser.py extensions/front/sub.py @@ -517,7 +500,6 @@ extensions/middle/DecomposeBidirectionalRNNSequence.py extensions/middle/Deconvolution3rdInputNormalization.py extensions/middle/DeleteControlFlowEdges.py extensions/middle/DeleteNotExecutable.py -extensions/middle/DepthToSpace.py extensions/middle/DilatedConvolution.py extensions/middle/EltwiseChecker.py extensions/middle/EltwiseInputNormalization.py @@ -539,8 +521,6 @@ extensions/middle/LayoutChangeForConstantShapePaths.py extensions/middle/LeakyReluPattern.py extensions/middle/LSTMRNNSequenceToTensorIterator.py extensions/middle/MarkSubgraphsWithCorrectLayout.py -extensions/middle/MinimumMiddleReplacer.py -extensions/middle/MulAddToSS.py extensions/middle/MulFakeQuantizeFuse.py extensions/middle/MXNetRNNSequenceNormalize.py extensions/middle/MXNetSplitMultiLayers.py @@ -571,7 +551,6 @@ extensions/middle/ScaleInput.py extensions/middle/SharedWeightsDuplication.py 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 diff --git a/model-optimizer/extensions/back/ActivationsNormalizer.py b/model-optimizer/extensions/back/ActivationsNormalizer.py deleted file mode 100644 index 5830b966a06..00000000000 --- a/model-optimizer/extensions/back/ActivationsNormalizer.py +++ /dev/null @@ -1,42 +0,0 @@ -""" - 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. -""" - -from extensions.ops.activation_ops import activation_ops -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph, Node -from mo.ops.activation import Activation - - -class ActivationsNormalizer(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('activation', dict(type=lambda type: type in activation_ops)) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: [str, Node]): - node = match['activation'] - if node.type == 'LogicalNot': - operation = 'not' - else: - operation = node.type.lower() - Activation.update_node_stat(node, dict(operation=operation)) diff --git a/model-optimizer/extensions/back/AvgPool.py b/model-optimizer/extensions/back/AvgPool.py index 18bc6012f56..6f2c7a85c29 100644 --- a/model-optimizer/extensions/back/AvgPool.py +++ b/model-optimizer/extensions/back/AvgPool.py @@ -22,7 +22,6 @@ class AvgPool(BackReplacementPattern): Rename Pooling/avg to AvgPool """ enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): return dict( diff --git a/model-optimizer/extensions/back/CellNormalizer.py b/model-optimizer/extensions/back/CellNormalizer.py index fb81e3e84e7..bb9834fbd2f 100644 --- a/model-optimizer/extensions/back/CellNormalizer.py +++ b/model-optimizer/extensions/back/CellNormalizer.py @@ -31,8 +31,6 @@ class CellNormalizer(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - def pattern(self): return dict( nodes=[ diff --git a/model-optimizer/extensions/back/ConvolutionNormalizer.py b/model-optimizer/extensions/back/ConvolutionNormalizer.py index fd8c0918130..dbc69b547ff 100644 --- a/model-optimizer/extensions/back/ConvolutionNormalizer.py +++ b/model-optimizer/extensions/back/ConvolutionNormalizer.py @@ -29,7 +29,6 @@ from mo.ops.strided_slice import StridedSlice class ConvolutionNormalizer(BackReplacementPattern): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): return dict( @@ -45,78 +44,6 @@ class ConvolutionNormalizer(BackReplacementPattern): del node['kernel_spatial'] -class ConvolutionReshaper(BackReplacementPattern): - """ - Workarounds absence of 1D Convolution support in Inference Engine by converting it to 2D Convolution - - updating shape dependent Convolution parameters with fake H: dilation, kernel, pad, stride - - reshape weights from [OIX] -> [OIYX] = [OI1X] - - inserting fake H dimension by adding reshapes before and after Convolution: [NCW] -> [NCHW] = [NC1W] - """ - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_before(self): - return [ReshapeMutation] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('conv', dict(type='Convolution')) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: dict): - conv = match['conv'] - - assert len(conv.out_nodes()) == 1, "Convolution operation {} should have 1 output data node".format(conv.id) - out_data = conv.out_node() - - assert out_data.has_valid('shape'), 'Output shape is undefined for {} in back phase'.format(conv.id) - out_shape = out_data.shape - - if out_shape.size != 3: - return - - assert len(conv.in_nodes()) >= 1, "Convolution operation {} should have more than 1 input data node".format( - conv.id) - inp_data = conv.in_node() - - assert inp_data.has_valid('shape'), 'Input shape is undefined for {} in back phase'.format(conv.id) - inp_shape = inp_data.shape - new_inp_shape = np.insert(inp_shape, 2, 1) - - # setting to None to be overwritten by infer function - conv.kernel_spatial_idx = None - conv.spatial_dims = None - - # inserting fake H dimension - conv.dilation = np.insert(conv.dilation, 2, 1) - conv.kernel_spatial = np.append([1], conv.kernel_spatial) - conv.pad = np.insert(conv.pad, 2, [0, 0], axis=0) - conv.stride = np.insert(conv.stride, 2, 1) - - weights_node = conv.in_node(1) - weights_node.value = np.reshape(weights_node.value, np.insert(weights_node.value.shape, 2, 1)) - weights_node.shape = np.array(weights_node.value.shape, dtype=np.int64) - - reshape = Reshape(graph, {'name': conv.name + '/reshape'}).create_node() - reshape_dim = Const(graph, {'value': new_inp_shape, 'name': reshape.id + '/Dim'}).create_node() - conv.in_port(0).get_connection().insert_node(reshape) - reshape.in_port(1).connect(reshape_dim.out_port(0)) - - reshape_back = Reshape(graph, {'name': conv.name + '/reshape_back'}).create_node() - reshape_back_dim = Const(graph, {'value': out_shape, 'name': reshape.id + '/Dim'}).create_node() - conv.out_port(0).get_connection().insert_node(reshape_back) - reshape_back.in_port(1).connect(reshape_back_dim.out_port(0)) - - # run shape inference manually for several nodes to override shapes of the model nodes which changed behaviour - reshape_dim.infer(reshape_dim) - reshape.infer(reshape) - conv.infer(conv) - - class V7ConvolutionWithGroupsResolver(BackReplacementPattern): """ Normalizes grouped convolution weights shape to fit special weights format [G*O I X Y] @@ -206,13 +133,12 @@ class ConvolutionWithGroupsResolver(BackReplacementPattern): return [ReshapeMutation] def run_after(self): - return [ConvolutionReshaper, ApplyReverseChannels] + return [ApplyReverseChannels] def find_and_replace_pattern(self, graph: Graph): V7ConvolutionWithGroupsResolver().find_and_replace_pattern(graph) PullReshapeThroughFQ().find_and_replace_pattern(graph) - if graph.graph['cmd_params'].generate_experimental_IR_V10: - V10ConvolutionWithGroupsResolver().find_and_replace_pattern(graph) + V10ConvolutionWithGroupsResolver().find_and_replace_pattern(graph) class PullReshapeThroughFQ(BackReplacementPattern): @@ -279,14 +205,13 @@ class PullReshapeThroughFQ(BackReplacementPattern): class DeconvolutionNormalizer(BackReplacementPattern): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] force_clean_up = True def run_before(self): return [ReshapeMutation] def run_after(self): - return [ConvolutionReshaper, ApplyReverseChannels] + return [ApplyReverseChannels] @staticmethod def pattern(): diff --git a/model-optimizer/extensions/back/CropToStridedSlice.py b/model-optimizer/extensions/back/CropToStridedSlice.py index bf18d737be4..7d52afe2a55 100644 --- a/model-optimizer/extensions/back/CropToStridedSlice.py +++ b/model-optimizer/extensions/back/CropToStridedSlice.py @@ -29,8 +29,6 @@ class CropToStridedSlice(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - def run_before(self): return [ForceStrictPrecision] diff --git a/model-optimizer/extensions/back/CutMemory.py b/model-optimizer/extensions/back/CutMemory.py index dea74a5de0a..d0f4ff80100 100644 --- a/model-optimizer/extensions/back/CutMemory.py +++ b/model-optimizer/extensions/back/CutMemory.py @@ -15,7 +15,6 @@ """ import numpy as np -from extensions.back.ParameterToPlaceholder import ParameterToInput from extensions.ops.parameter import Parameter from mo.back.replacement import BackReplacementPattern from mo.graph.graph import Graph @@ -31,9 +30,6 @@ class CutMemoryInput(BackReplacementPattern): graph_condition = [lambda graph: graph.graph['fw'] == "kaldi" and graph.graph['cmd_params'].remove_memory] force_clean_up = True - def run_before(self): - return [ParameterToInput] - @staticmethod def pattern(): return dict( @@ -67,9 +63,6 @@ class CutMemoryOutput(BackReplacementPattern): graph_condition = [lambda graph: graph.graph['fw'] == "kaldi" and graph.graph['cmd_params'].remove_memory] force_clean_up = True - def run_before(self): - return [ParameterToInput] - @staticmethod def pattern(): return dict( diff --git a/model-optimizer/extensions/back/DumpFakeQuantStat.py b/model-optimizer/extensions/back/DumpFakeQuantStat.py deleted file mode 100644 index 9336f76a4a5..00000000000 --- a/model-optimizer/extensions/back/DumpFakeQuantStat.py +++ /dev/null @@ -1,46 +0,0 @@ -""" - 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. -""" - -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph -from mo.middle.passes.eliminate import remove_op_node_with_data_node - - -class DumpFakeQuantStat(BackReplacementPattern): - enabled = True - - def find_and_replace_pattern(self, graph: Graph): - intervals = {} - for node in graph.get_op_nodes(type='FakeQuantize', keep_in_IR=False): - prev_node = node.in_node().in_node() - prev_node_id = prev_node.id - prev_node_out_shape = prev_node.out_node()['shape'] - C = prev_node_out_shape[1] - assert node.in_node(1).value.size == 1 - assert node.in_node(2).value.size == 1 - # Input and output ranges should match if we want to remove FakeQuantize from model - assert_msg = "FakeQuantize cannot be removed because input and output intervals do not match" - assert node.in_node(1).value == node.in_node(3).value, assert_msg - assert node.in_node(2).value == node.in_node(4).value, assert_msg - min = ', '.join([str(node.in_node(1).value.flatten()[0])] * C) - max = ', '.join([str(node.in_node(2).value.flatten()[0])] * C) - intervals[prev_node_id] = {'min': min, 'max': max} - remove_op_node_with_data_node(graph, node) - if intervals: - if 'statistics' not in graph.graph: - graph.graph['statistics'] = intervals - else: - graph.graph['statistics'].update(intervals) diff --git a/model-optimizer/extensions/back/ElementwiseOpsToEltwiseOps.py b/model-optimizer/extensions/back/ElementwiseOpsToEltwiseOps.py deleted file mode 100644 index c80af92cf81..00000000000 --- a/model-optimizer/extensions/back/ElementwiseOpsToEltwiseOps.py +++ /dev/null @@ -1,371 +0,0 @@ -""" - 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 logging as log - -import numpy as np - -from extensions.ops.elementwise import Mul, Add, Pow -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Node, Graph -from mo.middle.passes.fusing.helpers import get_value_in_port, get_tensor_in_port -from mo.middle.pattern_match import check_node_usages_out_of_match -from mo.ops.const import Const -from mo.ops.eltwise import Eltwise -from mo.ops.power import AttributedPower - -simple_eltwise_types = ['Power', 'Add', 'Multiply', 'Maximum', 'LogicalAnd', 'LogicalOr', 'LogicalXor', 'Less', - 'LessEqual', - 'Greater', 'GreaterEqual', 'Equal', 'NotEqual', 'FloorMod'] - -type_to_operation_map = { - 'Power': 'pow', - 'Add': 'sum', - 'Multiply': 'mul', - 'Maximum': 'max', - 'LogicalAnd': 'logical_and', - 'LogicalOr': 'logical_or', - 'LogicalXor': 'logical_xor', - 'Less': 'less', - 'LessEqual': 'less_equal', - 'Greater': 'greater', - 'GreaterEqual': 'greater_equal', - 'Equal': 'equal', - 'NotEqual': 'not_equal', - 'FloorMod': 'floor_mod', -} - - -class SimpleEltwiseToEltwiseOp(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('op', dict(type=lambda t: t in type_to_operation_map.keys(), op=lambda op: op != 'AttributedPower'))], - edges=[], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - Eltwise.update_node_stat(match['op'], {'operation': type_to_operation_map[match['op'].type]}) - - -class DivideToEltwises(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] - - @staticmethod - def pattern(): - return dict( - nodes=[('div', {'type': 'Divide'})], - edges=[], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - node = match['div'] - power_of_exponent = Const(graph, {'value': np.float64(-1)}).create_node() - reciprocal = Pow(graph, {'name': node.name + '/reciprocal_'}).create_node() - mul = Mul(graph, {'name': node.name + '/mul_'}).create_node() - - # Connect nodes - node.in_port(1).get_connection().set_destination(reciprocal.in_port(0)) - power_of_exponent.out_port(0).connect(reciprocal.in_port(1)) - node.in_port(0).get_connection().set_destination(mul.in_port(1)) - reciprocal.out_port(0).connect(mul.in_port(0)) - - node.out_port(0).get_connection().set_source(mul.out_port(0)) - - -class SubtractToEltwises(BackReplacementPattern): - enabled = True - force_clean_up = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] - - @staticmethod - def pattern(): - return dict( - nodes=[('sub', {'type': 'Subtract'})], - edges=[], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - node = match['sub'] - - # Add new nodes - negate_const = Const(graph, dict(name=node.name + '/negate_const', value=np.array(-1))).create_node() - negate = Mul(graph, {'name': node.name + '/negate_'}).create_node() - add = Add(graph, {'name': node.name + '/add_'}).create_node() - - # Connect nodes - node.in_port(1).get_connection().set_destination(negate.in_port(0)) - negate_const.out_port(0).connect(negate.in_port(1)) - node.in_port(0).get_connection().set_destination(add.in_port(1)) - negate.out_port(0).connect(add.in_port(0)) - - node.out_port(0).get_connection().set_source(add.out_port(0)) - - -class EltwisesWithScalarInputToPower(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - eltw_types = ['Add', 'Multiply', 'Power'] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] - - @staticmethod - def pattern(): - return dict( - nodes=[('op', {'type': lambda type: type in EltwisesWithScalarInputToPower.eltw_types})], - edges=[], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - op = match['op'] - op_type = op.type - - if op.has_and_set('stop_value_propagation'): - return - - const_port, tensor_port = get_value_in_port(op), get_tensor_in_port(op) - if const_port is None or tensor_port is None: - return - value = const_port.data.get_value() - assert value is not None - if value.size != 1: - return - value = value.item(0) - - assert op_type in EltwisesWithScalarInputToPower.eltw_types - if op_type == 'Add': - delete_node = value == 0 - AttributedPower.update_node_stat(op, {'shift': value}) - elif op_type == 'Multiply': - delete_node = value == 1 - AttributedPower.update_node_stat(op, {'scale': value}) - elif op_type == 'Power': - delete_node = value == 1 - AttributedPower.update_node_stat(op, {'power': value}) - op.type_infer = AttributedPower.type_infer - - const_port.disconnect() - if tensor_port.idx != 0: - tensor_port.get_connection().set_destination(op.in_port(0)) - op.delete_input_port(1) - - # TODO: uncomment this lines in future to allow useless operations deleting - # if delete_node: - # op.out_port(0).get_connection().set_source(op.in_port(0).get_connection().get_source()) - - -class MulAddPowerMerge(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [EltwisesWithScalarInputToPower] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('mul', dict(op='AttributedPower', shift=lambda x: np.all(x == 0), power=lambda x: np.all(x == 1))), - ('mul_d', dict()), - ('add', dict(op='AttributedPower', scale=lambda x: np.all(x == 1), power=lambda x: np.all(x == 1))), - ('add_d', dict()) - ], - edges=[ - ('mul', 'mul_d'), - ('mul_d', 'add'), - ('add', 'add_d'), - ], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - consumers = [n for n in match if n not in ['mul', 'add_d'] and not check_node_usages_out_of_match(match, n)] - if consumers: - log.warning('Power(mul,add) pattern was detected. Non pattern consumers of nodes: "{}" were found.' - ' Won\'t replace'.format(', '.join([match[n].id for n in consumers]))) - return - mul = match['mul'] - add = match['add'] - new_power = AttributedPower(graph, {'name': mul.name + '/fused_power', 'scale': mul.scale, - 'shift': add.shift}).create_node() - - source = mul.in_port(0).get_connection().get_source() - mul.in_port(0).disconnect() - new_power.in_port(0).connect(source) - add.out_port(0).get_connection().set_source(new_power.out_port(0)) - - log.debug('Power nodes {} and {} were fused to single Power node {}'.format(mul.name, add.name, new_power.name)) - - -class MulPowPowerMerge(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [MulAddPowerMerge] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('mul', dict(op='AttributedPower', shift=lambda x: np.all(x == 0), power=lambda x: np.all(x == 1))), - ('mul_d', dict()), - ('pow', dict(op='AttributedPower', scale=lambda x: np.all(x == 1), shift=lambda x: np.all(x == 0))), - ('pow_d', dict()) - ], - edges=[ - ('mul', 'mul_d'), - ('mul_d', 'pow'), - ('pow', 'pow_d'), - ], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - consumers = [n for n in match if n not in ['mul', 'pow_d'] and not check_node_usages_out_of_match(match, n)] - if consumers: - log.warning('Power(mul,pow) pattern was detected. Non pattern consumers of nodes: "{}" were found.' - ' Won\'t replace'.format(', '.join([match[n].id for n in consumers]))) - return - mul = match['mul'] - pow = match['pow'] - new_power = AttributedPower(graph, {'name': mul.name + '/fused_power', 'scale': mul.scale, - 'power': pow.power}).create_node() - - source = mul.in_port(0).get_connection().get_source() - mul.in_port(0).disconnect() - new_power.in_port(0).connect(source) - pow.out_port(0).get_connection().set_source(new_power.out_port(0)) - - log.debug('Power nodes {} and {} were fused to single Power node {}'.format(mul.name, pow.name, new_power.name)) - - -class AddPowPowerMerge(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [MulAddPowerMerge] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('add', dict(op='AttributedPower', scale=lambda x: np.all(x == 1), power=lambda x: np.all(x == 1))), - ('add_d', dict()), - ('pow', dict(op='AttributedPower', scale=lambda x: np.all(x == 1), shift=lambda x: np.all(x == 0))), - ('pow_d', dict()) - ], - edges=[ - ('add', 'add_d'), - ('add_d', 'pow'), - ('pow', 'pow_d'), - ], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - consumers = [n for n in match if n not in ['add', 'pow_d'] and not check_node_usages_out_of_match(match, n)] - if consumers: - log.warning('Power(add,pow) pattern was detected. Non pattern consumers of nodes: "{}" were found.' - ' Won\'t replace'.format(', '.join([match[n].id for n in consumers]))) - return - add = match['add'] - pow = match['pow'] - new_power = AttributedPower(graph, {'name': add.name + '/fused_power', 'shift': add.shift, - 'power': pow.power}).create_node() - - source = add.in_port(0).get_connection().get_source() - add.in_port(0).disconnect() - new_power.in_port(0).connect(source) - pow.out_port(0).get_connection().set_source(new_power.out_port(0)) - - log.debug('Power nodes {} and {} were fused to single Power node {}'.format(add.name, pow.name, new_power.name)) - - -class MulAddPowPowerMerge(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [MulAddPowerMerge, MulPowPowerMerge, AddPowPowerMerge] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('mul_add', dict(op='AttributedPower', power=lambda x: np.all(x == 1))), - ('mul_add_d', dict()), - ('pow', dict(op='AttributedPower', scale=lambda x: np.all(x == 1), shift=lambda x: np.all(x == 0))), - ('pow_d', dict()) - ], - edges=[ - ('mul_add', 'mul_add_d'), - ('mul_add_d', 'pow'), - ('pow', 'pow_d'), - ], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: [str, Node]): - consumers = [n for n in match if n not in ['mul_add', 'pow_d'] and not check_node_usages_out_of_match(match, n)] - if consumers: - log.warning('Power(mul_add,pow) pattern was detected. Non pattern consumers of nodes: "{}" were found.' - ' Won\'t replace'.format(', '.join([match[n].id for n in consumers]))) - return - mul_add = match['mul_add'] - pow = match['pow'] - new_power = AttributedPower(graph, {'name': mul_add.name + '/fused_power', 'shift': mul_add.shift, - 'scale': mul_add.scale, - 'power': pow.power}).create_node() - - source = mul_add.in_port(0).get_connection().get_source() - mul_add.in_port(0).disconnect() - new_power.in_port(0).connect(source) - pow.out_port(0).get_connection().set_source(new_power.out_port(0)) - - log.debug('Power nodes {} and {} were fused to single Power node {}'.format(mul_add.name, pow.name, - new_power.name)) diff --git a/model-optimizer/extensions/back/FuseTransposesSequence.py b/model-optimizer/extensions/back/FuseTransposesSequence.py index f860c6a0404..a9e16d71bdc 100644 --- a/model-optimizer/extensions/back/FuseTransposesSequence.py +++ b/model-optimizer/extensions/back/FuseTransposesSequence.py @@ -28,13 +28,8 @@ class FuseTransposesSequence(BackReplacementPattern): This pass finds sequence of Transpose operations and merge them to single Transpose operation In case if resulting Permutation do nothing, we just remove it """ - enabled = True - def run_before(self): - from extensions.back.TransposeToPermute import TransposeToPermute - return [TransposeToPermute] - def find_and_replace_pattern(self, graph: Graph): for permute_node in graph.get_op_nodes(type='Transpose'): if permute_node.id not in graph.nodes(): diff --git a/model-optimizer/extensions/back/GatherNormalizer.py b/model-optimizer/extensions/back/GatherNormalizer.py index b2f36c9d61f..0bb1a8d96a4 100644 --- a/model-optimizer/extensions/back/GatherNormalizer.py +++ b/model-optimizer/extensions/back/GatherNormalizer.py @@ -13,88 +13,18 @@ See the License for the specific language governing permissions and limitations under the License. """ -import logging as log -import numpy as np - -from extensions.ops.gather import AttributedGather from mo.back.replacement import BackReplacementPattern from mo.front.common.partial_infer.utils import int64_array from mo.front.tf.graph_utils import create_op_node_with_second_input from mo.graph.graph import Graph -from mo.ops.const import Const from mo.ops.squeeze import Squeeze -class Gather0D(BackReplacementPattern): - """ - This is a workaround until InferenceEngine starts support 0D. - The pass finds Gather with 0D constant input with indices to gather and converts it to 1D with 1 element and - then add Squeeze to restore initial number of dimension. - """ - - enabled = True - force_shape_inference = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def find_and_replace_pattern(self, graph: Graph): - for gather in graph.get_op_nodes(type='Gather'): - indices = gather.in_port(1).get_source().node - indices_value = gather.in_port(1).data.get_value() - if indices.op == 'Const' and indices_value is not None and indices_value.ndim == 0: - log.debug('The Gather node {} has constant 0D input with indices'.format(gather.id)) - - new_indices = Const(graph, {'value': np.array([indices_value.item()])}).create_node() - - # the input shape is changed so need to disconnect port first - gather.in_port(1).disconnect() - gather.in_port(1).connect(new_indices.out_port(0)) - - # the output of Gather is changed so need to run shape inference for it and override the existing shape - gather['override_output_shape'] = True - gather['need_shape_inference'] = True - - # insert Squeeze to remove the dimension 'axis' which become equal to 1 after change of the Gather - # indices constant - squeeze = Squeeze(graph, {'name': gather.id + '/Squeeze'}).create_node() - squeeze_axis = Const(graph, {'name': squeeze.id + '/axis', - 'value': int64_array([gather.axis])}).create_node() - - gather.out_port(0).get_connection().insert_node(squeeze) - squeeze.in_port(1).connect(squeeze_axis.out_port(0)) - - -class GatherNormalizer(BackReplacementPattern): - enabled = True - force_clean_up = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def find_and_replace_pattern(self, graph: Graph): - for node in graph.get_op_nodes(op='Gather'): - name = node.soft_get('name', node.id) - assert 2 in node.in_ports() and not node.in_port(2).disconnected() - assert not node.has_valid('axis') - - axis = node.in_port(2).data.get_value() - assert axis is not None - - attributed_gather = AttributedGather(graph, {'axis': axis, 'name': name}).create_node() - - node.out_port(0).get_connection().set_source(attributed_gather.out_port(0)) - node.in_port(0).get_connection().set_destination(attributed_gather.in_port(0)) - node.in_port(1).get_connection().set_destination(attributed_gather.in_port(1)) - - # shape inference (before cleaning this node up) will fail due to disconnected input ports - node['need_shape_inference'] = False - - class GatherTreeNormalizer(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - def find_and_replace_pattern(self, graph: Graph): for node in graph.get_op_nodes(type='GatherTree'): name = node.soft_get('name', node.id) diff --git a/model-optimizer/extensions/back/GroupedConvWeightsNormalize.py b/model-optimizer/extensions/back/GroupedConvWeightsNormalize.py index 8fb7c2affb0..97cc77f2d37 100644 --- a/model-optimizer/extensions/back/GroupedConvWeightsNormalize.py +++ b/model-optimizer/extensions/back/GroupedConvWeightsNormalize.py @@ -27,7 +27,6 @@ class GroupedConvWeightsNormalize(BackReplacementPattern): It requires that weights layout will be next: G*O*I,1,H,W """ enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] force_clean_up = True def pattern(self): diff --git a/model-optimizer/extensions/back/I64ToI32.py b/model-optimizer/extensions/back/I64ToI32.py deleted file mode 100644 index 3eb526dc7c6..00000000000 --- a/model-optimizer/extensions/back/I64ToI32.py +++ /dev/null @@ -1,49 +0,0 @@ -""" - 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 logging as log - -import numpy as np - -from extensions.back.ForceStrictPrecision import ForceStrictPrecision -from mo.back.replacement import BackReplacementPattern -from mo.front.subgraph_matcher import SubgraphMatch -from mo.graph.graph import Graph - - -class I64ToI32(BackReplacementPattern): - """ - Change the Cast to int64 to int32 since not all plugins support int64 data type for non IR V10 case. - """ - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - return [ForceStrictPrecision] - - def pattern(self): - return dict( - nodes=[ - ('cast', dict(op='Cast')) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: [dict, SubgraphMatch]): - node = match['cast'] - if node.dst_type == np.int64: - log.warning('Change data type from {} to {} for node {}'.format(node.dst_type, np.int32, node.name)) - node.dst_type = np.int32 diff --git a/model-optimizer/extensions/back/InterpolateToInterpOrResample.py b/model-optimizer/extensions/back/InterpolateToInterpOrResample.py deleted file mode 100644 index 990f91b617a..00000000000 --- a/model-optimizer/extensions/back/InterpolateToInterpOrResample.py +++ /dev/null @@ -1,118 +0,0 @@ -""" - 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. -""" -from extensions.back.ShapeOfToShape import ShapeOfToShape -from extensions.ops.interp import InterpOp -from extensions.ops.resample import ResampleOp -from extensions.ops.resize_factor_utils import factor_update -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph -from mo.ops.shape import Shape -from mo.utils.shape import node_to_get_batch_value, node_to_get_features_dimension_value, \ - new_shape_node_from_shape_nodes - - -class InterpolateToInterpOrResample(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - type_map = { - 'linear': 'caffe.ResampleParameter.LINEAR', - 'nearest': 'caffe.ResampleParameter.NEAREST', - 'cubic': 'caffe.ResampleParameter.CUBIC', - 'area': 'caffe.ResampleParameter.AREA', - } - - def run_before(self): - return [ShapeOfToShape] - - @staticmethod - def pattern(): - return dict( - nodes=[('interpolate', {'type': 'Interpolate'})], - edges=[], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['interpolate'] - - assert 1 in node.in_ports() and not node.in_port(1).disconnected() and \ - node.in_port(1).data.get_value() is not None, 'Interpolate node {} is corrupted: no 1-port input found' - - # common - mode = node.mode - assert mode in ['linear', 'nearest', 'cubic', 'area'] - in_shape = node.in_port(0).data.get_shape() - assert in_shape is not None and len(in_shape) in [4, 5] - out_shape = node.out_port(0).data.get_shape() - assert out_shape is not None and len(out_shape) in [4, 5] - in_height, in_width = in_shape[2], in_shape[3] - out_height, out_width = out_shape[2], out_shape[3] - factor = factor_update( - None if not node.has_valid('factor') else node.factor, - [float(out_height) / in_height, float(out_width) / in_width], - [in_height, in_width], - [out_height, out_width], - node.soft_get('name') - ) - update_attrs = { - 'width': out_width, - 'height': out_height, - 'factor': factor, - } - - if (node.has_valid('shrink_factor') and node.has_valid('zoom_factor')) or factor is None: - del update_attrs['factor'] - if node.has('factor'): - del node['factor'] - - if ((node.has_valid('shrink_factor') and node.shrink_factor != 1) or - (node.has_valid('zoom_factor') and node.zoom_factor != 1) or 'factor' in update_attrs) \ - and ((not node.has_valid('width') or node.width == 0) and - (not node.has_valid('height') or node.height == 0)): - update_attrs['width'] = 0 - update_attrs['height'] = 0 - - # specific - if mode in ['nearest', 'cubic', 'area'] or node.has_and_set('convert_to_resample'): - assert not node.align_corners - assert node.pads_begin == 0 and node.pads_end == 0 - update_attrs['resample_type'] = InterpolateToInterpOrResample.type_map[mode] - ResampleOp.update_node_stat(node, update_attrs) - - if not graph.graph['cmd_params'].keep_shape_ops or graph.graph['fw'] != 'tf': - node.in_port(1).disconnect() - else: - # we avoid making resample non-reshapable for tf version - shape = Shape(graph, {}).create_node() - node.in_port(0).get_source().connect(shape.in_port(0)) - - batch = node_to_get_batch_value(shape) - features = node_to_get_features_dimension_value(shape) - full_shape = new_shape_node_from_shape_nodes([batch, features, node.in_port(1).get_source().node]) - node.in_port(1).get_connection().set_source(full_shape.out_port(0)) - full_shape['override_output_shape'] = True - - elif mode == 'linear': - assert len(in_shape) == 4, 'Interp does not support 5D input' - update_attrs.update({ - 'pad_beg': node.pads_begin, - 'pad_end': node.pads_end, - 'align_corners': node.align_corners, - }) - InterpOp.update_node_stat(node, update_attrs) - node.in_port(1).disconnect() diff --git a/model-optimizer/extensions/back/LRNToNorm.py b/model-optimizer/extensions/back/LRNToNorm.py index ede3fb3386b..4984ae49263 100644 --- a/model-optimizer/extensions/back/LRNToNorm.py +++ b/model-optimizer/extensions/back/LRNToNorm.py @@ -26,7 +26,6 @@ class LRN_normalization(BackReplacementPattern): Transforming LRN with `region` attribute to LRN with second `axis`-input """ enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): return dict( diff --git a/model-optimizer/extensions/back/LeakyReLUMutation.py b/model-optimizer/extensions/back/LeakyReLUMutation.py index 773ce643fe3..46d4a24ffb6 100644 --- a/model-optimizer/extensions/back/LeakyReLUMutation.py +++ b/model-optimizer/extensions/back/LeakyReLUMutation.py @@ -25,7 +25,6 @@ from mo.ops.const import Const class LeakyReLUMutation(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def run_before(self): return [ForceStrictPrecision] diff --git a/model-optimizer/extensions/back/LeakyReluToReluWithNegativeSlope.py b/model-optimizer/extensions/back/LeakyReluToReluWithNegativeSlope.py deleted file mode 100644 index 8f6f20528e6..00000000000 --- a/model-optimizer/extensions/back/LeakyReluToReluWithNegativeSlope.py +++ /dev/null @@ -1,34 +0,0 @@ -""" - 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. -""" - -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph, Node - - -class LeakyReluToReluWithNegativeSlope(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def pattern(self): - return dict( - nodes=[ - ('leakyrelu', dict(kind='op', op='LeakyReLU')) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: [str, Node]): - match['leakyrelu']['type'] = 'ReLU' diff --git a/model-optimizer/extensions/back/MatMulNormalizer.py b/model-optimizer/extensions/back/MatMulNormalizer.py index e9ba2786a59..37ab98db401 100644 --- a/model-optimizer/extensions/back/MatMulNormalizer.py +++ b/model-optimizer/extensions/back/MatMulNormalizer.py @@ -16,17 +16,11 @@ import numpy as np -from extensions.back.ReshapeMutation import ReshapeMutation -from extensions.back.TransposeToPermute import TransposeToPermute -from extensions.ops.MatMul import FullyConnected, Gemm, MatMul from extensions.ops.transpose import Transpose from mo.back.replacement import BackReplacementPattern from mo.front.common.partial_infer.utils import int64_array -from mo.front.tf.graph_utils import create_op_node_with_second_input from mo.graph.graph import Graph -from mo.middle.passes.fusing.helpers import get_tensor_in_port, get_value_in_port from mo.ops.const import Const -from mo.ops.reshape import Reshape from mo.ops.unsqueeze import Unsqueeze @@ -75,17 +69,8 @@ class MatMulConstTransposesExtraction(BackReplacementPattern): @staticmethod def replace_pattern(graph: Graph, match: dict): node = match['matmul'] - is_v10 = graph.graph['cmd_params'].generate_experimental_IR_V10 - if not is_v10 and node.has_and_set('transpose_a') and node.in_port(0).data.get_value() is not None: - MatMulConstTransposesExtraction.insert_transpose(node, 0) - node['transpose_a'] = False - - if not is_v10 and node.has_and_set('transpose_b') and node.in_port(1).data.get_value() is not None: - MatMulConstTransposesExtraction.insert_transpose(node, 1) - node['transpose_b'] = False - - if is_v10 and not node.has_and_set('transpose_b'): + if not node.has_and_set('transpose_b'): B_shape = node.in_port(1).data.get_shape() B_value = node.in_port(1).data.get_value() FQ_on_weights = node.in_port(1).get_source().node.has_and_set('stop_value_propagation') @@ -94,320 +79,6 @@ class MatMulConstTransposesExtraction(BackReplacementPattern): node['transpose_b'] = True -class MatMulToFullyConnected(BackReplacementPattern): - """ - All infers are done during replacement because otherwise shape_inference will raise on shape collision, - but it is appropriate here cause operation semantic change (MatMul->FullyConnected) - """ - - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_before(self): - return [ReshapeMutation, TransposeToPermute] - - def run_after(self): - return [MatMulConstTransposesExtraction] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('matmul', dict(kind='op', op='MatMul'))], - edges=[] - ) - - @staticmethod - def get_matmul_BIKO(node): - A_shape, B_shape = MatMul.shape_alignment(node) - - I = A_shape[-2] - K = A_shape[-1] - O = B_shape[-1] - B = A_shape[:-2] - - return B, I, K, O, A_shape, B_shape - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['matmul'] - name = node.soft_get('name', node.id) - - A_shape = node.in_port(0).data.get_shape() - B_shape = node.in_port(1).data.get_shape() - out_shape = node.out_port(0).data.get_shape() - - assert A_shape is not None and B_shape is not None and out_shape is not None - - B_value = node.in_port(1).data.get_value() - if (B_value is not None or node.in_port(1).get_source().node.has_and_set('stop_value_propagation')) and B_shape[ - B_shape != 1].size <= 2: - # transferring from MatMul representation: [B, I, K] * [B, K, O] = [B, I, O] - # to FullyConnected representation: [I, K] * [O, K] = [I, O] - B, I, K, O, aligned_A_shape, aligned_B_shape = MatMulToFullyConnected.get_matmul_BIKO(node) - - # weights normalization - if not node.transpose_b: - # FullyConnected weights layout is OI - # MatMul second input layout is (B)IO - transpose_order = list(range(B_shape.size)) - transpose_order[-1], transpose_order[-2] = transpose_order[-2], transpose_order[-1] - - order = Const(graph, {'value': int64_array(transpose_order)}).create_node() - transpose = Transpose(graph, {'name': name + '/weights_transpose'}).create_node() - - weights_source = node.in_port(1).get_source() - node.in_port(1).get_connection().set_source(transpose.out_port(0)) - transpose.in_port(0).connect(weights_source) - transpose.in_port(1).connect(order.out_port(0)) - - order.infer(order) - transpose.infer(transpose) - - if node.in_port(1).data.get_shape().size != 2: - const = Const(graph, {'value': int64_array([-1, K])}).create_node() - reshape = Reshape(graph, {'name': name + '/weights_reshape'}).create_node() - - weights_source = node.in_port(1).get_source() - node.in_port(1).get_connection().set_source(reshape.out_port(0)) - - reshape.in_port(0).connect(weights_source) - reshape.in_port(1).connect(const.out_port(0)) - - const.infer(const) - reshape.infer(reshape) - - assert np.all(np.array_equal(node.in_port(1).data.get_shape(), int64_array([O, K]))), \ - "MatMul `{}` was not converted to FullyConnected: wrong weights shape: {}, " \ - "B={}, I={}, K={}, O={}".format(name, node.in_port(1).data.get_shape(), B, I, K, O) - - node.in_port(1).bin = 'weights' - del node['transpose_b'] - - # input normalization - if node.transpose_a: - transpose_order = list(range(A_shape.size)) - transpose_order[-1], transpose_order[-2] = transpose_order[-2], transpose_order[-1] - - order = Const(graph, {'value': int64_array(transpose_order)}).create_node() - transpose = Transpose(graph, {'name': name + '/input_transpose'}).create_node() - - input_source = node.in_port(0).get_source() - node.in_port(0).get_connection().set_source(transpose.out_port(0)) - transpose.in_port(0).connect(input_source) - transpose.in_port(1).connect(order.out_port(0)) - - order.infer(order) - transpose.infer(transpose) - - if A_shape.size != 2: - const = Const(graph, {'value': int64_array([-1, K])}).create_node() - reshape = Reshape(graph, {'name': name + '/input_reshape'}).create_node() - - input_source = node.in_port(0).get_source() - node.in_port(0).get_connection().set_source(reshape.out_port(0)) - reshape.in_port(0).connect(input_source) - reshape.in_port(1).connect(const.out_port(0)) - - const.infer(const) - reshape.infer(reshape) - - assert np.all(np.array_equal(node.in_port(0).data.get_shape(), int64_array([np.prod(B) * I, K]))), \ - "MatMul `{}` wasn't converted to FullyConnected: wrong input shape: {}, " \ - "B={}, I={}, K={}, O={}".format(name, node.in_port(0).data.get_shape(), B, I, K, O) - - del node['transpose_a'] - - FullyConnected.update_node_stat(node, {'out-size': O}) - - # output normalization - if out_shape.size != 2: - const = Const(graph, {'value': int64_array([*B, I, O])}).create_node() - reshape = Reshape(graph, {'name': name + '/output_reshape'}).create_node() - - dst = node.out_port(0).get_destination() - node.out_port(0).get_connection().set_destination(reshape.in_port(0)) - const.out_port(0).connect(reshape.in_port(1)) - reshape.out_port(0).connect(dst) - - node.infer(node) - - const.infer(const) - reshape.infer(reshape) - - else: - assert A_shape.size == out_shape.size - assert B_shape.size <= out_shape.size - if B_shape.size != out_shape.size: - unsqueeze_dim = Const(graph, {'value': int64_array(list(range(out_shape.size - B_shape.size))) - }).create_node() - unsqueeze = Unsqueeze(graph, {}).create_node() - B_source = node.in_port(1).get_source() - node.in_port(1).get_connection().set_source(unsqueeze.out_port(0)) - unsqueeze.in_port(0).connect(B_source) - unsqueeze.in_port(1).connect(unsqueeze_dim.out_port(0)) - - unsqueeze_dim.infer(unsqueeze_dim) - unsqueeze.infer(unsqueeze) - - Gemm.update_node_stat(node, { - 'transpose_a': node.has_and_set('transpose_a'), - 'transpose_b': node.has_and_set('transpose_b'), - }) - - -class SSBiasAddonForFC(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [MatMulToFullyConnected] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('fc', dict(kind='op', op='FullyConnected')), - ('fc_d', dict(kind='data')), - ('scale_shift', dict(kind='op', op='ScaleShift')), - ], - edges=[ - ('fc', 'fc_d'), - ('fc_d', 'scale_shift'), - ] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['fc'] - ss = match['scale_shift'] - name = node.soft_get('name', node.id) - - weights_value = ss.in_port(1).data.get_value() - assert weights_value is not None - if not np.all(weights_value == 1): - return - out_size = node.soft_get('out-size', None) - assert out_size is not None, \ - "FullyConnected should have `out-size` parameter, but it doesn't for node {}".format(name) - shift_shape = ss.in_port(2).data.get_shape() - - if not np.array_equal(int64_array([out_size]), shift_shape): - return - - node.add_input_port(2, skip_if_exist=True) - ss.in_port(2).get_connection().set_destination(node.in_port(2)) - ss.out_port(0).get_connection().set_source(ss.in_port(0).get_source()) - - -class BiasAddonForFC(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [MatMulToFullyConnected] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('fc', dict(kind='op', op='FullyConnected')), - ('fc_d', dict(kind='data')), - ('add', dict(kind='op', op='Add')), - ], - edges=[ - ('fc', 'fc_d'), - ('fc_d', 'add'), - ] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['fc'] - name = node.soft_get('name', node.id) - add = match['add'] - - if 2 in node.in_ports() and not node.in_port(2).disconnected(): - return - - out_size = node.soft_get('out-size', None) - assert out_size is not None, \ - "FullyConnected should have `out-size` parameter, but it doesn't for node {}".format(name) - - tensor_port, value_port = get_tensor_in_port(add), get_value_in_port(add) - if value_port is None: - return - - shift_shape = value_port.data.get_shape() - if not any([np.array_equal(int64_array(suitable_shape), shift_shape) - for suitable_shape in [[1, out_size], [1, 1], [out_size], [1], []]]): - return - - broadcasted_value = np.broadcast_to(value_port.data.get_value(), [1, out_size]) - const = Const(graph, {'name': name + '/Bias_', 'value': broadcasted_value}).create_node() - - node.add_input_port(2, skip_if_exist=True) - const.out_port(0).connect(node.in_port(2)) - add.out_port(0).get_connection().set_source(tensor_port.get_source()) - node.in_port(2).bin = 'biases' - - -class FullyConnectedFinalization(BackReplacementPattern): - enabled = True - graph_condition = [ - lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10, - ] - force_clean_up = True - - def run_after(self): - return [SSBiasAddonForFC, BiasAddonForFC, PullTransposeThroughFQUp] - - @staticmethod - def pattern(): - return dict( - nodes=[('fc', dict(kind='op', op='FullyConnected'))], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['fc'] - name = node.soft_get('name', node.id) - out_size = node.soft_get('out-size', None) - - assert out_size is not None, \ - "FullyConnected should have `out-size` parameter, but it doesn't for node {}".format(name) - - in_ports = node.in_ports() - - # [I, K] * [O, K] = [I, O] - if 1 not in in_ports or node.in_port(1).disconnected(): - # add fake weights - input_shape = node.in_port(0).data.get_shape() - assert input_shape is not None - K = input_shape[-1] - node.add_input_port(1, skip_if_exist=True) - const = Const(graph, {'value': np.ones([out_size, K])}).create_node() - node.in_port(1).connect(const.out_port(0)) - node.in_port(1).bin = 'weights' - - if 2 not in in_ports or node.in_port(2).disconnected(): - # add fake biases - node.add_input_port(2, skip_if_exist=True) - const = Const(graph, {'value': np.zeros([out_size])}).create_node() - node.in_port(2).connect(const.out_port(0)) - node.in_port(2).bin = 'biases' - - bias_reshape = create_op_node_with_second_input( - graph, Reshape, int64_array([-1]), {'name': name + '/1D_bias_', 'override_output_shape': True}, - node.in_port(2).get_source().node - ) - node.in_port(2).get_connection().set_source(bias_reshape.out_port(0)) - - class PullTransposeThroughFQUp(BackReplacementPattern): """ BEFORE AFTER @@ -425,10 +96,7 @@ class PullTransposeThroughFQUp(BackReplacementPattern): force_clean_up = True def run_after(self): - return [MatMulToFullyConnected] - - def run_before(self): - return [TransposeToPermute] + return [MatMulConstTransposesExtraction] @staticmethod def pattern(): diff --git a/model-optimizer/extensions/back/MaxPool.py b/model-optimizer/extensions/back/MaxPool.py index 652b7628e4a..71f62c1d999 100644 --- a/model-optimizer/extensions/back/MaxPool.py +++ b/model-optimizer/extensions/back/MaxPool.py @@ -22,7 +22,6 @@ class MaxPool(BackReplacementPattern): Rename Pooling/max to MaxPool """ enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): return dict( diff --git a/model-optimizer/extensions/back/NonMaximumSuppressionNormalize.py b/model-optimizer/extensions/back/NonMaximumSuppressionNormalize.py deleted file mode 100644 index 1f8373ff824..00000000000 --- a/model-optimizer/extensions/back/NonMaximumSuppressionNormalize.py +++ /dev/null @@ -1,49 +0,0 @@ -""" - 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. -""" -from extensions.back.ScalarConstNormalize import ScalarNormalize -from mo.back.replacement import BackReplacementPattern -from mo.front.common.partial_infer.utils import int64_array -from mo.front.tf.graph_utils import create_op_node_with_second_input -from mo.graph.graph import Graph -from mo.ops.reshape import Reshape - - -class NonMaximumSuppressionNormalizer(BackReplacementPattern): - """ - Converts NonMaximumSuppression layer to the V7 specification. - """ - enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_deprecated_IR_V7] - - def run_before(self): - return [ScalarNormalize] - - def find_and_replace_pattern(self, graph: Graph): - for nms in graph.get_op_nodes(type='NonMaxSuppression'): - mapping = {'corner': 0, 'center': 1} - - if graph.graph['cmd_params'].generate_deprecated_IR_V7: - nms['center_point_box'] = mapping[nms.box_encoding] - - # change the 0D inputs to 1D with shape [1] - for port_id in range(2, 5): - if port_id in nms.in_ports() and not nms.in_port(port_id).disconnected(): - reshape_1d = create_op_node_with_second_input(graph, Reshape, int64_array([1]), - {'name': nms.soft_get('name') + - '/Reshape_1D'.format(port_id), - 'override_output_shape': True, - }) - nms.in_port(port_id).get_connection().insert_node(reshape_1d) diff --git a/model-optimizer/extensions/back/NormalizeToNormalizeL2.py b/model-optimizer/extensions/back/NormalizeToNormalizeL2.py index 97acff24931..482c536cc85 100644 --- a/model-optimizer/extensions/back/NormalizeToNormalizeL2.py +++ b/model-optimizer/extensions/back/NormalizeToNormalizeL2.py @@ -15,7 +15,6 @@ """ import numpy as np -from extensions.back.ElementwiseOpsToEltwiseOps import SimpleEltwiseToEltwiseOp from extensions.back.insert_compatibility_l2normalization import CompatibilityL2NormalizationPattern from extensions.ops.elementwise import Mul from extensions.ops.normalize_l2 import NormalizeL2Op @@ -28,10 +27,6 @@ from mo.graph.graph import Graph, rename_node class NormalizeToNormalizeL2(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_before(self): - return [SimpleEltwiseToEltwiseOp] def run_after(self): return [CompatibilityL2NormalizationPattern] diff --git a/model-optimizer/extensions/back/OneHotNormalizer.py b/model-optimizer/extensions/back/OneHotNormalizer.py deleted file mode 100644 index 7ec7ab99677..00000000000 --- a/model-optimizer/extensions/back/OneHotNormalizer.py +++ /dev/null @@ -1,70 +0,0 @@ -""" - 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 logging as log - -import numpy as np - -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph -from mo.middle.passes.convert_data_type import data_type_str_to_np - - -class OneHotNormalizer(BackReplacementPattern): - """ - The transformation converts the OneHot layer to V7 specification: - 1. The inputs with on/off values are converted to attributes "on_value" and "off_value". - 2. The input with depth value is converted to attribute "depth". - 3. The output data type of the layer is inferred from the data type of on/off value taking into account IE supported - types. - """ - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def find_and_replace_pattern(self, graph: Graph): - assert_msg = "OneHot `{0}` ({1} input port value) should be scalar: node: `{2}`, {0} value: `{3}`" - for node in graph.get_op_nodes(type='OneHot'): - depth = node.in_port(1).data.get_value() - assert depth is not None and depth.ndim == 0, assert_msg.format('depth', '1', node.name, depth) - depth = depth.item(0) - - on_value = node.in_port(2).data.get_value() - assert on_value is not None and on_value.ndim == 0, assert_msg.format('on_value', '2', node.name, on_value) - off_value = node.in_port(3).data.get_value() - assert off_value is not None and off_value.ndim == 0, assert_msg.format('off_value', '3', node.name, - off_value) - - if on_value.dtype in [np.int64, np.bool]: - log.warning('Converting on_value and off_value to int32') - on_value = np.int32(on_value.item(0)) - off_value = np.int32(off_value.item(0)) - node.data_type = np.int32 - if on_value.dtype == np.float32 and data_type_str_to_np(node.graph.graph['cmd_params'].data_type) == np.float16: - log.warning('Converting on_value and off_value to fp16') - on_value = np.float16(on_value.item(0)) - off_value = np.float16(off_value.item(0)) - node.data_type = np.float16 - else: - node.data_type = on_value.dtype - on_value = on_value.item(0) - off_value = off_value.item(0) - - node['depth'] = depth - node['on_value'] = on_value - node['off_value'] = off_value - - node.in_port(1).disconnect() - node.in_port(2).disconnect() - node.in_port(3).disconnect() diff --git a/model-optimizer/extensions/back/OptimizeTransposeReshapeSequence.py b/model-optimizer/extensions/back/OptimizeTransposeReshapeSequence.py index 6b898af842e..5ef773670ed 100644 --- a/model-optimizer/extensions/back/OptimizeTransposeReshapeSequence.py +++ b/model-optimizer/extensions/back/OptimizeTransposeReshapeSequence.py @@ -186,8 +186,7 @@ class OptimizeTransposeReshapeSequence(BackReplacementPattern): return [ReshapeMutation] def run_after(self): - from extensions.back.TileNormalizer import Tile3DReshaper - return [FuseTransposesSequence, Tile3DReshaper] + return [FuseTransposesSequence] def is_node_match_for_optimization(self, node: Node): """ diff --git a/model-optimizer/extensions/back/PackBinaryWeights.py b/model-optimizer/extensions/back/PackBinaryWeights.py index 763f6e1aff4..0035ad2b6b1 100644 --- a/model-optimizer/extensions/back/PackBinaryWeights.py +++ b/model-optimizer/extensions/back/PackBinaryWeights.py @@ -53,7 +53,7 @@ class PackBinaryWeights(BackReplacementPattern): packed = np.packbits(weights_rounded) conv.in_port(1).data.set_value(packed) conv['packed_weights'] = 1 - if graph.graph['cmd_params'].generate_experimental_IR_V10: - conv.in_node(1)['force_shape'] = initial_shape.copy() - conv.in_node(1)['shape'] = initial_shape.copy() - conv.in_node(1)['force_type'] = 'U1' + + conv.in_node(1)['force_shape'] = initial_shape.copy() + conv.in_node(1)['shape'] = initial_shape.copy() + conv.in_node(1)['force_type'] = 'U1' diff --git a/model-optimizer/extensions/back/PadToV7.py b/model-optimizer/extensions/back/PadToV7.py deleted file mode 100644 index 21350803e40..00000000000 --- a/model-optimizer/extensions/back/PadToV7.py +++ /dev/null @@ -1,49 +0,0 @@ -""" - 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 mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph - - -class PadToV7(BackReplacementPattern): - """ - Transformation converts Pad representation from IR V10 to IR V7. - """ - enabled = True - force_clean_up = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def find_and_replace_pattern(self, graph: Graph): - for node in graph.get_op_nodes(type='Pad'): - pad_name = node.soft_get('name', node.id) - pb = node.in_port(1).data.get_value() - pe = node.in_port(2).data.get_value() - - assert pb is not None, 'Begin pads are not constants for node "{}"'.format(pad_name) - assert pe is not None, 'End pads are not constants for node "{}"'.format(pad_name) - - node['pads'] = np.concatenate([pb.reshape([-1, 1]), pe.reshape([-1, 1])], axis=1) - - if not node.in_port(3).disconnect(): - fill_value = node.in_port(3).data.get_value() - assert fill_value is not None, 'Fill value is not constants for node "{}"'.format(pad_name) - node.fill_value = fill_value - - node.in_port(1).disconnect() - node.in_port(2).disconnect() - if not node.in_port(3).disconnected(): - node.in_port(3).disconnect() diff --git a/model-optimizer/extensions/back/ParameterToPlaceholder.py b/model-optimizer/extensions/back/ParameterToPlaceholder.py deleted file mode 100644 index fe73fc61d80..00000000000 --- a/model-optimizer/extensions/back/ParameterToPlaceholder.py +++ /dev/null @@ -1,34 +0,0 @@ -""" - 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. -""" - -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph - - -class ParameterToInput(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def pattern(self): - return dict( - nodes=[ - ('parameter', dict(kind='op', type='Parameter')) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: dict): - match['parameter']['type'] = 'Input' diff --git a/model-optimizer/extensions/back/ProposalMutation.py b/model-optimizer/extensions/back/ProposalMutation.py index 917d0b42e30..34bcd1af493 100644 --- a/model-optimizer/extensions/back/ProposalMutation.py +++ b/model-optimizer/extensions/back/ProposalMutation.py @@ -30,7 +30,6 @@ from mo.ops.strided_slice import StridedSlice class ProposalMutation(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def run_before(self): return [ReshapeMutation, StridedSliceMasksNormalizer] diff --git a/model-optimizer/extensions/back/ReadValueAssignToMemory.py b/model-optimizer/extensions/back/ReadValueAssignToMemory.py deleted file mode 100644 index 3f33e44e2c8..00000000000 --- a/model-optimizer/extensions/back/ReadValueAssignToMemory.py +++ /dev/null @@ -1,140 +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. -""" -from extensions.back.CutMemory import CutMemoryInput, CutMemoryOutput -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph -from mo.ops.memory import Memory - - -""" - All transformations in this file should be removed after removing IR v7 support -""" - - -class ReplaceReadValueByMemory(BackReplacementPattern): - """ - Replace ReadValue by Memory. Should be removed after v7 IR support removing. - """ - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [CutMemoryInput] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('op', dict(kind='op', op='ReadValue'))], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['op'] - node_id = node['variable_id'] - - node.in_port(0).disconnect() - new_in = Memory(graph, {'name': node.id, 'id': node_id, 'index': 1, 'size': 2, - 'shape': list(node.out_port(0).data.get_shape())[1:]}).create_node() - for dest in node.out_port(0).get_destinations(): - dest.disconnect() - new_in.out_port(0).connect(dest) - - -class ReplaceAssignByMemory(BackReplacementPattern): - """ - Replace Assign by Memory. Should be removed after v7 IR support removing. - """ - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [CutMemoryOutput] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('op', dict(kind='op', op='Assign'))], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['op'] - node_id = node['variable_id'] - - new_out = Memory(graph, {'name': node.id, 'id': node_id, 'index': 0, 'size': 2, - 'shape': list(node.out_port(0).data.get_shape())[1:]}).create_node() - node.in_port(0).get_source().connect(new_out.in_port(0)) - node.in_port(0).disconnect() - node.out_port(0).get_connection().set_source(new_out.out_port(0)) - - -class KaldiRemoveMemoryOutputBackReplacementPatternV7(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - from extensions.back.pass_separator import BackFinish - return [BackFinish] - - def run_before(self): - from extensions.back.SpecialNodesFinalization import RemoveOutputOps - return [RemoveOutputOps] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('memory_node', dict(op='Memory')), - ('data_node', dict(kind='data')), - ('op_output', dict(op='Result')) - ], - edges=[ - ('memory_node', 'data_node'), - ('data_node', 'op_output') - ] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - """ - Need to find the pattern: Memory -> Data -> Result - - It is needed to make Memory nodes appear in IR, - but they are output nodes by default and we remove the Result node after each output memory. - - DO NOT use graph clean up after it - otherwise Memory nodes would be removed as they are not on the path from input to output - - Parameters - ---------- - graph : Graph - Graph with loaded model. - match : dict - Patterns which were found in graph structure. - """ - memory = match['memory_node'] - data = match['data_node'] - op_output = match['op_output'] - - graph.remove_edge(memory.id, data.id) - graph.remove_node(data.id) - graph.remove_node(op_output.id) diff --git a/model-optimizer/extensions/back/ReduceToPooling.py b/model-optimizer/extensions/back/ReduceToPooling.py index 46c9459280a..a670a1f1b4c 100644 --- a/model-optimizer/extensions/back/ReduceToPooling.py +++ b/model-optimizer/extensions/back/ReduceToPooling.py @@ -18,19 +18,12 @@ import logging as log import numpy as np -from extensions.back.AvgPool import AvgPool -from extensions.back.MaxPool import MaxPool from extensions.back.ScalarConstNormalize import ScalarNormalize from extensions.ops.ReduceOps import reduce_map from mo.back.replacement import BackReplacementPattern -from mo.front.caffe.extractors.utils import get_canonical_axis_index from mo.front.common.partial_infer.utils import int64_array from mo.graph.graph import Graph from mo.ops.concat import Concat -from mo.ops.const import Const -from mo.ops.pooling import Pooling -from mo.ops.power import AttributedPower -from mo.ops.reshape import Reshape class ReduceMerge(BackReplacementPattern): @@ -44,7 +37,7 @@ class ReduceMerge(BackReplacementPattern): force_clean_up = True def run_before(self): - return [ReduceReplacer, ScalarNormalize] + return [ScalarNormalize] @staticmethod def fuse_reduces(first_reduce, second_reduce): @@ -101,158 +94,3 @@ class ReduceMerge(BackReplacementPattern): first_reduce_node = second_reduce_node.in_port(0).get_source().node if first_reduce_node.soft_get('type', None) == reduce_type: ReduceMerge.fuse_reduces(first_reduce=first_reduce_node, second_reduce=second_reduce_node) - - -class ReduceReplacer(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - force_clean_up = True - - pool_method_map = { - 'ReduceMax': 'max', - 'ReduceMean': 'avg', - 'ReduceSum': 'avg', - } - - supported_reduce_types = pool_method_map.keys() - - def run_before(self): - from extensions.back.ReshapeMutation import ReshapeMutation - return [ReshapeMutation, MaxPool, AvgPool, ScalarNormalize] - - def pattern(self): - return dict( - nodes=[ - ('reduce', dict(kind='op', type=lambda node_type: node_type in self.supported_reduce_types)) - ], - edges=[] - ) - - @staticmethod - def initial_reshape_dim_normalizer(number_of_elements: np.int64): - """ - decomposes `number_of_elements` into the product of two numbers with minimum distance - """ - new_window = [1, number_of_elements] - for divisor in range(2, int(np.sqrt(number_of_elements)) + 1): - if number_of_elements % divisor == 0: - quotient = number_of_elements / divisor - if abs(quotient - divisor) < abs(new_window[0] - new_window[1]): - new_window = [int(quotient), int(divisor)] - - assert np.prod(new_window) == number_of_elements - return sorted(new_window) - - def replace_pattern(self, graph: Graph, match: dict): - node = match['reduce'] - - if node.out_port(0).data.get_value() is not None: - # We leave Reduce* operations located in constant sub-graph as is - # to keep model reshapable with --keep_shape_ops cli key - return - - reduce_type = node.type - if reduce_type not in self.pool_method_map: - log.error("Reduce type {} is not included in pool_method_map. Please update pool_method_map with new key " - "{}".format(reduce_type, reduce_type)) - return - - input_data = node.in_node() - output_data = node.out_node() - - input_shape = node.in_port(0).data.get_shape() - output_shape = node.out_port(0).data.get_shape() - - # normalize node axes to exclude negative indices - axes_data_value = node.in_port(1).data.get_value() - axes = int64_array([axes_data_value.item()]) if axes_data_value.size == 1 else axes_data_value - axes = [get_canonical_axis_index(input_shape, a) for a in axes] - axes = sorted(axes) - - # Check that values in axes list are consecutive - for idx in range(1, len(axes)): - if axes[idx] != (axes[idx - 1] + 1): - log.error("Reduce with not consecutive axes {} is not supported ".format(axes)) - return - # So now we are sure that we can convert Reduce to appropriate operation - - # 1. Calculate shape that will be used in reduction - reduction_dim = np.prod([input_shape[idx] for idx in axes]) - begin_dims = np.array([input_shape[idx] for idx in range(axes[0])]) - end_dim = np.prod([input_shape[idx] for idx in range(axes[-1] + 1, len(input_shape))]) - - # 2. Create reshape with appropriate shape - if len(begin_dims) > 2: - if 0 not in axes: - begin_dims = int64_array([begin_dims[0], np.prod(begin_dims[1:])]) - else: - begin_dims = int64_array([np.prod(begin_dims[0:-1]), begin_dims[-1]]) - else: - # Expand begin_dims to 2 - begin_dims = int64_array(np.append(begin_dims, [1] * (2 - len(begin_dims)))) - - reshape_shape = int64_array([*begin_dims, reduction_dim, end_dim]) - pool_window = int64_array([1, 1, reduction_dim, 1]) - - if end_dim == 1: - new_window = ReduceReplacer.initial_reshape_dim_normalizer(reduction_dim) - reshape_shape = int64_array([*begin_dims, *new_window]) - pool_window = int64_array([1, 1, *new_window]) - - # 3. Reduce => Reshape->Pooling->Reshape - reshape_op = Reshape(graph, {'name': node.id + '/Reshape'}) - reshape_dim_const_data = Const(graph, {'name': node.id + '/Reshape/Dim', - 'value': reshape_shape}).create_node_with_data() - - final_reshape_op = Reshape(graph, {'name': node.id + '/FinalReshape'}) - final_reshape_dim_const_data = Const(graph, {'name': node.id + '/FinalReshape/Dim', - 'value': output_shape}).create_node_with_data() - pooling_op = Pooling(graph, - dict(name=node.id + '/Pool', - window=pool_window, - output_spatial_shape=None, - batch_dims=int64_array([0]), - channel_dims=int64_array([1]), - exclude_pad='false', pool_method=self.pool_method_map[reduce_type])) - - graph.remove_edge(input_data.id, node.id) - graph.remove_edge(node.id, output_data.id) - - if np.array_equal(input_shape, reshape_shape): - input_to_pooling = input_data - else: - input_to_pooling = reshape_op.create_node_with_data(inputs=[input_data, reshape_dim_const_data]) - pooling = pooling_op.create_node_with_data(inputs=[input_to_pooling]) - final_reshape_op.create_node_with_data(inputs=[pooling, final_reshape_dim_const_data], data_nodes=output_data) - - # convert batch dimension to 0 to produce reshape-able IR over the batch dimension - if 0 not in axes: - reshape_dim_const_data.in_node(0).value[0] = 0 - final_reshape_dim_const_data.in_node(0).value[0] = 0 - - # 4. If it is reduction with summation, we need to multiply by size of the reduction slice with Mul op - if reduce_type == 'ReduceSum': - output_data.in_node().insert_node_with_data_after( - output_data, - AttributedPower, - {'name': node.name + '/Mul', 'scale': float(reduction_dim)} - ) - - -class ReduceLogicalReplacer(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def pattern(self): - return dict( - nodes=[ - ('reduce', dict(kind='op', type=lambda node_type: node_type is not None and - node_type.startswith('ReduceLogical'))) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: dict): - node = match['reduce'] - node.type = node.type.replace('Logical', '') diff --git a/model-optimizer/extensions/back/ReduceToPooling_test.py b/model-optimizer/extensions/back/ReduceToPooling_test.py deleted file mode 100644 index 57c233b717d..00000000000 --- a/model-optimizer/extensions/back/ReduceToPooling_test.py +++ /dev/null @@ -1,489 +0,0 @@ -""" - 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 unittest - -import numpy as np -from generator import generator, generate - -from extensions.back.ReduceToPooling import ReduceReplacer, ReduceMerge -from mo.front.common.partial_infer.utils import int64_array -from mo.middle.passes.eliminate import shape_inference -from mo.middle.passes.eliminate_test import build_graph -from mo.utils.ir_engine.compare_graphs import compare_graphs - -# The dictionary with nodes attributes used to build various graphs. A key is the name of the node and the value is the -# dictionary with node attributes. -nodes_attributes = { - # Placeholder layers - 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - - # Reduce layers - 'const': {'type': 'Const', 'value': None, 'kind': 'op'}, - 'const_data': {'kind': 'data', 'value': None, 'shape': None}, - 'reduce_1': {'type': 'Reduce', 'kind': 'op', 'op': 'Reduce'}, - 'reduce_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'const_2': {'type': 'Const', 'value': None, 'kind': 'op'}, - 'const_2_data': {'kind': 'data', 'value': None, 'shape': None}, - 'reduce_2': {'type': 'Reduce', 'kind': 'op', 'op': 'Reduce'}, - 'reduce_2_data': {'value': None, 'shape': None, 'kind': 'data'}, - - # Reshape layers - 'reshape_1': {'type': 'Reshape', 'kind': 'op', 'op': 'Reshape'}, - 'reshape_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'reshape_1_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': None}, - 'reshape_1_const_data': {'kind': 'data', 'value': None, 'shape': None}, - - 'reshape_2': {'type': 'Reshape', 'kind': 'op', 'op': 'Reshape'}, - 'reshape_2_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'reshape_2_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': None}, - 'reshape_2_const_data': {'kind': 'data', 'value': None, 'shape': None}, - - # Pooling - 'pooling': {'type': 'Pooling', 'kind': 'op', 'op': 'Pooling'}, - 'pooling_data': {'value': None, 'shape': None, 'kind': 'data'}, - - # Power - 'power': {'type': 'Power', 'kind': 'op', 'op': 'AttributedPower'}, - 'power_data': {'value': None, 'shape': None, 'kind': 'data'}, - - # Concat - 'concat': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'}, - - # Result - 'result': {'type': 'Result', 'kind': 'op', 'op': 'Result'}, -} - - -class ReduceReplacerTest(unittest.TestCase): - def test1(self): - # Original graph - # data(1,64,1)-->Reduce(axis=1,keep_dims=True)-->data(1,1,1) - # - # Reference graph - # data(1,64,1)->Reshape(1,1,8,8)->Pool(1,1,1,1)->Reshape(1,1,1) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'concat'), - ], - {'placeholder_1_data': {'shape': int64_array([1, 64, 1])}, - 'reduce_1': {'keep_dims': True, 'type': 'ReduceMean'}, - 'const_data': {'value': int64_array([1])}, - 'reduce_1_data': {'shape': int64_array([1, 1, 1])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reshape_1'), - ('reshape_1_const', 'reshape_1_const_data'), - ('reshape_1_const_data', 'reshape_1'), - ('reshape_1', 'reshape_1_data'), - ('reshape_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'concat'), - ], - {'placeholder_1_data': {'shape': int64_array([1, 64, 1])}, - 'reshape_1_const': {'value': int64_array([0, 1, 8, 8]), 'shape': int64_array([4])}, - 'reshape_1_const_data': {'value': int64_array([0, 1, 8, 8]), - 'shape': int64_array([4])}, - 'reshape_1_data': {'shape': int64_array([1, 1, 8, 8])}, - 'pooling': {'window': int64_array([1, 1, 8, 8])}, - 'pooling_data': {'shape': int64_array([1, 1, 1, 1])}, - 'reshape_2_const': {'value': int64_array([0, 1, 1]), 'shape': int64_array([3])}, - 'reshape_2_const_data': {'value': int64_array([0, 1, 1]), 'shape': int64_array([3])}, - 'reshape_2_data': {'shape': int64_array([1, 1, 1])}, - }, nodes_with_edges_only=True) - - ReduceReplacer().find_and_replace_pattern(graph) - shape_inference(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test2(self): - # Original graph - # data(1,3,64,64)-->Reduce(axis=2,keep_dims=True)-->data(1,3,1,64) - # - # Reference graph - # data(1,3,64,64)->Pool(1,3,1,64)->Reshape(1,3,1,64) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 3, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([1, 3, 64, 64])}, - 'reduce_1': {'keep_dims': True, 'type': 'ReduceMean'}, - 'const_data': {'value': int64_array([2])}, - 'reduce_1_data': {'shape': int64_array([1, 3, 1, 64])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 3, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([1, 3, 64, 64])}, - 'pooling': {'window': int64_array([1, 1, 64, 1])}, - 'pooling_data': {'shape': int64_array([1, 3, 1, 64])}, - 'reshape_2_const': {'value': int64_array([0, 3, 1, 64]), 'shape': int64_array([4])}, - 'reshape_2_const_data': {'value': int64_array([0, 3, 1, 64]), - 'shape': int64_array([4])}, - 'reshape_2_data': {'shape': int64_array([1, 3, 1, 64])}, - }, nodes_with_edges_only=True) - - ReduceReplacer().find_and_replace_pattern(graph) - shape_inference(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test3(self): - # Original graph - # data(1,3,64,64)-->Reduce(axis=[2,3],keep_dims=True)-->data(1,3,1,1) - # - # Reference graph - # data(1,3,64,64)->Pool(1,3,1,1)->Reshape(1,3,1,1) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 3, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([1, 3, 64, 64])}, - 'reduce_1': {'keep_dims': True, 'type': 'ReduceMean'}, - 'const_data': {'value': int64_array([2, 3])}, - 'reduce_1_data': {'shape': int64_array([1, 3, 1, 1])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 3, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([1, 3, 64, 64])}, - 'pooling': {'window': int64_array([1, 1, 64, 64])}, - 'pooling_data': {'shape': int64_array([1, 3, 1, 1])}, - 'reshape_2_const': {'value': int64_array([0, 3, 1, 1]), 'shape': int64_array([4])}, - 'reshape_2_const_data': {'value': int64_array([0, 3, 1, 1]), - 'shape': int64_array([4])}, - 'reshape_2_data': {'shape': int64_array([1, 3, 1, 1])}, - }, nodes_with_edges_only=True) - - ReduceReplacer().find_and_replace_pattern(graph) - shape_inference(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test4(self): - # Original graph - # data(2,3,64,64)-->Reduce(axis=[1,2,3],keep_dims=False)-->data(2) - # - # Reference graph - # data(2,3,64,64)->Reshape(2,1,96,128)->Pool(2,1,1,1)->Reshape(2) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([2, 3, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([2, 3, 64, 64])}, - 'reduce_1': {'keep_dims': False, 'type': 'ReduceMean'}, - 'const_data': {'value': int64_array([1, 2, 3])}, - 'reduce_1_data': {'shape': int64_array([2])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reshape_1'), - ('reshape_1_const', 'reshape_1_const_data'), - ('reshape_1_const_data', 'reshape_1'), - ('reshape_1', 'reshape_1_data'), - ('reshape_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([2, 3, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([2, 3, 64, 64])}, - 'reshape_1_const': {'value': int64_array([0, 1, 96, 128]), - 'shape': int64_array([4])}, - 'reshape_1_const_data': {'value': int64_array([0, 1, 96, 128]), - 'shape': int64_array([4])}, - 'reshape_1_data': {'shape': int64_array([2, 1, 96, 128])}, - 'pooling': {'window': int64_array([1, 1, 96, 128])}, - 'pooling_data': {'shape': int64_array([2, 1, 1, 1])}, - 'reshape_2_const': {'value': int64_array([0]), 'shape': int64_array([1])}, - 'reshape_2_const_data': {'value': int64_array([0]), 'shape': int64_array([1])}, - 'reshape_2_data': {'shape': int64_array([2])}, - }, nodes_with_edges_only=True) - - ReduceReplacer().find_and_replace_pattern(graph) - shape_inference(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test5(self): - # Original graph - # data(1, 16, 64, 64, 64, 4)-->Reduce(axis=[5],keep_dims=False)-->data(1, 16, 64, 64, 64) - # - # Reference graph - # data(1, 16, 64, 64, 64, 4)->Reshape(1*16*64*64, 64, 2, 2)->Pool(1, 1, 2, 2)->Reshape(1, 16, 64, 64, 64) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 16, 64, 64, 64, 4])}, - 'placeholder_1_data': {'shape': int64_array([1, 16, 64, 64, 64, 4])}, - 'reduce_1': {'keep_dims': False, 'type': 'ReduceMax'}, - 'const_data': {'value': int64_array([5])}, - 'reduce_1_data': {'shape': int64_array([1, 16, 64, 64, 64])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reshape_1'), - ('reshape_1_const', 'reshape_1_const_data'), - ('reshape_1_const_data', 'reshape_1'), - ('reshape_1', 'reshape_1_data'), - ('reshape_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 16, 64, 64, 64, 4])}, - 'placeholder_1_data': {'shape': int64_array([1, 16, 64, 64, 64, 4])}, - 'reshape_1_const': {'value': int64_array([0, 4194304, 2, 2]), - 'shape': int64_array([4])}, - 'reshape_1_const_data': {'value': int64_array([0, 4194304, 2, 2]), - 'shape': int64_array([4])}, - 'reshape_1_data': {'shape': int64_array([1, 4194304, 2, 2])}, - 'pooling': {'window': int64_array([1, 1, 2, 2])}, - 'pooling_data': {'shape': int64_array([1, 4194304, 1, 1])}, - 'reshape_2_const': {'value': int64_array([0, 16, 64, 64, 64]), - 'shape': int64_array([5])}, - 'reshape_2_const_data': {'value': int64_array([0, 16, 64, 64, 64]), - 'shape': int64_array([5])}, - 'reshape_2_data': {'shape': int64_array([1, 16, 64, 64, 64])}, - }, nodes_with_edges_only=True) - - ReduceReplacer().find_and_replace_pattern(graph) - shape_inference(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test6(self): - # Original graph - # data(1,64,1)-->Reduce(axis=-2,keep_dims=True, reduce_type=Sum)-->data(1,1,1) - # - # Reference graph - # data(1,61,1)->Reshape(1,1,8,8)->Pool(1,1,1,1)->Reshape(1,1,1)->Power(scale=64) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 64, 1])}, - 'placeholder_1_data': {'shape': int64_array([1, 64, 1])}, - 'reduce_1': {'keep_dims': True, 'type': 'ReduceSum'}, - 'const_data': {'value': int64_array([-2])}, - 'reduce_1_data': {'shape': int64_array([1, 1, 1])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reshape_1'), - ('reshape_1_const', 'reshape_1_const_data'), - ('reshape_1_const_data', 'reshape_1'), - ('reshape_1', 'reshape_1_data'), - ('reshape_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'power'), - ('power', 'power_data'), - ('power_data', 'concat'), - ], - {'placeholder_1': {'shape': int64_array([1, 64, 1])}, - 'placeholder_1_data': {'shape': int64_array([1, 64, 1])}, - 'reshape_1_const': {'value': int64_array([0, 1, 8, 8]), 'shape': int64_array([4])}, - 'reshape_1_const_data': {'value': int64_array([0, 1, 8, 8]), - 'shape': int64_array([4])}, - 'reshape_1_data': {'shape': int64_array([1, 1, 8, 8])}, - 'pooling': {'window': int64_array([1, 1, 8, 8])}, - 'pooling_data': {'shape': int64_array([1, 1, 1, 1])}, - 'reshape_2_const': {'value': int64_array([0, 1, 1]), 'shape': int64_array([3])}, - 'reshape_2_const_data': {'value': int64_array([0, 1, 1]), 'shape': int64_array([3])}, - 'reshape_2_data': {'shape': int64_array([1, 1, 1])}, - 'power': {'scale': 64.0}, - 'power_data': {'shape': int64_array([1, 1, 1])}, - }, nodes_with_edges_only=True) - - ReduceReplacer().find_and_replace_pattern(graph) - shape_inference(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test7(self): - # Original graph - # data(1,1,64,64)-->Reduce(axis=-1,keep_dims=True, reduce_type=Mean)-->Reduce(same, axis=-2)-->data(1,1,1,1) - # - # Reference graph - # data(1,61,1)->Reshape(1,1,8,8)->Pool(1,1,1,1)->Reshape(1,1,1)->Power(scale=64) - # - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reduce_1'), - ('const', 'const_data'), - ('const_data', 'reduce_1', {'in': 1}), - ('reduce_1', 'reduce_1_data'), - ('reduce_1_data', 'reduce_2'), - ('const_2', 'const_2_data'), - ('const_2_data', 'reduce_2', {'in': 1}), - ('reduce_2', 'reduce_2_data'), - ('reduce_2_data', 'result'), - ], - {'placeholder_1': {'shape': int64_array([1, 1, 64, 64])}, - 'placeholder_1_data': {'shape': int64_array([1, 1, 64, 64])}, - 'reduce_1': {'keep_dims': True, 'type': 'ReduceMean'}, - 'const_data': {'value': int64_array([-1])}, - 'reduce_1_data': {'shape': int64_array([1, 1, 64, 1])}, - 'reduce_2': {'keep_dims': True, 'type': 'ReduceMean'}, - 'const_2_data': {'value': int64_array([-2])}, - 'reduce_2_data': {'shape': int64_array([1, 1, 1, 1])}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'reshape_1'), - ('reshape_1_const', 'reshape_1_const_data'), - ('reshape_1_const_data', 'reshape_1'), - ('reshape_1', 'reshape_1_data'), - ('reshape_1_data', 'pooling'), - ('pooling', 'pooling_data'), - ('pooling_data', 'reshape_2'), - ('reshape_2_const', 'reshape_2_const_data'), - ('reshape_2_const_data', 'reshape_2'), - ('reshape_2', 'reshape_2_data'), - ('reshape_2_data', 'result'), - ], - {'placeholder_1': {'shape': int64_array([1, 1, 64, 64])}, - 'reshape_1_const': {'value': int64_array([0, 1, 8, 8]), 'shape': int64_array([4])}, - 'reshape_1_const_data': {'value': int64_array([0, 1, 8, 8]), - 'shape': int64_array([4])}, - 'reshape_1_data': {'shape': int64_array([1, 1, 8, 8])}, - 'pooling': {'window': int64_array([1, 1, 8, 8])}, - 'pooling_data': {'shape': int64_array([1, 1, 1, 1])}, - 'reshape_2_const': {'value': int64_array([0, 1, 1, 1]), 'shape': int64_array([4])}, - 'reshape_2_const_data': {'value': int64_array([0, 1, 1, 1]), - 'shape': int64_array([4])}, - 'reshape_2_data': {'shape': int64_array([1, 1, 1, 1])}, - }, nodes_with_edges_only=True) - - ReduceMerge().find_and_replace_pattern(graph) - ReduceReplacer().find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) - self.assertTrue(flag, resp) - - -@generator -class DimNormalizer(unittest.TestCase): - @generate(*[ - (1, [1, 1]), - (2, [1, 2]), - (3, [1, 3]), - (4, [2, 2]), - (5, [1, 5]), - (9, [3, 3]), - (19, [1, 19]), - (1000, [25, 40]), - (1000003, [1, 1000003]), - (1005973, [997, 1009]), - ]) - def test_initial_reshape_dim_normalizer(self, number, expected_output): - window = ReduceReplacer.initial_reshape_dim_normalizer(number) - self.assertIsNotNone(window, "window is None for i={}".format(number)) - self.assertEqual(number, np.prod(window), "{} != prod({})".format(number, window)) - self.assertEqual(expected_output, window, "{} != {}".format(expected_output, window)) diff --git a/model-optimizer/extensions/back/ReduceTransposeDimensions.py b/model-optimizer/extensions/back/ReduceTransposeDimensions.py index f69c0e35472..16ceed18a29 100644 --- a/model-optimizer/extensions/back/ReduceTransposeDimensions.py +++ b/model-optimizer/extensions/back/ReduceTransposeDimensions.py @@ -102,8 +102,7 @@ class ReduceTransposeDimensions(BackReplacementPattern): def run_before(self): from extensions.back.ReshapeMutation import ReshapeMutation - from extensions.back.TransposeToPermute import TransposeToPermute - return [ReshapeMutation, TransposeToPermute] + return [ReshapeMutation] @staticmethod def pattern(): diff --git a/model-optimizer/extensions/back/Reshape0DToSqueeze.py b/model-optimizer/extensions/back/Reshape0DToSqueeze.py index bf988658b3b..3bfb93e700f 100644 --- a/model-optimizer/extensions/back/Reshape0DToSqueeze.py +++ b/model-optimizer/extensions/back/Reshape0DToSqueeze.py @@ -18,7 +18,6 @@ import logging as log import numpy as np from extensions.back.ForceStrictPrecision import ForceStrictPrecision -from extensions.back.ReduceToPooling import ReduceReplacer from mo.back.replacement import BackReplacementPattern from mo.front.common.partial_infer.utils import int64_array from mo.front.tf.graph_utils import create_op_node_with_second_input @@ -35,9 +34,6 @@ class Reshape0DToSqueeze(BackReplacementPattern): run_not_recursively = True force_shape_inference = True - def run_after(self): - return [ReduceReplacer] - def run_before(self): return [ForceStrictPrecision] diff --git a/model-optimizer/extensions/back/ReshapeMutation.py b/model-optimizer/extensions/back/ReshapeMutation.py index efe1950ee08..685cccd11ff 100644 --- a/model-optimizer/extensions/back/ReshapeMutation.py +++ b/model-optimizer/extensions/back/ReshapeMutation.py @@ -15,8 +15,7 @@ """ from extensions.back.ForceStrictPrecision import ForceStrictPrecision from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph, Node -from mo.middle.pattern_match import for_each_sub_graph_recursively +from mo.graph.graph import Graph class ReshapeMutation(BackReplacementPattern): @@ -39,47 +38,4 @@ class ReshapeMutation(BackReplacementPattern): reshape = match['reshape'] if reshape.soft_get('type') == 'Reshape': - if graph.graph['cmd_params'].generate_experimental_IR_V10: - reshape['force_precision_in_ports'] = {1: 'int64'} - else: - reshape['force_precision_in_ports'] = {1: 'int32'} - - -class DisableReshapeMutationInTensorIterator(BackReplacementPattern): - enabled = True - force_clean_up = True - run_not_recursively = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - return [ReshapeMutation] - - @staticmethod - def add_supported_attrs_to_node(node: Node, params: list): - node.graph.node[node.id].update({ - 'IE': [( - 'layer', - [('id', lambda node: node.node), 'name', 'precision', 'type', 'version'], - [ - ('data', params, []), - '@ports', - '@consts'])] - }) - - def reshapes_with_two_inputs_to_reshape_with_dim(self, graph: Graph): - reshapes = graph.get_op_nodes(op='Reshape') - - for reshape in reshapes: - in_nodes = reshape.in_nodes() - - assert len(in_nodes) == 2 - reshape['dim'] = reshape.in_port(1).data.get_value() - - reshape.in_port(1).disconnect() - - params = [('dim', lambda node: ','.join(map(str, node['dim'])))] - self.add_supported_attrs_to_node(reshape, params) - - def find_and_replace_pattern(self, graph: Graph): - for_each_sub_graph_recursively(graph, self.reshapes_with_two_inputs_to_reshape_with_dim) + reshape['force_precision_in_ports'] = {1: 'int64'} diff --git a/model-optimizer/extensions/back/ReverseInputChannels.py b/model-optimizer/extensions/back/ReverseInputChannels.py index 317daeca992..d5036460bb3 100644 --- a/model-optimizer/extensions/back/ReverseInputChannels.py +++ b/model-optimizer/extensions/back/ReverseInputChannels.py @@ -17,7 +17,6 @@ import logging as log import numpy as np -from extensions.back.split_normalizer import SplitNormalizer from extensions.ops.gather import Gather from extensions.ops.split import Split from mo.back.replacement import BackReplacementPattern @@ -408,9 +407,8 @@ class ApplyReverseChannels(BackReplacementPattern): force_clean_up = True def run_before(self): - from extensions.back.ParameterToPlaceholder import ParameterToInput from extensions.back.GroupedConvWeightsNormalize import GroupedConvWeightsNormalize - return [ParameterToInput, GroupedConvWeightsNormalize, SplitNormalizer] + return [GroupedConvWeightsNormalize] def find_and_replace_pattern(self, graph: Graph): """ diff --git a/model-optimizer/extensions/back/ScalarConstNormalize.py b/model-optimizer/extensions/back/ScalarConstNormalize.py index 1fb9e6bf8bd..2193e49428c 100644 --- a/model-optimizer/extensions/back/ScalarConstNormalize.py +++ b/model-optimizer/extensions/back/ScalarConstNormalize.py @@ -14,9 +14,6 @@ limitations under the License. """ -import logging as log - -from extensions.back.ElementwiseOpsToEltwiseOps import SimpleEltwiseToEltwiseOp from extensions.back.ReshapeMutation import ReshapeMutation from mo.back.replacement import BackReplacementPattern from mo.front.common.partial_infer.utils import int64_array @@ -26,11 +23,8 @@ from mo.ops.reshape import Reshape # Temporary nGraph workaround. TODO: REMOVE - - class ScalarNormalize(BackReplacementPattern): enabled = False - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] force_clean_up = True def run_before(self): @@ -53,73 +47,3 @@ class ScalarNormalize(BackReplacementPattern): node.out_port(0).get_connection().set_source(reshape.out_port(0)) node.out_port(0).connect(reshape.in_port(0)) reshape.infer(reshape) - - -class ScalarNormalizeForSpecificOps(BackReplacementPattern): - """ - Transformation performs safe replacement of the 0D constants with 1D for a specific operations. This transformation - allows to avoid problems with the fact that not all layers correctly handle 0D tensors during the constant folding. - """ - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_before(self): - return [ReshapeMutation] - - def run_after(self): - return [SimpleEltwiseToEltwiseOp] - - def find_and_replace_pattern(self, graph: Graph): - graph.strict_mode = False - # key is the type of the operation. The value is list of ports to convert from 0D to 1D - rules = {'Broadcast': [0], - 'Unsqueeze': [1], - 'Squeeze': [1], - 'Eltwise': [1], - 'Range': [0, 1, 2], - 'FakeQuantize': [1, 2, 3, 4] - } - for node in graph.get_op_nodes(): - if node.has_and_set('type') and node.type in rules: - for port in rules[node.type]: - if port in node.in_ports() and not node.in_port(port).disconnected(): - src_node = node.in_port(port).get_connection().get_source().node - if src_node is not None and src_node.has_and_set('type') and src_node.type == 'Const' and \ - src_node.value.ndim == 0: - log.info('Converting constant node "{}" from 0D to 1D'.format(src_node.soft_get('name'))) - reshape = create_op_node_with_second_input(graph, Reshape, int64_array([1]), - {'name': src_node.id + '/Dims'}) - src_node.out_port(0).get_connection().set_source(reshape.out_port(0)) - src_node.out_port(0).connect(reshape.in_port(0)) - reshape.infer(reshape) - graph.strict_mode = True - - -class RangeInputNormalize(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [ScalarNormalizeForSpecificOps] - - def find_and_replace_pattern(self, graph: Graph): - graph.strict_mode = False - - rules = { - 'Range': [0, 1, 2], - } - - for node in graph.get_op_nodes(): - if node.soft_get('type') in rules: - for port in rules[node.type]: - if port in node.in_ports() and not node.in_port(port).disconnected(): - src_node = node.in_port(port).get_connection().get_source().node - reshape = create_op_node_with_second_input( - graph, Reshape, int64_array([1]), - {'name': src_node.id + '/1D', 'override_output_shape': True}) - src_node.out_port(0).get_connection().set_source(reshape.out_port(0)) - src_node.out_port(0).connect(reshape.in_port(0)) - - graph.strict_mode = True diff --git a/model-optimizer/extensions/back/ShapeOfToShape.py b/model-optimizer/extensions/back/ShapeOfToShape.py deleted file mode 100644 index d03f958c3ca..00000000000 --- a/model-optimizer/extensions/back/ShapeOfToShape.py +++ /dev/null @@ -1,36 +0,0 @@ -""" - 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. -""" - -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph - - -class ShapeOfToShape(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - @staticmethod - def pattern(): - return dict( - nodes=[('shape', {'kind': 'op', 'type': 'ShapeOf'})], - edges=[], - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - match['shape']['type'] = 'Shape' - diff --git a/model-optimizer/extensions/back/ShuffleChannelPatternOptimization.py b/model-optimizer/extensions/back/ShuffleChannelPatternOptimization.py index 9818acf96ce..03b1050ae1f 100644 --- a/model-optimizer/extensions/back/ShuffleChannelPatternOptimization.py +++ b/model-optimizer/extensions/back/ShuffleChannelPatternOptimization.py @@ -16,7 +16,6 @@ import numpy as np from extensions.back.FuseTransposesSequence import FuseTransposesSequence -from extensions.back.TransposeToPermute import TransposeToPermute from mo.back.replacement import BackReplacementPattern from mo.front.common.partial_infer.utils import int64_array from mo.graph.graph import Graph @@ -29,9 +28,6 @@ class ShuffleChannelPatternOptimization(BackReplacementPattern): def run_after(self): return [FuseTransposesSequence] - def run_before(self): - return [TransposeToPermute] - @staticmethod def pattern(): return dict( diff --git a/model-optimizer/extensions/back/ShufflenetReLUReorder.py b/model-optimizer/extensions/back/ShufflenetReLUReorder.py index bbc42e94b0a..76e3fa08cf8 100644 --- a/model-optimizer/extensions/back/ShufflenetReLUReorder.py +++ b/model-optimizer/extensions/back/ShufflenetReLUReorder.py @@ -26,10 +26,6 @@ class ShufflenetReLUReorder(BackReplacementPattern): """ enabled = False - def run_before(self): - from extensions.back.TransposeToPermute import TransposeToPermute - return [TransposeToPermute] - def pattern(self): return dict( nodes=[ diff --git a/model-optimizer/extensions/back/SpecialNodesFinalization.py b/model-optimizer/extensions/back/SpecialNodesFinalization.py index 020ef5f2886..333c503521a 100644 --- a/model-optimizer/extensions/back/SpecialNodesFinalization.py +++ b/model-optimizer/extensions/back/SpecialNodesFinalization.py @@ -114,22 +114,6 @@ class CreateConstNodesReplacement(BackReplacementPattern): ) -class RemoveOutputOps(BackReplacementPattern): - enabled = False - - def run_after(self): - return [CreateConstNodesReplacement] - - def run_before(self): - return [] - - def find_and_replace_pattern(self, graph: Graph): - for node in list(graph.get_op_nodes(op='Result')): - if len(node.in_nodes()) > 0: - assert (len(node.in_nodes()) == 1) - graph.remove_node(node.id) - - class RemoveConstToResult(BackReplacementPattern): """ Transformation looks for a sub-graph "Const->Result" and removes Result node. @@ -169,9 +153,7 @@ class RemoveConstToResult(BackReplacementPattern): class NormalizeTI(BackReplacementPattern): """ - This transformation is used while generating IR of lower than 10 version - - Changes linking mechanism of TensorIterator outer graph with inner graph + Transformation changes linking mechanism of TensorIterator outer graph with inner graph from linking outer graph node ports with inner Parameter and Result operations to linking outer graph node ports with functional operations and their input/output ports @@ -192,69 +174,6 @@ class NormalizeTI(BackReplacementPattern): ti.output_port_map = [dict(unique_r) for unique_r in set([tuple(rec.items()) for rec in ti.output_port_map])] ti.back_edges = [dict(unique_rec) for unique_rec in set([tuple(rec.items()) for rec in ti.back_edges])] - @staticmethod - def normalize_ti(ti): - assert ti.has_valid('input_port_map') - assert ti.has_valid('output_port_map') - assert ti.has_valid('back_edges') - - body = ti.body - - for record in ti.input_port_map: - assert 'internal_layer_id' in record - assert 'internal_port_id' not in record - assert 'external_port_id' in record - internal_layer_id = copy(record['internal_layer_id']) - parameter = get_internal_node_by_layer_id(ti, internal_layer_id) - - dst = parameter.out_port(0).get_destination() - in_port_idx = dst.idx - internal_node = dst.node - internal_port_id = internal_node.in_edge(in_port_idx)['internal_port_id'] - - record['internal_layer_id'] = internal_node.internal_layer_id - record['internal_port_id'] = internal_port_id - TensorIterator.update_back_edge_map(ti=ti, direction='to', old_layer_id=internal_layer_id, old_port_id=None, - new_layer_id=internal_node.internal_layer_id, - new_port_id=internal_port_id) - - for record in ti.output_port_map: - assert 'internal_layer_id' in record - assert 'internal_port_id' not in record - assert 'external_port_id' in record - internal_layer_id = copy(record['internal_layer_id']) - result = get_internal_node_by_layer_id(ti, internal_layer_id) - - out_port_idx = result.in_port(0).get_source().idx - internal_node = result.in_port(0).get_source().node - internal_port_id = internal_node.out_edge(out_port_idx)['internal_port_id'] - - record['internal_layer_id'] = internal_node.internal_layer_id - record['internal_port_id'] = internal_port_id - TensorIterator.update_back_edge_map(ti=ti, direction='from', old_layer_id=internal_layer_id, - old_port_id=None, new_layer_id=internal_node.internal_layer_id, - new_port_id=internal_port_id) - - for record in ti.back_edges: - assert 'from_layer' in record - assert 'to_layer' in record - - internal_layer_id = record['from_layer'] - result = get_internal_node_by_layer_id(ti, internal_layer_id) - - if result.soft_get('type') == 'Result': - assert 'from_port' not in record - - out_port_idx = result.in_port(0).get_source().idx - internal_node = result.in_port(0).get_source().node - internal_port_id = internal_node.out_edge(out_port_idx)['internal_port_id'] - - TensorIterator.update_back_edge_map(ti=ti, direction='from', old_layer_id=internal_layer_id, - old_port_id=None, new_layer_id=internal_node.internal_layer_id, - new_port_id=internal_port_id) - - body.remove_nodes_from([n.id for n in body.get_op_nodes(type='Input')]) - body.remove_nodes_from([n.id for n in body.get_op_nodes(type='Parameter')]) @staticmethod def external_nodes_normalization(ti): @@ -334,10 +253,7 @@ class NormalizeTI(BackReplacementPattern): def find_and_replace_pattern(self, graph: Graph): for ti in graph.get_op_nodes(type='TensorIterator'): - if not graph.graph['cmd_params'].generate_experimental_IR_V10: - self.normalize_ti(ti) - else: - self.external_nodes_normalization(ti) + self.external_nodes_normalization(ti) if len([record for record in ti.input_port_map if record.get('axis') is not None]) == 0: for record in ti.output_port_map: diff --git a/model-optimizer/extensions/back/StridedSliceMasksNormalizer.py b/model-optimizer/extensions/back/StridedSliceMasksNormalizer.py index 0c63a78f79f..f34d4fe78e1 100644 --- a/model-optimizer/extensions/back/StridedSliceMasksNormalizer.py +++ b/model-optimizer/extensions/back/StridedSliceMasksNormalizer.py @@ -25,8 +25,6 @@ class StridedSliceMasksNormalizer(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - def run_after(self): return [CropToStridedSlice, DeconvolutionNormalizer] diff --git a/model-optimizer/extensions/back/TileNormalizer.py b/model-optimizer/extensions/back/TileNormalizer.py deleted file mode 100644 index 869dcddf10c..00000000000 --- a/model-optimizer/extensions/back/TileNormalizer.py +++ /dev/null @@ -1,244 +0,0 @@ -""" - 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.back.ReshapeMutation import ReshapeMutation -from mo.back.replacement import BackReplacementPattern -from mo.front.common.partial_infer.utils import int64_array -from mo.front.tf.graph_utils import create_op_node_with_second_input -from mo.graph.graph import Graph -from mo.ops.concat import Concat -from mo.ops.const import Const -from mo.ops.squeeze import Squeeze -from mo.ops.tile import Tile, AttributedTile -from mo.ops.unsqueeze import Unsqueeze -from mo.utils.shape import new_shape_node_from_shape_nodes - - -class TileInputAlignment(BackReplacementPattern): - """ - Aligns rank of data input and length of repeats input of Tile operation - """ - enabled = True - force_clean_up = True - force_shape_inference = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def pattern(self): - return dict( - nodes=[ - ('tile', dict(kind='op', op='Tile')) - ], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['tile'] - name = node.soft_get('name', node.id) - - input_shape = node.in_port(0).data.get_shape() - assert input_shape is not None - tiles = node.in_port(1).data.get_value() - assert tiles is not None, "Undefined `repeats` (1st port input value) of Tile node '{}'".format(name) - - if input_shape.size == tiles.size: - return - - if input_shape.size < tiles.size: - unsqueeze = create_op_node_with_second_input(graph, Unsqueeze, - int64_array(list(range(tiles.size - input_shape.size))), - {'name': name + '/input_alignment', - 'override_output_shape': True}) - node.in_port(0).get_source().connect(unsqueeze.in_port(0)) - node.in_port(0).get_connection().set_source(unsqueeze.out_port(0)) - else: - const = Const(graph, {'name': name + '/tile_alignment_const', - 'value': np.ones([input_shape.size - tiles.size], dtype=np.int64)}).create_node() - concat = Concat(graph, {'axis': 0, 'override_output_shape': True}).create_node() - concat.add_input_port(0) - concat.add_input_port(1) - - node.in_port(1).get_source().connect(concat.in_port(1)) - node.in_port(1).disconnect() - concat.in_port(0).connect(const.out_port(0)) - - node.in_port(1).connect(concat.out_port(0)) - - -class Tile3DReshaper(BackReplacementPattern): - enabled = True - force_clean_up = True - - def run_before(self): - return [ReshapeMutation, TileVersionDowngrader] - - def run_after(self): - return [TileInputAlignment] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('tile', dict(type='Tile')) - ], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - """ - Workarounds not supported type of Tile in Inference Engine (Tiles are supported for 2-D or 4-D tensors): - Searches for Tiles with 3D shapes and covers it with Reshapes. - - Example: Tile (axis=1, tiles=16): - in_shape: [1,1,101] - out_shape: [1,16,101] - - Old behaviour: - Tile -> [1,16,101] - New behaviour: - Reshape [1,1,101,1] -> Tile -> [1,16,101,1] -> Reshape [1,16,101] - """ - node = match['tile'] - name = node.soft_get('name', node.id) - - out_shape = node.out_port(0).data.get_shape() - assert out_shape is not None, 'Output shape is undefined for {} in back phase'.format(name) - if out_shape.size != 3: - return - - inp_shape = node.in_port(0).data.get_shape() - assert inp_shape is not None, 'Input shape is undefined for {} in back phase'.format(name) - - unsqueeze_dim = Const(graph, {'name': name + '/3D_Tile_Unsqueeze_dim', 'value': int64_array([3])}).create_node() - unsqueeze = Unsqueeze(graph, {'name': name + '/3D_Tile_Unsqueeze', 'override_output_shape': True}).create_node() - unsqueeze_dim.out_port(0).connect(unsqueeze.in_port(1)) - - const = Const(graph, {'name': name + '/additional_axis', 'value': int64_array([1])}).create_node() - new_tiles = new_shape_node_from_shape_nodes([node.in_port(1).get_source().node, const]) - - node.in_port(1).get_connection().set_source(new_tiles.out_port(0)) - - squeeze_dim = Const(graph, {'name': name + '/3D_Tile_Squeeze_dim', 'value': int64_array([3])}).create_node() - squeeze = Squeeze(graph, {'name': name + '/3D_Tile_Squeeze', 'override_output_shape': True}).create_node() - squeeze_dim.out_port(0).connect(squeeze.in_port(1)) - - source = node.in_port(0).get_source() - node.in_port(0).get_connection().set_source(unsqueeze.out_port(0)) - unsqueeze.in_port(0).connect(source) - - node.out_port(0).get_connection().set_source(squeeze.out_port(0)) - node.out_port(0).connect(squeeze.in_port(0)) - - node['override_output_shape'] = True - new_tiles['override_output_shape'] = True - node['need_shape_inference'] = True - - -class TileMultipleAxisReplacer(BackReplacementPattern): - """ - This class convert Tile operation with miltiple != 1 tile dimensions by sequence of Tiles. - """ - enabled = True - force_clean_up = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - return [TileInputAlignment] - - def pattern(self): - return dict( - nodes=[ - ('tile', dict(kind='op', op='Tile')) - ], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - tile = match['tile'] - name = tile.soft_get('name', tile.id) - - tile_array = tile.in_port(1).data.get_value() - assert tile_array is not None, "Undefined `repeats` (1st port input value) of Tile node '{}'".format(name) - assert len(tile_array) == len(tile.in_port(0).data.get_shape()) - - non_one_tile = np.argwhere(tile_array != 1).flatten() - if len(non_one_tile) == 1: - # We need to add new tiles only in case when we tile more than one dimension - return - - if len(non_one_tile) == 0: - # Deleting such Tile that does nothing - tile.out_port(0).get_connection().set_source(tile.in_port(0).get_connection().get_source()) - return - - last_tile = None - for i in non_one_tile: - tiles = int64_array(np.ones(tile_array.size)) - tiles[i] = tile_array[i] - new_tile = create_op_node_with_second_input(graph, Tile, tiles, {'name': name + '/Tile_{}/'.format(i)}) - - if not last_tile: - last_tile = new_tile - tile.in_port(0).get_connection().set_destination(new_tile.in_port(0)) - else: - last_tile.out_port(0).connect(new_tile.in_port(0)) - last_tile = new_tile - - # Reconnect output to new tile node and delete old tile - tile.out_port(0).get_connection().set_source(last_tile.out_port(0)) - - -class TileVersionDowngrader(BackReplacementPattern): - enabled = True - force_clean_up = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - return [TileMultipleAxisReplacer] - - def pattern(self): - return dict( - nodes=[ - ('tile', dict(kind='op', op='Tile')) - ], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - tile = match['tile'] - name = tile.soft_get('name', tile.id) - - tile_array = tile.in_port(1).data.get_value() - assert tile_array is not None, "Undefined `repeats` (1st port input value) of Tile node '{}'".format(name) - - non_one_tile = np.argwhere(tile_array != 1).flatten() - assert len(non_one_tile) == 1 - - axis = non_one_tile[0] - tiles = tile_array[axis] - - new_tile = AttributedTile(graph, {'name': name, 'axis': axis, 'tiles': tiles}).create_node() - - tile.out_port(0).get_connection().set_source(new_tile.out_port(0)) - tile.in_port(0).get_connection().get_source().connect(new_tile.in_port(0)) diff --git a/model-optimizer/extensions/back/TileNormalizer_test.py b/model-optimizer/extensions/back/TileNormalizer_test.py deleted file mode 100644 index bb005134b01..00000000000 --- a/model-optimizer/extensions/back/TileNormalizer_test.py +++ /dev/null @@ -1,182 +0,0 @@ -""" - 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 unittest - -import numpy as np - -from extensions.back.TileNormalizer import TileMultipleAxisReplacer, Tile3DReshaper -from mo.front.common.partial_infer.utils import int64_array -from mo.ops.tile import Tile -from mo.utils.ir_engine.compare_graphs import compare_graphs -from mo.utils.unittest.graph import build_graph - - -class TileMultipleAxisReplacerTest(unittest.TestCase): - nodes = { - 'input_op': {'kind': 'op'}, - 'input_op_data': {'kind': 'data', 'shape': np.array([1, 1, 5]), 'value': None}, - - 'const': {'kind': 'op'}, - 'const_data': {'kind': 'data', 'value': None}, - - 'tile': {'op': 'Tile', 'kind': 'op'}, - 'tile_data': {'kind': 'data', 'shape': np.array([3, 4, 5]), 'value': None}, - - 'next_op': {'kind': 'op', 'op': 'Result'}, - 'next_op_data': {'kind': 'data', 'shape': np.array([3, 4, 5]), 'value': None}, - } - edges = [('input_op', 'input_op_data'), - ('input_op_data', 'tile', {'in': 0}), - ('tile', 'tile_data'), - ('tile_data', 'next_op'), - ('next_op', 'next_op_data'), - - ('const', 'const_data'), - ('const_data', 'tile', {'in': 1}) - ] - - nodes_result = { - 'input_op': {'kind': 'op'}, - 'input_op_data': {'kind': 'data', 'shape': np.array([1, 1, 5]), 'value': None}, - - 'const': {'kind': 'op'}, - 'const_data': {'kind': 'data'}, - - 'tile_1': {'op': 'Tile', 'kind': 'op'}, - 'tile_1_data': {'kind': 'data', 'shape': np.array([3, 1, 5]), 'value': None}, - - 'const_1': {'kind': 'op'}, - 'const_1_data': {'kind': 'data'}, - - 'tile_2': {'op': 'Tile', 'kind': 'op'}, - 'tile_2_data': {'kind': 'data', 'shape': np.array([3, 4, 5]), 'value': None}, - - 'next_op': {'kind': 'op', 'op': 'Result'}, - } - edges_result = [ - ('input_op', 'input_op_data'), - ('input_op_data', 'tile_1'), - ('tile_1', 'tile_1_data'), - ('tile_1_data', 'tile_2'), - ('tile_2', 'tile_2_data'), - ('tile_2_data', 'next_op'), - - ('const', 'const_data'), - ('const_data', 'tile_1'), - - ('const_1', 'const_1_data'), - ('const_1_data', 'tile_2'), - ] - - # Test for case when we don't need to add new Tiles - def test_simple_tile(self): - graph = build_graph(nodes_attrs=self.nodes, edges=self.edges, - update_attributes={'const_data': {'value': np.array([3, 1, 1])}, - 'input_op_data': {'shape': np.array([1, 4, 5])}}) - pattern = TileMultipleAxisReplacer() - pattern.find_and_replace_pattern(graph) - - graph_ref = build_graph(nodes_attrs=self.nodes, edges=self.edges, - update_attributes={'const_data': {'value': np.array([3, 1, 1])}, - 'input_op_data': {'shape': np.array([1, 4, 5])}}) - - (flag, resp) = compare_graphs(graph, graph_ref, 'next_op', check_op_attrs=True) - self.assertTrue(flag, resp) - - # Test for case when we tile 2 dimensions - def test_need_to_tile_case(self): - graph = build_graph(nodes_attrs=self.nodes, edges=self.edges, - update_attributes={'const_data': {'value': np.array([3, 4, 1])}}) - pattern = TileMultipleAxisReplacer() - pattern.find_and_replace_pattern(graph) - - graph_ref = build_graph(nodes_attrs=self.nodes_result, edges=self.edges_result) - - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'next_op', check_op_attrs=True) - self.assertTrue(flag, resp) - - -nodes_attributes = { - 'prev_op': {'kind': 'op', 'op': 'SomeOp'}, - 'previous_data': {'shape': np.array([1, 1, 101]), 'value': None, 'kind': 'data'}, - - 'const': {'kind': 'op'}, - 'const_data': {'kind': 'data', 'value': np.array([1, 16, 1]), 'shape': np.array([3])}, - - 'tile': {'type': 'Tile', 'kind': 'op', 'infer': Tile.infer}, - 'tile_data': {'shape': np.array([1, 16, 101]), 'value': None, 'kind': 'data'}, - 'next_op': {'kind': 'op', 'op': 'Result'}, -} -edge_attributes = [ - ('prev_op', 'previous_data'), - ('previous_data', 'tile', {'in': 0}), - ('tile', 'tile_data'), - ('tile_data', 'next_op'), - - ('const', 'const_data'), - ('const_data', 'tile', {'in': 1}), -] - -nodes_attributes_ref = { - 'prev_op': {'kind': 'op', 'op': 'SomeOp'}, - 'previous_data': {'kind': 'data', 'shape': np.array([1, 1, 101])}, - 'reshape_op_before': {'type': 'Unsqueeze', 'kind': 'op'}, - 'reshape_op_before_const': {'kind': 'op', 'type': 'Const', 'op': 'Const', 'value': int64_array([3]), 'shape': [1]}, - 'reshape_op_before_const_data': {'kind': 'data', 'value': int64_array([3]), 'shape': [1]}, - 'reshape_data_before': {'kind': 'data', 'shape': np.array([1, 1, 101, 1])}, - - 'const': {'kind': 'op'}, - 'const_data': {'kind': 'data', 'value': np.array([1, 16, 1, 1]), 'shape': np.array([4])}, - - 'tile': {'type': 'Tile', 'kind': 'op', 'infer': Tile.infer}, - 'tile_data': {'shape': np.array([1, 16, 101, 1]), 'kind': 'data'}, - 'reshape_op_after': {'type': 'Squeeze', 'kind': 'op'}, - 'reshape_op_after_const': {'kind': 'op', 'type': 'Const', 'op': 'Const', 'value': int64_array([3]), 'shape': [1]}, - 'reshape_op_after_const_data': {'kind': 'data', 'value': int64_array([3]), 'shape': [1]}, - 'reshape_data_after': {'kind': 'data', 'shape': np.array([1, 16, 101])}, - 'next_op': {'kind': 'op', 'op': 'Result'}, -} -edge_attributes_ref = [ - ('prev_op', 'previous_data'), - ('previous_data', 'reshape_op_before'), - ('reshape_op_before_const', 'reshape_op_before_const_data'), - ('reshape_op_before_const_data', 'reshape_op_before'), - ('reshape_op_before', 'reshape_data_before'), - ('reshape_data_before', 'tile'), - ('tile', 'tile_data'), - ('tile_data', 'reshape_op_after'), - ('reshape_op_after_const', 'reshape_op_after_const_data'), - ('reshape_op_after_const_data', 'reshape_op_after'), - ('reshape_op_after', 'reshape_data_after'), - ('reshape_data_after', 'next_op'), - - ('const', 'const_data'), - ('const_data', 'tile', {'in': 1}), -] - - -class TileReshaperTests(unittest.TestCase): - def test_tile_reshaper(self): - graph = build_graph(nodes_attributes, edge_attributes) - - graph_ref = build_graph(nodes_attributes_ref, edge_attributes_ref) - - Tile3DReshaper().find_and_replace_pattern(graph) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'next_op', check_op_attrs=True) - self.assertTrue(flag, resp) diff --git a/model-optimizer/extensions/back/TopKNormalizer.py b/model-optimizer/extensions/back/TopKNormalizer.py index 257aaa68a2c..e590f4f2821 100644 --- a/model-optimizer/extensions/back/TopKNormalizer.py +++ b/model-optimizer/extensions/back/TopKNormalizer.py @@ -52,10 +52,8 @@ class TopKNormalizer(BackReplacementPattern): @staticmethod def replace_pattern(graph: Graph, match: dict): node = match['result'] - is_scalar = graph.graph['cmd_params'].generate_experimental_IR_V10 - reshape = create_op_node_with_second_input(graph, Reshape, int64_array([]) if is_scalar else int64_array([1]), - {'override_output_shape': True}) + reshape = create_op_node_with_second_input(graph, Reshape, int64_array([]), {'override_output_shape': True}) node.in_port(1).get_connection().insert_node(reshape) TopKNormalizer.normalize_outputs(node) diff --git a/model-optimizer/extensions/back/TransposeToPermute.py b/model-optimizer/extensions/back/TransposeToPermute.py deleted file mode 100644 index e4dce835737..00000000000 --- a/model-optimizer/extensions/back/TransposeToPermute.py +++ /dev/null @@ -1,46 +0,0 @@ -""" - 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. -""" -from extensions.back.OptimizeTransposeReshapeSequence import OptimizeTransposeReshapeSequence -from mo.back.replacement import BackReplacementPattern -from mo.graph.graph import Graph -from mo.ops.permute import Permute - - -class TransposeToPermute(BackReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - force_clean_up = True - - def run_after(self): - return [OptimizeTransposeReshapeSequence] - - @staticmethod - def pattern(): - return dict( - nodes=[ - ('transpose', dict(type='Transpose')) - ], - edges=[] - ) - - @staticmethod - def replace_pattern(graph: Graph, match: dict): - node = match['transpose'] - order = node.in_port(1).data.get_value() - assert order is not None - Permute.update_node_stat(node=node, attrs={'order': order.copy()}) - node['force_precision_in_ports'] = None - node.in_port(1).disconnect() diff --git a/model-optimizer/extensions/back/blob_normalizer.py b/model-optimizer/extensions/back/blob_normalizer.py index 6542bfafe2b..fc23124e3f9 100644 --- a/model-optimizer/extensions/back/blob_normalizer.py +++ b/model-optimizer/extensions/back/blob_normalizer.py @@ -35,11 +35,6 @@ class BlobNormalizer(BackReplacementPattern): """ enabled = True - graph_condition = [ - lambda graph: graph.graph['cmd_params'].blobs_as_inputs or - graph.graph['cmd_params'].generate_experimental_IR_V10 - ] - def run_before(self): return [] @@ -61,19 +56,16 @@ class BlobNormalizer(BackReplacementPattern): del conv.in_edges()[i]['bin'] def find_and_replace_pattern(self, graph: Graph): - if graph.graph['cmd_params'].generate_experimental_IR_V10: - for node in graph.get_op_nodes(): - if node.soft_get('type').lower() not in OpVersioning.opset_1_types and \ - not node.soft_get('version') in ["opset2", "opset3"]: - continue + for node in graph.get_op_nodes(): + if node.soft_get('type').lower() not in OpVersioning.opset_1_types and \ + not node.soft_get('version') in ["opset2", "opset3", "opset4"]: + continue - for _, d in node.in_edges().items(): - if 'bin' in d: - del d['bin'] - for node in graph.get_data_nodes(): - for d in node.in_edges(): - if 'bin' in d: - del d['bin'] - else: - if len(graph.get_op_nodes(type='FakeQuantize')): - BackReplacementPattern.find_and_replace_pattern(self, graph) + for _, d in node.in_edges().items(): + if 'bin' in d: + del d['bin'] + + for node in graph.get_data_nodes(): + for d in node.in_edges(): + if 'bin' in d: + del d['bin'] diff --git a/model-optimizer/extensions/back/compress_quantized_weights.py b/model-optimizer/extensions/back/compress_quantized_weights.py index cd2257d49b9..2bd2e40433c 100644 --- a/model-optimizer/extensions/back/compress_quantized_weights.py +++ b/model-optimizer/extensions/back/compress_quantized_weights.py @@ -97,8 +97,7 @@ class CompressQuantizeWeights(BackReplacementPattern): nodes=[ ('weights_const', dict(type='Const')), ('weights_d', dict(kind='data')), - ('quantize', dict(type='FakeQuantize', keep_in_IR=True, levels=lambda x: x is not None and - 2 < x <= 256)), + ('quantize', dict(type='FakeQuantize', levels=lambda x: x is not None and 2 < x <= 256)), ('quantize_d', dict(kind='data')), ('convolution', dict()) ], diff --git a/model-optimizer/extensions/back/compress_quantized_weights_test.py b/model-optimizer/extensions/back/compress_quantized_weights_test.py index d0dd1944ff6..eda2e77966e 100644 --- a/model-optimizer/extensions/back/compress_quantized_weights_test.py +++ b/model-optimizer/extensions/back/compress_quantized_weights_test.py @@ -37,12 +37,12 @@ nodes_attributes = { 'weights_data': {'kind': 'data'}, # quantize - 'quantize1': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 5, 'keep_in_IR': True}, - 'quantize2': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 2, 'keep_in_IR': True}, - 'quantize3': {'type': 'FakeQuantize', 'kind': 'op', 'levels': None, 'keep_in_IR': True}, - 'quantize4': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 122, 'keep_in_IR': True}, - 'quantize5': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 202, 'keep_in_IR': True}, - 'quantize6': {'type': 'FakeQuantize', 'kind': 'op', 'levels': 257, 'keep_in_IR': True}, + '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}, 'quantize_data': {'kind': 'data'}, 'new_quantize1': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 5}, 'new_quantize4': {'kind': 'op', 'type': 'FakeQuantize', 'levels': 122}, @@ -107,11 +107,9 @@ nodes_attributes = { 'ac_output_high': {'kind': 'op', 'type': 'Const', 'shape': None, 'value': None, 'infer': Const.infer}, 'ac_output_high_data': {'kind': 'data', 'value': None, 'shape': None}, - 'ac_fakeQuantize': {'kind': 'op', 'type': 'FakeQuantize', 'levels': None, 'keep_in_IR': True, - 'infer': FakeQuantize.infer}, + 'ac_fakeQuantize': {'kind': 'op', 'type': 'FakeQuantize', 'levels': None, 'infer': FakeQuantize.infer}, 'ac_fakeQuantize_data': {'kind': 'data', 'shape': None, 'value': None}, - 'ac_quantize': {'kind': 'op', 'type': 'fakeQuantize', 'levels': None, 'keep_in_IR': True, - 'infer': FakeQuantize.infer}, + 'ac_quantize': {'kind': 'op', 'type': 'fakeQuantize', 'levels': None, 'infer': FakeQuantize.infer}, 'ac_quantize_data': {'kind': 'data', 'shape': None, 'value': None}, 'ac_convolution': {'kind': 'op', 'type': 'Convolution'}, @@ -145,7 +143,7 @@ class WeightQuantizeTest(unittest.TestCase): ('add', 'quantize_data'), ('quantize_data', 'convolution')], nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -177,7 +175,7 @@ class WeightQuantizeTest(unittest.TestCase): ('quantize_data', 'convolution', {'in': 1})], nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -214,7 +212,7 @@ class WeightQuantizeTest(unittest.TestCase): ('quantize_data', 'convolution', {'in': 1})], nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -251,7 +249,7 @@ class WeightQuantizeTest(unittest.TestCase): ('quantize_data', 'convolution', {'in': 1})], nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -297,7 +295,7 @@ class WeightQuantizeTest(unittest.TestCase): 'input_high': {'shape': np.array([1]), 'value': 3}, 'input_high_data': {'value': 3}}, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -355,7 +353,7 @@ class WeightQuantizeTest(unittest.TestCase): 'input_high': {'shape': np.array([1]), 'value': 256.1}, 'input_high_data': {'value': 256.1}}, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -414,7 +412,7 @@ class WeightQuantizeTest(unittest.TestCase): 'input_high': {'shape': np.array([1]), 'value': -0.42}, 'input_high_data': {'value': -0.42}}, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32') graph_ref = build_graph(nodes_attributes, [('weights_const', 'weights_data'), @@ -529,8 +527,8 @@ class WeightQuantizeTest(unittest.TestCase): }, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True, keep_shape_ops=True) - graph_ref.graph['cmd_params'] = Namespace(keep_quantize_ops_in_IR=True, keep_shape_ops=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_shape_ops=True) + graph_ref.graph['cmd_params'] = Namespace(keep_shape_ops=True) graph.clean_up() graph_ref.clean_up() @@ -622,8 +620,8 @@ class WeightQuantizeTest(unittest.TestCase): }, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True, keep_shape_ops=True) - graph_ref.graph['cmd_params'] = Namespace(keep_quantize_ops_in_IR=True, keep_shape_ops=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_shape_ops=True) + graph_ref.graph['cmd_params'] = Namespace(keep_shape_ops=True) graph.clean_up() graph_ref.clean_up() @@ -715,8 +713,8 @@ class WeightQuantizeTest(unittest.TestCase): }, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True, keep_shape_ops=True) - graph_ref.graph['cmd_params'] = Namespace(keep_quantize_ops_in_IR=True, keep_shape_ops=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_shape_ops=True) + graph_ref.graph['cmd_params'] = Namespace(keep_shape_ops=True) graph.clean_up() graph_ref.clean_up() @@ -806,8 +804,8 @@ class WeightQuantizeTest(unittest.TestCase): }, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_quantize_ops_in_IR=True, keep_shape_ops=True) - graph_ref.graph['cmd_params'] = Namespace(keep_quantize_ops_in_IR=True, keep_shape_ops=True) + graph.graph['cmd_params'] = Namespace(data_type='FP32', keep_shape_ops=True) + graph_ref.graph['cmd_params'] = Namespace(keep_shape_ops=True) graph.clean_up() graph_ref.clean_up() diff --git a/model-optimizer/extensions/back/fuse_sub_div_min.py b/model-optimizer/extensions/back/fuse_sub_div_min.py index 2064d5a7634..647e262914d 100644 --- a/model-optimizer/extensions/back/fuse_sub_div_min.py +++ b/model-optimizer/extensions/back/fuse_sub_div_min.py @@ -24,8 +24,6 @@ class Negate(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - @staticmethod def pattern(): return dict( @@ -58,7 +56,6 @@ class Negate(BackReplacementPattern): class EltwisesToSubtract(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def run_after(self): return [Negate] @@ -98,7 +95,6 @@ class EltwisesToSubtract(BackReplacementPattern): class EltwisesToDiv(BackReplacementPattern): enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] @staticmethod def pattern(): diff --git a/model-optimizer/extensions/back/kaldi_remove_memory_output.py b/model-optimizer/extensions/back/kaldi_remove_memory_output.py index 0f9b4853888..b3e275ddc38 100644 --- a/model-optimizer/extensions/back/kaldi_remove_memory_output.py +++ b/model-optimizer/extensions/back/kaldi_remove_memory_output.py @@ -26,8 +26,8 @@ class KaldiRemoveMemoryOutputBackReplacementPattern(BackReplacementPattern): return [BackFinish] def run_before(self): - from extensions.back.SpecialNodesFinalization import RemoveOutputOps - return [RemoveOutputOps] + from extensions.back.SpecialNodesFinalization import CreateConstNodesReplacement + return [CreateConstNodesReplacement] @staticmethod def pattern(): diff --git a/model-optimizer/extensions/back/priorbox_mutation.py b/model-optimizer/extensions/back/priorbox_mutation.py index 75bda5fdba8..2babdea916e 100644 --- a/model-optimizer/extensions/back/priorbox_mutation.py +++ b/model-optimizer/extensions/back/priorbox_mutation.py @@ -28,7 +28,6 @@ from mo.ops.unsqueeze import Unsqueeze class PriorboxMutation(BackReplacementPattern): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] force_shape_inference = True def run_before(self): diff --git a/model-optimizer/extensions/back/split_normalizer.py b/model-optimizer/extensions/back/split_normalizer.py deleted file mode 100644 index 5c2b1a2fcc7..00000000000 --- a/model-optimizer/extensions/back/split_normalizer.py +++ /dev/null @@ -1,121 +0,0 @@ -""" - 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.ops.split import AttributedSplit -from mo.back.replacement import BackReplacementPattern -from mo.front.common.partial_infer.utils import int64_array -from mo.graph.graph import Graph - - -class SplitNormalizer(BackReplacementPattern): - enabled = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def find_and_replace_pattern(self, graph: Graph): - for node in graph.get_op_nodes(op='Split'): - name = node.soft_get('name', node.id) - - input_shape = node.in_port(0).data.get_shape() - assert input_shape is not None - axis = node.in_port(1).data.get_value() - assert axis is not None - num_splits = node.soft_get('num_splits', None) - assert num_splits is not None - - if axis < 0: - axis += input_shape.size - - split = AttributedSplit(graph, {'name': name, 'axis': axis, 'num_splits': num_splits}).create_node() - - for idx, port in node.out_ports().items(): - node.out_port(idx).get_connection().set_source(split.out_port(idx)) - - node.in_port(0).get_connection().set_destination(split.in_port(0)) - graph.remove_node(node.id) - - -class VariadicSplitNormalizer(BackReplacementPattern): - enabled = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def find_and_replace_pattern(self, graph: Graph): - for node in graph.get_op_nodes(op='VariadicSplit'): - name = node.soft_get('name', node.id) - - input_shape = node.in_port(0).data.get_shape() - assert input_shape is not None - - axis = node.in_port(1).data.get_value() - assert axis is not None - - size_splits = node.in_port(2).data.get_value() - assert size_splits is not None - - connected_outputs = {idx: port for idx, port in node.out_ports().items() if not port.disconnected()} - assert len(size_splits) >= len(connected_outputs) - - split_size = connected_outputs[list(connected_outputs.keys())[0]].data.get_shape()[axis] - if np.unique(size_splits).size != 1: - return - # all split sizes are equal - - assert input_shape[axis] % split_size == 0 - - num_splits = int64_array(input_shape[axis] / split_size) - assert num_splits is not None - - if axis < 0: - axis += input_shape.size - - split = AttributedSplit(graph, {'name': name, 'axis': axis, 'num_splits': num_splits}).create_node() - - for idx, port in node.out_ports().items(): - node.out_port(idx).get_connection().set_source(split.out_port(idx)) - - node.in_port(0).get_connection().set_destination(split.in_port(0)) - graph.remove_node(node.id) - - -class PassVariadicSplitAsIs(BackReplacementPattern): - enabled = True - force_clean_up = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - return [VariadicSplitNormalizer] - - def find_and_replace_pattern(self, graph: Graph): - for node in graph.get_op_nodes(op='VariadicSplit'): - input_shape = node.in_port(0).data.get_shape() - assert input_shape is not None - - axis = node.in_port(1).data.get_value() - assert axis is not None - node.in_port(1).disconnect() - - size_splits = node.in_port(2).data.get_value() - assert size_splits is not None - node.in_port(2).disconnect() - - if axis < 0: - axis += input_shape.size - - node['type'] = 'Split' - node['axis'] = axis diff --git a/model-optimizer/extensions/front/GeLUMerger_Erf.py b/model-optimizer/extensions/front/GeLUMerger_Erf.py index a212402439a..62dee898584 100644 --- a/model-optimizer/extensions/front/GeLUMerger_Erf.py +++ b/model-optimizer/extensions/front/GeLUMerger_Erf.py @@ -25,7 +25,6 @@ from mo.graph.graph import Graph class GeLUMergerErf(FrontReplacementSubgraph): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): log.info('Enabled GeLU Merger replacement for approximation with Erf') diff --git a/model-optimizer/extensions/front/GeLUMerger_Tanh.py b/model-optimizer/extensions/front/GeLUMerger_Tanh.py index 22ced0a619b..923cf362332 100644 --- a/model-optimizer/extensions/front/GeLUMerger_Tanh.py +++ b/model-optimizer/extensions/front/GeLUMerger_Tanh.py @@ -25,7 +25,6 @@ from mo.graph.graph import Graph class GeLUMergerTanh(FrontReplacementSubgraph): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): log.info('Enabled GeLU Merger for approximation with TanH') diff --git a/model-optimizer/extensions/front/LRNReplacer.py b/model-optimizer/extensions/front/LRNReplacer.py deleted file mode 100644 index 46d7dbb1e72..00000000000 --- a/model-optimizer/extensions/front/LRNReplacer.py +++ /dev/null @@ -1,51 +0,0 @@ -""" - Copyright (C) 2017-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.ops.elementwise import Mul -from mo.front.common.replacement import FrontReplacementOp -from mo.graph.graph import Graph -from mo.ops.const import Const - - -class LRNReplacer(FrontReplacementOp): - op = 'AttributedLRN' - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def replace_sub_graph(self, graph: Graph, match: dict): - node = match['op'] - - if not node.has_valid('bias') or (node.has_valid('bias') and node.bias == 1): - return - - # Calculate scale value & create Const op - scale_value = np.array(1. / (pow(node.bias, node.beta))) - node.alpha /= node.bias - const_node = Const(graph, {'value': scale_value, 'shape': scale_value.shape, - 'name': node.name + "/Const_Mul_"}).create_node() - - # Create Mul node - mul_node = Mul(graph, {'name': node.name + "/Mul_"}).create_node() - - # Connect nodes - const_node.out_port(0).connect(mul_node.in_port(1)) - node.out_port(0).get_connection().set_source(mul_node.out_port(0)) - node.out_port(0).connect(mul_node.in_port(0)) - - # Delete bias, if it is not deleted it will appear in IR v6 - del node['bias'] diff --git a/model-optimizer/extensions/front/LRNReplacer_test.py b/model-optimizer/extensions/front/LRNReplacer_test.py deleted file mode 100644 index 605618485c5..00000000000 --- a/model-optimizer/extensions/front/LRNReplacer_test.py +++ /dev/null @@ -1,111 +0,0 @@ -""" - 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 unittest - -import numpy as np - -from extensions.front.LRNReplacer import LRNReplacer -from mo.utils.ir_engine.compare_graphs import compare_graphs -from mo.utils.unittest.graph import build_graph - -nodes_attributes = { - 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - # LRN operation - 'LRN': {'type': None, 'kind': 'op', 'op': 'AttributedLRN'}, - # Test operation - 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None}, - # Mul operation - 'mul_1': {'type': None, 'value': None, 'kind': 'op', 'op': 'Mul'}, - 'const_mul_1_w': {'type': None, 'value': None, 'kind': 'op', 'op': 'Const'}, -} - - -class LRNReplacerTest(unittest.TestCase): - def test_LRNreplacer_test_1(self): - # Test with Mul operation - alpha = 0.0002 - beta = 0.5 - bias = 2.0 - nsize = 3 - - graph = build_graph(nodes_attributes, - [('placeholder_1', 'LRN'), - ('LRN', 'last'), - ], - {'placeholder_1': {'shape': np.array([1, 227, 227, 3])}, - 'LRN': {'alpha': np.array(alpha), 'beta': np.array(beta), - 'bias': np.array(bias), 'size': np.array(nsize)}, - }, nodes_with_edges_only=True) - - alpha /= bias - scale_value = np.array(1. / (pow(bias, beta))) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'LRN'), - ('LRN', 'mul_1'), - ('const_mul_1_w', 'mul_1'), - ('mul_1', 'last') - ], - {'placeholder_1': {'shape': np.array([1, 227, 227, 3])}, - 'LRN': {'alpha': np.array(alpha), 'beta': np.array(beta), - 'size': np.array(nsize)}, - 'const_mul_1_w': {'shape': scale_value.shape, - 'value': scale_value}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - graph.stage = 'front' - - replacer = LRNReplacer() - replacer.find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test_LRNreplacer_test_2(self): - # Test without Mul operation - alpha = 0.0002 - beta = 0.5 - bias = 1 - nsize = 3 - - graph = build_graph(nodes_attributes, - [('placeholder_1', 'LRN'), - ('LRN', 'last'), - ], - {'placeholder_1': {'shape': np.array([1, 227, 227, 3])}, - 'LRN': {'alpha': np.array(alpha), 'beta': np.array(beta), - 'bias': np.array(bias), 'size': np.array(nsize)}, - }, nodes_with_edges_only=True) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'LRN'), - ('LRN', 'last') - ], - {'placeholder_1': {'shape': np.array([1, 227, 227, 3])}, - 'LRN': {'alpha': np.array(alpha), 'beta': np.array(beta), - 'bias': np.array(bias), 'size': np.array(nsize)}, - }, nodes_with_edges_only=True) - - graph.graph['layout'] = 'NCHW' - graph.stage = 'front' - - replacer = LRNReplacer() - replacer.find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True) - self.assertTrue(flag, resp) diff --git a/model-optimizer/extensions/front/MatMul_normalizer.py b/model-optimizer/extensions/front/MatMul_normalizer.py index 3509f5a9930..1baddac0d58 100644 --- a/model-optimizer/extensions/front/MatMul_normalizer.py +++ b/model-optimizer/extensions/front/MatMul_normalizer.py @@ -48,10 +48,9 @@ class FullyConnectedDecomposer(FrontReplacementSubgraph): # biases normalization if 2 in node.in_ports() and not node.in_port(2).disconnected(): bias_node = Add(graph, {'name': name + '/Bias_'}).create_node() - if not graph.graph['cmd_params'].generate_deprecated_IR_V7: - node_name = node.name + '/WithoutBiases' - bias_node_name = node.name - rename_nodes([(node, node_name), (bias_node, bias_node_name)]) + node_name = node.name + '/WithoutBiases' + bias_node_name = node.name + rename_nodes([(node, node_name), (bias_node, bias_node_name)]) node.out_port(0).get_connection().set_source(bias_node.out_port(0)) node.in_port(2).get_connection().set_destination(bias_node.in_port(1)) node.out_port(0).connect(bias_node.in_port(0)) @@ -97,10 +96,9 @@ class GemmDecomposer(FrontReplacementSubgraph): # biases normalization bias_node = Add(graph, {'name': name + '/Bias_', 'can_be_scaleshift': False}).create_node() - if not graph.graph['cmd_params'].generate_deprecated_IR_V7: - node_name = node.name + '/WithoutBiases' - bias_node_name = node.name - rename_nodes([(node, node_name), (bias_node, bias_node_name)]) + node_name = node.name + '/WithoutBiases' + bias_node_name = node.name + rename_nodes([(node, node_name), (bias_node, bias_node_name)]) node.out_port(0).get_connection().set_source(bias_node.out_port(0)) node.in_port(2).get_connection().set_destination(bias_node.in_port(1)) node.out_port(0).connect(bias_node.in_port(0)) diff --git a/model-optimizer/extensions/front/caffe/proposal_ext_test.py b/model-optimizer/extensions/front/caffe/proposal_ext_test.py index 051ea603dd6..e2a15babde5 100644 --- a/model-optimizer/extensions/front/caffe/proposal_ext_test.py +++ b/model-optimizer/extensions/front/caffe/proposal_ext_test.py @@ -55,7 +55,6 @@ class TestProposalExt(unittest.TestCase): fake_pl = FakeProposalProtoLayer(FakeMultiParam(params)) fake_node = FakeNode(fake_pl, None) - fake_node.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=False) ProposalFrontExtractor.extract(fake_node) diff --git a/model-optimizer/extensions/front/caffe/proposal_python_ext_test.py b/model-optimizer/extensions/front/caffe/proposal_python_ext_test.py index 76c829790e9..b6f2f2b7779 100644 --- a/model-optimizer/extensions/front/caffe/proposal_python_ext_test.py +++ b/model-optimizer/extensions/front/caffe/proposal_python_ext_test.py @@ -42,7 +42,6 @@ class TestProposalPythonExt(unittest.TestCase): } fake_pl = FakeProposalPythonProtoLayer(FakeMultiParam(params)) fake_node = FakeNode(fake_pl, None) - fake_node.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=False) ProposalPythonFrontExtractor.extract(fake_node) @@ -68,7 +67,6 @@ class TestProposalPythonExt(unittest.TestCase): } fake_pl = FakeProposalPythonProtoLayer(FakeMultiParam(params)) fake_node = FakeNode(fake_pl, None) - fake_node.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=False) ProposalPythonFrontExtractor.extract(fake_node) @@ -94,7 +92,6 @@ class TestProposalPythonExt(unittest.TestCase): } fake_pl = FakeProposalPythonProtoLayer(FakeMultiParam(params)) fake_node = FakeNode(fake_pl, None) - fake_node.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=False) ProposalPythonFrontExtractor.extract(fake_node) diff --git a/model-optimizer/extensions/front/disable_weights_quantize_value_propagation.py b/model-optimizer/extensions/front/disable_weights_quantize_value_propagation.py index 52d38a4be08..85da9265a77 100644 --- a/model-optimizer/extensions/front/disable_weights_quantize_value_propagation.py +++ b/model-optimizer/extensions/front/disable_weights_quantize_value_propagation.py @@ -20,11 +20,6 @@ from mo.graph.graph import Graph class DisableQuantizeValuePropagation(FrontReplacementPattern): enabled = True - graph_condition = [ - lambda graph: graph.graph['cmd_params'].keep_quantize_ops_in_IR - and graph.graph['cmd_params'].blobs_as_inputs - or graph.graph['cmd_params'].generate_experimental_IR_V10 - ] def run_after(self): return [FakeQuantWithMinMaxVarsToQuantize] diff --git a/model-optimizer/extensions/front/div.py b/model-optimizer/extensions/front/div.py index 78083cdbef2..b31a1d45ed7 100644 --- a/model-optimizer/extensions/front/div.py +++ b/model-optimizer/extensions/front/div.py @@ -23,8 +23,8 @@ from mo.graph.graph import Graph, Node, rename_node class Div(FrontReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] + # This transformation is called directly from the 'model-optimizer/extensions/middle/fusings.py' transformation + enabled = False @staticmethod def div_to_mul_replacement(div: Node): diff --git a/model-optimizer/extensions/front/global_pooling_to_reduce.py b/model-optimizer/extensions/front/global_pooling_to_reduce.py index bb924728177..1887c3daa3c 100644 --- a/model-optimizer/extensions/front/global_pooling_to_reduce.py +++ b/model-optimizer/extensions/front/global_pooling_to_reduce.py @@ -30,8 +30,6 @@ class GlobalPoolingToReduce(FrontReplacementPattern): op = "Pooling" enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] - pool_method_to_reduce_type = { 'max': ReduceMax, 'avg': ReduceMean, diff --git a/model-optimizer/extensions/front/mxnet/deformable_psroi_pooling_ext.py b/model-optimizer/extensions/front/mxnet/deformable_psroi_pooling_ext.py index 41e488ca6be..5ee1e456a1d 100644 --- a/model-optimizer/extensions/front/mxnet/deformable_psroi_pooling_ext.py +++ b/model-optimizer/extensions/front/mxnet/deformable_psroi_pooling_ext.py @@ -49,10 +49,5 @@ class DeformablePSROIPoolingFrontExtractor(FrontExtractorOp): 'pooled_height': pooled_size, } - # update the attributes of the node - if not node.graph.graph['cmd_params'].generate_experimental_IR_V10: - data.update({'no_trans': no_trans}) - PSROIPoolingOp.update_node_stat(node, data) - else: - DeformablePSROIPoolingOp.update_node_stat(node, data) + DeformablePSROIPoolingOp.update_node_stat(node, data) return cls.enabled diff --git a/model-optimizer/extensions/front/mxnet/eltwise_scalar_replacers.py b/model-optimizer/extensions/front/mxnet/eltwise_scalar_replacers.py index d6bab55da6d..d0722d31186 100644 --- a/model-optimizer/extensions/front/mxnet/eltwise_scalar_replacers.py +++ b/model-optimizer/extensions/front/mxnet/eltwise_scalar_replacers.py @@ -24,10 +24,6 @@ class DivScalarFrontReplacer(FrontReplacementOp): op = '_div_scalar' enabled = True - def run_before(self): - from extensions.front.div import Div - return [Div] - def replace_op(self, graph: Graph, node: Node): div_node = scalar_ops_replacer(graph, node, Div) return [div_node.id] @@ -91,10 +87,6 @@ class MinusScalarFrontReplacer(FrontReplacementOp): op = '_minus_scalar' enabled = True - def run_before(self): - from extensions.front.sub import Sub - return [Sub] - def replace_op(self, graph: Graph, node: Node): sub_node = scalar_ops_replacer(graph, node, Sub) return [sub_node.id] diff --git a/model-optimizer/extensions/front/onnx/pad_ext_test.py b/model-optimizer/extensions/front/onnx/pad_ext_test.py index 81710d11c52..f70e0efee06 100644 --- a/model-optimizer/extensions/front/onnx/pad_ext_test.py +++ b/model-optimizer/extensions/front/onnx/pad_ext_test.py @@ -40,7 +40,6 @@ class TestPad(BaseExtractorsTestingClass): outputs=['b'] ) graph = Graph() - graph.graph['cmd_params'] = Namespace(generate_experimental_IR_V10=True) node = PB({'pb': pb, 'graph': graph}) return node diff --git a/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py b/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py index 2d91ffc9288..f57db79f9d4 100644 --- a/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py +++ b/model-optimizer/extensions/front/onnx/quantize_dequantize_linear.py @@ -32,7 +32,6 @@ class QuantizeDequantizeLinear(FrontReplacementSubgraph): Covers cases when the values for zero point and scale are same in both QuantizeLinear and DequantizeLinear. """ enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): return dict( diff --git a/model-optimizer/extensions/front/onnx/quantize_dequantize_linear_test.py b/model-optimizer/extensions/front/onnx/quantize_dequantize_linear_test.py index b36144c8e88..28f1d100e53 100644 --- a/model-optimizer/extensions/front/onnx/quantize_dequantize_linear_test.py +++ b/model-optimizer/extensions/front/onnx/quantize_dequantize_linear_test.py @@ -72,7 +72,7 @@ class TestQuantizeDeQuantize2FakeQuantize(unittest.TestCase): 'scale_param_dq': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)}, 'zerop_param_dq': {'shape': np.array([1]), 'value': np.uint8(0)}, }, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(keep_quantize_ops_in_IR=True, keep_shape_ops=True) + graph.graph['cmd_params'] = Namespace(keep_shape_ops=True) graph_ref = build_graph(nodes_ref_attributes, [('input', 'fq', {'in': 0}), @@ -108,7 +108,7 @@ class TestQuantizeDeQuantize2FakeQuantize(unittest.TestCase): {'scale_param': {'shape': np.array([1]), 'value': np.float32(1.0 / 255)}, 'zerop_param': {'shape': np.array([1]), 'value': np.int8(0)}, }, nodes_with_edges_only=True) - graph.graph['cmd_params'] = Namespace(keep_quantize_ops_in_IR=True, keep_shape_ops=True) + graph.graph['cmd_params'] = Namespace(keep_shape_ops=True) graph_ref = build_graph(nodes_ref_attributes, [('input', 'fq', {'in': 0}), diff --git a/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py b/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py index cf241f52fd3..dec16f70456 100644 --- a/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py +++ b/model-optimizer/extensions/front/onnx/remove_filtering_boxes_by_size.py @@ -14,7 +14,6 @@ limitations under the License. """ from extensions.front.split_normalizer import AttributedVariadicSplitToVariadicSplit -from extensions.front.sub import Sub from extensions.ops.range import Range from mo.front.common.partial_infer.utils import int64_array from mo.front.common.replacement import FrontReplacementSubgraph @@ -43,9 +42,6 @@ class RemoveFilteringBoxesBySize(FrontReplacementSubgraph): enabled = True force_clean_up = True - def run_before(self): - return [Sub] - def run_after(self): return [AttributedVariadicSplitToVariadicSplit] diff --git a/model-optimizer/extensions/front/onnx/resize_to_interpolate.py b/model-optimizer/extensions/front/onnx/resize_to_interpolate.py index 48496104d52..3d7a34d339a 100644 --- a/model-optimizer/extensions/front/onnx/resize_to_interpolate.py +++ b/model-optimizer/extensions/front/onnx/resize_to_interpolate.py @@ -17,7 +17,6 @@ import logging as log import numpy as np -from extensions.front.div import Div from extensions.ops.elementwise import Mul from extensions.ops.interpolate import Interpolate from mo.front.common.partial_infer.utils import int64_array @@ -29,9 +28,6 @@ from mo.ops.const import Const class ResizeToInterpolate2D(FrontReplacementSubgraph): enabled = True - def run_before(self): - return [Div] - def pattern(self): return dict( nodes=[ @@ -105,9 +101,6 @@ class ResizeToInterpolate2D(FrontReplacementSubgraph): class ResizeToInterpolate3D(FrontReplacementSubgraph): enabled = True - def run_before(self): - return [Div] - def pattern(self): return dict( nodes=[ diff --git a/model-optimizer/extensions/front/softmax.py b/model-optimizer/extensions/front/softmax.py index 4183e34f9b0..9b93f0001eb 100644 --- a/model-optimizer/extensions/front/softmax.py +++ b/model-optimizer/extensions/front/softmax.py @@ -17,9 +17,7 @@ import logging as log import numpy as np -from extensions.front.div import Div from extensions.front.reduce_axis_normalizer import ReduceAxisNormalizer -from extensions.front.sub import Sub from mo.front.common.replacement import FrontReplacementSubgraph from mo.front.subgraph_matcher import SubgraphMatch from mo.graph.graph import Graph @@ -33,9 +31,6 @@ class SoftmaxFromKeras(FrontReplacementSubgraph): """ enabled = True - def run_before(self): - return [Sub, Div] - def run_after(self): return [ReduceAxisNormalizer] diff --git a/model-optimizer/extensions/front/squared_difference.py b/model-optimizer/extensions/front/squared_difference.py deleted file mode 100644 index 76112fa93e1..00000000000 --- a/model-optimizer/extensions/front/squared_difference.py +++ /dev/null @@ -1,57 +0,0 @@ -""" - Copyright (C) 2017-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.ops.elementwise import Add, Pow, Mul -from mo.front.common.replacement import FrontReplacementOp -from mo.graph.graph import Node, Graph -from mo.ops.const import Const - - -class SquaredDifference(FrontReplacementOp): - """ - Example class illustrating how to implement replacement of a single op in the front-end of the MO pipeline. - This class replaces a single op "SquaredDifference" by a sub-graph consisting of 3 lower-level ops. - """ - op = "SquaredDifference" - enabled = True - - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def replace_op(self, graph: Graph, node: Node): - # Create nodes - const_neg = Const(graph, dict(value=np.array(-1), name=node.name + '/negate_const_')).create_node() - negate = Mul(graph, {'name': node.name + '/negate_'}).create_node() - add = Add(graph, {'name': node.name + '/add_'}).create_node() - - # convert the power value to an appropriate data type - power_value = np.array(2) - if node.has_valid('data_type'): - power_value = power_value.astype(node.data_type) - - const = Const(graph, {'value': power_value}).create_node() - squared = Pow(graph, {'name': node.name + '/squared_'}).create_node() - - # Connect nodes - node.in_port(0).get_connection().set_destination(add.in_port(0)) - node.in_port(1).get_connection().set_destination(negate.in_port(0)) - const_neg.out_port(0).connect(negate.in_port(1)) - negate.out_port(0).connect(add.in_port(1)) - add.out_port(0).connect(squared.in_port(0)) - const.out_port(0).connect(squared.in_port(1)) - - # The "explicit" version of the return value is: [(out_node.id, 0)]) - return [squared.id] diff --git a/model-optimizer/extensions/front/squared_difference_test.py b/model-optimizer/extensions/front/squared_difference_test.py deleted file mode 100644 index 26d095c041e..00000000000 --- a/model-optimizer/extensions/front/squared_difference_test.py +++ /dev/null @@ -1,65 +0,0 @@ -""" - 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 unittest - -import numpy as np - -from extensions.front.squared_difference import SquaredDifference -from mo.utils.ir_engine.compare_graphs import compare_graphs -from mo.utils.unittest.graph import build_graph - -nodes_attributes = { - 'placeholder_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter', 'shape': np.array([1, 227, 227, 3])}, - 'placeholder_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter', 'shape': np.array([1, 227, 227, 3])}, - # SquaredDifference operation - 'squared_difference': {'type': 'SquaredDifference', 'kind': 'op', 'op': 'SquaredDifference'}, - # Test operation - 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None}, - # Mul and Add operations - 'n_const': {'kind': 'op', 'op': 'Const', 'value': np.array(-1)}, - 'negate_1': {'type': 'Multiply', 'kind': 'op', 'op': 'Mul'}, - 's_const': {'kind': 'op', 'op': 'Const', 'value': np.array(2)}, - 'square_1': {'type': 'Power', 'kind': 'op', 'op': 'Pow'}, - 'add_1': {'value': None, 'operation': None, 'type': 'Add', 'kind': 'op'}, -} - - -class SquaredDifferenceTest(unittest.TestCase): - def test_squared_difference_test_1(self): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'squared_difference'), - ('placeholder_2', 'squared_difference'), - ('squared_difference', 'last'), - ], nodes_with_edges_only=True) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'add_1'), - ('placeholder_2', 'negate_1'), - ('n_const', 'negate_1'), - ('negate_1', 'add_1'), - ('add_1', 'square_1', {'in': 0}), - ('s_const', 'square_1', {'in': 1}), - ('square_1', 'last'), - ], nodes_with_edges_only=True) - - graph.stage = 'front' - - replacer = SquaredDifference() - replacer.find_and_replace_pattern(graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True) - self.assertTrue(flag, resp) diff --git a/model-optimizer/extensions/front/sub.py b/model-optimizer/extensions/front/sub.py index a537222d535..8e1e915e58f 100644 --- a/model-optimizer/extensions/front/sub.py +++ b/model-optimizer/extensions/front/sub.py @@ -23,8 +23,8 @@ from mo.graph.graph import Graph, Node, rename_node class Sub(FrontReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] + # This transformation is called directly from the 'model-optimizer/extensions/middle/fusings.py' transformation + enabled = False @staticmethod def sub_to_add_replacement(sub: Node): diff --git a/model-optimizer/extensions/front/tf/FakeQuantWithMinMaxVars.py b/model-optimizer/extensions/front/tf/FakeQuantWithMinMaxVars.py index 015cb5946e8..878e703eabf 100644 --- a/model-optimizer/extensions/front/tf/FakeQuantWithMinMaxVars.py +++ b/model-optimizer/extensions/front/tf/FakeQuantWithMinMaxVars.py @@ -28,11 +28,6 @@ class FakeQuantWithMinMaxVarsToQuantize(FrontReplacementOp): op = "FakeQuantWithMinMaxVars" enabled = True - def run_before(self): - from extensions.front.sub import Sub - from extensions.front.div import Div - return [Sub, Div] - def replace_sub_graph(self, graph: Graph, match: Dict[str, Node]): node = match['op'] name = node.name diff --git a/model-optimizer/extensions/front/tf/ObjectDetectionAPI.py b/model-optimizer/extensions/front/tf/ObjectDetectionAPI.py index 83a4523953e..9c2d88c8467 100644 --- a/model-optimizer/extensions/front/tf/ObjectDetectionAPI.py +++ b/model-optimizer/extensions/front/tf/ObjectDetectionAPI.py @@ -21,10 +21,8 @@ import numpy as np from extensions.front.Pack import Pack from extensions.front.TransposeOrderNormalizer import TransposeOrderNormalizer -from extensions.front.div import Div from extensions.front.split_normalizer import SqueezeAxis from extensions.front.standalone_const_eraser import StandaloneConstEraser -from extensions.front.sub import Sub from extensions.front.tf.CropAndResizeReplacement import CropAndResizeReplacement from extensions.front.tf.FakeQuantWithMinMaxVars import FakeQuantWithMinMaxVarsToQuantize from extensions.front.tf.pad_tf_to_pad import PadTFToPad @@ -477,7 +475,7 @@ class ObjectDetectionAPIPreprocessorReplacement(FrontReplacementFromConfigFileSu # But the inputs corresponding to padding values is re-used as inputs for newly created Pad node. This input # is removed during removing nodes from the DO sub-graph so the first input to Transpose is missing which # results in TransposeOrderNormalizer transformation failure. - return [Pack, Sub, TransposeOrderNormalizer, PadTFToPad] + return [Pack, TransposeOrderNormalizer, PadTFToPad] def nodes_to_remove(self, graph: Graph, match: SubgraphMatch): new_nodes_to_remove = match.matched_nodes_names() @@ -549,7 +547,7 @@ class ObjectDetectionAPIDetectionOutputReplacement(FrontReplacementFromConfigFil replacement_id = 'ObjectDetectionAPIDetectionOutputReplacement' def run_before(self): - return [ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement, SqueezeAxis, Sub, TransposeOrderNormalizer] + return [ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement, SqueezeAxis, TransposeOrderNormalizer] def run_after(self): return [ObjectDetectionAPIProposalReplacement, CropAndResizeReplacement, FakeQuantWithMinMaxVarsToQuantize] @@ -818,7 +816,7 @@ class ObjectDetectionAPIProposalReplacement(FrontReplacementFromConfigFileSubGra return [ObjectDetectionAPIPreprocessorReplacement] def run_before(self): - return [Sub, CropAndResizeReplacement, TransposeOrderNormalizer] + return [CropAndResizeReplacement, TransposeOrderNormalizer] def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict): return {match.output_node(0)[0].id: new_sub_graph['proposal_node'].id} @@ -969,10 +967,7 @@ class ObjectDetectionAPISSDPostprocessorReplacement(FrontReplacementFromConfigFi return [ObjectDetectionAPIPreprocessorReplacement, FakeQuantWithMinMaxVarsToQuantize] def run_before(self): - # the replacer uses node of type "RealDiv" as one of the start points, but Model Optimizer replaces nodes of - # type "RealDiv" with a new ones, so it is necessary to replace the sub-graph before replacing the "RealDiv" - # nodes - return [Div, StandaloneConstEraser, TransposeOrderNormalizer] + return [StandaloneConstEraser, TransposeOrderNormalizer] def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict): # the DetectionOutput in IE produces single tensor, but in TF it produces two tensors, so create only one output diff --git a/model-optimizer/extensions/front/tf/RetinaNetFilteredDetectionsReplacement.py b/model-optimizer/extensions/front/tf/RetinaNetFilteredDetectionsReplacement.py index 46434aa29ca..3914e4c2383 100644 --- a/model-optimizer/extensions/front/tf/RetinaNetFilteredDetectionsReplacement.py +++ b/model-optimizer/extensions/front/tf/RetinaNetFilteredDetectionsReplacement.py @@ -48,10 +48,6 @@ class RetinaNetFilteredDetectionsReplacement(FrontReplacementFromConfigFileSubGr """ replacement_id = 'RetinaNetFilteredDetectionsReplacement' - def run_before(self): - from extensions.front.sub import Sub - return [Sub] - def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict): return {match.output_node(0)[0].id: new_sub_graph['detection_output_node'].id} diff --git a/model-optimizer/extensions/front/tf/mvn.py b/model-optimizer/extensions/front/tf/mvn.py index 4d57a2e0c1f..adb94c84b42 100644 --- a/model-optimizer/extensions/front/tf/mvn.py +++ b/model-optimizer/extensions/front/tf/mvn.py @@ -16,7 +16,6 @@ import logging as log -from extensions.front.squared_difference import SquaredDifference from extensions.ops.elementwise import Mul, Add from extensions.ops.mvn import MVN from mo.front.common.replacement import FrontReplacementSubgraph @@ -26,9 +25,6 @@ from mo.graph.graph import Node, Graph class MVNReplacer(FrontReplacementSubgraph): enabled = True - def run_before(self): - return [SquaredDifference] - def pattern(self): log.debug('Enabled MVN replacement') return dict( diff --git a/model-optimizer/extensions/front/tf/mvn_unrolled.py b/model-optimizer/extensions/front/tf/mvn_unrolled.py index 3d345f5279f..49b403a542e 100644 --- a/model-optimizer/extensions/front/tf/mvn_unrolled.py +++ b/model-optimizer/extensions/front/tf/mvn_unrolled.py @@ -17,9 +17,6 @@ import logging as log from extensions.front.PowerToEltwises import PowerToEltwises -from extensions.front.div import Div -from extensions.front.squared_difference import SquaredDifference -from extensions.front.sub import Sub from extensions.ops.mvn import MVN from mo.front.common.replacement import FrontReplacementSubgraph from mo.graph.graph import Node, Graph @@ -28,9 +25,6 @@ from mo.graph.graph import Node, Graph class MVNUnrolled(FrontReplacementSubgraph): enabled = True - def run_before(self): - return [SquaredDifference, Div, Sub] - def run_after(self): return [PowerToEltwises] diff --git a/model-optimizer/extensions/front/tf/prelu.py b/model-optimizer/extensions/front/tf/prelu.py index 6688aa3090a..1c5fd8d6afe 100644 --- a/model-optimizer/extensions/front/tf/prelu.py +++ b/model-optimizer/extensions/front/tf/prelu.py @@ -17,7 +17,6 @@ import logging as log from extensions.front.PowerToEltwises import PowerToEltwises -from extensions.front.sub import Sub from extensions.ops.prelu import PreluOp from mo.front.common.replacement import FrontReplacementSubgraph from mo.graph.graph import Graph @@ -66,9 +65,6 @@ class PReLU(FrontReplacementSubgraph): class PReLUWithAbs(FrontReplacementSubgraph): enabled = True - def run_before(self): - return [Sub] - def pattern(self): return dict( nodes=[('op', dict(kind='op')), diff --git a/model-optimizer/extensions/front/tf/transposed_mvn_unrolled.py b/model-optimizer/extensions/front/tf/transposed_mvn_unrolled.py index ecd4f12461b..5567335da1b 100644 --- a/model-optimizer/extensions/front/tf/transposed_mvn_unrolled.py +++ b/model-optimizer/extensions/front/tf/transposed_mvn_unrolled.py @@ -19,9 +19,6 @@ import logging as log import numpy as np from extensions.front.PowerToEltwises import PowerToEltwises -from extensions.front.div import Div -from extensions.front.squared_difference import SquaredDifference -from extensions.front.sub import Sub from extensions.front.tf.mvn_unrolled import MVNUnrolled from extensions.ops.elementwise import Add, Mul from extensions.ops.mvn import MVN @@ -105,7 +102,7 @@ class TransposedMVNUnrolled(FrontReplacementSubgraph): def run_before(self): from extensions.front.tf.mvn import MVNReplacer - return [MVNReplacer, MVNUnrolled, Sub, Div, SquaredDifference, PowerToEltwises] + return [MVNReplacer, MVNUnrolled, PowerToEltwises] def pattern(self): log.debug('Enabled Transposed MVN replacement') diff --git a/model-optimizer/extensions/middle/AddFakeQuantizeFuse.py b/model-optimizer/extensions/middle/AddFakeQuantizeFuse.py index 68f6c66bf5b..d59b779582d 100644 --- a/model-optimizer/extensions/middle/AddFakeQuantizeFuse.py +++ b/model-optimizer/extensions/middle/AddFakeQuantizeFuse.py @@ -19,7 +19,7 @@ from typing import Dict from extensions.middle.MulFakeQuantizeFuse import resolve_shared_inputs from mo.graph.graph import Graph, Node -from mo.middle.passes.conv import get_tensor_in_port, get_value_in_port +from mo.middle.passes.fusing.helpers import get_tensor_in_port, get_value_in_port from mo.middle.replacement import MiddleReplacementPattern @@ -39,7 +39,7 @@ class AddFakeQuantizeFuse(MiddleReplacementPattern): nodes=[ ('preop', dict(op='Add', can_be_fused=True)), ('preoped', dict()), - ('quantize', dict(op='FakeQuantize', keep_in_IR=True)), + ('quantize', dict(op='FakeQuantize')), ], edges=[ ('preop', 'preoped'), diff --git a/model-optimizer/extensions/middle/ArgMaxToTopK.py b/model-optimizer/extensions/middle/ArgMaxToTopK.py index 2b603b05182..149c44d618a 100644 --- a/model-optimizer/extensions/middle/ArgMaxToTopK.py +++ b/model-optimizer/extensions/middle/ArgMaxToTopK.py @@ -28,7 +28,6 @@ class ArgMaxToTopK(MiddleReplacementPattern): op = "ArgMax" enabled = True force_clean_up = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] def pattern(self): return dict( diff --git a/model-optimizer/extensions/middle/DecomposeBias.py b/model-optimizer/extensions/middle/DecomposeBias.py index eafb2e8f743..57623772a0b 100644 --- a/model-optimizer/extensions/middle/DecomposeBias.py +++ b/model-optimizer/extensions/middle/DecomposeBias.py @@ -25,7 +25,6 @@ from mo.ops.reshape import Reshape class DecomposeBias(MiddleReplacementPattern): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] force_clean_up = True @staticmethod diff --git a/model-optimizer/extensions/middle/Deconvolution3rdInputNormalization.py b/model-optimizer/extensions/middle/Deconvolution3rdInputNormalization.py index f0f0901a955..558cac27846 100644 --- a/model-optimizer/extensions/middle/Deconvolution3rdInputNormalization.py +++ b/model-optimizer/extensions/middle/Deconvolution3rdInputNormalization.py @@ -24,7 +24,6 @@ from mo.ops.op import PermuteAttrs class Deconvolution3rdInputNormalization(MiddleReplacementPattern): enabled = True - graph_condition = [lambda graph: graph.graph['cmd_params'].generate_experimental_IR_V10] force_clean_up = True @staticmethod diff --git a/model-optimizer/extensions/middle/DepthToSpace.py b/model-optimizer/extensions/middle/DepthToSpace.py deleted file mode 100644 index d488bb29d8e..00000000000 --- a/model-optimizer/extensions/middle/DepthToSpace.py +++ /dev/null @@ -1,84 +0,0 @@ -""" - 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. -""" -from extensions.middle.InsertLayoutPropagationTransposes import mark_as_correct_data_layout, \ - mark_input_as_in_correct_layout, mark_output_as_in_correct_layout -from extensions.ops.transpose import Transpose -from mo.front.common.partial_infer.utils import int64_array -from mo.graph.graph import Graph -from mo.middle.replacement import MiddleReplacementPattern -from mo.ops.const import Const -from mo.ops.reshape import Reshape - - -class DepthToSpace(MiddleReplacementPattern): - """ - Replaces DepthToSpace with 6D_Reshape->Transpose->4D_Reshape sequence - """ - - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - from extensions.middle.pass_separator import MiddleStart - return [MiddleStart] - - def run_before(self): - from extensions.middle.pass_separator import MiddleFinish - return [MiddleFinish] - - def pattern(self): - return dict( - nodes=[ - ('in_data', dict(kind='data')), - ('op', dict(op='DepthToSpace', data_format='NHWC')), - ('out_data', dict(kind='data')) - ], - edges=[ - ('in_data', 'op'), - ('op', 'out_data') - ]) - - def replace_pattern(self, graph: Graph, match: dict): - node = match['op'] - - N, H, W, C = match['in_data'].shape - block_size = node['block_size'] - - graph.remove_edge(match['in_data'].id, node.id) - graph.remove_edge(node.id, match['out_data'].id) - - dim_6D = int64_array([0, block_size, block_size, int(C / (block_size ** 2)), H, W]) - order_6D = int64_array([0, 3, 4, 1, 5, 2]) - dim_4D = int64_array([0, int(H * block_size), int(W * block_size), int(C / (block_size ** 2))]) - - reshape_6_op = Reshape(graph, dict(name=node.id + '/Reshape_to_6D')) - reshape_6_const_data = Const(graph, dict(value=dim_6D)).create_node_with_data() - reshape_6_data_node = reshape_6_op.create_node_with_data([match['in_data'], reshape_6_const_data]) - mark_as_correct_data_layout(reshape_6_data_node.in_node(0)) - - order_const_data = Const(graph, dict(value=order_6D)).create_node_with_data() - - transpose_op = Transpose(graph, dict(name=node.id + '/Transpose')) - transpose_data_node = transpose_op.create_node_with_data([reshape_6_data_node, order_const_data]) - mark_as_correct_data_layout(transpose_data_node.in_node(0)) - - reshape_4_op = Reshape(graph, dict(name=node.id + '/Reshape_to_4D')) - reshape_4_const_data = Const(graph, dict(value=dim_4D)).create_node_with_data() - reshape_4_data_node = reshape_4_op.create_node_with_data([transpose_data_node, reshape_4_const_data], - data_nodes=[match['out_data']]) - mark_input_as_in_correct_layout(reshape_4_data_node.in_node(0), 0) - mark_output_as_in_correct_layout(reshape_4_data_node.in_node(0), 0) - diff --git a/model-optimizer/extensions/middle/MinimumMiddleReplacer.py b/model-optimizer/extensions/middle/MinimumMiddleReplacer.py deleted file mode 100644 index affd661f4b6..00000000000 --- a/model-optimizer/extensions/middle/MinimumMiddleReplacer.py +++ /dev/null @@ -1,67 +0,0 @@ -""" - 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.ops.elementwise import Maximum, Mul -from mo.graph.graph import Graph -from mo.middle.replacement import MiddleReplacementPattern -from mo.ops.const import Const - - -class MinimumMiddleReplacer(MiddleReplacementPattern): - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - from extensions.middle.pass_separator import MiddleStart - return [MiddleStart] - - def run_before(self): - from extensions.middle.pass_separator import MiddleFinish - return [MiddleFinish] - - def pattern(self): - return dict( - nodes=[ - ('minimum', dict(kind='op', op='Minimum')) - ], - edges=[] - ) - - def replace_pattern(self, graph: Graph, match: dict): - node = match['minimum'] - # Constant propagation case - if node.in_node(0).value is not None and node.in_node(1).value is not None: - return - - neg_1_const = Const(graph, dict(value=np.array(-1), name=node.name + '/negate1_const')) - neg_2_const = Const(graph, dict(value=np.array(-1), name=node.name + '/negate2_const')) - negate_1 = Mul(graph, dict(name=node.name + '/negate1_')) - negate_2 = Mul(graph, dict(name=node.name + '/negate2_')) - maximum = Maximum(graph, dict(name=node.name + '/Max_')) - negate_output_const = Const(graph, dict(value=np.array(-1), name=node.name + '/negate_out_const_')) - negate_output = Mul(graph, dict(scale=-1, name=node.name + '/negate_out_')) - - negate_output.create_node_with_data( - inputs=[ - maximum.create_node_with_data( - [negate_1.create_node_with_data([node.in_node(0), neg_1_const.create_node_with_data()]), - negate_2.create_node_with_data([node.in_node(1), neg_2_const.create_node_with_data()])]), - negate_output_const.create_node_with_data() - ], - data_nodes=node.out_node()) - # Delete minimum vertex - node.graph.remove_node(node.id) diff --git a/model-optimizer/extensions/middle/MinumumMiddleReplacer_test.py b/model-optimizer/extensions/middle/MinumumMiddleReplacer_test.py deleted file mode 100644 index 52f16f745af..00000000000 --- a/model-optimizer/extensions/middle/MinumumMiddleReplacer_test.py +++ /dev/null @@ -1,98 +0,0 @@ -""" - 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 unittest - -import numpy as np - -from extensions.middle.MinimumMiddleReplacer import MinimumMiddleReplacer -from mo.utils.ir_engine.compare_graphs import compare_graphs -from mo.utils.unittest.graph import build_graph - -nodes_attributes = { - 'placeholder_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'placeholder_1_data': {'kind': 'data', 'data_type': None, 'value': 3, 'shape': np.array([])}, - - 'placeholder_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, - 'placeholder_2_data': {'value': None, 'shape': np.array([5, 5]), 'kind': 'data', 'data_type': None}, - - # minimum node: - 'minimum': {'type': 'Minimum', 'kind': 'op', 'op': 'Minimum'}, - # negates - 'const_1': {'kind': 'op', 'op': 'Const', 'value': np.array(-1)}, - 'const_1_d': {'kind': 'data', 'value': np.array(-1)}, - - 'negate_1': {'type': 'Multiply', 'kind': 'op', 'op': 'Mul'}, - 'negate_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - - 'const_2': {'kind': 'op', 'op': 'Const', 'value': np.array(-1)}, - 'const_2_d': {'kind': 'data', 'value': np.array(-1)}, - - 'negate_2': {'type': 'Multiply', 'kind': 'op', 'op': 'Mul'}, - 'negate_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - - 'const_3': {'kind': 'op', 'op': 'Const', 'value': np.array(-1)}, - 'const_3_d': {'kind': 'data', 'value': np.array(-1)}, - - 'negate_output': {'type': 'Multiply', 'kind': 'op', 'op': 'Mul'}, - 'negate_output_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - - # Maximum - 'maximum': {'type': 'Maximum', 'kind': 'op', 'op': 'Maximum'}, - 'maximum_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, - # output - 'output_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None}, -} - - -class MinumumMiddleReplacerTest(unittest.TestCase): - def test_1(self): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_2', 'placeholder_2_data'), - ('placeholder_1_data', 'minimum'), - ('placeholder_2_data', 'minimum'), - ('minimum', 'output_data') - ]) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_2', 'placeholder_2_data'), - ('placeholder_1_data', 'negate_1'), - ('const_1', 'const_1_d'), - ('const_1_d', 'negate_1'), - ('placeholder_2_data', 'negate_2'), - ('const_2', 'const_2_d'), - ('const_2_d', 'negate_2'), - ('negate_1', 'negate_1_data'), - ('negate_2', 'negate_2_data'), - ('negate_1_data', 'maximum'), - ('negate_2_data', 'maximum'), - ('maximum', 'maximum_data'), - ('maximum_data', 'negate_output'), - ('const_3', 'const_3_d'), - ('const_3_d', 'negate_output'), - ('negate_output', 'negate_output_data') - ]) - - graph.graph['layout'] = 'NHWC' - - tested_class = MinimumMiddleReplacer() - tested_class.find_and_replace_pattern(graph=graph) - - (flag, resp) = compare_graphs(graph, graph_ref, 'minimum/negate_out_', last_node_ref='negate_output', - check_op_attrs=True) - self.assertTrue(flag, resp) diff --git a/model-optimizer/extensions/middle/MulAddToSS.py b/model-optimizer/extensions/middle/MulAddToSS.py deleted file mode 100644 index 6c8e7dbb220..00000000000 --- a/model-optimizer/extensions/middle/MulAddToSS.py +++ /dev/null @@ -1,46 +0,0 @@ -""" - 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. -""" -from extensions.middle.EltwiseChecker import EltwiseChecker -from extensions.middle.LeakyReluPattern import LeakyReLU -from extensions.middle.pass_separator import PostMiddleStart -from mo.graph.graph import Graph -from mo.middle.passes.conv import convert_muladd_to_scaleshift, convert_add_or_mul_to_scaleshift -from mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively -from mo.middle.replacement import MiddleReplacementPattern - - -class MulAddToSS(MiddleReplacementPattern): - enabled = True - run_not_recursively = True - - def run_after(self): - return [LeakyReLU] - - def run_before(self): - return [PostMiddleStart] - - def find_and_replace_pattern(self, graph: Graph): - for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up()) - - EltwiseChecker().find_and_replace_pattern(graph) - - # turn off run of transformation for body of TI due to error on TF_Multicell topology - convert_muladd_to_scaleshift(graph) - graph.clean_up() - - # turn off run of transformation for body of TI due to error on TF_Multicell topology - convert_add_or_mul_to_scaleshift(graph) - graph.clean_up() diff --git a/model-optimizer/extensions/middle/MulFakeQuantizeFuse.py b/model-optimizer/extensions/middle/MulFakeQuantizeFuse.py index 85454f42df2..31234f42a12 100644 --- a/model-optimizer/extensions/middle/MulFakeQuantizeFuse.py +++ b/model-optimizer/extensions/middle/MulFakeQuantizeFuse.py @@ -20,7 +20,7 @@ from typing import Dict, List import numpy as np from mo.graph.graph import Graph, Node -from mo.middle.passes.conv import get_tensor_in_port, get_value_in_port +from mo.middle.passes.fusing.helpers import get_tensor_in_port, get_value_in_port from mo.middle.replacement import MiddleReplacementPattern from mo.ops.const import Const @@ -64,7 +64,7 @@ class MulFakeQuantizeFuse(MiddleReplacementPattern): nodes=[ ('preop', dict(op='Mul', can_be_fused=True)), ('preoped', dict()), - ('quantize', dict(op='FakeQuantize', keep_in_IR=True)), + ('quantize', dict(op='FakeQuantize')), ], edges=[ ('preop', 'preoped'), diff --git a/model-optimizer/extensions/middle/MulQuantizeFuse_test.py b/model-optimizer/extensions/middle/MulQuantizeFuse_test.py index a22685afdea..29b76bb9123 100644 --- a/model-optimizer/extensions/middle/MulQuantizeFuse_test.py +++ b/model-optimizer/extensions/middle/MulQuantizeFuse_test.py @@ -46,7 +46,7 @@ nodes = { 'ma_o': {'op': 'Const', 'type': 'Const', 'kind': 'op', 'value': None, 'shape': None}, 'ma_o_data': {'value': np.array([]), 'shape': np.array([]), 'kind': 'data'}, - 'quantize': {'type': 'FakeQuantize', 'kind': 'op', 'op': 'FakeQuantize', 'levels': 2, 'keep_in_IR': True}, + 'quantize': {'type': 'FakeQuantize', 'kind': 'op', 'op': 'FakeQuantize', 'levels': 2}, 'quantize_data': {'value': None, 'shape': np.array([1, 64, 56, 56]), 'kind': 'data'}, 'output': {'op': 'Result', 'kind': 'op'}, diff --git a/model-optimizer/extensions/middle/ReluQuantizeFuse.py b/model-optimizer/extensions/middle/ReluQuantizeFuse.py index 3e025f01402..3c2493874da 100644 --- a/model-optimizer/extensions/middle/ReluQuantizeFuse.py +++ b/model-optimizer/extensions/middle/ReluQuantizeFuse.py @@ -47,7 +47,7 @@ class ReluFakeQuantizeMark(MiddleReplacementPattern): nodes=[ ('relu', dict(op='ReLU')), ('relu_d', dict()), - ('quantize', dict(op='FakeQuantize', keep_in_IR=True)), + ('quantize', dict(op='FakeQuantize')), ], edges=[ ('relu', 'relu_d'), @@ -109,7 +109,7 @@ class ClampQuantizeMark(MiddleReplacementPattern): nodes=[ ('clamp', dict(op='Clamp')), ('clamp_d', dict()), - ('quantize', dict(op='FakeQuantize', keep_in_IR=True)), + ('quantize', dict(op='FakeQuantize')), ], edges=[ ('clamp', 'clamp_d'), @@ -172,7 +172,7 @@ class ReluQuantizeFuse(MiddleReplacementPattern): nodes=[ ('relu', dict(removable_before_quantize=True)), ('relu_d', dict()), - ('quantize', dict(op='FakeQuantize', keep_in_IR=True)), + ('quantize', dict(op='FakeQuantize')), ], edges=[ ('relu', 'relu_d'), diff --git a/model-optimizer/extensions/middle/ReluQuantizeFuse_test.py b/model-optimizer/extensions/middle/ReluQuantizeFuse_test.py index 0af60efebf9..0065a3577b3 100644 --- a/model-optimizer/extensions/middle/ReluQuantizeFuse_test.py +++ b/model-optimizer/extensions/middle/ReluQuantizeFuse_test.py @@ -41,10 +41,10 @@ nodes = { 'const_4': {'op': 'Const', 'kind': 'op'}, 'const_4_d': {'kind': 'data', 'value': None}, - 'quantize': {'kind': 'op', 'op': 'FakeQuantize', 'keep_in_IR': True}, + 'quantize': {'kind': 'op', 'op': 'FakeQuantize'}, 'quantize_d': {'value': None, 'shape': None, 'kind': 'data'}, - 'quantize_1': {'kind': 'op', 'op': 'FakeQuantize', 'keep_in_IR': True}, + 'quantize_1': {'kind': 'op', 'op': 'FakeQuantize'}, 'quantize_1_d': {'value': None, 'shape': None, 'kind': 'data'}, # Result diff --git a/model-optimizer/extensions/middle/UpsampleToResample.py b/model-optimizer/extensions/middle/UpsampleToResample.py index 18ac2eb0d4f..b39c649a770 100644 --- a/model-optimizer/extensions/middle/UpsampleToResample.py +++ b/model-optimizer/extensions/middle/UpsampleToResample.py @@ -142,8 +142,7 @@ class UpsampleToResample(MiddleReplacementPattern): upsample.out_port(0).get_connection().set_source(resample_op.out_port(0)) convert_to_float = Cast(graph, dict(dst_type=np.float32)).create_node() - int_np_type = np.int64 if graph.graph['cmd_params'].generate_experimental_IR_V10 else np.int32 - convert_to_int = Cast(graph, dict(dst_type=int_np_type)).create_node() + convert_to_int = Cast(graph, dict(dst_type=np.int64)).create_node() mul.in_port(0).get_connection().insert_node(convert_to_float) mul.out_port(0).get_connection().insert_node(convert_to_int) diff --git a/model-optimizer/extensions/middle/preprocessing.py b/model-optimizer/extensions/middle/preprocessing.py index 2fe4dfcef58..24ab8a5436f 100644 --- a/model-optimizer/extensions/middle/preprocessing.py +++ b/model-optimizer/extensions/middle/preprocessing.py @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. """ -from extensions.middle.MulAddToSS import MulAddToSS +from extensions.middle.LeakyReluPattern import LeakyReLU from extensions.middle.pass_separator import PostMiddleStart from mo.graph.graph import Graph from mo.middle.passes.mean_scale_values import move_scaleshift_to_preprocess @@ -28,7 +28,7 @@ class Preprocessing(MiddleReplacementPattern): force_clean_up = True def run_after(self): - return [MulAddToSS] + return [LeakyReLU] def run_before(self): return [PostMiddleStart] diff --git a/model-optimizer/extensions/middle/quantize_fuses.py b/model-optimizer/extensions/middle/quantize_fuses.py index a392cc20f47..d479bc14a2e 100644 --- a/model-optimizer/extensions/middle/quantize_fuses.py +++ b/model-optimizer/extensions/middle/quantize_fuses.py @@ -91,7 +91,7 @@ class FakeQuantizeFuse(MiddleReplacementPattern): return [BinarizeWeightsM1P1] def find_and_replace_pattern(self, graph: Graph): - for quantize_node in graph.get_op_nodes(op='FakeQuantize', keep_in_IR=True): + for quantize_node in graph.get_op_nodes(op='FakeQuantize'): while len(quantize_node.out_port(0).get_destinations()) == 1: if not quantize_node.out_port(0).get_destination().node.has_valid('fuse_up_to_quantize_ports'): break diff --git a/model-optimizer/extensions/middle/quantize_fuses_test.py b/model-optimizer/extensions/middle/quantize_fuses_test.py index 0d063baef4a..d32af2d69d7 100644 --- a/model-optimizer/extensions/middle/quantize_fuses_test.py +++ b/model-optimizer/extensions/middle/quantize_fuses_test.py @@ -36,7 +36,7 @@ nodes = { 'ma_o': {'kind': 'op', 'op': 'Const'}, 'ma_o_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None}, - 'quantize': {'kind': 'op', 'op': 'FakeQuantize', 'keep_in_IR': True}, + 'quantize': {'kind': 'op', 'op': 'FakeQuantize'}, 'quantize_d': {'kind': 'data', 'shape': None}, 'mul_val': {'kind': 'op', 'op': 'Const'}, diff --git a/model-optimizer/extensions/middle/space_to_depth.py b/model-optimizer/extensions/middle/space_to_depth.py deleted file mode 100644 index ed354be596b..00000000000 --- a/model-optimizer/extensions/middle/space_to_depth.py +++ /dev/null @@ -1,83 +0,0 @@ -""" - 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. -""" -from extensions.middle.InsertLayoutPropagationTransposes import mark_as_correct_data_layout, \ - mark_input_as_in_correct_layout, mark_output_as_in_correct_layout -from extensions.ops.transpose import Transpose -from mo.front.common.partial_infer.utils import int64_array -from mo.graph.graph import Graph -from mo.middle.replacement import MiddleReplacementPattern -from mo.ops.const import Const -from mo.ops.reshape import Reshape - - -class SpaceToDepth(MiddleReplacementPattern): - """ - Replaces SpaceToDepth with 6D_Reshape->Transpose->4D_Reshape sequence - """ - - enabled = True - graph_condition = [lambda graph: not graph.graph['cmd_params'].generate_experimental_IR_V10] - - def run_after(self): - from extensions.middle.pass_separator import MiddleStart - return [MiddleStart] - - def run_before(self): - from extensions.middle.pass_separator import MiddleFinish - return [MiddleFinish] - - def pattern(self): - return dict( - nodes=[ - ('in_data', dict(kind='data')), - ('op', dict(op='SpaceToDepth', data_format='NHWC')), - ('out_data', dict(kind='data')) - ], - edges=[ - ('in_data', 'op'), - ('op', 'out_data') - ]) - - def replace_pattern(self, graph: Graph, match: dict): - node = match['op'] - - N, H, W, C = match['in_data'].shape - block_size = node['block_size'] - - graph.remove_edge(match['in_data'].id, node.id) - graph.remove_edge(node.id, match['out_data'].id) - - dim_6D = int64_array([N, C, int(H / block_size), block_size, int(W / block_size), block_size]) - order_6D = int64_array([0, 3, 5, 1, 2, 4]) - dim_4D = int64_array([N, int(H / block_size), int(W / block_size), int(C * (block_size ** 2))]) - - reshape_6_op = Reshape(graph, dict(name=node.id + '/Reshape_to_6D')) - reshape_6_const_data = Const(graph, dict(value=dim_6D)).create_node_with_data() - reshape_6_data_node = reshape_6_op.create_node_with_data([match['in_data'], reshape_6_const_data]) - mark_as_correct_data_layout(reshape_6_data_node.in_node(0)) - - order_const_data = Const(graph, dict(value=order_6D)).create_node_with_data() - - transpose_op = Transpose(graph, dict(name=node.id + '/Transpose')) - transpose_data_node = transpose_op.create_node_with_data([reshape_6_data_node, order_const_data]) - mark_as_correct_data_layout(transpose_data_node.in_node(0)) - - reshape_4_op = Reshape(graph, dict(name=node.id + '/Reshape_to_4D')) - reshape_4_const_data = Const(graph, dict(value=dim_4D)).create_node_with_data() - reshape_4_data_node = reshape_4_op.create_node_with_data([transpose_data_node, reshape_4_const_data], - data_nodes=[match['out_data']]) - mark_input_as_in_correct_layout(reshape_4_data_node.in_node(0), 0) - mark_output_as_in_correct_layout(reshape_4_data_node.in_node(0), 0) diff --git a/model-optimizer/extensions/ops/ReduceOps.py b/model-optimizer/extensions/ops/ReduceOps.py index 9ae3d06cd3c..ca0ff3e2007 100644 --- a/model-optimizer/extensions/ops/ReduceOps.py +++ b/model-optimizer/extensions/ops/ReduceOps.py @@ -97,7 +97,7 @@ class ReduceOp(Op): 'in_ports_count': 2, 'out_ports_count': 1, 'force_precision_in_ports': { - 1: 'int64' if graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32'}, + 1: 'int64'}, }, attrs) assert isinstance(self.attrs['keep_dims'], int) or isinstance(self.attrs['keep_dims'], bool) self.attrs['keep_dims'] = bool(self.attrs['keep_dims']) diff --git a/model-optimizer/extensions/ops/activation_ops.py b/model-optimizer/extensions/ops/activation_ops.py index dff51de81b8..d12057b8ea5 100644 --- a/model-optimizer/extensions/ops/activation_ops.py +++ b/model-optimizer/extensions/ops/activation_ops.py @@ -205,8 +205,7 @@ class LogicalNot(Activation): @staticmethod def type_infer(node: Node): - output_data_type = np.int32 if node.graph.graph['cmd_params'].generate_deprecated_IR_V7 else np.bool - node.out_port(0).set_data_type(output_data_type) + node.out_port(0).set_data_type(np.bool) class Log(Activation): diff --git a/model-optimizer/extensions/ops/elementwise.py b/model-optimizer/extensions/ops/elementwise.py index 754287fb9a6..ee86c122229 100644 --- a/model-optimizer/extensions/ops/elementwise.py +++ b/model-optimizer/extensions/ops/elementwise.py @@ -139,8 +139,7 @@ class Pow(Elementwise): class LogicalElementwise(Elementwise): @staticmethod def type_infer(node): - output_data_type = np.int32 if node.graph.graph['cmd_params'].generate_deprecated_IR_V7 else np.bool - node.out_port(0).set_data_type(output_data_type) + node.out_port(0).set_data_type(np.bool) class Greater(LogicalElementwise): diff --git a/model-optimizer/extensions/ops/fakequantize.py b/model-optimizer/extensions/ops/fakequantize.py index f9981b1b8dd..b725f79f7fa 100644 --- a/model-optimizer/extensions/ops/fakequantize.py +++ b/model-optimizer/extensions/ops/fakequantize.py @@ -41,22 +41,18 @@ class FakeQuantize(Op): def __init__(self, graph: Graph, attrs: dict): mandatory_props = { - 'type': __class__.op, - 'op': __class__.op, + 'type': self.op, + 'op': self.op, 'version': 'opset1', 'levels': None, 'is_eltwise': True, - # flag to switch between dumping FakeQuantize as statistics and keeping it as layer in IR - 'keep_in_IR': None, - 'infer': __class__.infer, + 'infer': self.infer, 'in_ports_count': 5, 'out_ports_count': 1, } super().__init__(graph, mandatory_props, attrs) if self.attrs['levels'] is None: raise Error("FakeQuantize operation has no levels parameter") - # TODO remove following lines after FakeQuantize supported for int8 workflow - self.attrs['keep_in_IR'] = self.attrs['levels'] == 2 or graph.graph['cmd_params'].keep_quantize_ops_in_IR def supported_attrs(self): return [ diff --git a/model-optimizer/extensions/ops/non_max_suppression.py b/model-optimizer/extensions/ops/non_max_suppression.py index 66bca864660..f161b8f6368 100644 --- a/model-optimizer/extensions/ops/non_max_suppression.py +++ b/model-optimizer/extensions/ops/non_max_suppression.py @@ -40,7 +40,7 @@ class NonMaxSuppression(Op): 'out_ports_count': 1, 'sort_result_descending': 1, 'force_precision_in_ports': { - 2: 'int64' if graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32'}, + 2: 'int64'}, 'type_infer': self.type_infer, } super().__init__(graph, mandatory_props, attrs) @@ -81,10 +81,7 @@ class NonMaxSuppression(Op): @staticmethod def type_infer(node): - if not node.graph.graph['cmd_params'].generate_experimental_IR_V10: - node.out_port(0).set_data_type(np.int32) + if node.get_opset() == 'opset3': + node.out_port(0).set_data_type(node.output_type) else: - if node.get_opset() == 'opset3': - node.out_port(0).set_data_type(node.output_type) - else: - node.out_port(0).set_data_type(np.int64) + node.out_port(0).set_data_type(np.int64) diff --git a/model-optimizer/extensions/ops/non_max_suppression_test.py b/model-optimizer/extensions/ops/non_max_suppression_test.py index bf3c1ff3af5..bfbb0155e42 100644 --- a/model-optimizer/extensions/ops/non_max_suppression_test.py +++ b/model-optimizer/extensions/ops/non_max_suppression_test.py @@ -43,19 +43,8 @@ class TestNonMaxSuppressionInfer(unittest.TestCase): *connect('nms', 'output'), ], nodes_with_edges_only=True) - def test_nms_infer_v7(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=False, ir_version=7) - - nms_node = Node(self.graph, 'nms') - nms_node['version'] = 'opset1' - NonMaxSuppression.infer(nms_node) - NonMaxSuppression.type_infer(nms_node) - - self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(), [100, 3])) - self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32) - def test_nms_infer_v10_opset1(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=True, ir_version=10) + self.graph.graph['cmd_params'] = FakeAttr(ir_version=10) nms_node = Node(self.graph, 'nms') nms_node['version'] = 'opset1' @@ -66,7 +55,7 @@ class TestNonMaxSuppressionInfer(unittest.TestCase): self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64) def test_nms_infer_v10_i64_opset3(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=True, ir_version=10) + self.graph.graph['cmd_params'] = FakeAttr(ir_version=10) nms_node = Node(self.graph, 'nms') nms_node['version'] = 'opset3' @@ -78,7 +67,7 @@ class TestNonMaxSuppressionInfer(unittest.TestCase): self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64) def test_nms_infer_v10_i32_opset3(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=True, ir_version=10) + self.graph.graph['cmd_params'] = FakeAttr(ir_version=10) nms_node = Node(self.graph, 'nms') nms_node['version'] = 'opset3' diff --git a/model-optimizer/extensions/ops/one_hot.py b/model-optimizer/extensions/ops/one_hot.py index 948390bf6a8..3a48055ae88 100644 --- a/model-optimizer/extensions/ops/one_hot.py +++ b/model-optimizer/extensions/ops/one_hot.py @@ -35,7 +35,7 @@ class OneHot(Op): 'out_ports_count': 1, 'in_ports_count': 4, 'data_type': None, - 'force_precision_in_ports': {1: 'int64'} if not graph.graph['cmd_params'].generate_deprecated_IR_V7 else None, + 'force_precision_in_ports': {1: 'int64'}, 'type_infer': self.type_infer, } super().__init__(graph, mandatory_props, attrs) @@ -104,7 +104,4 @@ class OneHot(Op): @staticmethod def type_infer(node: Node): - if not node.graph.graph['cmd_params'].generate_experimental_IR_V10: - node.out_port(0).set_data_type(node.data_type) - else: - node.out_port(0).set_data_type(node.in_port(2).get_data_type()) + node.out_port(0).set_data_type(node.in_port(2).get_data_type()) diff --git a/model-optimizer/extensions/ops/prelu.py b/model-optimizer/extensions/ops/prelu.py index 716af9a86da..f15c6ed0235 100644 --- a/model-optimizer/extensions/ops/prelu.py +++ b/model-optimizer/extensions/ops/prelu.py @@ -54,9 +54,6 @@ class PreluOp(Op): node['channel_shared'] = 1 else: node['channel_shared'] = 0 - if not node.graph.graph['cmd_params'].generate_experimental_IR_V10: - mark_input_bins(node) - else: - node.in_node(1)['correct_data_type'] = True + node.in_node(1)['correct_data_type'] = True copy_shape_infer(node) diff --git a/model-optimizer/extensions/ops/psroipooling.py b/model-optimizer/extensions/ops/psroipooling.py index a04152af9c3..249dcac01c4 100644 --- a/model-optimizer/extensions/ops/psroipooling.py +++ b/model-optimizer/extensions/ops/psroipooling.py @@ -25,8 +25,8 @@ class PSROIPoolingOp(Op): def __init__(self, graph: Graph, attrs: dict): mandatory_props = { - 'type': __class__.op, - 'op': __class__.op, + 'type': self.op, + 'op': self.op, 'version': 'opset2', 'mode': 'average', 'in_ports_count': 2, @@ -38,7 +38,7 @@ class PSROIPoolingOp(Op): super().__init__(graph, mandatory_props, attrs) def supported_attrs(self): - attrs = [ + return [ 'spatial_scale', 'output_dim', ('group_size', lambda node: int(node.group_size)), @@ -48,9 +48,6 @@ class PSROIPoolingOp(Op): 'pooled_width', 'pooled_height', ] - if not self.graph.graph['cmd_params'].generate_experimental_IR_V10: - attrs.extend(['no_trans', 'trans_std', 'part_size']) - return attrs @staticmethod def psroipooling_infer(node: Node): @@ -82,8 +79,8 @@ class DeformablePSROIPoolingOp(PSROIPoolingOp): def __init__(self, graph: Graph, attrs: dict): updated_attrs = { - 'type': __class__.op, - 'op': __class__.op, + 'type': self.op, + 'op': self.op, 'version': 'opset1', 'mode': 'bilinear_deformable', 'in_ports_count': 3, diff --git a/model-optimizer/extensions/ops/tensor_iterator.py b/model-optimizer/extensions/ops/tensor_iterator.py index 5d43ffb25a9..367d2ee81e8 100644 --- a/model-optimizer/extensions/ops/tensor_iterator.py +++ b/model-optimizer/extensions/ops/tensor_iterator.py @@ -15,8 +15,6 @@ """ from copy import copy, deepcopy -import numpy as np - from extensions.ops.parameter import Parameter from mo.graph.graph import Node, dict_includes, Graph from mo.ops.const import Const @@ -370,48 +368,6 @@ class TensorIterator(Op): @staticmethod def ti_type_infer(node): - if node.graph.graph['cmd_params'].generate_experimental_IR_V10: - TensorIterator.ti_type_infer_v10(node) - else: - TensorIterator._ti_type_infer(node) - - @staticmethod - def _ti_type_infer(node): - from mo.middle.passes.infer import type_infer - ti_graph = node.body - - # create fake const node to make type inference work correctly for all TI input nodes - fake_input_const_nodes = [] - for port_map in __class__.generate_port_map(node, node.input_port_map): - internal_input_data = Node(ti_graph, port_map['internal_layer_id']).in_node(port_map['internal_port_id']) - if len(internal_input_data.in_nodes()) == 0: - input_producer_port = node.in_port(port_map['external_port_id']).get_connection().get_source() - input_type = input_producer_port.get_data_type() - const_node = Const(ti_graph, {'name': 'fake_const_', - 'value': np.ones([1], dtype=input_type)}).create_node() - fake_input_const_nodes.append(const_node) - ti_graph.create_edge(const_node, internal_input_data) - - # create const Op node for constant data nodes inside the TI - for data_node in ti_graph.get_data_nodes(has_value=True): - if len(data_node.in_nodes()) == 0: - const_node = Const(ti_graph, {'name': 'const_', 'value': data_node.value}).create_node() - fake_input_const_nodes.append(const_node) - ti_graph.create_edge(const_node, data_node) - - type_infer(ti_graph) - - # propagate data types to the TI output ports - output_port_map = __class__.generate_port_map(node, node.output_port_map) - for port_map in output_port_map: - internal_output_port = Node(ti_graph, port_map['internal_layer_id']).out_port(port_map['internal_port_id']) - ti_output_port = node.out_port(port_map['external_port_id']) - ti_output_port.set_data_type(internal_output_port.get_data_type()) - - ti_graph.remove_nodes_from([node.id for node in fake_input_const_nodes]) - - @staticmethod - def ti_type_infer_v10(node): from mo.middle.passes.infer import type_infer ti_graph = node.body @@ -457,44 +413,27 @@ def _get_internal_idxs_to_names_dict(graph: Graph, ports_type='in'): """ Create mapping from (internal_layer_id, internal_port_id) to layer id in body of TensorIterator. """ - v10 = graph.graph['cmd_params'].generate_experimental_IR_V10 mapping = {} ordered_nodes = graph.pseudo_topological_sort() for node in ordered_nodes: if node.kind == 'op' and node.has_valid('internal_layer_id'): - if v10: - mapping[node.internal_layer_id] = node.id - else: - edges = node.out_edges() if ports_type == 'out' else node.in_edges() - for port in edges: - if 'internal_port_id' in edges[port]: - internal_port = edges[port]['internal_port_id'] - mapping[(node.internal_layer_id, internal_port)] = node.out_node(port).id if ports_type == 'out' \ - else node.in_node(port).id + mapping[node.internal_layer_id] = node.id return mapping def _get_internal_output_node_id(graph: Graph, ti_node_id: str, external_port: int): node = Node(graph, ti_node_id) outputs = node['output_port_map'] - v10 = graph.graph['cmd_params'].generate_experimental_IR_V10 mapping = _get_internal_idxs_to_names_dict(node['body'], 'out') for out in outputs: if out['external_port_id'] == external_port: - if v10: - return mapping[out['internal_layer_id']] - else: - return mapping[(out['internal_layer_id'], out['internal_port_id'])] + return mapping[out['internal_layer_id']] def _get_internal_input_node_id(graph: Graph, ti_node_id: str, external_port: int): node = Node(graph, ti_node_id) inputs = node['input_port_map'] - v10 = graph.graph['cmd_params'].generate_experimental_IR_V10 mapping = _get_internal_idxs_to_names_dict(node['body'], 'in') for inp in inputs: if inp['external_port_id'] == external_port: - if v10: - return mapping[inp['internal_layer_id']] - else: - return mapping[(inp['internal_layer_id'], inp['internal_port_id'])] + return mapping[inp['internal_layer_id']] diff --git a/model-optimizer/extensions/ops/topk_test.py b/model-optimizer/extensions/ops/topk_test.py index f06962268e5..4607d5dc63d 100644 --- a/model-optimizer/extensions/ops/topk_test.py +++ b/model-optimizer/extensions/ops/topk_test.py @@ -46,21 +46,8 @@ class TestTopKInfer(unittest.TestCase): ('topk_d2', 'output_2'), ], nodes_with_edges_only=True) - def test_topk_infer_v7(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=False, ir_version=7) - - topk_node = Node(self.graph, 'topk') - topk_node['version'] = 'opset1' - TopK.infer(topk_node) - TopK.type_infer(topk_node) - - self.assertTrue(np.array_equal(topk_node.out_port(0).data.get_shape(), int64_array([20, 10, 4]))) - self.assertTrue(np.array_equal(topk_node.out_port(1).data.get_shape(), int64_array([20, 10, 4]))) - self.assertTrue(topk_node.out_port(0).get_data_type() == np.float32) - self.assertTrue(topk_node.out_port(1).get_data_type() == np.int32) - def test_topk_infer_v10_opset1(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=True, ir_version=10) + self.graph.graph['cmd_params'] = FakeAttr(ir_version=10) topk_node = Node(self.graph, 'topk') topk_node['version'] = 'opset1' @@ -73,7 +60,7 @@ class TestTopKInfer(unittest.TestCase): self.assertTrue(topk_node.out_port(1).get_data_type() == np.int32) def test_topk_infer_v10_i64_opset3(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=True, ir_version=10) + self.graph.graph['cmd_params'] = FakeAttr(ir_version=10) topk_node = Node(self.graph, 'topk') topk_node['version'] = 'opset3' @@ -87,7 +74,7 @@ class TestTopKInfer(unittest.TestCase): self.assertTrue(topk_node.out_port(1).get_data_type() == np.int64) def test_topk_infer_v10_i32_opset3(self): - self.graph.graph['cmd_params'] = FakeAttr(generate_experimental_IR_V10=True, ir_version=10) + self.graph.graph['cmd_params'] = FakeAttr(ir_version=10) topk_node = Node(self.graph, 'topk') topk_node['version'] = 'opset3' diff --git a/model-optimizer/mo/back/ie_ir_ver_2/emitter.py b/model-optimizer/mo/back/ie_ir_ver_2/emitter.py index 4e1c51ddae3..275e32843af 100644 --- a/model-optimizer/mo/back/ie_ir_ver_2/emitter.py +++ b/model-optimizer/mo/back/ie_ir_ver_2/emitter.py @@ -69,8 +69,7 @@ def serialize_constants_recursively(graph: Graph, bin_file, data_type, bin_hashe graph.node[node.node]['offset'] = bin_hashes[blob_hash]['offset'] graph.node[node.node]['size'] = bin_hashes[blob_hash]['size'] graph.node[node.node]['blob_precision'] = np_data_type_to_precision(blob.dtype) - if graph.graph['cmd_params'].generate_experimental_IR_V10: - update_offset_size_in_const_node(node) + update_offset_size_in_const_node(node) else: start = bin_file.tell() blob.tofile(bin_file) @@ -82,8 +81,7 @@ def serialize_constants_recursively(graph: Graph, bin_file, data_type, bin_hashe bin_hashes[blob_hash] = {'offset': graph.node[node.node]['offset'], 'size': graph.node[node.node]['size'], 'blob': blob} - if graph.graph['cmd_params'].generate_experimental_IR_V10: - update_offset_size_in_const_node(node) + update_offset_size_in_const_node(node) assert (blob.dtype.itemsize * np.prod(node.shape) == end - start) or node.has_valid('force_shape'), node.attrs() @@ -177,7 +175,7 @@ def xml_ports(node: Node, element: Element, edges: Element): def xml_consts(graph: Graph, node: Node, element: Element): blobs = None # sub-element that will be created on-demand for u, d in node.get_sorted_inputs(): - if 'bin' in d and (node.type != 'Const' or not graph.graph['cmd_params'].generate_experimental_IR_V10): + if 'bin' in d and (node.type != 'Const'): if not blobs: blobs = SubElement(element, 'blobs') const = SubElement(blobs, d['bin']) diff --git a/model-optimizer/mo/front/common/partial_infer/slice.py b/model-optimizer/mo/front/common/partial_infer/slice.py index e599a7078e3..5c850f20a89 100644 --- a/model-optimizer/mo/front/common/partial_infer/slice.py +++ b/model-optimizer/mo/front/common/partial_infer/slice.py @@ -109,8 +109,7 @@ def tf_strided_slice_infer(node): for attr in ('shrink_axis_mask', 'new_axis_mask', 'ellipsis_mask', 'begin_mask', 'end_mask'): node[attr] = np.array(node[attr], dtype=np.int32) - data_type_str = 'int64' if node.graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32' - node['force_precision_in_ports'] = {port: data_type_str for port in range(1, len(node.in_nodes()))} + node['force_precision_in_ports'] = {port: 'int64' for port in range(1, len(node.in_nodes()))} node.out_node().value = value.copy() if node.in_node(0).value is not None else None node.out_node().shape = np.array(value.shape, dtype=np.int64) diff --git a/model-optimizer/mo/graph/port.py b/model-optimizer/mo/graph/port.py index 357ff0ac7f9..dd06e22a894 100644 --- a/model-optimizer/mo/graph/port.py +++ b/model-optimizer/mo/graph/port.py @@ -138,16 +138,19 @@ class Port: if self.type == 'in': data_node = self.node.in_node(self.idx, control_flow=self.control_flow) const_node = data_node.in_node(control_flow=self.control_flow) + # Set value to data node data_node.value = value data_node.shape = int64_array(value.shape) + # Set value to constant producer - const_node.value = value - const_node.shape = int64_array(value.shape) + if const_node.soft_get('type') == 'Const': + const_node.value = value + const_node.shape = int64_array(value.shape) else: self.node.out_node(self.idx, control_flow=self.control_flow).value = value self.node.out_node(self.idx, control_flow=self.control_flow).shape = int64_array(value.shape) - if self.node.has_valid('type') and self.node.type == 'Const': + if self.node.soft_get('type') == 'Const': self.node.value = value self.node.shape = int64_array(value.shape) diff --git a/model-optimizer/mo/main.py b/model-optimizer/mo/main.py index d180dec7e76..59c4fe1c98c 100644 --- a/model-optimizer/mo/main.py +++ b/model-optimizer/mo/main.py @@ -24,8 +24,7 @@ from collections import OrderedDict import numpy as np -from extensions.back.SpecialNodesFinalization import RemoveConstOps, CreateConstNodesReplacement, RemoveOutputOps, \ - NormalizeTI +from extensions.back.SpecialNodesFinalization import RemoveConstOps, CreateConstNodesReplacement, NormalizeTI from mo.utils.get_ov_update_message import get_ov_update_message from mo.graph.graph import Graph from mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively, for_each_sub_graph_recursively @@ -34,8 +33,7 @@ from mo.pipeline.unified import unified_pipeline from mo.utils import import_extensions from mo.utils.cli_parser import get_placeholder_shapes, get_tuple_values, get_model_name, \ get_common_cli_options, get_caffe_cli_options, get_tf_cli_options, get_mxnet_cli_options, get_kaldi_cli_options, \ - get_onnx_cli_options, get_mean_scale_dictionary, parse_tuple_pairs, get_freeze_placeholder_values, \ - append_exp_keys_to_namespace, get_meta_info + get_onnx_cli_options, get_mean_scale_dictionary, parse_tuple_pairs, get_freeze_placeholder_values, get_meta_info from mo.utils.error import Error, FrameworkError from mo.utils.guess_framework import deduce_framework_by_namespace from mo.utils.logger import init_logger @@ -240,10 +238,6 @@ def emit_ir(graph: Graph, argv: argparse.Namespace): NormalizeTI().find_and_replace_pattern(graph) for_graph_and_each_sub_graph_recursively(graph, RemoveConstOps().find_and_replace_pattern) for_graph_and_each_sub_graph_recursively(graph, CreateConstNodesReplacement().find_and_replace_pattern) - if not graph.graph['cmd_params'].generate_experimental_IR_V10: - for_each_sub_graph_recursively(graph, RemoveOutputOps().find_and_replace_pattern) - if not graph.graph['cmd_params'].generate_experimental_IR_V10: - for_graph_and_each_sub_graph_recursively(graph, RemoveOutputOps().find_and_replace_pattern) prepare_emit_ir(graph=graph, data_type=graph.graph['cmd_params'].data_type, @@ -296,12 +290,6 @@ def main(cli_parser: argparse.ArgumentParser, framework: str): argv = cli_parser.parse_args() if framework: argv.framework = framework - append_exp_keys_to_namespace(argv) - - # set output precision for operations producing bool values to be I32 as it was for the IRv7 - if argv.generate_deprecated_IR_V7: - from mo.middle.passes.convert_data_type import SUPPORTED_DATA_TYPES - SUPPORTED_DATA_TYPES['bool'] = (np.bool, 'I32', 'boolean') ov_update_message = None if not hasattr(argv, 'silent') or not argv.silent: diff --git a/model-optimizer/mo/main_test.py b/model-optimizer/mo/main_test.py index b451201e287..c7fbe4a615a 100644 --- a/model-optimizer/mo/main_test.py +++ b/model-optimizer/mo/main_test.py @@ -23,7 +23,7 @@ from mo.utils.error import FrameworkError class TestMainErrors(unittest.TestCase): - @patch('argparse.ArgumentParser.parse_args', return_value=argparse.Namespace(generate_deprecated_IR_V7=False)) + @patch('argparse.ArgumentParser.parse_args', return_value=argparse.Namespace()) @patch('mo.main.driver', side_effect=FrameworkError('FW ERROR MESSAGE')) def test_FrameworkError(self, mock_argparse, mock_driver): with self.assertLogs() as logger: diff --git a/model-optimizer/mo/middle/passes/conv.py b/model-optimizer/mo/middle/passes/conv.py index b196b24a04e..34ad656a767 100644 --- a/model-optimizer/mo/middle/passes/conv.py +++ b/model-optimizer/mo/middle/passes/conv.py @@ -22,10 +22,8 @@ from mo.front.common.layout import get_batch_dim, get_features_dim from mo.front.extractor import add_attrs_props from mo.front.extractor import update_ie_fields from mo.graph.graph import Node, Graph -from mo.middle.passes.fusing.helpers import get_value_id, get_tensor_id, get_tensor_in_port, get_value_in_port +from mo.middle.passes.fusing.helpers import get_value_id, get_tensor_id from mo.middle.pattern_match import apply_pattern -from mo.ops.const import Const -from mo.ops.scale_shift import ScaleShiftOp def pad_op_transform(graph: Graph, match: dict): @@ -164,34 +162,6 @@ def muladd_to_scaleshift_action(graph: Graph, match: dict): return -def convert_muladd_to_scaleshift(graph: Graph): - if hasattr(graph, 'graph') and 'cmd_params' in graph.graph and graph.graph['cmd_params'].generate_experimental_IR_V10: - return - # TODO nGraph remove BEGIN - apply_pattern( - graph, - nodes=[ - ('input', dict(kind='data')), - ('weights', dict(kind='data')), - ('bias', dict(kind='data')), - ('mout', dict(kind='data')), - ('output', dict(kind='data')), - ('mul', dict(kind='op', op='Mul')), - ('add', dict(kind='op', op='Add')) - ], - edges=[ - ('weights', 'mul'), - ('input', 'mul'), - ('mul', 'mout'), - ('mout', 'add'), - ('bias', 'add'), - ('add', 'output'), - ], - action=muladd_to_scaleshift_action - ) - # TODO nGraph remove END - - def batch_norm_fuse_action(graph: Graph, match: dict): """ Multiply convolution kernel by batch normalization coefficient and remove mul op. @@ -229,56 +199,3 @@ def batch_norm_fuse(graph: Graph): action=batch_norm_fuse_action ) return graph - - -def convert_add_or_mul_to_scaleshift(graph: Graph): - if graph.graph['cmd_params'].generate_experimental_IR_V10: - return - graph.strict_mode = False - for node in graph.get_op_nodes(): - if node.soft_get('op') in ['Add', 'Mul'] and len(node.in_ports()) == 2: - - tensor_port, value_port = get_tensor_in_port(node), get_value_in_port(node) - - if tensor_port is not None and not tensor_port.disconnected() and value_port is not None and \ - node.soft_get('can_be_scaleshift') is not False: - original_value = value_port.data.get_value() - if original_value.size == 1: - continue - - # Remove 1 dims from value array (should be 1D) - value_port.data.set_value(np.squeeze(original_value)) # Updated shapes accordingly - - # Create ScaleShift operation - scsh_op = ScaleShiftOp(graph, dict(name='ScaleShift/{}'.format(node.name))).create_node() - - if node.op == 'Mul': - # Create fake biases for scale shift node - const_op = Const(graph, dict(name='{}/biases'.format(scsh_op.name), - value=np.zeros(value_port.data.get_shape(), dtype=np.float32), - shape=np.array(value_port.data.get_shape()), - )).create_node() - const_op.out_port(0).connect(scsh_op.in_port(2)) - scsh_op.in_port(2).bin = 'biases' - - # Reconnect input and weights to scale shift node - tensor_port.get_connection().set_destination(scsh_op.in_port(0)) - value_port.get_connection().set_destination(scsh_op.in_port(1)) - else: - # Create fake weights for scale shift node - const_op = Const(graph, dict(name='{}/weights'.format(scsh_op.name), - value=np.ones(value_port.data.get_shape(), dtype=np.float32), - shape=np.array(value_port.data.get_shape()), - )).create_node() - - # Reconnect input and biases to scale shift node - tensor_port.get_connection().set_destination(scsh_op.in_port(0)) - const_op.out_port(0).connect(scsh_op.in_port(1)) - value_port.get_connection().set_destination(scsh_op.in_port(2)) - scsh_op.in_port(2).bin = 'biases' - - node.out_port(0).get_connection().set_source(scsh_op.out_port(0)) - - # Set bin attribute to ScaleShift input ports - scsh_op.in_port(1).bin = 'weights' - graph.strict_mode = True diff --git a/model-optimizer/mo/middle/passes/conv_test.py b/model-optimizer/mo/middle/passes/conv_test.py deleted file mode 100644 index d7a75a5af85..00000000000 --- a/model-optimizer/mo/middle/passes/conv_test.py +++ /dev/null @@ -1,284 +0,0 @@ -""" - 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 unittest - -import numpy as np - -from mo.graph.graph import Node -from mo.middle.passes.conv import convert_muladd_to_scaleshift, convert_add_or_mul_to_scaleshift -from mo.utils.ir_engine.compare_graphs import compare_graphs -from mo.utils.unittest.graph import build_graph - -nodes_attributes = { - 'placeholder_1': {'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', 'value': None, 'kind': 'op', 'op': 'ScaleShift'}, - 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op'}, - 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op'}, - 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'}, - 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - # Mul and Add operations - 'mul_1': {'value': None, 'kind': 'op', 'op': 'Mul'}, - 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op'}, - 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'add_1': {'value': None, 'kind': 'op', 'op': 'Add'}, - 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op'}, - 'add_1_w': {'value': None, 'shape': None, 'kind': 'data'}, - 'add_1_data': {'value': None, 'shape': None, 'kind': 'data'}, - 'op_output': {'kind': 'op', 'op': 'Result'}, -} - - -class MulAddToScaleShift(unittest.TestCase): - def _create_graph_with_mul_add(self, mul_w, add_w): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'mul_1'), - ('const_mul_1_w', 'mul_1_w'), - ('mul_1_w', 'mul_1'), - ('mul_1', 'mul_1_data'), - ('mul_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'mul_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'add_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'const_mul_1_w': {'shape': np.array(mul_w.shape) if mul_w is not None else None, - 'value': np.array(mul_w) if mul_w is not None else None}, - 'mul_1_w': {'shape': np.array(mul_w.shape) if mul_w is not None else None, - 'value': np.array(mul_w) if mul_w is not None else None}, - 'const_add_1_w': {'shape': np.array(add_w.shape) if add_w is not None else None, - 'value': np.array(add_w) if add_w is not None else None}, - 'add_1_w': {'shape': np.array(add_w.shape) if add_w is not None else None, - 'value': np.array(add_w) if add_w is not None else None}, - }) - del graph['mul_1']['mul_1_data'][0]['in'] - del graph['add_1']['add_1_data'][0]['in'] - return graph - - @unittest.skip("ScaleShift is not supported") - def test_mul_add_to_scaleshift_1(self): - graph = self._create_graph_with_mul_add(np.array([1, 2, 3]), np.array([1, 2, 3])) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'scaleshift_1'), - ('const_scaleshift_1_w', 'scaleshift_1_w'), - ('scaleshift_1_w', 'scaleshift_1'), - ('const_scaleshift_1_b', 'scaleshift_1_b'), - ('scaleshift_1_b', 'scaleshift_1'), - ('scaleshift_1', 'scaleshift_1_data'), - ('scaleshift_1_data', 'op_output'), - ], - {'const_scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - 'scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - 'const_scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - 'scaleshift_1_data': {} - }) - - convert_muladd_to_scaleshift(graph) - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'add_1_data', 'scaleshift_1_data') - self.assertTrue(flag, resp) - - @unittest.skip("Power is not supported") - def test_mul_add_neg_1(self): - graph = self._create_graph_with_mul_add(None, np.array([2])) - graph_ref = self._create_graph_with_mul_add(None, np.array([2])) - - convert_muladd_to_scaleshift(graph) - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'add_1_data', 'add_1_data', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test_mul_add_neg_2(self): - graph = self._create_graph_with_mul_add(np.array([2]), None) - graph_ref = self._create_graph_with_mul_add(np.array([2]), None) - - convert_muladd_to_scaleshift(graph) - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'add_1_data', 'add_1_data', check_op_attrs=True) - self.assertTrue(flag, resp) - - def test_mul_add_neg_3(self): - graph = self._create_graph_with_mul_add(None, None) - graph_ref = self._create_graph_with_mul_add(None, None) - - convert_muladd_to_scaleshift(graph) - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'add_1_data', 'add_1_data', check_op_attrs=True) - self.assertTrue(flag, resp) - - @unittest.skip("TODO investigate why this test is not passing") - def test_mul_add_neg_4(self): - graph = self._create_graph_with_mul_add(np.array([1, 2, 3]), np.array([3])) - graph_ref = self._create_graph_with_mul_add(np.array([1, 2, 3]), np.array([3])) - - convert_muladd_to_scaleshift(graph) - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'add_1_data', 'add_1_data', check_op_attrs=True) - self.assertTrue(flag, resp) - - @unittest.skip("ScaleShift is not supported") - def test_mul_add_neg_5(self): - graph = self._create_graph_with_mul_add(np.array([3]), np.array([3, 2, 1])) - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'scaleshift_1'), - ('const_scaleshift_1_w', 'scaleshift_1_w'), - ('scaleshift_1_w', 'scaleshift_1'), - ('const_scaleshift_1_b', 'scaleshift_1_b'), - ('scaleshift_1_b', 'scaleshift_1'), - ('scaleshift_1', 'add_1_data'), - ('add_1_data', 'op_output'), - ], - {'const_scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([3, 3, 3])}, - 'scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([3, 3, 3])}, - 'const_scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([3, 2, 1])}, - 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([3, 2, 1])}, - }) - - convert_muladd_to_scaleshift(graph) - graph.clean_up() - (flag, resp) = compare_graphs(graph, graph_ref, 'add_1_data', 'add_1_data', check_op_attrs=True) - self.assertTrue(flag, resp) - - -class AddToScaleShift(unittest.TestCase): - @staticmethod - def _create_graph_with_add(add_w: np.ndarray): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'add_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'const_add_1_w': {'shape': np.array(add_w.shape) if add_w is not None else None, - 'value': np.array(add_w) if add_w is not None else None}, - 'add_1_w': {'shape': np.array(add_w.shape) if add_w is not None else None, - 'value': np.array(add_w) if add_w is not None else None}, - }, nodes_with_edges_only=True) - del graph['add_1']['add_1_data'][0]['in'] - return graph - - @staticmethod - def _create_graph_with_mul(mul_w: np.ndarray): - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'mul_1'), - ('const_mul_1_w', 'mul_1_w'), - ('mul_1_w', 'mul_1'), - ('mul_1', 'mul_1_data'), - ('mul_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'mul_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'const_mul_1_w': {'shape': np.array(mul_w.shape) if mul_w is not None else None, - 'value': np.array(mul_w) if mul_w is not None else None}, - 'mul_1_w': {'shape': np.array(mul_w.shape) if mul_w is not None else None, - 'value': np.array(mul_w) if mul_w is not None else None}, - }, nodes_with_edges_only=True) - del graph['mul_1']['mul_1_data'][0]['in'] - return graph - - @unittest.skip("ScaleShift is not supported") - def test_add_to_scaleshift_1(self): - graph = AddToScaleShift._create_graph_with_add(np.array([1, 2, 3], dtype=np.float32)) - graph.stage = 'middle' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'scaleshift_1'), - ('const_scaleshift_1_w', 'scaleshift_1_w'), - ('const_scaleshift_1_b', 'scaleshift_1_b'), - ('scaleshift_1_w', 'scaleshift_1'), - ('scaleshift_1_b', 'scaleshift_1'), - ('scaleshift_1', 'scaleshift_1_data'), - ('scaleshift_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'scaleshift_1_data': {'shape': np.array([1, 227, 227, 3])}, - - 'const_scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 1, 1])}, - 'scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 1, 1])}, - - 'const_scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - }, nodes_with_edges_only=True) - - convert_add_or_mul_to_scaleshift(graph) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'op_output') - self.assertTrue(flag, resp) - - scsh_node = Node(graph, 'op_output').in_port(0).get_source().node - - self.assertTrue(graph.get_edge_data(scsh_node.in_node(1).id, scsh_node.id)[0]['bin'] == 'weights') - self.assertTrue(graph.get_edge_data(scsh_node.in_node(2).id, scsh_node.id)[0]['bin'] == 'biases') - - @unittest.skip("ScaleShift is not supported") - def test_mul_to_scaleshift_1(self): - graph = AddToScaleShift._create_graph_with_mul(np.array([1, 2, 3], dtype=np.float32)) - graph.stage = 'middle' - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'scaleshift_1'), - ('const_scaleshift_1_w', 'scaleshift_1_w'), - ('const_scaleshift_1_b', 'scaleshift_1_b'), - ('scaleshift_1_w', 'scaleshift_1'), - ('scaleshift_1_b', 'scaleshift_1'), - ('scaleshift_1', 'scaleshift_1_data'), - ('scaleshift_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}, - 'scaleshift_1_data': {'shape': np.array([1, 227, 227, 3])}, - - 'const_scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - 'scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}, - - 'const_scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([0, 0, 0])}, - 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([0, 0, 0])}, - }, nodes_with_edges_only=True) - - convert_add_or_mul_to_scaleshift(graph) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'op_output') - self.assertTrue(flag, resp) - - scsh_node = Node(graph, 'op_output').in_port(0).get_source().node - - self.assertTrue(graph.get_edge_data(scsh_node.in_node(1).id, scsh_node.id)[0]['bin'] == 'weights') - self.assertTrue(graph.get_edge_data(scsh_node.in_node(2).id, scsh_node.id)[0]['bin'] == 'biases') - - - -if __name__ == '__main__': - unittest.main() diff --git a/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops.py b/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops.py index 61fb027705b..cb833c143dc 100644 --- a/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops.py +++ b/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops.py @@ -15,7 +15,6 @@ """ import logging as log -from typing import List import numpy as np @@ -47,7 +46,7 @@ def _fuse_mul(graph: Graph, node: Node, fuse_nodes: list, backward: bool = True) for fuse_node in fuse_nodes: if fuse_node.soft_get('can_be_fused') is False: - log.warning('Node {} can\'t be used in fusing due to user specified attr can_be_fused = False'.format(fuse_node.name)) + log.warning('Node {} can\'t be used in fusing because attr can_be_fused = False'.format(fuse_node.name)) return False if len(fuse_node.in_ports()) < 2: @@ -59,7 +58,8 @@ def _fuse_mul(graph: Graph, node: Node, fuse_nodes: list, backward: bool = True) return False weights_port = fuse_node.in_port(1) - if not weights_port.data.has_valid('output_channel_dim') or not weights_port.data.has_valid('input_channel_dim'): + if not weights_port.data.has_valid('output_channel_dim') or \ + not weights_port.data.has_valid('input_channel_dim'): log.warning( 'Cannot do fuse_mul for node {} because there is no field ' + 'output_channel_dim and/or input_channel_dim in weights.' @@ -67,7 +67,8 @@ def _fuse_mul(graph: Graph, node: Node, fuse_nodes: list, backward: bool = True) ) return False - inp_ch, out_ch = weights_port.data.get_attr('input_channel_dim'), weights_port.data.get_attr('output_channel_dim') + inp_ch = weights_port.data.get_attr('input_channel_dim') + out_ch = weights_port.data.get_attr('output_channel_dim') if max(inp_ch, out_ch) >= len(weights_port.data.get_shape()): log.warning('Node {} has wrong weights shape'.format(fuse_node.name)) return False @@ -80,7 +81,7 @@ def _fuse_mul(graph: Graph, node: Node, fuse_nodes: list, backward: bool = True) # TODO : ch_dim should be equal to node.in_node(1).value.shape # We will multiply weights according output/input channel dimension - ch_dim = weights_port.data.get_attr('output_channel_dim') if backward else weights_port.data.get_attr('input_channel_dim') + ch_dim = weights_port.data.get_attr('output_channel_dim' if backward else 'input_channel_dim') shape = np.array([weights_port.data.get_shape()[ch_dim]]) # Scalar broadcast @@ -137,90 +138,6 @@ def _fuse_mul(graph: Graph, node: Node, fuse_nodes: list, backward: bool = True) return is_fused -def _fuse_add(graph: Graph, node: Node, fuse_nodes: List[Node], backward: bool = True): - """ - This function takes Add node and Convolution/FC nodes for further fusion and then deletes Add node - In case if Convolution/FC Bias absence it will be created - """ - is_fused = False - const_port, tensor_port = get_value_in_port(node), get_tensor_in_port(node) - - if const_port is None or tensor_port is None: - log.warning('Cannot do fuse_add for node {} because this node has wrong inputs'.format(node.id)) - return False - - # if len(node.in_node(const_id).shape) > 2 or any([x == 0 for x in node.in_node(const_id).shape]): - # log.warning('Cannot do fuse_add for node {} because this node has wrong shape'.format(node.id)) - # return False - - for fuse_node in fuse_nodes: - if fuse_node.soft_get('can_be_fused') is False: - log.warning('Node {} can\'t be used in fusing due to user specified attr can_be_fused = False'.format(fuse_node.name)) - return False - if not fuse_node.has_valid('layout'): - log.warning('Node {} has no layout attr'.format(fuse_node.name)) - return False - if len(fuse_node.in_ports()) < 2: - log.warning('Node {} has no weights node'.format(fuse_node.name)) - return False - - for fuse_node in fuse_nodes: - weights_port = fuse_node.in_port(1) - value = np.array(const_port.data.get_value()) - - # If forward, broadcast value - if not backward: - cnt = weights_port.data.get_shape()[-1] / const_port.data.get_value().size - if fuse_node.layout == 'NCHW': - tmp = [] - for val in value: - tmp = np.concatenate((tmp, np.repeat(val, cnt))) - value = np.array(tmp) - else: - value = np.tile(value, int(cnt)) - - value = np.squeeze(value) - - # Create BIAS data node if not exists - if len(fuse_node.in_ports()) <= 2: - fuse_node.add_input_port(idx=2) - if fuse_node.in_port(2).disconnected() or fuse_node.in_port(2).data.get_value() is None: - # Broadcast if scalar - if value.size == 1: - id = weights_port.data.get_attr('output_channel_dim') if backward else weights_port.data.get_attr('input_channel_dim') - vshape = weights_port.data.get_shape()[id] - value = np.full(vshape, value.item()) - - if not backward: - value = np.dot(weights_port.data.get_value(), value) - - const_bias_node = Const(graph, dict(name="bias_data", value=np.array(value))).create_node() - - fuse_node.in_port(2).connect(const_bias_node.out_port(0)) - fuse_node.in_port(2).bin = 'biases' - const_bias_node.infer(const_bias_node) - - fuse_node['bias_term'] = True - else: - bias_value = fuse_node.in_port(2).data.get_value() - if not backward: - fuse_node.in_port(2).data.set_value(bias_value + np.dot(fuse_node.in_port(1).data.get_value(), value)) - else: - fuse_node.in_port(2).data.set_value(bias_value + value) - - log.debug('Fused: {} to {}'.format(node.name, fuse_node.name)) - is_fused = True - - if is_fused: - # Delete Add node - producer_port = tensor_port.get_source() - tensor_port.disconnect() - const_port.disconnect() - node.out_port(0).get_connection().set_source(producer_port) - - return is_fused - - def fuse_linear_ops(graph: Graph): """ This function makes fusing of linear operations (Mul,Add) to Convolution/FC. @@ -233,19 +150,10 @@ def fuse_linear_ops(graph: Graph): is_fused = False # Fuse Mul to Convolution/FC - if node.soft_get('op') == 'Mul' and get_value_in_port(node) is not None and node.soft_get('can_be_fused') is True: + if node.soft_get('op') == 'Mul' and get_value_in_port(node) is not None and node.has_and_set('can_be_fused'): fuse_nodes = backward_bfs(node, [], ['Convolution', 'Deconvolution', 'MatMul']) is_fused = _fuse_mul(graph, node, fuse_nodes) - if hasattr(graph, 'graph') and 'cmd_params' in graph.graph and \ - not graph.graph['cmd_params'].generate_experimental_IR_V10: - # Fuse Add to Convolution/FC - if node.soft_get('op') == 'Add'\ - and get_value_in_port(node) is not None\ - and node.soft_get('can_be_fused') is True: - fuse_nodes = backward_bfs(node, [], ['Convolution', 'Deconvolution', 'MatMul']) - is_fused = _fuse_add(graph, node, fuse_nodes) - fuse_count += is_fused # Fusion in forward direction @@ -254,19 +162,10 @@ def fuse_linear_ops(graph: Graph): is_fused = False # Fuse Mul to Convolution/FC - if node.soft_get('op') == 'Mul' and get_value_in_port(node) is not None and node.soft_get('can_be_fused') is True: + if node.soft_get('op') == 'Mul' and get_value_in_port(node) is not None and node.has_and_set('can_be_fused'): fuse_nodes = forward_bfs(node, [], ['Convolution', 'Deconvolution', 'MatMul']) is_fused = _fuse_mul(graph, node, fuse_nodes, False) - # Fuse Add to Convolution/FC - if hasattr(graph, 'graph') and 'cmd_params' in graph.graph and \ - not graph.graph['cmd_params'].generate_experimental_IR_V10: - if node.soft_get('op') == 'Add' and \ - get_value_in_port(node) is not None and \ - node.soft_get('can_be_fused') is True: - fuse_nodes = forward_bfs(node, [], ['MatMul']) - is_fused = _fuse_add(graph, node, fuse_nodes, False) - fuse_count += is_fused log.debug("Fused {} nodes".format(fuse_count)) diff --git a/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops_test.py b/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops_test.py index a9968da3494..5bc4f3301ad 100644 --- a/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops_test.py +++ b/model-optimizer/mo/middle/passes/fusing/fuse_linear_ops_test.py @@ -20,7 +20,7 @@ import numpy as np from mo.front.common.partial_infer.eltwise import eltwise_infer from mo.graph.graph import Node -from mo.middle.passes.fusing.fuse_linear_ops import _fuse_mul, _fuse_add, fuse_linear_ops +from mo.middle.passes.fusing.fuse_linear_ops import _fuse_mul, fuse_linear_ops from mo.utils.ir_engine.compare_graphs import compare_graphs from mo.utils.unittest.graph import build_graph @@ -784,246 +784,6 @@ class FuseMulTests(unittest.TestCase): self.assertTrue(flag, resp) -# Unit tests for fuse_add -class FuseAddTests(unittest.TestCase): - # Add(array)->FC(w+b) - def test_fuse_add_to_fc_1(self): - # Placeholder->Add->FC - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('const_fc_1_b', 'fc_1_b'), - ('fc_1_w', 'fc_1'), - ('fc_1_b', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'op_output') - - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'add_1_data': {'shape': np.array([1, 2048])}, - 'const_add_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])}, - 'add_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])}, - 'const_fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048))}, - 'fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048)), - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2}, - 'const_fc_1_b': {'shape': np.array([10260]), 'value': np.ones(10260)}, - 'fc_1_b': {'shape': np.array([10260]), 'value': np.ones(10260)}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - ref_weights = np.ones((10260, 2048)) - ref_biases = np.ones(10260) + np.dot(np.ones((10260, 2048)), np.array([x for x in range(2048)])) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('const_fc_1_b', 'fc_1_b'), - ('fc_1_w', 'fc_1'), - ('fc_1_b', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'const_fc_1_w': {'shape': ref_weights.shape, 'value': ref_weights}, - 'fc_1_w': {'shape': ref_weights.shape, 'value': ref_weights, - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2}, - 'const_fc_1_b': {'shape': ref_biases.shape, 'value': ref_biases}, - 'fc_1_b': {'shape': ref_biases.shape, 'value': ref_biases}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - _fuse_add(graph, Node(graph, 'add_1'), [Node(graph, 'fc_1')], backward=False) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1') - self.assertTrue(flag, resp) - - # FC(w)->Add(array) - def test_fuse_add_to_fc_2(self): - # Placeholder->FC->Add - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('fc_1_w', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'op_output_1') - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'add_1_data': {'shape': np.array([1, 10260])}, - 'const_add_1_w': {'shape': np.array([10260]), 'value': np.array([x for x in range(10260)])}, - 'add_1_w': {'shape': np.array([10260]), 'value': np.array([x for x in range(10260)]), - 'data_type': None}, - 'const_fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048))}, - 'fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048)), - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2, 'data_type': None}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - ref_weights = np.ones((10260, 2048)) - ref_biases = np.array([x for x in range(10260)]) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('const_fc_1_b', 'fc_1_b'), - ('fc_1_w', 'fc_1'), - ('fc_1_b', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'const_fc_1_w': {'shape': ref_weights.shape, 'value': ref_weights}, - 'fc_1_w': {'shape': ref_weights.shape, 'value': ref_weights, - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2}, - 'const_fc_1_b': {'shape': ref_biases.shape, 'value': ref_biases}, - 'fc_1_b': {'shape': ref_biases.shape, 'value': ref_biases}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - _fuse_add(graph, Node(graph, 'add_1'), [Node(graph, 'fc_1')], backward=True) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1') - self.assertTrue(flag, resp) - - # FC(w)->Add(scalar) - def test_fuse_add_to_fc_3(self): - # Placeholder->FC->Add - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('fc_1_w', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'add_1_data': {'shape': np.array([1, 10260])}, - 'const_add_1_w': {'shape': np.array([1]), 'value': 6, 'data_type': None}, - 'add_1_w': {'shape': np.array([1]), 'value': 6, 'data_type': None}, - 'const_fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048))}, - 'fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048)), - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2, 'data_type': None}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - ref_weights = np.ones((10260, 2048)) - ref_biases = np.full([10260], 6) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('const_fc_1_b', 'fc_1_b'), - ('fc_1_w', 'fc_1'), - ('fc_1_b', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'op_output') - - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'const_fc_1_w': {'shape': ref_weights.shape, 'value': ref_weights}, - 'fc_1_w': {'shape': ref_weights.shape, 'value': ref_weights, - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2}, - 'const_fc_1_b': {'shape': ref_biases.shape, 'value': ref_biases}, - 'fc_1_b': {'shape': ref_biases.shape, 'value': ref_biases}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - _fuse_add(graph, Node(graph, 'add_1'), [Node(graph, 'fc_1')], backward=True) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1') - self.assertTrue(flag, resp) - - # Add(array)->FC(w+b) can_be_fused = False - def test_fuse_add_to_fc_4(self): - # Placeholder->Add->FC - graph = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('const_fc_1_b', 'fc_1_b'), - ('fc_1_w', 'fc_1'), - ('fc_1_b', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'op_output') - - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'add_1_data': {'shape': np.array([1, 2048])}, - 'const_add_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])}, - 'add_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])}, - 'fc_1': {'can_be_fused': False}, - 'const_fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048))}, - 'fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048)), - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2}, - 'const_fc_1_b': {'shape': np.array([10260]), 'value': np.ones(10260)}, - 'fc_1_b': {'shape': np.array([10260]), 'value': np.ones(10260)}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - graph_ref = build_graph(nodes_attributes, - [('placeholder_1', 'placeholder_1_data'), - ('placeholder_1_data', 'add_1'), - ('const_add_1_w', 'add_1_w'), - ('add_1_w', 'add_1'), - ('add_1', 'add_1_data'), - ('add_1_data', 'fc_1'), - ('const_fc_1_w', 'fc_1_w'), - ('const_fc_1_b', 'fc_1_b'), - ('fc_1_w', 'fc_1'), - ('fc_1_b', 'fc_1'), - ('fc_1', 'fc_1_data'), - ('fc_1_data', 'op_output') - ], - {'placeholder_1_data': {'shape': np.array([1, 2048])}, - 'add_1_data': {'shape': np.array([1, 2048])}, - 'const_add_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])}, - 'add_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])}, - 'fc_1': {'can_be_fused': False}, - 'const_fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048))}, - 'fc_1_w': {'shape': np.array([10260, 2048]), 'value': np.ones((10260, 2048)), - 'output_channel_dim': 0, 'input_channel_dim': 1, - 'dims_number': 2}, - 'const_fc_1_b': {'shape': np.array([10260]), 'value': np.ones(10260)}, - 'fc_1_b': {'shape': np.array([10260]), 'value': np.ones(10260)}, - 'fc_1_data': {'shape': np.array([1, 10260])}, - }) - - _fuse_add(graph, Node(graph, 'add_1'), [Node(graph, 'fc_1')], backward=False) - graph.clean_up() - - (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1') - self.assertTrue(flag, resp) - - # Unit tests for fuse_linear_ops class FuseLinOpsTests(unittest.TestCase): # Op->Mul(array)-+->Conv(w+b)->Add-+->Concat Op-+->Conv1-+-->Concat diff --git a/model-optimizer/mo/ops/broadcast.py b/model-optimizer/mo/ops/broadcast.py index 119f7ef7c87..cfb182fb7c4 100644 --- a/model-optimizer/mo/ops/broadcast.py +++ b/model-optimizer/mo/ops/broadcast.py @@ -43,8 +43,8 @@ class Broadcast(Op): 'in_ports_count': 3, 'out_ports_count': 1, 'force_precision_in_ports': - {1: 'int64' if graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32', - 2: 'int64' if graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32', + {1: 'int64', + 2: 'int64', }, 'infer': __class__.infer, }, attrs) diff --git a/model-optimizer/mo/ops/convolution.py b/model-optimizer/mo/ops/convolution.py index 8d85a7f93e6..daa09536889 100644 --- a/model-optimizer/mo/ops/convolution.py +++ b/model-optimizer/mo/ops/convolution.py @@ -249,9 +249,6 @@ class Convolution(Op): pad_spatial_shape -= output_padding for dim in range(len(pad_spatial_shape)): node.pad_spatial_shape[dim][1] -= pad_spatial_shape[dim] - if not node.graph.graph['cmd_params'].generate_experimental_IR_V10: - node.pad[node.spatial_dims] = node.pad_spatial_shape - node['output_padding'] = None float_spatial = Convolution.calc_deconvolution(node, input_spatial_shape, pad_spatial_shape, kernel_extent) diff --git a/model-optimizer/mo/ops/deconvolution.py b/model-optimizer/mo/ops/deconvolution.py index 8733c9ade5d..c40a0c7a775 100644 --- a/model-optimizer/mo/ops/deconvolution.py +++ b/model-optimizer/mo/ops/deconvolution.py @@ -151,8 +151,4 @@ class Deconvolution(Op): node.get_weights_permute if node.has_valid('get_weights_permute') else None) PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'shape') - if not node.graph.graph['cmd_params'].generate_experimental_IR_V10: - node.graph.remove_edge(node.in_node(2).id, node.id) - node['shape_input'] = False - else: - node['force_precision_in_ports'] = {2: 'int64'} + node['force_precision_in_ports'] = {2: 'int64'} diff --git a/model-optimizer/mo/ops/pad.py b/model-optimizer/mo/ops/pad.py index 66b88c376e6..c1ee619198c 100644 --- a/model-optimizer/mo/ops/pad.py +++ b/model-optimizer/mo/ops/pad.py @@ -44,8 +44,8 @@ class Pad(Op): 'mode': 'constant', 'fill_value': float(0), 'force_precision_in_ports': { - 1: 'int64' if graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32', - 2: 'int64' if graph.graph['cmd_params'].generate_experimental_IR_V10 else 'int32', + 1: 'int64', + 2: 'int64', }, }, attrs) diff --git a/model-optimizer/mo/ops/strided_slice_test.py b/model-optimizer/mo/ops/strided_slice_test.py index d8fa18c3d09..871e0cd4102 100644 --- a/model-optimizer/mo/ops/strided_slice_test.py +++ b/model-optimizer/mo/ops/strided_slice_test.py @@ -38,6 +38,7 @@ nodes_attributes = { 'begin': { 'kind': 'op', 'op': 'Const', + 'type': 'Const', 'value': None, 'shape': None }, @@ -49,6 +50,7 @@ nodes_attributes = { 'end': { 'kind': 'op', 'op': 'Const', + 'type': 'Const', 'value': None, 'shape': None }, @@ -60,6 +62,7 @@ nodes_attributes = { 'stride': { 'kind': 'op', 'op': 'Const', + 'type': 'Const', 'value': None, 'shape': None }, diff --git a/model-optimizer/mo/pipeline/common.py b/model-optimizer/mo/pipeline/common.py index d89cb739938..55a7fac24ff 100644 --- a/model-optimizer/mo/pipeline/common.py +++ b/model-optimizer/mo/pipeline/common.py @@ -199,11 +199,9 @@ def prepare_emit_ir(graph: Graph, data_type: str, output_dir: str, output_model_ convert_data_type.convert_blobs(sub_graph, data_type) # restore data type for specific inputs/outputs of specific ops to the data types required by nGraph - if not graph.graph['cmd_params'].generate_deprecated_IR_V7: - for_graph_and_each_sub_graph_recursively(graph, convert_inputs_of_specific_ops) + for_graph_and_each_sub_graph_recursively(graph, convert_inputs_of_specific_ops) - if graph.graph['cmd_params'].generate_experimental_IR_V10: - for_graph_and_each_sub_graph_recursively(graph, OpVersioning().find_and_replace_pattern) + for_graph_and_each_sub_graph_recursively(graph, OpVersioning().find_and_replace_pattern) # do not run the type inference in sub-graphs. It will be called automatically as part of the type inference of # the TensorIterator nodes @@ -242,10 +240,4 @@ def get_ir_version(argv: argparse.Namespace): :param argv: the parsed command line arguments :return: the IR version """ - if argv.generate_experimental_IR_V10: - version = 10 - elif argv.generate_deprecated_IR_V2: - version = 2 - else: - version = 7 - return version + return 10 diff --git a/model-optimizer/mo/utils/cli_parser.py b/model-optimizer/mo/utils/cli_parser.py index 7b70e807192..b0d41a81eeb 100644 --- a/model-optimizer/mo/utils/cli_parser.py +++ b/model-optimizer/mo/utils/cli_parser.py @@ -44,12 +44,14 @@ class DeprecatedStoreTrue(argparse.Action): setattr(namespace, self.dest, True) -class DeprecatedTensorflowOffloadFeatureAction(argparse.Action): +class IgnoredAction(argparse.Action): + def __init__(self, nargs=0, **kw): + super().__init__(nargs=nargs, **kw) + def __call__(self, parser, namespace, values, option_string=None): - msg = "Use of deprecated cli option {} detected. Option use in the following releases will be fatal." \ - "".format(option_string) - log.error(msg, extra={'is_warning': True}) - setattr(namespace, self.dest, values) + dep_msg = "Use of removed cli option '{}' detected. The option is ignored. ".format(option_string) + log.error(dep_msg, extra={'is_warning': True}) + setattr(namespace, self.dest, True) class CanonicalizePathAction(argparse.Action): @@ -312,9 +314,8 @@ def get_common_cli_parser(parser: argparse.ArgumentParser = None): 'Use --input option to specify a value for freezing.', default=None) common_group.add_argument('--generate_deprecated_IR_V7', - help='Force to generate old deprecated IR V7' - ' with layers from old IR specification.', - action=DeprecatedStoreTrue, + help='Force to generate deprecated IR V7 with layers from old IR specification.', + action=IgnoredAction, default=False) common_group.add_argument('--keep_shape_ops', help='[ Experimental feature ] Enables `Shape` operation with all children keeping. ' @@ -640,13 +641,6 @@ def get_all_cli_parser(): return parser -def append_exp_keys_to_namespace(argv: argparse.Namespace): - setattr(argv, 'keep_quantize_ops_in_IR', True) - setattr(argv, 'blobs_as_inputs', True) - setattr(argv, 'generate_experimental_IR_V10', not argv.generate_deprecated_IR_V7) - setattr(argv, 'generate_deprecated_IR_V2', False) - - def remove_data_type_from_input_value(input_value: str): """ Removes the type specification from the input string. The type specification is a string enclosed with curly braces. diff --git a/model-optimizer/mo/utils/ir_reader/extenders/fakequantize_extender.py b/model-optimizer/mo/utils/ir_reader/extenders/fakequantize_extender.py index a1958d6040e..785db350155 100644 --- a/model-optimizer/mo/utils/ir_reader/extenders/fakequantize_extender.py +++ b/model-optimizer/mo/utils/ir_reader/extenders/fakequantize_extender.py @@ -23,5 +23,4 @@ class FakeQuantize_extender(Extender): @staticmethod def extend(op: Node): - op['keep_in_IR'] = True op['stop_value_propagation'] = True diff --git a/model-optimizer/mo/utils/unittest/graph.py b/model-optimizer/mo/utils/unittest/graph.py index 9b1a1188d96..fd7d8468898 100644 --- a/model-optimizer/mo/utils/unittest/graph.py +++ b/model-optimizer/mo/utils/unittest/graph.py @@ -206,7 +206,7 @@ def build_graph(nodes_attrs: dict, edges: list, update_attributes: dict = None, for attr in out_edges.values(): node.add_output_port(idx=attr['out']) - graph.graph['cmd_params'] = Namespace(generate_experimental_IR_V10=False, keep_shape_ops=False) + graph.graph['cmd_params'] = Namespace(keep_shape_ops=False) return graph