was not found")
- out_dim = read_binary_integer32_token(pb)
-
- assert in_dim % out_dim == 0
-
- group = in_dim / out_dim
-
- try:
- collect_until_token(pb, b'')
- except Error:
- raise Error("
was not found")
- p = read_binary_float_token(pb)
-
- attrs = {
- 'group': group,
- 'p': p,
- }
-
- PNormOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/rectified_linear_component_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/rectified_linear_component_ext.py
deleted file mode 100644
index 2538af9d325238..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/rectified_linear_component_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import ReLU
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class RectifiedLinearComponentFrontExtractor(FrontExtractorOp):
- op = 'rectifiedlinearcomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ReLU.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/rescale_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/rescale_ext.py
deleted file mode 100644
index 4c7b72b98657b1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/rescale_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.caffe.extractors.utils import embed_input
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.kaldi.utils import read_binary_vector, read_learning_info
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-
-
-class RescaleFrontExtractor(FrontExtractorOp):
- op = 'rescale'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.parameters
- read_learning_info(pb)
- weights = read_binary_vector(pb)
- mapping_rule = {}
- embed_input(mapping_rule, 1, 'weights', weights)
- ScaleShiftOp.update_node_stat(node, mapping_rule)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/restrictedattentioncomponent_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/restrictedattentioncomponent_ext.py
deleted file mode 100644
index b2eae6d5a56ba9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/restrictedattentioncomponent_ext.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.kaldi.loader.utils import read_binary_bool_token, \
- read_binary_integer32_token, collect_until_token, read_binary_float_token
-from openvino.tools.mo.front.kaldi.utils import read_binary_vector, read_binary_matrix
-from openvino.tools.mo.ops.restrictedattentioncomponent import RestrictedAttentionComponent
-
-
-class RestrictedAttentionComponentFrontExtractor(FrontExtractorOp):
- """
- This class is used for extracting attributes of RestrictedAttention Kaldi operator.
- """
- op = 'restrictedattentioncomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- """
- This method extracts attributes of RestrictedAttention operator from Kaldi model.
- Description of all attributes can be found in the operator documentation:
- https://kaldi-asr.org/doc/classkaldi_1_1nnet3_1_1RestrictedAttentionComponent.html
- """
- params = node.parameters
-
- attrs = {}
-
- collect_until_token(params, b'')
- attrs['num_heads'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['key_dim'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['value_dim'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['num_left_inputs'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['num_right_inputs'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['time_stride'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['num_left_inputs_required'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['num_right_inputs_required'] = read_binary_integer32_token(params)
-
- collect_until_token(params, b'')
- attrs['output_context'] = read_binary_bool_token(params)
-
- collect_until_token(params, b'')
- attrs['key_scale'] = read_binary_float_token(params)
-
- collect_until_token(params, b'')
- attrs['stats_count'] = read_binary_float_token(params)
-
- collect_until_token(params, b'')
- entropy_stats = read_binary_vector(params)
- attrs['entropy_stats'] = mo_array(
- entropy_stats) if len(entropy_stats) != 0 else None
-
- collect_until_token(params, b'')
- posterior_stats, posterior_stats_shape = read_binary_matrix(params)
- attrs['posterior_stats'] = np.reshape(
- posterior_stats, posterior_stats_shape)
-
- RestrictedAttentionComponent.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/scale_component_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/scale_component_ext.py
deleted file mode 100644
index 022346f13d2524..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/scale_component_ext.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.caffe.extractors.utils import embed_input
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.kaldi.loader.utils import find_next_tag, read_placeholder, collect_until_token
-from openvino.tools.mo.front.kaldi.utils import read_binary_vector
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-
-
-class NaturalGradientPerElementScaleComponentFrontExtractor(FrontExtractorOp):
- op = 'naturalgradientperelementscalecomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.parameters
- collect_until_token(pb, b'')
- weights = read_binary_vector(pb)
- find_next_tag(pb)
- read_placeholder(pb, 1)
-
- mapping_rule = {
- 'layout': 'NCHW'
- }
- embed_input(mapping_rule, 1, 'weights', weights)
-
- ScaleShiftOp.update_node_stat(node, mapping_rule)
- return cls.enabled
-
-
-class FixedScaleComponentFrontExtractor(FrontExtractorOp):
- op = 'fixedscalecomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.parameters
- collect_until_token(pb, b'')
- weights = read_binary_vector(pb)
- find_next_tag(pb)
- read_placeholder(pb, 1)
-
- mapping_rule = {
- 'layout': 'NCHW',
- 'out-size': weights.shape[0],
- }
- embed_input(mapping_rule, 1, 'weights', weights)
-
- ScaleShiftOp.update_node_stat(node, mapping_rule)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/softmax_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/softmax_ext.py
deleted file mode 100644
index 7881d79a28b4f2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/softmax_ext.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.softmax import Softmax
-
-
-class SoftmaxComponentFrontExtractor(FrontExtractorOp):
- op = 'softmaxcomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- return SoftmaxFrontExtractor.extract(node)
-
-
-class SoftmaxFrontExtractor(FrontExtractorOp):
- op = 'softmax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Softmax.update_node_stat(node, {'infer': copy_shape_infer})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/specaugment_component_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/specaugment_component_ext.py
deleted file mode 100644
index b4a460c4248200..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/specaugment_component_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.identity import Identity
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SpecAugmentComponentFrontExtractor(FrontExtractorOp):
- op = 'specaugmenttimemaskcomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Identity.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/splice_component_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/splice_component_ext.py
deleted file mode 100644
index 1b153ad6225b0d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/splice_component_ext.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.splice import Splice
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.kaldi.loader.utils import find_next_tag, read_placeholder, read_binary_integer32_token, \
- collect_until_whitespace
-from openvino.tools.mo.front.kaldi.utils import read_binary_vector
-from openvino.tools.mo.utils.error import Error
-
-
-class SpliceFrontExtractor(FrontExtractorOp):
- op = 'splicecomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.parameters
- mapping_rule = {
- 'context': list()
- }
- tag = find_next_tag(pb)
- if tag == '':
- read_placeholder(pb, 1)
- l_context = read_binary_integer32_token(pb)
- tag = find_next_tag(pb)
- if tag != '':
- raise Error('Unknown token {} in SpliceComponent node {}'.format(tag, node.id))
- read_placeholder(pb, 1)
- r_context = read_binary_integer32_token(pb)
- for i in range(-l_context, r_context + 1):
- mapping_rule['context'].append(i)
- elif tag == '':
- collect_until_whitespace(pb)
- mapping_rule['context'] = read_binary_vector(pb, False, dtype=np.int32)
- else:
- raise Error('Unknown token {} in SpliceComponent node {}'.format(tag, node.id))
-
- tag = find_next_tag(pb)
- if tag == '':
- read_placeholder(pb, 1)
- const_dim = read_binary_integer32_token(pb)
- mapping_rule['const_dim'] = const_dim
-
- Splice.update_node_stat(node, mapping_rule)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/tdnncomponent_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/tdnncomponent_ext.py
deleted file mode 100644
index 810df8594064be..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/tdnncomponent_ext.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.kaldi.loader.utils import read_binary_bool_token, read_binary_integer32_token, collect_until_token, \
- read_binary_float_token
-from openvino.tools.mo.front.kaldi.utils import read_binary_vector, read_binary_matrix
-from openvino.tools.mo.ops.tdnncomponent import TdnnComponent
-
-
-class TdnnComponentFrontExtractor(FrontExtractorOp):
- op = 'tdnncomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.parameters
-
- collect_until_token(pb, b'')
- max_change = read_binary_float_token(pb)
-
- collect_until_token(pb, b'')
- collect_until_token(pb, b'')
-
- collect_until_token(pb, b'')
- time_offsets = read_binary_vector(pb, False, np.int32)
-
- collect_until_token(pb, b'')
- weights, weights_shape = read_binary_matrix(pb)
- collect_until_token(pb, b'')
- bias_params = read_binary_vector(pb)
-
- collect_until_token(pb, b'')
- orthonormal_constraint = read_binary_float_token(pb) # used only on training
-
- collect_until_token(pb, b'')
- use_natural_grad = read_binary_bool_token(pb) # used only on training
- collect_until_token(pb, b'')
- num_samples_hist = read_binary_float_token(pb)
-
- collect_until_token(pb, b'')
- alpha_in_out = read_binary_float_token(pb), read_binary_float_token(pb) # for training, usually (4, 4)
-
- # according to Kaldi documentation http://kaldi-asr.org/doc/classkaldi_1_1nnet3_1_1TdnnComponent.html#details
- # it looks like it's used only during training (but not 100% sure)
- collect_until_token(pb, b'')
- rank_in_out = read_binary_integer32_token(pb), read_binary_integer32_token(pb)
-
- biases = mo_array(bias_params) if len(bias_params) != 0 else None
- attrs = {
- 'weights': np.reshape(weights, weights_shape),
- 'biases': biases,
- 'time_offsets': time_offsets,
- }
- TdnnComponent.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/extractors/timeheightconvolution_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/extractors/timeheightconvolution_ext.py
deleted file mode 100644
index df5e627e85c563..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/extractors/timeheightconvolution_ext.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import embed_input
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.kaldi.loader.utils import collect_until_token, read_token_value
-from openvino.tools.mo.front.kaldi.utils import read_binary_matrix, read_binary_vector, read_binary_vector_of_pairs
-from openvino.tools.mo.ops.timeheightconvolution import TimeHeightConvolutionComponent
-
-
-class TimeHeightConvolutionFrontExtractor(FrontExtractorOp):
- op = 'timeheightconvolutioncomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.parameters
- collect_until_token(pb, b'')
- in_shape = read_token_value(pb, b'')
- out_shape = read_token_value(pb, b'')
- height_in = read_token_value(pb, b'')
- height_out = read_token_value(pb, b'')
- height_subsample = read_token_value(pb, b'')
- collect_until_token(pb, b'')
- offsets = read_binary_vector_of_pairs(pb, read_token=False, dtype=np.int32)
- collect_until_token(pb, b'')
- time_offsets = read_binary_vector(pb, read_token=False, dtype=np.int32)
- collect_until_token(pb, b'')
- weights, _ = read_binary_matrix(pb)
- collect_until_token(pb, b'')
- biases = read_binary_vector(pb)
-
- offsets = offsets.reshape([len(offsets)//2, 2])
- mapping_rule = { # stride for h axis
- 'height_subsample': height_subsample,
- # input dimension for h axis
- 'height_in': height_in,
- # output dimension for h axis
- 'height_out': height_out,
- # input dimension for channel axis
- 'in_channels': in_shape,
- # output dimension for channel axis
- 'out_channels': out_shape,
- # array with pairs like the following
- # [ (-1, -1) (-1, 0) (-1, 1)
- # (0, -1) (0, 0) (0, 1)
- # (1, -1) (1, 0) (1, 1)]
- # it means that kernel 3x3 will be applied to calculate current value of output
- 'offsets': offsets,
- # required time offsets to calculate current convolution
- # time_offsets = [-1, 0, 1] for previous example means no padding for time axis and
- # 3 values should be prepared
- # time_offsets = [0] means zero padding [1, 1] for time axis
- 'time_offsets': time_offsets,
- 'out-size': out_shape * height_out}
-
- embed_input(mapping_rule, 1, 'weights', weights)
- embed_input(mapping_rule, 2, 'biases', biases)
-
- TimeHeightConvolutionComponent.update_node_stat(node, mapping_rule)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/loader/__init__.py b/tools/mo/openvino/tools/mo/front/kaldi/loader/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/loader/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/loader/loader.py b/tools/mo/openvino/tools/mo/front/kaldi/loader/loader.py
deleted file mode 100644
index 05a713d8d5cc4a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/loader/loader.py
+++ /dev/null
@@ -1,560 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from io import IOBase
-
-import networkx as nx
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Mul
-from openvino.tools.mo.ops.split import AttributedVariadicSplit
-from openvino.tools.mo.front.common.partial_infer.utils import float_array, int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import add_outputs_identity
-from openvino.tools.mo.front.kaldi.loader.utils import find_next_tag, read_placeholder, find_next_component, get_name_from_path, \
- find_end_of_component, end_of_nnet_tag, read_binary_integer32_token, get_parameters, read_token_value, \
- collect_until_token, collect_until_token_and_read, create_edge_attrs, get_args_for_specifier
-from openvino.tools.mo.front.kaldi.utils import read_binary_vector
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-def load_parallel_component(file_descr, graph: Graph, prev_layer_id):
- """
- Load ParallelComponent of the Kaldi model.
- ParallelComponent contains parallel nested networks.
- VariadicSplit is inserted before nested networks.
- Outputs of nested networks concatenate with layer Concat.
-
- :param file_descr: descriptor of the model file
- :param graph: graph with the topology.
- :param prev_layer_id: id of the input layers for parallel component layer
- :return: id of the concat layer - last layer of the parallel component layers
- """
- nnet_count = read_token_value(file_descr, b'')
- log.debug('Model contains parallel component with {} nested networks'.format(nnet_count))
-
- split_points = []
- outputs = []
- inputs = []
-
- for i in range(nnet_count):
- read_token_value(file_descr, b'')
- collect_until_token(file_descr, b'')
- g = Graph()
- load_kalid_nnet1_model(g, file_descr, 'Nested_net_{}'.format(i))
-
- # input to nnet1 models is of a rank 1 but we also insert batch_size to 0th axis
- # 1st axis contains input_size of the nested subnetwork
- # we split input from the main network to subnetworks
- input_node = Node(g, 'Parameter')
- split_points.append(input_node['shape'][1])
- g.remove_node(input_node.id)
-
- mapping = {node: graph.unique_id(node) for node in g.nodes(data=False) if node in graph}
- g = nx.relabel_nodes(g, mapping)
- for val in mapping.values():
- g.node[val]['name'] = val
- graph.add_nodes_from(g.nodes(data=True))
- graph.add_edges_from(g.edges(data=True))
- sorted_nodes = tuple(nx.topological_sort(g))
-
- outputs.append(Node(graph, sorted_nodes[-1]))
- inputs.append(Node(graph, sorted_nodes[0]))
-
- split_id = graph.unique_id(prefix='NestedNets/VariadicSplit')
- attrs = {'out_ports_count': nnet_count, 'size_splits': split_points, 'axis': 1, 'name': split_id}
- variadic_split_node = AttributedVariadicSplit(graph, attrs).create_node()
- prev_layer_node = Node(graph, prev_layer_id)
- prev_layer_node.add_output_port(0)
- graph.create_edge(prev_layer_node, variadic_split_node, 0, 0, create_edge_attrs(prev_layer_id, variadic_split_node.id, prev_layer_id))
-
- concat_id = graph.unique_id(prefix='Concat')
- graph.add_node(concat_id, parameters=None, op='concat', kind='op')
- concat_node = Node(graph, concat_id)
-
- # Connect each output of variadic_split_node to each subnetwork's inputs in ParallelComponent
- # and each subnetwork's output to concat_node
- for i, (input_node, output_node) in enumerate(zip(inputs, outputs)):
- output_node.add_output_port(0)
- concat_node.add_input_port(i)
- graph.create_edge(output_node, concat_node, 0, i, create_edge_attrs(output_node.id, concat_id, output_node.id, i, 0))
- graph.create_edge(variadic_split_node, input_node, i, 0, create_edge_attrs(variadic_split_node.id, input_node.id, variadic_split_node.id, 0, i))
- return concat_id
-
-
-def load_kaldi_model(graph, nnet_path):
- """
- Structure of the file is the following:
- magic-number(16896) weights etc.
- :param nnet_path:
- :return:
- """
- nnet_name = None
- if isinstance(nnet_path, str):
- file_desc = open(nnet_path, "rb")
- nnet_name = get_name_from_path(nnet_path)
- elif isinstance(nnet_path, IOBase):
- file_desc = nnet_path
- else:
- raise Error('Unsupported type of Kaldi model')
-
- tag = find_next_tag(file_desc)
- # start new model / submodel
- if tag == '':
- load_function = load_kalid_nnet1_model
- elif tag == '':
- while tag != '' and tag != '':
- tag = find_next_tag(file_desc)
-
- if tag == '':
- load_function = load_kaldi_nnet3_model
- else:
- load_function = load_kalid_nnet2_model
- elif tag == '':
- load_function = load_kaldi_nnet3_model
- else:
- raise Error('Kaldi model should start with or tag. ',
- refer_to_faq_msg(89))
- read_placeholder(file_desc, 1)
-
- return load_function(graph, file_desc, nnet_name)
-
-
-def load_kalid_nnet1_model(graph, file_descr, name):
- prev_layer_id = 'Parameter'
- graph.add_node(prev_layer_id, name=prev_layer_id, kind='op', op='Parameter', parameters=None)
-
- # find out output layer, it can be only one due to chain structure of nnet1 model
- output_layer = None
- while True:
- component_type = find_next_component(file_descr)
- if component_type == end_of_nnet_tag.lower()[1:-1]:
- break
-
- layer_o = read_binary_integer32_token(file_descr)
- layer_i = read_binary_integer32_token(file_descr)
-
- if component_type == 'parallelcomponent':
- prev_layer_id = load_parallel_component(file_descr, graph, prev_layer_id)
- find_end_of_component(file_descr, component_type)
- continue
-
- start_index = file_descr.tell()
- end_tag, end_index = find_end_of_component(file_descr, component_type)
- end_index -= len(end_tag)
- layer_id = graph.unique_id(prefix=component_type)
- graph.add_node(layer_id,
- parameters=get_parameters(file_descr, start_index, end_index),
- op=component_type,
- kind='op',
- layer_i=layer_i,
- layer_o=layer_o)
- if hasattr(graph, 'op_names_statistic'):
- graph.op_names_statistic[component_type] += 1
-
- prev_node = Node(graph, prev_layer_id)
- if prev_node.op == 'Parameter':
- prev_node['shape'] = int64_array([1, layer_i])
-
- prev_node.add_output_port(0)
- Node(graph, layer_id).add_input_port(0)
- graph.create_edge(prev_node, Node(graph, layer_id), 0, 0, create_edge_attrs(prev_layer_id, layer_id, prev_layer_id))
- prev_layer_id = layer_id
- output_layer = layer_id
- log.debug('{} (type is {}) was loaded'.format(prev_layer_id, component_type))
-
- # Tensor names information corresponding to a node is stored on outgoing edges.
- # As output nodes do not have outgoing edges, fake outputs are required. In the following code
- # for each output Identity node is added, and tensor name for the output is kept
- # on (output, fake output) edge. After Result nodes adding transformation fake outputs
- # are deleted from graph.
- assert output_layer is not None, "Output layer is not found in graph"
- add_outputs_identity(graph, [output_layer], lambda g, output, fake_output: g.create_edge(
- Node(g, output), Node(g, fake_output), 0, 0, create_edge_attrs(output, fake_output, output)))
-
-
-def load_kalid_nnet2_model(graph, file_descr, nnet_name):
- input_name = 'Input'
- graph.add_node(input_name, name=input_name, kind='op', op='Parameter', parameters=None, shape=None)
-
- prev_layer_id = input_name
-
- all_components = load_components(file_descr, graph)
-
- used_layers = set()
- for layer_id in all_components:
- prev_node = Node(graph, prev_layer_id)
- if prev_node.op == 'Parameter':
- parameters = Node(graph, layer_id).parameters
- input_dim = read_token_value(parameters, b'')
- prev_node['shape'] = int64_array([1, input_dim])
- prev_node.add_output_port(0)
- Node(graph, layer_id).add_input_port(0)
- graph.create_edge(prev_node, Node(graph, layer_id), 0, 0, create_edge_attrs(prev_layer_id, layer_id, prev_layer_id))
- used_layers.add(prev_layer_id)
- prev_layer_id = layer_id
- log.debug('{} and {} were connected'.format(prev_layer_id, layer_id))
-
- # Tensor names information corresponding to a node is stored on outgoing edges.
- # As output nodes do not have outgoing edges, fake outputs are required. In the following code
- # for each output Identity node is added, and tensor name for the output is kept
- # on (output, fake output) edge. After Result nodes adding transformation fake outputs
- # are deleted from graph.
- output_layers = graph.nodes - used_layers
- add_outputs_identity(graph, output_layers, lambda g, output, fake_output: g.create_edge(
- Node(g, output), Node(g, fake_output), 0, 0, create_edge_attrs(output, fake_output, output)))
-
-
-def load_kaldi_nnet3_model(graph, file_descr, nnet_name):
- file_descr.read(1)
- component_layer_map = load_topology_map(file_descr, graph)
- # add information for shape calculation for MemoryOffset
- # shape calculation for MemoryOffset can't be done through shape of previous layer because
- # it is separated in 2 parts to remove cycle from graph
- for node in graph.get_op_nodes(**{'op': 'Parameter'}):
- for o_n_name, params in node.get_outputs():
- o_n = Node(graph, o_n_name)
- if o_n['op'] == 'MemoryOffset':
- # don't take batch from Parameter, it will be overwritten
- # take only second dimension because we have only 2 dimensions
- o_n['parameters']['element_size'] = int64_array([1, node.shape[1]])
-
- load_components(file_descr, graph, component_layer_map)
- load_priors(file_descr, graph)
-
-
-def load_priors(file_descr, graph):
- try:
- collect_until_token(file_descr, b'')
- except Error:
- # just ignore if priors were not found
- return
- if graph.graph['cmd_params'].counts is not None:
- graph.graph['priors'] = read_binary_vector(file_descr)
- else:
- log.error("Model contains Prior values, if you want to embed them into the generated IR add option --counts=\"\" to command line",
- extra={'is_warning': True})
-
-
-def load_components(file_descr, graph, component_layer_map=None):
- num_components = collect_until_token_and_read(file_descr, b'')
- log.debug('Network contains {} components'.format(num_components))
- is_nnet3 = False if component_layer_map is None else True
-
- if not is_nnet3:
- collect_until_token(file_descr, b'')
-
- all_components = list()
- name = ""
- for _ in range(num_components):
- if is_nnet3:
- name = collect_until_token_and_read(file_descr, b'', np.string_)
-
- component_type = find_next_component(file_descr)
- if component_type == end_of_nnet_tag.lower()[1:-1]:
- break
-
- start_index = file_descr.tell()
- end_tag, end_index = find_end_of_component(file_descr, component_type)
- # read dim info where possible to simplify shape calculation for MemoryOffset
- # shape calculation for MemoryOffset can't be done through shape of previous layer because
- # it is separated in 2 parts to remove cycle from graph
- file_descr.seek(start_index)
- dim = 0
- dim_words = {b'', b''}
- for dim_word in dim_words:
- try:
- collect_until_token(file_descr, dim_word, size_search_zone=end_index - start_index)
- cur_index = file_descr.tell()
- if start_index < cur_index < end_index:
- dim = read_binary_integer32_token(file_descr)
- break
- else:
- file_descr.seek(start_index)
- except Error:
- file_descr.seek(start_index)
-
- if is_nnet3:
- if name in component_layer_map:
- layer_id = component_layer_map[name][0]
- for layer in component_layer_map[name]:
- node = Node(graph, layer)
- node['parameters'] = get_parameters(file_descr, start_index, end_index)
- node['op'] = component_type
- # Read dim info where possible to simplify shape calculation for MemoryOffset
- for o_n_name, params in node.get_outputs():
- o_n = Node(graph, o_n_name)
- if o_n['op'] == 'MemoryOffset' and dim != 0:
- o_n['parameters']['element_size'] = int64_array([1, dim])
- else:
- raise Error("Something wrong with layer {}".format(name))
- else:
- layer_id = graph.unique_id(prefix=component_type)
- graph.add_node(layer_id,
- parameters=get_parameters(file_descr, start_index, end_index),
- op=component_type,
- kind='op')
- if hasattr(graph, 'op_names_statistic'):
- graph.op_names_statistic[component_type] += 1
-
- all_components.append(layer_id)
- log.debug('{} (type is {}) was loaded'.format(layer_id, component_type))
-
- return all_components
-
-
-def load_topology_map(file_descr, graph):
- not_finished = True
- component_layer_map = {}
- layer_node_map = {}
- while not_finished:
- not_finished = read_node(file_descr, graph, component_layer_map, layer_node_map)
- return component_layer_map
-
-
-def read_node(file_descr, graph, component_layer_map, layer_node_map):
- s = file_descr.readline()
- if s == b'\n':
- return False
- tokens = s.split(b' ')
- if tokens[0] == b'input-node':
- in_name = s[s.find(b'name=') + len(b'name='):].split(b' ')[0]
- in_name = str(in_name).strip('b').replace('\'', "")
- in_shape = mo_array([1, s[s.find(b'dim=') + len(b'dim='):].split(b' ')[0]], dtype=int)
-
- if in_name not in layer_node_map:
- graph.add_node(in_name, name=in_name, kind='op', op='Parameter', parameters=None, shape=in_shape)
- layer_node_map[in_name] = in_name
- else:
- Node(graph, in_name)['op'] = 'Parameter'
- Node(graph, in_name)['shape'] = in_shape
- elif tokens[0] == b'component-node':
- layer_name = s[s.find(b'name=') + len(b'name='):].split(b' ')[0]
- layer_name = str(layer_name).strip('b').replace('\'', "")
-
- component_name = s[s.find(b'component=') + len(b'component='):].split(b' ')[0]
- if layer_name not in layer_node_map:
- node_name = graph.unique_id(prefix=layer_name)
- graph.add_node(node_name,
- parameters=None,
- op=None,
- kind='op')
- layer_node_map[layer_name] = node_name
- else:
- node_name = layer_node_map[layer_name]
-
- if component_name in component_layer_map:
- component_layer_map[component_name].append(node_name)
- else:
- component_layer_map[component_name] = [node_name]
-
- # parse input
- in_node_id = parse_input_for_node(s[s.find(b'input=') + 6:], graph, layer_node_map)
- # don't create cyclic edges node to itself to avoid removing later
- if in_node_id != node_name:
- out_port = len(Node(graph, in_node_id).out_nodes())
- in_port = len(Node(graph, node_name).in_nodes())
-
- Node(graph, node_name).add_input_port(in_port)
- Node(graph, in_node_id).add_output_port(out_port, skip_if_exist=True)
-
- graph.add_edge(in_node_id, node_name, **create_edge_attrs(in_node_id, node_name, in_node_id, in_port, out_port))
- elif tokens[0] == b'output-node':
- layer_name = s[s.find(b'name=') + len(b'name='):].split(b' ')[0]
- layer_name = str(layer_name).strip('b').replace('\'', "")
- node_name = graph.unique_id(prefix=layer_name)
- graph.add_node(node_name,
- parameters=None,
- op='Identity',
- kind='op')
- out_name = graph.unique_id(prefix=node_name + "_out")
- graph.add_node(out_name,
- parameters=None,
- op='Result',
- kind='op')
- Node(graph, node_name).add_input_port(0)
- Node(graph, node_name).add_output_port(0)
- Node(graph, out_name).add_input_port(0)
- graph.add_edge(node_name, out_name, **create_edge_attrs(node_name, out_name, node_name))
-
- # parse input
- in_node_id = parse_input_for_node(s[s.find(b'input=') + len(b'input='):], graph, layer_node_map)
-
- out_port = len(Node(graph, in_node_id).out_nodes())
- Node(graph, in_node_id).add_output_port(out_port)
- graph.create_edge(Node(graph, in_node_id), Node(graph, node_name), out_port, 0, create_edge_attrs(in_node_id, node_name, in_node_id, 0, out_port))
-
- objective_type = s[s.find(b'objective=') + 10:].split(b' ')[0].split(b'\n')[0]
- if objective_type != b'linear':
- raise Error("Unsupported objective-type for output {}".format(node_name))
- elif tokens[0] == b'dim-range-node':
- layer_name = s[s.find(b'name=') + len(b'name='):].split(b' ')[0]
- layer_name = str(layer_name).strip('b').replace('\'', "")
- offset = int(s[s.find(b'dim-offset=') + len(b'dim-offset='):].split(b' ')[0])
- dim = int(s[s.find(b'dim=') + len(b'dim='):].split(b' ')[0])
-
- if layer_name in layer_node_map:
- node_name = layer_node_map[layer_name]
- node = Node(graph, node_name)
- node['parameters'] = {'offset': mo_array([offset]), 'dim': mo_array([dim]), 'axis': mo_array([1])}
- node['op'] = 'Crop'
- else:
- node_name = graph.unique_id(prefix=layer_name)
- graph.add_node(node_name,
- parameters={'offset': mo_array([offset]), 'dim': mo_array([dim]), 'axis': mo_array([1])},
- op='Crop',
- kind='op')
- layer_node_map[layer_name] = node_name
- node = Node(graph, node_name)
-
- in_node_id = parse_input_for_node(s[s.find(b'input-node=') + len(b'input-node='):], graph, layer_node_map)
- out_port = len(Node(graph, in_node_id).out_nodes())
- in_port = len(Node(graph, node_name).in_nodes())
-
- node.add_input_port(in_port)
- Node(graph, in_node_id).add_output_port(out_port)
-
- graph.create_edge(Node(graph, in_node_id), node, out_port, in_port, create_edge_attrs(in_node_id, node_name, in_node_id, in_port, out_port))
-
- # read dim info where possible to simplify shape calculation for MemoryOffset
- # shape calculation for MemoryOffset can't be done through shape of previous layer because
- # it is separated in 2 parts to remove cycle from graph
- for o_n_name, params in node.get_outputs():
- o_n = Node(graph, o_n_name)
- if o_n['op'] == 'MemoryOffset':
- o_n['parameters']['element_size'] = int64_array([1, dim])
- else:
- raise Error("Unsupported node specifier {}".format(tokens[0]))
- return True
-
-
-def parse_input_for_node(string, graph, component_layer_map):
- return parse_specifier(string, graph, component_layer_map)
-
-
-def parse_specifier(string, graph, layer_node_map):
- pos = string.find(b'(')
- if pos == -1:
- # node name
- input_name = str(string.split(b' ')[0]).strip('b').replace("\'", '').replace('\\n', '')
-
- if input_name not in layer_node_map:
- node_name = graph.unique_id(prefix=input_name)
- graph.add_node(node_name, parameters=[], op="", kind='op')
- layer_node_map[input_name] = node_name
- else:
- node_name = layer_node_map[input_name]
- return node_name
-
- spec = string[:pos]
- args = get_args_for_specifier(string[pos:])
- if spec == b'Append':
- nodes = []
- for i in range(len(args)):
- nodes.append(parse_specifier(args[i], graph, layer_node_map))
- layer_name = 'Append_'
- for node in nodes:
- layer_name = layer_name + node + "_"
-
- if layer_name not in layer_node_map:
- concat_name = graph.unique_id(prefix=layer_name)
- graph.add_node(concat_name,
- parameters=None,
- op='concat',
- kind='op')
- layer_node_map[layer_name] = concat_name
- i = 0
- Node(graph, concat_name).add_sequence_of_ports('in', range(len(nodes)))
- for node in nodes:
- out_port = len(Node(graph, node).out_nodes())
- Node(graph, node).add_output_port(out_port)
- graph.create_edge(Node(graph, node), Node(graph, concat_name), out_port, i, create_edge_attrs(node, concat_name, node, i, out_port))
- i = i + 1
- else:
- concat_name = layer_node_map[layer_name]
- return concat_name
- elif spec == b'Offset':
- node = parse_specifier(args[0], graph, layer_node_map)
- t = int(args[1])
- if len(args) > 2:
- raise Error("ModelOptimizer supports only 2 arguments for Offset")
- layer_name = 'Offset_' + node + '_'
- if t < 0:
- layer_name = layer_name + '_' + str(-t)
- else:
- layer_name = layer_name + str(t)
-
- if layer_name not in layer_node_map:
- memory_name = graph.unique_id(prefix=layer_name)
- layer_node_map[layer_name] = memory_name
- memory_name_2 = memory_name + '_out'
- graph.add_node(memory_name,
- parameters=dict(t=t, pair_name=memory_name_2, has_default=False),
- op='MemoryOffset',
- kind='op')
- out_port = len(Node(graph, node).out_nodes())
- in_port = len(Node(graph, memory_name).in_nodes())
- Node(graph, memory_name).add_input_port(in_port)
- Node(graph, node).add_output_port(out_port, skip_if_exist=True)
- graph.create_edge(Node(graph, node), Node(graph, memory_name), out_port, in_port, create_edge_attrs(node, memory_name, node, in_port, out_port))
- else:
- memory_name = layer_node_map[layer_name]
- return memory_name
- elif spec == b'Sum':
- nodes = []
- for i in range(len(args)):
- nodes.append(parse_specifier(args[i], graph, layer_node_map))
-
- layer_name = 'Sum_'
- for node in nodes:
- layer_name = layer_name + node + "_"
-
- if layer_name not in layer_node_map:
- sum_name = graph.unique_id(prefix=layer_name)
- graph.add_node(sum_name, parameters=None, op='Add', kind='op')
- layer_node_map[layer_name] = sum_name
- else:
- sum_name = layer_node_map[layer_name]
-
- for i, node in enumerate(nodes):
- out_port = len(Node(graph, node).out_nodes())
- Node(graph, node).add_output_port(out_port, skip_if_exist=True)
- Node(graph, sum_name).add_input_port(i)
- graph.add_edge(node, sum_name, **create_edge_attrs(node, sum_name, node, i))
-
- return sum_name
- elif spec == b'IfDefined':
- node_id = parse_specifier(args[0], graph, layer_node_map)
- node = Node(graph, node_id)
- if node.op == 'MemoryOffset':
- node['parameters']['has_default'] = True
- return node_id
- elif spec == b'ReplaceIndex':
- node = parse_specifier(args[0], graph, layer_node_map)
- return node
- elif spec == b'Scale':
- node_name = parse_specifier(args[1], graph, layer_node_map)
- scale_value = float(args[0])
- layer_name = '{}/Mul/{}'.format(node_name, scale_value)
-
- if layer_name not in layer_node_map:
- scale_name = graph.unique_id(prefix=layer_name)
- scale_node = Mul(graph, {'name': scale_name}).create_node()
-
- layer_node_map[layer_name] = scale_name
-
- scale_const_name = 'Const_{}'.format(scale_value)
- const_node = Const(graph, {'name': scale_const_name, 'value': float_array([scale_value])}).create_node()
-
- node = Node(graph, node_name)
- graph.create_edge(const_node, scale_node, 0, 0, create_edge_attrs(const_node.id, scale_node.id, const_node.id))
- out_port = len(node.out_nodes())
- graph.create_edge(node, scale_node, out_port, 1, create_edge_attrs(node_name, scale_node.id, node_name, 1, out_port))
- else:
- scale_name = layer_node_map[layer_name]
-
- return scale_name
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/loader/utils.py b/tools/mo/openvino/tools/mo/front/kaldi/loader/utils.py
deleted file mode 100644
index 7beb6a69f5f5bb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/loader/utils.py
+++ /dev/null
@@ -1,413 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import io
-import os
-import struct
-
-import numpy as np
-
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-end_of_nnet_tag = ' '
-end_of_component_tag = ''
-
-supported_components = [
- 'addshift',
- 'affinecomponent',
- 'affinecomponentpreconditionedonline',
- 'affinetransform',
- 'backproptruncationcomponent',
- 'batchnormcomponent',
- 'clipgradientcomponent',
- 'convolutional1dcomponent',
- 'convolutionalcomponent',
- 'copy',
- 'dropoutmaskcomponent',
- 'elementwiseproductcomponent',
- 'fixedaffinecomponent',
- 'fixedscalecomponent',
- 'fixedbiascomponent',
- 'generaldropoutcomponent',
- 'linearcomponent',
- 'logsoftmaxcomponent',
- 'lstmnonlinearitycomponent',
- 'lstmprojected',
- 'lstmprojectedstreams',
- 'maxpoolingcomponent',
- 'naturalgradientaffinecomponent',
- 'naturalgradientperelementscalecomponent',
- 'noopcomponent',
- 'normalizecomponent',
- 'parallelcomponent',
- 'pnormcomponent',
- 'rectifiedlinearcomponent',
- 'rescale',
- 'restrictedattentioncomponent',
- 'sigmoid',
- 'sigmoidcomponent',
- 'softmax',
- 'softmaxcomponent',
- 'specaugmenttimemaskcomponent',
- 'splicecomponent',
- 'sumgroupcomponent',
- 'tanhcomponent',
- 'tdnncomponent',
- 'timeheightconvolutioncomponent',
-]
-
-
-def get_bool(s: bytes) -> bool:
- """
- Get bool value from bytes
- :param s: bytes array contains bool value
- :return: bool value from bytes array
- """
- if str(s) == "b\'F\'":
- return False
- elif str(s) == "b\'T\'":
- return True
- else:
- return struct.unpack('?', s)[0]
-
-
-def get_uint16(s: bytes) -> int:
- """
- Get unsigned int16 value from bytes
- :param s: bytes array contains unsigned int16 value
- :return: unsigned int16 value from bytes array
- """
- return struct.unpack('H', s)[0]
-
-
-def get_uint32(s: bytes) -> int:
- """
- Get unsigned int32 value from bytes
- :param s: bytes array contains unsigned int32 value
- :return: unsigned int32 value from bytes array
- """
- return struct.unpack('I', s)[0]
-
-
-def get_uint64(s: bytes) -> int:
- """
- Get unsigned int64 value from bytes
- :param s: bytes array contains unsigned int64 value
- :return: unsigned int64 value from bytes array
- """
- return struct.unpack('q', s)[0]
-
-
-def read_binary_bool_token(file_desc: io.BufferedReader) -> bool:
- """
- Get next bool value from file
- The carriage moves forward to 1 position.
- :param file_desc: file descriptor
- :return: next boolean value in file
- """
- return get_bool(file_desc.read(1))
-
-
-def read_binary_integer32_token(file_desc: io.BufferedReader) -> int:
- """
- Get next int32 value from file
- The carriage moves forward to 5 position.
- :param file_desc: file descriptor
- :return: next uint32 value in file
- """
- buffer_size = file_desc.read(1)
- return get_uint32(file_desc.read(buffer_size[0]))
-
-
-def read_binary_integer64_token(file_desc: io.BufferedReader) -> int:
- """
- Get next int64 value from file
- The carriage moves forward to 9 position.
- :param file_desc: file descriptor
- :return: next uint64 value in file
- """
- buffer_size = file_desc.read(1)
- return get_uint64(file_desc.read(buffer_size[0]))
-
-
-def read_binary_float_token(file_desc: io.BufferedReader) -> float:
- """
- Get next float32 value from file
- The carriage moves forward to 5 position.
- :param file_desc: file descriptor
- :return: next float32 value in file
- """
- buffer_size = file_desc.read(1)
- s = file_desc.read(buffer_size[0])
- return np.frombuffer(s, dtype=np.float32)[0]
-
-
-def read_string(file_desc: io.BufferedReader) -> int:
- return collect_until_whitespace(file_desc)
-
-
-def find_next_tag(file_desc: io.BufferedReader) -> str:
- """
- Get next tag in the file
- :param file_desc:file descriptor
- :return: string like ''
- """
- tag = b''
- while True:
- symbol = file_desc.read(1)
- if symbol == b'':
- raise Error('Unexpected end of Kaldi model')
- if tag == b'' and symbol != b'<':
- continue
- elif symbol == b'<':
- tag = b''
- tag += symbol
- if symbol != b'>':
- continue
- try:
- return tag.decode('ascii')
- except UnicodeDecodeError:
- # Tag in Kaldi model always in ascii encoding
- tag = b''
-
-
-def read_placeholder(file_desc: io.BufferedReader, size=3) -> bytes:
- """
- Read size bytes from file
- :param file_desc:file descriptor
- :param size:number of reading bytes
- :return: bytes
- """
- return file_desc.read(size)
-
-
-def find_next_component(file_desc: io.BufferedReader) -> str:
- """
- Read next component in the file.
- All components are contained in supported_components
- :param file_desc:file descriptor
- :return: string like ''
- """
- is_start = True
- while True:
- tag = find_next_tag(file_desc)
- # Tag is . But we want get without '<' and '>'
- component_name = tag[1:-1].lower()
- if component_name in supported_components or tag == end_of_nnet_tag:
- # There is whitespace after component's name
- read_placeholder(file_desc, 1)
- return component_name
- elif tag == '':
- raise Error('Component has unsupported or not specified type')
- elif not (is_start and tag == end_of_component_tag) and tag.find('Component') != -1:
- raise Error('Component has unsupported type {}'.format(tag))
- is_start = False
-
-
-def get_name_from_path(path: str) -> str:
- """
- Get name from path to the file
- :param path: path to the file
- :return: name of the file
- """
- return os.path.splitext(os.path.basename(path))[0]
-
-
-def find_end_of_component(file_desc: io.BufferedReader, component: str, end_tags: tuple = ()):
- """
- Find an index and a tag of the ent of the component
- :param file_desc: file descriptor
- :param component: component from supported_components
- :param end_tags: specific end tags
- :return: the index and the tag of the end of the component
- """
- end_tags_of_component = ['{}>'.format(component),
- end_of_component_tag.lower(),
- end_of_nnet_tag.lower(),
- *end_tags,
- *['<{}>'.format(component) for component in supported_components]]
- next_tag = find_next_tag(file_desc)
- while next_tag.lower() not in end_tags_of_component:
- next_tag = find_next_tag(file_desc)
- return next_tag, file_desc.tell()
-
-
-def get_parameters(file_desc: io.BufferedReader, start_index: int, end_index: int):
- """
- Get part of file
- :param file_desc: file descriptor
- :param start_index: Index of the start reading
- :param end_index: Index of the end reading
- :return: part of the file
- """
- file_desc.seek(start_index)
- buffer = file_desc.read(end_index - start_index)
- return io.BytesIO(buffer)
-
-
-def read_token_value(file_desc: io.BufferedReader, token: bytes = b'', value_type: type = np.uint32):
- """
- Get value of the token.
- Read next token (until whitespace) and check if next teg equals token
- :param file_desc: file descriptor
- :param token: token
- :param value_type: type of the reading value
- :return: value of the token
- """
- getters = {
- np.uint32: read_binary_integer32_token,
- np.uint64: read_binary_integer64_token,
- bool: read_binary_bool_token
- }
- current_token = collect_until_whitespace(file_desc)
- if token != b'' and token != current_token:
- raise Error('Can not load token {} from Kaldi model'.format(token) +
- refer_to_faq_msg(94))
- return getters[value_type](file_desc)
-
-
-def collect_until_whitespace(file_desc: io.BufferedReader):
- """
- Read from file until whitespace
- :param file_desc: file descriptor
- :return:
- """
- res = b''
- while True:
- new_sym = file_desc.read(1)
- if new_sym == b' ' or new_sym == b'':
- break
- res += new_sym
- return res
-
-
-def collect_until_token(file_desc: io.BufferedReader, token, size_search_zone=0):
- """
- Read from file until the token
- :param file_desc: file descriptor
- :param token: token that we find
- :return:
- """
- while True:
- # usually there is the following structure DIM VALUEFM
- res = collect_until_whitespace(file_desc)
- if res == token or res[-len(token):] == token:
- return
- size = size_search_zone
- if size == 0 and isinstance(file_desc, io.BytesIO):
- size = len(file_desc.getbuffer())
- elif size == 0 and isinstance(file_desc, io.BufferedReader):
- size = os.fstat(file_desc.fileno()).st_size
- if file_desc.tell() >= size:
- raise Error('End of the file. Token {} not found. {}'.format(token, file_desc.tell()))
-
-
-def collect_until_token_and_read(file_desc: io.BufferedReader, token, value_type: type = np.uint32):
- """
- Read from file until the token
- :param file_desc: file descriptor
- :param token: token to find and read
- :param value_type: type of value to read
- :return:
- """
- getters = {
- np.uint32: read_binary_integer32_token,
- np.uint64: read_binary_integer64_token,
- bool: read_binary_bool_token,
- np.string_: read_string
- }
- collect_until_token(file_desc, token)
- return getters[value_type](file_desc)
-
-
-def create_edge_attrs(prev_layer_id: str, next_layer_id: str, tensor_name: str, in_port=0, out_port=0) -> dict:
- """
- Create common edge's attributes
- :param prev_layer_id: id of previous layer
- :param next_layer_id: id of next layer
- :param tensor_name: framework tensor name
- :param in_port: 'in' port
- :param out_port: 'out' port
- :return: dictionary contains common attributes for edge
- """
- return {
- 'out': out_port,
- 'in': in_port,
- 'name': next_layer_id,
- 'fw_tensor_debug_info': [(prev_layer_id, tensor_name + ":" + str(out_port))],
- 'in_attrs': ['in', 'permutation'],
- 'out_attrs': ['out', 'permutation'],
- 'data_attrs': ['fw_tensor_debug_info']
- }
-
-
-def read_blob(file_desc: io.BufferedReader, size: int, dtype=np.float32):
- """
- Read blob from the file
- :param file_desc: file descriptor
- :param size: size of the blob
- :param dtype: type of values of the blob
- :return: np array contains blob
- """
- dsizes = {
- np.float32: 4,
- np.int32: 4
- }
- data = file_desc.read(size * dsizes[dtype])
- return np.frombuffer(data, dtype=dtype)
-
-
-def get_args_for_specifier(string):
- """
- Parse arguments in brackets and return list of arguments
- :param string: string in format (, , .., )
- :return: list with arguments
- """
- open_bracket = 1
- pos = 1
- args = []
- prev_arg_pos = 1
- pos_close = string.rfind(b')')
- string = string[:pos_close + 1]
- while pos < len(string):
- pos_open = string.find(b'(', pos)
- pos_close = string.find(b')', pos)
- pos_sep = string.find(b',', pos)
-
- if pos_open == -1:
- if open_bracket == 1:
- args = args + string[prev_arg_pos:pos_close].replace(b' ', b'').split(b',')
- pos = len(string)
- else:
- open_bracket = open_bracket - 1
- while open_bracket > 1:
- pos_close = string.find(b')', pos_close + 1)
- if pos_close != -1:
- open_bracket = open_bracket - 1
- else:
- raise Error("Syntax error in model: incorrect number of brackets")
- args.append(string[prev_arg_pos:pos_close + 1].strip())
- prev_arg_pos = string.find(b',', pos_close + 1) + 1
- if prev_arg_pos != 0 and string[prev_arg_pos:-2].replace(b' ', b'').split(b',') != [b'']:
- args = args + string[prev_arg_pos:-1].replace(b' ', b'').split(b',')
- pos = len(string)
- else:
- if pos_sep < pos_open and open_bracket == 1:
- pos_sep = string[pos_sep:pos_open].rfind(b',') + pos_sep
- args = args + string[prev_arg_pos:pos_sep].replace(b' ', b'').split(b',')
- prev_arg_pos = pos_sep + 1
-
- if pos_open < pos_close:
- open_bracket = open_bracket + 1
- pos = pos_open + 1
- else:
- open_bracket = open_bracket - 1
- if open_bracket == 1:
- args.append(string[prev_arg_pos:pos_close + 1].strip())
- prev_arg_pos = string.find(b',', pos_close + 1) + 1
- pos = prev_arg_pos
- else:
- pos = pos_close + 1
-
- return args
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/logsoftmax_component_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/logsoftmax_component_ext.py
deleted file mode 100644
index a3ebc861b2f843..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/logsoftmax_component_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.log_softmax import LogSoftmax
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class LogSoftMaxComponentExtractor(FrontExtractorOp):
- op = 'logsoftmaxcomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogSoftmax.update_node_stat(node, {'axis': 1})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/memory_offset_adjustment.py b/tools/mo/openvino/tools/mo/front/kaldi/memory_offset_adjustment.py
deleted file mode 100644
index a939f0e100be7f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/memory_offset_adjustment.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-
-
-def find_max_frame_time(node: Node):
- in_frame_time_max = 0
- should_align = False
- for inp in node.in_ports():
- if node.in_port(inp).disconnected():
- continue
- in_node = node.in_port(inp).get_source().node
- if in_node.frame_time > in_frame_time_max:
- in_frame_time_max = in_node.frame_time
-
- if in_frame_time_max == 0:
- return in_frame_time_max, False
-
- for inp in node.in_ports():
- if node.in_port(inp).disconnected():
- continue
- if in_frame_time_max != node.in_port(inp).get_source().node.frame_time:
- should_align = True
- break
-
- return in_frame_time_max, should_align
-
-
-def align_frame_time(graph: Graph, node: Node, frame_time_max):
- for inp in node.in_ports():
- if node.in_port(inp).disconnected():
- continue
- in_node = node.in_port(inp).get_source().node
- in_node_out_port = node.in_port(inp).get_source()
- in_port = node.in_port(inp)
- # Adding MemoryOffset for Const does not make sense
- if in_node.frame_time < frame_time_max and in_node.op != 'Const':
- # Change existing MemoryOffset to avoid adding new one
- if in_node.op == 'MemoryOffset':
- in_node.t = in_node.frame_time - frame_time_max
- in_node.frame_time = in_node.t
- else:
- mem_name = graph.unique_id("align_" + node.id)
- memory_align = MemoryOffset(graph, attrs={'id': mem_name,
- 'name': mem_name,
- 'pair_name': mem_name + "_pair",
- 't': in_node.frame_time - frame_time_max,
- 'splitted': False}).create_node()
- # add element_size for MemoryOffset after Parameter for infer
- if in_node.op == 'Parameter':
- memory_align['element_size'] = in_node.shape
-
- memory_align.in_port(0).get_connection().set_source(in_node_out_port)
- in_port.get_connection().set_source(memory_align.out_port(0))
- memory_align['frame_time'] = memory_align.t
- # remove MemoryOffset with maximum delay
- elif in_node.frame_time == frame_time_max and in_node.op == 'MemoryOffset':
- in_node_out_port.get_connection().set_source(in_node.in_port(0).get_source())
- graph.remove_node(in_node.id)
-
-
-class MemoryOffsetAdjustment(FrontReplacementSubgraph):
- r"""
- Pass used to fix wrong results in the following situation:
- input
- | \
- ... ...
- | \
- MemoryOffset(k) \
- | |
- ... |
- \ |
- \ |
- Concat
- In Left branch we have MemoryOffset with k > 0 so we wait until kth frame will be calculated. In right branch
- we have no such offsets. As result we Concat (or use in any calculations with more than 1 input) kth frame from
- left branch and 0th from right branch. So we need to add synchronization before Concat node. it can be done with
- MemoryOffset(k) inserted before Concat.
-
- Main idea of this change that when we found memoryOffset with t>0 we should re-calculate all delays relative to this
- t.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'kaldi']
-
- def run_before(self):
- # transformation can't work with splitted MemoryOffsets
- from openvino.tools.mo.front.kaldi.split_recurrent_memoryoffset import SplitRecurrentMemoryOffset
- return [SplitRecurrentMemoryOffset]
-
- def find_and_replace_pattern(self, graph: Graph):
- should_continue = False
- for n in graph:
- if Node(graph, n).op == 'MemoryOffset' and Node(graph, n).t > 0:
- should_continue = True
- break
-
- if not should_continue:
- return
-
- try:
- nodes = list(nx.topological_sort(graph))
- except:
- return
-
- nx.set_node_attributes(G=graph, name='frame_time', values=-1)
-
- for n in nodes:
- node = Node(graph, n)
-
- # calculate frame_time (delay) that was not calculated
- if node.frame_time < 0:
- # MemoryOffset with t>0 increases frame delay
- if node.op == "MemoryOffset":
- node.frame_time = node.in_port(0).get_source().node.frame_time + node.t
- # for node with several inputs frame_time = maximum of delays from branches
- # other branches should be synced by adding MemoryOffset(branch frame_time - max)
- # After that MemoryOffset with maximum delay should be deleted (t becomes 0)
- elif len(node.in_edges()) > 1:
- # find out maximum of delay and check that we have at least one branch with another delay
- in_frame_time_max, should_align = find_max_frame_time(node)
- if should_align:
- align_frame_time(graph, node, in_frame_time_max)
- node.frame_time = in_frame_time_max
- elif len(node.in_edges()) == 1:
- node.frame_time = node.in_port(0).get_source().node.frame_time
- else:
- # for all input nodes (without inputs) frame_time is 0
- node.frame_time = 0
-
- for n in graph:
- node = Node(graph, n)
- if 'frame_time' in node:
- del node['frame_time']
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/memoryoffset_batch_update.py b/tools/mo/openvino/tools/mo/front/kaldi/memoryoffset_batch_update.py
deleted file mode 100644
index 5a747ef7906e74..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/memoryoffset_batch_update.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-
-
-class MemoryOffsetBatchUpdate(FrontReplacementPattern):
- """
- Update batch for MemoryOffset nodes with set element_size.
- element_size is set in loader according to shape saved in model (for example Parameter node have shape in attribute).
- But batch can be changed on front stage if user set batch through command line. So, element_size should be updated
- accordingly.
- """
- enabled = True
- run_not_recursively = True
-
- def run_after(self):
- from openvino.tools.mo.front.user_data_repack import UserDataRepack
- from openvino.tools.mo.front.kaldi.split_recurrent_memoryoffset import SplitRecurrentMemoryOffset
- return [UserDataRepack, SplitRecurrentMemoryOffset]
-
- def find_and_replace_pattern(self, graph: Graph):
- batch = graph.get_op_nodes(op="Parameter")[0].shape[0]
- for memoryoffset_node in graph.get_op_nodes(op='MemoryOffset'):
- if memoryoffset_node.has_valid('element_size'):
- memoryoffset_node.element_size[0] = batch
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/register_custom_ops.py b/tools/mo/openvino/tools/mo/front/kaldi/register_custom_ops.py
deleted file mode 100644
index cb87f2148d7c01..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/register_custom_ops.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp, FrontReplacementSubgraph, FrontReplacementPattern
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-def get_front_classes():
- front_classes = [FrontExtractorOp, FrontReplacementOp, FrontReplacementPattern, FrontReplacementSubgraph]
- return front_classes
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/replace_dropoutmask.py b/tools/mo/openvino/tools/mo/front/kaldi/replace_dropoutmask.py
deleted file mode 100644
index cedea76e1166e5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/replace_dropoutmask.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from openvino.tools.mo.middle.InsertSelect import check_inputs
-from openvino.tools.mo.middle.MakeKaldiConstReshapable import create_const_with_batch_from_input
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-
-
-class ReplaceDropoutMaskPattern(FrontReplacementPattern):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.restore_ports import RestorePorts
- return [RestorePorts]
-
- def run_before(self):
- from openvino.tools.mo.front.kaldi.replace_lstm_nonlinearity import ReplaceLstmNonLinearityPattern
- return [ReplaceLstmNonLinearityPattern]
-
- def find_and_replace_pattern(self, graph: Graph):
- inp = check_inputs(graph)
- batch_port = inp.out_port(0)
- replace_nodes = graph.get_op_nodes(op='dropoutmaskcomponent')
- for dropout_node in replace_nodes:
- assert dropout_node.has_and_set('size'), "DropoutMaskComponent has not set size attribute"
- assert dropout_node.size > 0, "DropoutMaskComponent has negative or zero size attribute"
- assert dropout_node.has_and_set('dropout_proportion'), \
- "DropoutMaskComponent has not set dropout_proportion attribute"
- assert dropout_node.dropout_proportion > 0, \
- "DropoutMaskComponent has negative or zero dropout_proportion attribute"
- dp_const_node = create_const_with_batch_from_input(batch_port, dropout_node.size,
- dropout_node.dropout_proportion)
- dropout_node.out_port(0).get_connection().set_source(dp_const_node.out_port(0))
- graph.remove_node(dropout_node.id)
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/replace_eltwise_nin1.py b/tools/mo/openvino/tools/mo/front/kaldi/replace_eltwise_nin1.py
deleted file mode 100644
index 63752e34f96bfe..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/replace_eltwise_nin1.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.elementwise import Add, Mul
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.eltwise_n import EltwiseN
-from openvino.tools.mo.utils.error import Error
-
-
-class ReplaceEltwiseNin1NodePattern(FrontReplacementOp):
- """
- In nnet3 models Kaldi gather all inputs of Mul or Sum in 1. This pass separates inputs as it should be for IE.
- """
- op = "EltwiseNin1"
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.restore_ports import RestorePorts
- return [RestorePorts]
-
- def replace_op(self, graph: Graph, node: Node):
- ss_node = create_op_with_const_inputs(graph, Split, {1: int64_array(1)}, {'name': 'Split_eltwise_' + node.name,
- 'num_splits': node['num_inputs']})
-
- inp = node.get_inputs()
- in_node = inp[0][0]
- edge_attrs = inp[0][1]
- graph.add_edge(in_node, ss_node.id, **edge_attrs)
- if ss_node.num_splits == 2:
- if node['operation'] == 'mul':
- eltwise_node = Mul(graph, attrs={'name': 'Eltwise_' + node.name}).create_node()
- elif node['operation'] == 'sum':
- eltwise_node = Add(graph, attrs={'name': 'Eltwise_' + node.name}).create_node()
- else:
- raise Error('Error on replacing Kaldi eltwise: unknown type ' + node['operation'])
- elif ss_node.num_splits > 2:
- eltwise_node = EltwiseN(graph, attrs={'name': 'Eltwise_' + node.name,
- 'operation': node['operation']}).create_node()
- else:
- raise Error('Error on replacing Kaldi eltwise')
- for i in range(ss_node.num_splits):
- ss_node.out_port(i).get_connection().set_destination(eltwise_node.in_port(i))
- return [eltwise_node.id]
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/replace_lstm_node_pattern.py b/tools/mo/openvino/tools/mo/front/kaldi/replace_lstm_node_pattern.py
deleted file mode 100644
index c10902f2c65574..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/replace_lstm_node_pattern.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.middle.MakeKaldiConstReshapable import create_const_with_batch_from_input
-from openvino.tools.mo.ops.MatMul import FullyConnected
-from openvino.tools.mo.ops.activation_ops import Tanh, Sigmoid
-from openvino.tools.mo.ops.elementwise import Add, Mul
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.front.caffe.extractors.utils import input_as_const
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.assign import Assign
-from openvino.tools.mo.ops.clamp import Clamp
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.read_value import ReadValue
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-
-
-def unique_id(prefix: str = 'id') -> str:
- """
- Generates a unique id
- The optional string prefix can be specified.
- """
- index = len(unique_id.names)
- name = prefix
- while name in unique_id.names:
- name = '{}_{}'.format(prefix, index)
- index += 1
- unique_id.names.append(name)
- return name
-
-
-unique_id.names = []
-
-
-class ReplaceLSTMNodePattern(FrontReplacementOp):
- op = "LSTMCell"
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.restore_ports import RestorePorts
- return [RestorePorts]
-
- def run_before(self):
- # current pass should be rewritten to use MatMul ops only (No FullyConnected ops should be created here)
- from openvino.tools.mo.front.MatMul_normalizer import FullyConnectedDecomposer
- from openvino.tools.mo.front.MoveEmbeddedInputsToInputs import MoveEmbeddedInputsToInputs
- return [FullyConnectedDecomposer,
- MoveEmbeddedInputsToInputs]
-
- def pattern(self):
- return dict(
- nodes=[
- ('op', dict(op=self.__class__.op, format='kaldi'))],
- edges=[]
- )
-
- def replace_op(self, graph: Graph, node: Node):
- input_out_port = node.in_port(0).get_source()
-
- memory_pair_input = unique_id('id')
- memory_pair_output = unique_id('id')
-
- # Input -> FullyConnected
- fc_layer_after_input_attrs = {'name': 'input_fullyconnected',
- 'out-size': node.gifo_x_weights_shape[0],
- 'transpose_weights': True,
- 'bias_term': True,
- }
-
- fc_layer_after_input = FullyConnected(graph, fc_layer_after_input_attrs).create_node()
- fc_layer_after_input.in_port(0).connect(input_out_port)
- input_as_const(fc_layer_after_input, fc_layer_after_input_attrs, 1, 'weights', node.gifo_x_weights)
- input_as_const(fc_layer_after_input, fc_layer_after_input_attrs, 2, 'biases', node.gifo_biases)
-
- init_value_prev_lstm_output = create_const_with_batch_from_input(input_out_port,
- node.gifo_r_weights_shape[1])
- prev_lstm_output = ReadValue(graph, {'name': 'prev_memory_output',
- 'variable_id': memory_pair_input,
- 'variable_shape': None,
- 'variable_type': None
- }).create_node()
- prev_lstm_output.in_port(0).connect(init_value_prev_lstm_output.out_port(0))
-
- # *Memory(output) -> FullyConnected
- fc_layer_from_prev_state_attrs = {'name': 'prev_memory_output_fullyconnected',
- 'out-size': node.gifo_r_weights_shape[0],
- 'transpose_weights': True,
- 'bias_term': False,
- }
-
- fc_layer_from_prev_state = FullyConnected(graph, fc_layer_from_prev_state_attrs).create_node()
- fc_layer_from_prev_state.in_port(0).connect(prev_lstm_output.out_port(0))
- input_as_const(fc_layer_from_prev_state, fc_layer_from_prev_state_attrs, 1, 'weights', node.gifo_r_weights)
-
- # Memory -> FullyConnected \
- # *Eltwise(sum)
- # Input -> FullyConnected /
- join_input_prev_state_sum = Add(graph, {'name': 'join_input_eltwise'}).create_node()
- join_input_prev_state_sum.in_port(0).connect(fc_layer_from_prev_state.out_port(0))
- join_input_prev_state_sum.in_port(1).connect(fc_layer_after_input.out_port(0))
-
- # *Eltwise(sum) -> Split
- # it is split into 4 nodes: Act, Eltw*3
- # the following order is mandatory
- # ___Tanh
- # /
- # Split ---(2)Eltwise(sum)
- # |\
- # | \__(3)Eltwise(sum)
- # |____(4)Eltwise(sum)
- split_joined_input_axis = Const(graph, {'value': np.int64(1)}).create_node()
- split_joined_input = Split(graph, {'name': 'join_input_split',
- 'num_splits': 4, 'out_ports_count': 4}).create_node()
- split_joined_input.in_port(0).connect(join_input_prev_state_sum.out_port(0))
- split_joined_input.in_port(1).connect(split_joined_input_axis.out_port(0))
-
- init_value_prev_lstm_state = create_const_with_batch_from_input(split_joined_input.out_port(0),
- node.input_gate_weights.shape[0])
- prev_lstm_state = ReadValue(graph, {'name': 'prev_memory_state',
- 'variable_id': memory_pair_output,
- 'variable_shape': None,
- 'variable_type': None
- }).create_node()
- prev_lstm_state.in_port(0).connect(init_value_prev_lstm_state.out_port(0))
-
- # *Memory(state) -> *ScaleShift(input)
- state_input_scaleshift_attrs = {'name': 'input_scaleshift',
- 'bias_term': False
- }
- state_input_scaleshift = ScaleShiftOp(graph, state_input_scaleshift_attrs).create_node()
- state_input_scaleshift.in_port(0).connect(prev_lstm_state.out_port(0))
- input_as_const(state_input_scaleshift, state_input_scaleshift_attrs, 1, 'weights', node.input_gate_weights)
-
- # *Memory(state) -> *ScaleShift(forget)
- state_forget_scaleshift_attrs = {'name': 'forget_scaleshift',
- 'bias_term': False
- }
- state_forget_scaleshift = ScaleShiftOp(graph, state_forget_scaleshift_attrs).create_node()
- state_forget_scaleshift.in_port(0).connect(prev_lstm_state.out_port(0))
- input_as_const(state_forget_scaleshift, state_forget_scaleshift_attrs, 1, 'weights', node.forget_gate_weights)
-
- # Split \
- # (2)Eltwise(sum)
- # Memory(state) -> *ScaleShift(input) /
- join_prev_lstm_input_joined_input_sum = Add(graph, {'name': 'join_prev_lstm_input_joined_input_eltwise'
- }).create_node()
- join_prev_lstm_input_joined_input_sum.in_port(0).connect(split_joined_input.out_port(1))
- join_prev_lstm_input_joined_input_sum.in_port(1).connect(state_input_scaleshift.out_port(0))
- # Split \
- # (3)Eltwise(sum)
- # Memory(state) -> *ScaleShift(forget) /
- join_prev_lstm_input_joined_forget_sum = Add(graph, {'name': 'join_prev_lstm_input_joined_forget_sum',
- }).create_node()
- join_prev_lstm_input_joined_forget_sum.in_port(0).connect(split_joined_input.out_port(2))
- join_prev_lstm_input_joined_forget_sum.in_port(1).connect(state_forget_scaleshift.out_port(0))
-
- # Split -> Tanh
- remember_tahn = Tanh(graph, {'name': 'remember_tahnv'}).create_node()
- remember_tahn.in_port(0).connect(split_joined_input.out_port(0))
-
- # Split -> (2)Eltwise(sum) -> *Sigmoid
- remember_sigmoid = Sigmoid(graph, {'name': 'remember_sigmoid'}).create_node()
- remember_sigmoid.in_port(0).connect(join_prev_lstm_input_joined_input_sum.out_port(0))
-
- # Split -> (3)Eltwise(sum) -> **Sigmoid
- forget_sigmoid = Sigmoid(graph, {'name': 'forget_sigmoid'}).create_node()
- forget_sigmoid.in_port(0).connect(join_prev_lstm_input_joined_forget_sum.out_port(0))
-
- # *Memory(state) \
- # (6)Eltwise(mul)
- # Split -> (3)Eltwise(sum) -> **Sigmoid /
- join_forget_prev_state_mul = Mul(graph, {'name': 'join_forget_prev_state_mul'}).create_node()
- join_forget_prev_state_mul.in_port(0).connect(forget_sigmoid.out_port(0))
- join_forget_prev_state_mul.in_port(1).connect(prev_lstm_state.out_port(0))
-
- # Split -> Tahn \
- # (5)Eltwise(mul)
- # Split -> (2)Eltwise(sum) -> *Sigmoid /
- join_remember_candidates_mul = Mul(graph, {'name': 'join_remember_candidates_mul'}).create_node()
- join_remember_candidates_mul.in_port(0).connect(remember_tahn.out_port(0))
- join_remember_candidates_mul.in_port(1).connect(remember_sigmoid.out_port(0))
-
- # (5)Eltwise(mul) \
- # (7)Eltwise(sum)
- # (6)Eltwise(mul) /
- join_forget_remember_sum = Add(graph, {'name': 'join_forget_remember_sum'}).create_node()
- join_forget_remember_sum.in_port(0).connect(join_forget_prev_state_mul.out_port(0))
- join_forget_remember_sum.in_port(1).connect(join_remember_candidates_mul.out_port(0))
-
- # (7)Eltwise(sum) -> Clamp
- join_forget_clamp = create_op_with_const_inputs(graph, Clamp, {1: float32_array(-node.clip_value),
- 2: float32_array(node.clip_value)},
- {'name': 'join_forget_clamp'},
- join_forget_remember_sum)
- #
- # Clamp -> (2)Memory(state)
- next_lstm_state = Assign(graph, {'name': 'next_lstm_state',
- 'variable_id': memory_pair_output}).create_node()
- next_lstm_state.in_port(0).connect(join_forget_clamp.out_port(0))
-
- res_node = Result(graph, {'name': 'next_lstm_state_out'}).create_node()
- res_node.in_port(0).connect(next_lstm_state.out_port(0))
-
- # Clamp -> (2)Tahn
- state_filtered_tahn = Tanh(graph, {'name': 'state_filtered_tahn'}).create_node()
- state_filtered_tahn.in_port(0).connect(join_forget_clamp.out_port(0))
-
- # Clamp -> (2)ScaleShift
- clamp_scaleshift_attrs = {'name': 'clamp_scaleshift',
- 'bias_term': False}
- clamp_scaleshift = ScaleShiftOp(graph, clamp_scaleshift_attrs).create_node()
- clamp_scaleshift.in_port(0).connect(join_forget_clamp.out_port(0))
- input_as_const(clamp_scaleshift, clamp_scaleshift_attrs, 1, 'weights', node.output_gate_weights)
-
- # Split \
- # (4)Eltwise(sum)
- # Clamp -> (2)ScaleShift /
- join_next_lstm_input_joined_input_sum = Add(graph, {'name': 'join_next_lstm_input_joined_input_sum',
- }).create_node()
- join_next_lstm_input_joined_input_sum.in_port(0).connect(split_joined_input.out_port(3))
- join_next_lstm_input_joined_input_sum.in_port(1).connect(clamp_scaleshift.out_port(0))
-
- # (4)Eltwise(sum) -> (3)Sigmoid
- output_sigmoid = Sigmoid(graph, {'name': 'output_sigmoid'}).create_node()
- output_sigmoid.in_port(0).connect(join_next_lstm_input_joined_input_sum.out_port(0))
-
- # (4)Eltwise(sum) -> (3)Sigmoid \
- # (5)Eltwise(mul)
- # Clamp -> (2)Tahn /
- joined_output_mul = Mul(graph, {'name': 'joined_output_mul'}).create_node()
- joined_output_mul.in_port(0).connect(state_filtered_tahn.out_port(0))
- joined_output_mul.in_port(1).connect(output_sigmoid.out_port(0))
-
- # (5)Eltwise(mul) -> (3)FullyConnected
- fc_output_attrs = {'name': 'FullyConnected',
- 'out-size': node.projection_weights_shape[0],
- 'transpose_weights': True,
- 'bias_term': False}
- fc_output = FullyConnected(graph, fc_output_attrs).create_node()
- fc_output.in_port(0).connect(joined_output_mul.out_port(0))
- input_as_const(fc_output, fc_output_attrs, 1, 'weights', node.projection_weights)
-
- # / (2)Memory(output)
- # (3)FullyConnected
- # \ Output (any next node) (edge created automatically after replacement)
- next_lstm_output = Assign(graph, {'name': 'next_lstm_output',
- 'variable_id': memory_pair_input}).create_node()
- next_lstm_output.in_port(0).connect(fc_output.out_port(0))
-
- res_node_lstm_output = Result(graph, {'name': 'next_lstm_output_out'}).create_node()
- res_node_lstm_output.in_port(0).connect(next_lstm_output.out_port(0))
-
- return [fc_output.id]
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/replace_lstm_nonlinearity.py b/tools/mo/openvino/tools/mo/front/kaldi/replace_lstm_nonlinearity.py
deleted file mode 100644
index c9feccb4e40e18..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/replace_lstm_nonlinearity.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.activation_ops import Sigmoid, Tanh
-from openvino.tools.mo.ops.elementwise import Add, Mul
-from openvino.tools.mo.ops.split import Split, AttributedVariadicSplit
-from openvino.tools.mo.front.caffe.extractors.utils import input_as_const
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-
-
-class ReplaceLstmNonLinearityPattern(FrontReplacementOp):
- op = "LstmNonLinearity"
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.restore_ports import RestorePorts
- return [RestorePorts]
-
- def run_before(self):
- from openvino.tools.mo.front.MatMul_normalizer import FullyConnectedDecomposer
- return [FullyConnectedDecomposer]
-
- def replace_op(self, graph: Graph, node: Node):
- node_name = node.soft_get('name', node.id)
- # check if we have dropout
- input_port = node.in_port(0)
- if node.has_and_set('use_dropout'):
- split_dropout = AttributedVariadicSplit(graph,
- {'name': node_name + '/split_dropout',
- 'size_splits': int64_array([-1, 1, 1, 1]),
- 'axis': int64_array(1)}).create_node()
- input_port.get_connection().set_destination(split_dropout.in_port(0))
- input_port = split_dropout.out_port(0)
- i_drop_scale = split_dropout.out_port(1)
- f_drop_scale = split_dropout.out_port(2)
- o_drop_scale = split_dropout.out_port(3)
-
- # split input to (i_part, f_part, c_part, o_part, ct_1)
- split_node = create_op_with_const_inputs(graph, Split, {1: np.int64(1)},
- {'name': node_name + '/split_lstm_input',
- 'num_splits': 5})
- input_port.get_connection().set_destination(split_node.in_port(0))
-
- i_part = split_node.out_port(0)
- f_part = split_node.out_port(1)
- c_part = split_node.out_port(2)
- o_part = split_node.out_port(3)
- ct_1 = split_node.out_port(4)
-
- # i_t = Sigmoid(i_part + w_ic*ct_1)
- i_scale_attrs = {'name': node_name + '/i_scaleshift',
- 'bias_term': False}
- i_scale = ScaleShiftOp(graph, i_scale_attrs).create_node()
- input_as_const(i_scale, i_scale_attrs, 1, 'weights', node.i_weights)
- ct_1.connect(i_scale.in_port(0))
-
- sum_i_c = Add(graph, {'name': node_name + '/sum_i_c_'}).create_node()
- i_part.connect(sum_i_c.in_port(0))
- i_scale.out_port(0).connect(sum_i_c.in_port(1))
-
- i_sigmoid = Sigmoid(graph, {'name': node_name + '/i_sigmoid'}).create_node()
- sum_i_c.out_port(0).connect(i_sigmoid.in_port(0))
-
- if node['use_dropout']:
- mul_dropout_i = Mul(graph, {'name': split_node.soft_get('name', split_node.id) + '/mul_i'}).create_node()
- mul_dropout_i.in_port(0).connect(i_sigmoid.out_port(0))
- mul_dropout_i.in_port(1).connect(i_drop_scale) # pylint: disable=possibly-used-before-assignment
- i_sigmoid = mul_dropout_i
-
- # f_t = Sigmoid(f_part + w_fc*ct_1)
- f_scale_attrs = {'name': node_name + '/f_scaleshift',
- 'bias_term': False}
- f_scale = ScaleShiftOp(graph, f_scale_attrs).create_node()
- input_as_const(f_scale, f_scale_attrs, 1, 'weights', node.f_weights)
- ct_1.connect(f_scale.in_port(0))
-
- sum_f_c = Add(graph, {'name': node_name + '/sum_f_c_'}).create_node()
- f_part.connect(sum_f_c.in_port(0))
- f_scale.out_port(0).connect(sum_f_c.in_port(1))
-
- f_sigmoid = Sigmoid(graph, {'name': node_name + '/f_sigmoid'}).create_node()
- sum_f_c.out_port(0).connect(f_sigmoid.in_port(0))
-
- if node['use_dropout']:
- mul_dropout_f = Mul(graph, {'name': split_node.soft_get('name', split_node.id) + '/mul_f'}).create_node()
- mul_dropout_f.in_port(0).connect(f_sigmoid.out_port(0))
- mul_dropout_f.in_port(1).connect(f_drop_scale) # pylint: disable=possibly-used-before-assignment
- f_sigmoid = mul_dropout_f
-
- # c_t = f_t*ct_1 + i_t * tanh(c_part)
- c_tanh = Tanh(graph, {'name': node_name + '/c_tanh'}).create_node()
- c_part.connect(c_tanh.in_port(0))
-
- prod_i_c_tanh = Mul(graph, {'name': node_name + '/prod_i_c_tanh_'}).create_node()
- i_sigmoid.out_port(0).connect(prod_i_c_tanh.in_port(0))
- c_tanh.out_port(0).connect(prod_i_c_tanh.in_port(1))
-
- prod_f_ct_1 = Mul(graph, {'name': node_name + '/prod_f_ct_1_'}).create_node()
- f_sigmoid.out_port(0).connect(prod_f_ct_1.in_port(0))
- ct_1.connect(prod_f_ct_1.in_port(1))
-
- sum_f_i = Add(graph, {'name': node_name + '/sum_f_i_'}).create_node()
- prod_f_ct_1.out_port(0).connect(sum_f_i.in_port(0))
- prod_i_c_tanh.out_port(0).connect(sum_f_i.in_port(1))
-
- # o_t = Sigmoid(o_part + w_oc*c_t)
- o_scale_attrs = {'name': node_name + '/o_scaleshift',
- 'bias_term': False}
- o_scale = ScaleShiftOp(graph, o_scale_attrs).create_node()
- input_as_const(o_scale, o_scale_attrs, 1, 'weights', node.o_weights)
- sum_f_i.out_port(0).connect(o_scale.in_port(0))
-
- sum_o_c = Add(graph, {'name': node_name + '/sum_o_c_'}).create_node()
- o_part.connect(sum_o_c.in_port(0))
- o_scale.out_port(0).connect(sum_o_c.in_port(1))
-
- o_sigmoid = Sigmoid(graph, {'name': node_name + '/o_sigmoid'}).create_node()
- sum_o_c.out_port(0).connect(o_sigmoid.in_port(0))
-
- if node['use_dropout']:
- mul_dropout_o = Mul(graph, {'name': split_node.soft_get('name', split_node.id) + '/mul_o'}).create_node()
- mul_dropout_o.in_port(0).connect(o_sigmoid.out_port(0))
- mul_dropout_o.in_port(1).connect(o_drop_scale) # pylint: disable=possibly-used-before-assignment
- o_sigmoid = mul_dropout_o
-
- # m_t = o_t * Tanh(c_t)
- c_t_tanh = Tanh(graph, {'name': node_name + '/c_t_tanh'}).create_node()
- sum_f_i.out_port(0).connect(c_t_tanh.in_port(0))
-
- prod_o_c_t_tanh = Mul(graph, {'name': node_name + '/prod_o_c_t_tanh_'}).create_node()
- o_sigmoid.out_port(0).connect(prod_o_c_t_tanh.in_port(0))
- c_t_tanh.out_port(0).connect(prod_o_c_t_tanh.in_port(1))
-
- # add concat to create 1 output
- concat = Concat(graph, {'name': node_name + '/concat_c_m'}).create_node()
- concat.add_sequence_of_ports('in', range(2))
- sum_f_i.out_port(0).connect(concat.in_port(0))
- prod_o_c_t_tanh.out_port(0).connect(concat.in_port(1))
-
- return [concat.id]
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/replace_timeheightconvolution.py b/tools/mo/openvino/tools/mo/front/kaldi/replace_timeheightconvolution.py
deleted file mode 100644
index 1e2666196725af..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/replace_timeheightconvolution.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Node, Graph, rename_node
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-
-
-class ReplaceTimeHeightConvolutionPattern(FrontReplacementPattern):
- enabled = True
- run_not_recursively = True
-
- def run_after(self):
- from openvino.tools.mo.front.MoveEmbeddedInputsToInputs import MoveEmbeddedInputsToInputs
- return [MoveEmbeddedInputsToInputs]
-
- def run_before(self):
- from openvino.tools.mo.front.kaldi.add_reshape_transpose_around_conv_pool import AddReshapeTransposeAroundConvPool
- from openvino.tools.mo.front.kaldi.memory_offset_adjustment import MemoryOffsetAdjustment
- from openvino.tools.mo.front.kaldi.split_recurrent_memoryoffset import SplitRecurrentMemoryOffset
- return [MemoryOffsetAdjustment, AddReshapeTransposeAroundConvPool, SplitRecurrentMemoryOffset]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='timeheightconvolutioncomponent'):
- self.replace_timeheightconv(graph, node)
-
- def replace_timeheightconv(self, graph: Graph, node: Node):
- req_time_offsets = node.soft_get('time_offsets')
- offsets = node.soft_get("offsets", [[]])
- all_time_offsets = list(set(offsets[:, 0]))
- all_time_offsets.sort()
- in_name = node.soft_get('name', node.id)
- rename_node(node, in_name + '/to_delete')
-
- # create memoryoffsets for context gathering
- # we need concat if time offsets more than 1
- concat = Concat(graph, attrs={'name': in_name + '/Concat',
- 'in_ports_count': len(all_time_offsets)}).create_node()
- i = 0
- for t in all_time_offsets:
- # if time offset included in required_time_offsets we don't need default value
- has_default = t not in req_time_offsets
- memoff = MemoryOffset(graph, attrs={'name': in_name + '/MemoryOffset_' + str(i),
- 't': t, 'has_default': has_default, 'splitted': False,
- 'pair_name': in_name + '/MemoryOffset_pair_' + str(i)}).create_node()
- concat.in_port(i).connect(memoff.out_port(0))
- memoff.in_port(0).connect(node.in_port(0).get_source())
- i = i + 1
-
- stride = node.soft_get("height_subsample", 1)
-
- kernel = int64_array([0, 0])
- kernel[0] = len(set(offsets[:, 0]))
- kernel[1] = len(set(offsets[:, 1]))
-
- pad_h = int64_array([0, 0])
- pad_h[0] = -min(offsets[:, 1]) if min(offsets[:, 1]) < 0 else 0
- pad_h[1] = stride * node.height_out - (node.height_in - max([max(offsets[:, 1]), 0]))
-
- dilation_t = (max(offsets[:, 0]) - min(offsets[:, 0])) / (kernel[0] - 1) if kernel[0] > 1 else 1
- dilation_h = (max(offsets[:, 1]) - min(offsets[:, 1])) / (kernel[1] - 1) if kernel[0] > 1 else 1
-
- conv_attrs = {
- 'name': in_name,
- 'output': node['out_channels'],
- 'height_in': node.height_in,
- 'bias_term': None,
- 'pad': int64_array([[0, 0], [0, 0], [0, 0], pad_h]),
- 'pad_spatial_shape': int64_array([[0, 0], pad_h]),
- 'dilation': int64_array([1, 1, dilation_t, dilation_h]),
- 'kernel': int64_array([node.out_channels, node.in_channels, kernel[0], kernel[1]]),
- 'stride': int64_array([1, 1, 1, stride]),
- 'kernel_spatial': kernel,
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'channel_dims': int64_array([1]),
- 'spatial_dims': int64_array([2, 3]),
- 'batch_dims': int64_array([0]),
- 'kernel_spatial_idx': int64_array([2, 3]),
- 'group': 1,
- 'reshape_kernel': True,
- 'bias_addable': True,
- }
- conv = Convolution(graph, attrs=conv_attrs).create_node()
- conv.in_port(0).connect(concat.out_port(0))
- conv.in_port(1).connect(node.in_port(1).get_source())
-
- # change layout for weights from OHWI to OIHW
- # in future should be replaced by common Permute mechanics
- weights = conv.in_port(1).get_source().node.value
- weights = weights.reshape(int64_array([node.out_channels, -1, node.in_channels]))
- weights = weights.transpose(int64_array([0, 2, 1]))
- weights = weights.flatten()
- conv.in_port(1).get_source().node.value = weights
-
- conv.in_port(2).connect(node.in_port(2).get_source())
- node.out_port(0).get_connection().set_source(conv.out_port(0))
- graph.remove_node(node.id)
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/restrictedattentioncomponent_replacer.py b/tools/mo/openvino/tools/mo/front/kaldi/restrictedattentioncomponent_replacer.py
deleted file mode 100644
index c84a6b2217f105..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/restrictedattentioncomponent_replacer.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils \
- import create_op_with_const_inputs, create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.split import VariadicSplit
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.ops.einsum import Einsum
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.ops.softmax import Softmax
-
-
-class RestrictedAttentionComponentReplacer(FrontReplacementPattern):
- r"""
- This class expands RestrictedAttention operator into the following subgraph:
-
- placeholder
- |
- Reshape[batch*num_heads, -1]
- |
- VariadicSplit(val_dim, key_dim, key_dim + context_dim)
- |
- __________________________
- | | \
- | MemoryOffset* VariadicSplit(key_dim, contex_dim)
- | \ / |
- | Einsum(dot) |
- | | |
- | Mul(key_scale) |
- | \ |
- | ______
- | |
- | Add
- | |
- MemoryOffset* SoftMax
- \ / |
- __________________ |
- | |
- Einsum(dot) |
- \ /
- __________
- |
- Concat
- |
- Reshape[batch, -1]
- |
-
- where context_dim = num_left_inputs + num_right_inputs + 1.
- *MemoryOffsets are described in the create_memory_offsets_subgraph method.
- Specification of the RestrictedAttention Kaldi operator can be found in the Kaldi documentation:
- https://kaldi-asr.org/doc/classkaldi_1_1nnet3_1_1RestrictedAttentionComponent.html.
- """
- enabled = True
- run_not_recursively = True
-
- def __init__(self) -> None:
- self.in_name: str
- self.num_left_inputs: int
- self.num_right_inputs: int
- self.time_stride: int
- super().__init__()
-
- def run_before(self):
- from openvino.tools.mo.front.kaldi.memory_offset_adjustment import MemoryOffsetAdjustment
- return [MemoryOffsetAdjustment]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='restrictedattentioncomponent'):
- self.replace_restrictedattention(graph, node)
-
- def create_memory_offsets_subgraph(self, graph: Graph, input_node: Node, out_port,
- mem_offset_idx):
- r"""
- This method creates the following subgraph and returns endpoint Concat node:
- input_node
- __________________|___________________________
- / | \ \
- MemoryOffset(t1) MemoryOffset(t2) ... MemoryOffset(tk)
- \_____________ _____|______________/____________/
- |
- Concat
- where t1 = -time_stride*num_left_inputs, t2 = t1 + time_stride and
- tk = time_stride*num_right_inputs
- """
- concat_node = Concat(
- graph, attrs={'name': self.in_name + f'/Concat_tmp_{mem_offset_idx}'}).create_node()
-
- for idx, t in enumerate(list(range(-self.time_stride*self.num_left_inputs,
- self.time_stride*self.num_right_inputs+1)\
- [::self.time_stride])):
- concat_node.add_input_port(idx)
- if t != 0:
- memoff = MemoryOffset(graph, attrs={'name': self.in_name +\
- f'/MemoryOffset_{mem_offset_idx}_' +\
- str(idx),
- 't': t, 'has_default': False,
- 'splitted': False,
- 'pair_name': self.in_name +
- f'/MemoryOffset_{mem_offset_idx}_pair_' +
- str(idx)}).create_node()
- memoff.out_port(0).connect(concat_node.in_port(idx))
- input_node.out_port(out_port).connect(memoff.in_port(0))
- else:
- # 0 time delay is not allowed in IE, it's meaningless
- # if time offset is 0 then connect input directly to Concat without memoryoffset
- input_node.out_port(out_port).connect(concat_node.in_port(idx))
-
- return concat_node
-
- def replace_restrictedattention(self, graph: Graph, restrictedattention_node: Node):
- """
- This method replaces RestrictedAttention operator with a subgraph composed with supported
- OpenVino operators.
- """
-
- self.num_left_inputs = restrictedattention_node['num_left_inputs']
- self.num_right_inputs = restrictedattention_node['num_right_inputs']
- context_dim = self.num_left_inputs + self.num_right_inputs + 1
- num_heads = restrictedattention_node['num_heads']
- key_dim = restrictedattention_node['key_dim']
- value_dim = restrictedattention_node['value_dim']
- self.time_stride = restrictedattention_node['time_stride']
- key_scale = restrictedattention_node['key_scale']
-
- batch_axis = 0
- input_shape = restrictedattention_node.in_port(0).data.get_shape()
- if input_shape:
- batch_num = input_shape[batch_axis]
- else:
- batch_num = 1
-
- self.in_name = restrictedattention_node.soft_get('name', restrictedattention_node.id)
-
- reshape_1_node = create_op_node_with_second_input(graph, Reshape,
- int64_array([batch_num * num_heads, -1]),
- {'name': self.in_name + '/Reshape_1'})
- restrictedattention_node.in_port(0).get_source().connect(reshape_1_node.in_port(0))
-
- split_1_node = create_op_with_const_inputs(graph, VariadicSplit,
- {1: int64_array(1),
- 2: int64_array([key_dim, value_dim,
- key_dim + context_dim])},
- {'name': self.in_name + '/VariadicSplit_1',
- 'out_ports_count': 3})
- reshape_1_node.out_port(0).connect(split_1_node.in_port(0))
-
- concat_1_node = self.create_memory_offsets_subgraph(graph, split_1_node, 0, 1)
-
- split_2_node = create_op_with_const_inputs(graph, VariadicSplit,
- {1: int64_array(1),
- 2: int64_array([key_dim, context_dim])},
- {'name': self.in_name + '/VariadicSplit_2',
- 'out_ports_count': 2})
- split_1_node.out_port(2).connect(split_2_node.in_port(0))
-
- einsum_1_node = Einsum(graph, {'name': self.in_name + '/Einsum_1',
- 'override_output_shape': False,
- 'in_ports_count': 2,
- 'equation': 'ij,ik->i'}).create_node()
-
- reshape_helper_1_node = create_op_node_with_second_input(graph, Reshape,
- int64_array(
- [num_heads, 1]),
- {'name': self.in_name +\
- '/Reshape_helper_1'})
- einsum_1_node.out_port(0).connect(reshape_helper_1_node.in_port(0))
-
- concat_1_node.out_port(0).connect(einsum_1_node.in_port(0))
-
- split_2_node.out_port(0).connect(einsum_1_node.in_port(1))
-
- mul_node = create_op_with_const_inputs(graph, Mul, {1: mo_array(key_scale, dtype=float)},
- {'name': self.in_name + '/Mul'})
- reshape_helper_1_node.out_port(0).connect(mul_node.in_port(0))
-
- add_node = Add(graph, {'name': self.in_name + '/Add'}).create_node()
- mul_node.out_port(0).connect(add_node.in_port(1))
- split_2_node.out_port(1).connect(add_node.in_port(0))
-
- softmax_node = Softmax(graph, {'axis': 1, 'name': self.in_name + '/Softmax'}).create_node()
- add_node.out_port(0).connect(softmax_node.in_port(0))
-
- concat_2_node = self.create_memory_offsets_subgraph(graph, split_1_node, 1, 2)
-
- reshape_helper_2_node = create_op_node_with_second_input(graph, Reshape,
- int64_array([num_heads,
- value_dim,
- context_dim]),
- {'name': self.in_name +\
- '/Reshape_helper_2'})
- concat_2_node.out_port(0).connect(reshape_helper_2_node.in_port(0))
-
- reshape_helper_3_node = create_op_node_with_second_input(graph, Reshape,
- int64_array(
- [num_heads, 1, context_dim]),
- {'name': self.in_name +\
- '/Reshape_helper_3'})
-
- einsum_2_node = Einsum(graph, {'name': self.in_name + '/Einsum_2',
- 'in_ports_count': 2,
- 'equation': 'ijk,ilk->ij'}).create_node()
- reshape_helper_2_node.out_port(0).connect(einsum_2_node.in_port(0))
-
- softmax_node.out_port(0).connect(reshape_helper_3_node.in_port(0))
- reshape_helper_3_node.out_port(0).connect(einsum_2_node.in_port(1))
-
- concat_3_node = Concat(graph, {'name': self.in_name + '/Concat_2',
- 'in_ports_count': 2}).create_node()
- einsum_2_node.out_port(0).connect(concat_3_node.in_port(0))
- softmax_node.out_port(0).connect(concat_3_node.in_port(1))
-
- reshape_2_node = create_op_node_with_second_input(graph, Reshape,
- int64_array([batch_num, -1]),
- {'name': self.in_name + '/Reshape_2'})
- concat_3_node.out_port(0).connect(reshape_2_node.in_port(0))
-
- restrictedattention_node.in_port(0).disconnect()
- restrictedattention_node.out_port(0).get_connection().set_source(reshape_2_node.out_port(0))
- graph.remove_node(restrictedattention_node.id)
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/set_ports.py b/tools/mo/openvino/tools/mo/front/kaldi/set_ports.py
deleted file mode 100644
index 2208880bb6b8fb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/set_ports.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils.error import Error
-
-
-class SetPortsPattern(FrontReplacementSubgraph):
- """
- Pass used to set ports for loaded graph for Kaldi
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.restore_ports import RestorePorts
- return [RestorePorts]
-
- def run_after(self):
- from openvino.tools.mo.load.loader import LoadFinish
- return [LoadFinish]
-
- def find_and_replace_pattern(self, graph: Graph):
- graph.stage = 'front'
- for node_id in graph.nodes(data=False):
- node = Node(graph, node_id)
- inputs = node.get_sorted_inputs()
- outputs = node.get_sorted_outputs()
-
- in_ports_count = node.in_ports_count if node.has_valid('in_ports_count') else len(inputs)
- out_ports_count = node.out_ports_count if node.has_valid('out_ports_count') else len(outputs)
-
- if len(outputs) > out_ports_count > 1:
- raise Error("Node {} has more children than it should: " +
- "should be {} but there is {}".format(node_id, out_ports_count, len(outputs)))
-
- node['_in_ports'] = {}
- node['_out_ports'] = {}
- if in_ports_count is not None:
- for idx in range(in_ports_count):
- node.add_input_port(idx=idx)
-
- if out_ports_count is not None:
- for idx in range(out_ports_count):
- node.add_output_port(idx=idx)
- idx = 0
- for in_node_id, edge_attrs in inputs:
- graph.remove_edge(in_node_id, node_id)
- if len(Node(graph, in_node_id).out_ports()) == 0:
- Node(graph, in_node_id).add_output_port(0)
- in_node = Node(graph, in_node_id)
- in_node.out_port(edge_attrs['out']).connect(node.in_port(idx))
- # need to keep this attribute in edge for correct .mapping file generation and
- # for generation of "names" field in IR
- in_node.out_edge(edge_attrs['out'])['fw_tensor_debug_info'] = edge_attrs['fw_tensor_debug_info']
- if idx < in_ports_count - 1:
- idx = idx + 1
-
- idx = 0
- for out_node_id, edge_attrs in outputs:
- graph.remove_edge(node_id, out_node_id)
- if len(Node(graph, out_node_id).in_ports()) == 0:
- Node(graph, out_node_id).add_input_port(0)
- node.out_port(idx).connect(Node(graph, out_node_id).in_port(edge_attrs['in']))
- # need to keep this attribute in edge for correct .mapping file generation and
- # for generation of "names" field in IR
- node.out_edge(idx)['fw_tensor_debug_info'] = edge_attrs['fw_tensor_debug_info']
- if idx < out_ports_count - 1:
- idx = idx + 1
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/sigmoid_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/sigmoid_ext.py
deleted file mode 100644
index a41dc8af8b6a26..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/sigmoid_ext.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import Sigmoid
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SigmoidFrontExtractor(FrontExtractorOp):
- op = 'sigmoid'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sigmoid.update_node_stat(node)
- return cls.enabled
-
-
-class SigmoidComponentFrontExtractor(FrontExtractorOp):
- op = 'sigmoidcomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sigmoid.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/split_recurrent_memoryoffset.py b/tools/mo/openvino/tools/mo/front/kaldi/split_recurrent_memoryoffset.py
deleted file mode 100644
index e7b0370aebcbba..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/split_recurrent_memoryoffset.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.graph import Node
-
-
-class SplitRecurrentMemoryOffset(FrontReplacementSubgraph):
- """
- Splits MemoryOffsets in recurrent blocks (typically LSTM blocks) into 2 parts.
-
- These parts then will be converted to ReadValue and Assign. Splitting complicates shape inference but
- MemoryOffsets in recurrent blocks are cycled and, in order to make topological sort possible
- during shape inference, they are splitted earlier on the front phase. In contrast,
- MemoryOffsets in TDNN blocks are not cycled, so they will be splitted after shape infer on the middle.
- Now only LSTM blocks with MemoryOffset are present.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'kaldi']
-
- @staticmethod
- def split_offset(offset_node: Node):
- paired_node = MemoryOffset(offset_node.graph, {'name': offset_node.pair_name, 'splitted': True,
- 'pair_name': offset_node.id,
- 'element_size': offset_node['element_size'],
- 't': offset_node.t,
- 'has_default': offset_node.has_default}).create_node()
- offset_node['splitted'] = True
- offset_node.out_port(0).get_connection().set_source(paired_node.out_port(0))
- res_node = Result(offset_node.graph, {'name': offset_node.id + '_output'}).create_node()
- offset_node.out_port(0).connect(res_node.in_port(0))
-
- def find_and_replace_pattern(self, graph: Graph):
- for offset_node in graph.get_op_nodes(op='MemoryOffset', splitted=False):
- try:
- # if graph contains recurrent block -> split MemoryOffset to enable shape infer
- nx.find_cycle(graph, offset_node.id)
- except nx.NetworkXNoCycle as e:
- # MemoryOffset node is not in a recurrent block -- no splitting is needed
- return
-
- # check that node has information for future partial infer
- # element_size is set in loader based on dimensions of previous layer from original Kaldi model
- if not offset_node.has_valid('element_size'):
- # check if previous layer contains information about its shape in out-size
- # out-size is set in extractor of some nodes like affinecomponent based on weight's size
- if offset_node.in_port(0).get_source().node.has_valid('out-size'):
- offset_node['element_size'] = int64_array([1, offset_node.in_port(0).get_source().node['out-size']])
- else:
- raise Error("In a recurrent block 'element_size' for node {} is not set".format(offset_node.id))
- SplitRecurrentMemoryOffset.split_offset(offset_node)
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/tanh_component_ext.py b/tools/mo/openvino/tools/mo/front/kaldi/tanh_component_ext.py
deleted file mode 100644
index e972760822bff2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/tanh_component_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import Tanh
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class TanhFrontExtractor(FrontExtractorOp):
- op = 'tanhcomponent'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Tanh.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/tdnn_component_replacer.py b/tools/mo/openvino/tools/mo/front/kaldi/tdnn_component_replacer.py
deleted file mode 100644
index f29aaf5ef5ebc1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/tdnn_component_replacer.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.MatMul import FullyConnected
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.graph import rename_nodes
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-
-
-class TdnnComponentReplacer(FrontReplacementPattern):
- r"""
- Expand TdnnComponent into MemoryOffsets, Concat and FullyConected nodes
-
- BEFORE:
- placeholder
- |
- TdnnComponent('time_offsets': t1, t2,... tk)
- |
- _______________________________________________________________
-
- AFTER:
- placeholder
- __________________|___________________________
- / | \ \
- MemoryOffset(t1) MemoryOffset(t2) ... MemoryOffset(tk)
- \_____________ _____|______________/____________/
- Concat
- |
- FullyConnected
- |
- """
- enabled = True
- run_not_recursively = True
-
- def run_before(self):
- from openvino.tools.mo.front.kaldi.memory_offset_adjustment import MemoryOffsetAdjustment
- return [MemoryOffsetAdjustment]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='tdnncomponent'):
- self.replace_tdnn(graph, node)
-
- def replace_tdnn(self, graph: Graph, tdnn_node: Node):
- tdnn_name = tdnn_node.soft_get('name', tdnn_node.id)
-
- concat_node = Concat(graph, {'axis': 1}).create_node()
- rename_nodes([(tdnn_node, tdnn_name + '/to_be_removed'), (concat_node, tdnn_name)])
-
- for offset_ind, t in enumerate(tdnn_node['time_offsets']):
- concat_node.add_input_port(offset_ind)
- if t != 0:
- memory_name = tdnn_name + '/MemoryOffset/' + str(abs(t))
- memoryoffset_node = MemoryOffset(graph, {'name': memory_name, 't': t,
- 'pair_name': memory_name + '_out',
- 'has_default': False, 'splitted': False}).create_node()
-
- tdnn_node.in_port(0).get_source().connect(memoryoffset_node.in_port(0))
- memoryoffset_node.out_port(0).connect(concat_node.in_port(offset_ind))
- else:
- # 0 time delay is not allowed in IE, it's meaningless
- # if time offset is 0 then connect input of tdnncomponent directly to Concat without memoryoffset
- tdnn_node.in_port(0).get_source().connect(concat_node.in_port(offset_ind))
-
- weights = tdnn_node['weights']
- fc_inputs = {1: weights}
-
- bias_term = False
- if tdnn_node.has_valid('biases'):
- assert len(tdnn_node['biases']) == weights.shape[0]
- fc_inputs.update({2: tdnn_node['biases']})
- bias_term = True
-
- fc_node = create_op_with_const_inputs(graph, FullyConnected, fc_inputs,
- {'name': tdnn_name + '/FC', 'out-size': weights.shape[0],
- 'transpose_weights': True, 'bias_term': bias_term})
-
- concat_node.out_port(0).connect(fc_node.in_port(0))
- tdnn_node.in_port(0).disconnect()
- tdnn_node.out_port(0).get_connection().set_source(fc_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/kaldi/utils.py b/tools/mo/openvino/tools/mo/front/kaldi/utils.py
deleted file mode 100644
index 4871c27150debe..00000000000000
--- a/tools/mo/openvino/tools/mo/front/kaldi/utils.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import io
-import logging as log
-import os
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.loader.utils import read_placeholder, read_binary_integer32_token, read_blob, read_token_value, \
- find_next_tag
-from openvino.tools.mo.utils.error import Error
-
-
-def read_binary_matrix(file_desc: io.BufferedReader, read_token: bool = True):
- if read_token:
- read_placeholder(file_desc)
- rows_number = read_binary_integer32_token(file_desc)
- cols_number = read_binary_integer32_token(file_desc)
- # to compare: ((float *)a->buffer())[10]
- return read_blob(file_desc, rows_number * cols_number), (rows_number, cols_number)
-
-
-def read_binary_vector(file_desc: io.BufferedReader, read_token: bool = True, dtype=np.float32):
- if read_token:
- read_placeholder(file_desc)
- elements_number = read_binary_integer32_token(file_desc)
- return read_blob(file_desc, elements_number, dtype)
-
-
-def read_binary_vector_of_pairs(file_desc: io.BufferedReader, read_token: bool = True, dtype=np.float32):
- if read_token:
- read_placeholder(file_desc)
- elements_number = read_binary_integer32_token(file_desc)
- return read_blob(file_desc, 2 * elements_number, dtype)
-
-
-def read_learning_info(pb: io.BufferedReader):
- while True:
- read_placeholder(pb, 1)
- first_char = pb.read(1)
- pb.seek(-2, os.SEEK_CUR)
- position = pb.tell()
- if first_char == b'L':
- cur_pos = pb.tell()
- token = find_next_tag(pb)
- pb.seek(cur_pos)
- if token in ['', '']:
- token = bytes(token, 'ascii')
- else:
- log.debug('Unexpected tag: {}'.format(token))
- break
- elif first_char == b'B':
- token = b''
- elif first_char == b'M':
- token = b''
- elif first_char == b'!': # token = b''
- break
- else:
- break
- try:
- read_token_value(pb, token)
- except Error:
- pb.seek(position)
- break
-
diff --git a/tools/mo/openvino/tools/mo/front/no_op_eraser.py b/tools/mo/openvino/tools/mo/front/no_op_eraser.py
deleted file mode 100644
index 3c24b19ac0fa02..00000000000000
--- a/tools/mo/openvino/tools/mo/front/no_op_eraser.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-
-
-class NoOpEraser(FrontReplacementSubgraph):
- enabled = True
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('noop', dict(kind='op', op='NoOp')),
- ('output', dict(kind='op', op='Result'))
- ],
- edges=[('noop', 'output')]
- )
-
- @staticmethod
- def replace_sub_graph(graph: Graph, match: dict):
- graph.erase_node(match['output'])
- graph.erase_node(match['noop'])
- log.info("NoOp node \"{}\" was removed from the graph".format(match['noop'].id))
diff --git a/tools/mo/openvino/tools/mo/front/non_max_suppression_normalize.py b/tools/mo/openvino/tools/mo/front/non_max_suppression_normalize.py
deleted file mode 100644
index 11cc1b5d1e3ee0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/non_max_suppression_normalize.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class NonMaxSuppressionNormalize(FrontReplacementSubgraph):
- """
- The transformation converts several inputs of the NonMaxSuppression layer to be 1D instead of 0D with shape [1] to
- comply with the layer specification.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for nms in graph.get_op_nodes(op='NonMaxSuppression'):
- # make inputs 2 to 5 to have shape [1] instead of [0] (convert 0D to 1D)
- nms_name = nms.soft_get('name', nms.id)
- for port_id in range(2, 6):
- 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_name + '/Reshape_1D_{}'.format(port_id)})
- nms.in_port(port_id).get_connection().insert_node(reshape_1d)
diff --git a/tools/mo/openvino/tools/mo/front/onnx/AttributedSliceToSlice.py b/tools/mo/openvino/tools/mo/front/onnx/AttributedSliceToSlice.py
deleted file mode 100644
index 433597c9c85147..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/AttributedSliceToSlice.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.slice import Slice
-
-
-class AttributedSliceToSliceReplacer(FrontReplacementOp):
- """
- This class replaces AttributedSlice -> Slice
- """
- op = 'AttributedSlice'
- enabled = True
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- node = match['op']
- slice_name = node.soft_get('name', node.id)
-
- slice_node = create_op_with_const_inputs(graph, Slice, {1: node.starts, 2: node.ends, 3: node.axes})
- rename_nodes([(node, slice_name + '/to_be_removed'), (slice_node, slice_name)])
-
- node.in_port(0).get_connection().set_destination(slice_node.in_port(0))
- node.out_port(0).get_connection().set_source(slice_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/CTCGreedyDecoder_ext.py b/tools/mo/openvino/tools/mo/front/onnx/CTCGreedyDecoder_ext.py
deleted file mode 100644
index e6f66c42b0244c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/CTCGreedyDecoder_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ctc_greedy_decoder_seq_len import CTCGreedyDecoderSeqLenOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class CTCCGreedyDecoderFrontExtractor(FrontExtractorOp):
- op = 'CTCGreedyDecoder'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'merge_repeated': bool(onnx_attr(node, 'merge_repeated', 'i', default=1)),
- }
- CTCGreedyDecoderSeqLenOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/LoopNormalize.py b/tools/mo/openvino/tools/mo/front/onnx/LoopNormalize.py
deleted file mode 100644
index 222e63d631db64..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/LoopNormalize.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.pass_separator import FrontStart
-from openvino.tools.mo.front.restore_ports import RestorePorts
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mo_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class ONNXLoopNormalize(FrontReplacementSubgraph):
- enabled = True
-
- def run_before(self):
- return [FrontStart]
-
- def run_after(self):
- return [RestorePorts]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='Loop'):
- self.normalize_body_graph(node)
-
- @staticmethod
- def normalize_body_graph(loop_node: Node):
- loop_name = loop_node.soft_get('name', loop_node.id)
- # connect "trip count" input if it is not connected with default value "Infinity" (-1)
- if not loop_node.is_in_port_connected(0):
- loop_node.add_input_port(0, skip_if_exist=True)
- Const(loop_node.graph, {'name': loop_name + '/trip_count', 'value': int64_array(-1)}).\
- create_node().out_port(0).connect(loop_node.in_port(0))
-
- # connect "execution condition" input if it is not connected with default value True
- if not loop_node.is_in_port_connected(1):
- loop_node.add_input_port(1, skip_if_exist=True)
- Const(loop_node.graph, {'name': loop_name + '/execution_cond', 'value': mo_array(True, dtype=bool)}).\
- create_node().out_port(0).connect(loop_node.in_port(1))
-
- # scan output need Unsqueeze over axis 0
- for record in loop_node.output_port_map:
- body_node = Loop.get_body_node_by_internal_id(loop_node, record['internal_layer_id'])
- assert body_node is not None
- assert body_node.soft_get('type') == 'Result'
-
- if record['axis'] is not None:
- unsqueeze = create_op_with_const_inputs(loop_node.body, Unsqueeze, {1: int64_array([0])})
- body_node.in_port(0).get_connection().insert_node(unsqueeze)
-
- Loop.normalize_input_output_ports(loop_node)
diff --git a/tools/mo/openvino/tools/mo/front/onnx/MvnOnnxToMvn.py b/tools/mo/openvino/tools/mo/front/onnx/MvnOnnxToMvn.py
deleted file mode 100644
index 3a3438d39b5664..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/MvnOnnxToMvn.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-
-
-class MvnOnnxToMvn(FrontReplacementPattern):
- """
- Replace AttributedMVN operation from ONNX with MVN
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='MVNOnnx'):
- node_name = node.soft_get('name', node.id)
-
- new_mvn = create_op_with_const_inputs(graph, MVN, {1: node.axes},
- {'eps': node.eps,
- 'eps_mode': node.eps_mode,
- 'normalize_variance': node.normalize_variance})
- node.in_port(0).get_connection().set_destination(new_mvn.in_port(0))
- node.out_port(0).get_connection().set_source(new_mvn.out_port(0))
- rename_nodes([(node, node_name + '/to_be_removed'), (new_mvn, node_name)])
-
- graph.remove_node(node.id)
diff --git a/tools/mo/openvino/tools/mo/front/onnx/ONNXResize10ToInterpolate.py b/tools/mo/openvino/tools/mo/front/onnx/ONNXResize10ToInterpolate.py
deleted file mode 100644
index d4eb4240ecddb4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/ONNXResize10ToInterpolate.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.activation_ops import Floor
-from openvino.tools.mo.ops.elementwise import Add, Mul
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.ops.rank import Rank
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-def replace_resize(graph: Graph, resize: Node):
- log.debug("Converting of ONNX Resize-10 to Interpolate-4 "
- "is triggered for node {}.".format(resize.soft_get('name', resize.id)))
-
- resize_name = resize.soft_get('name', resize.id)
-
- rank_node = Rank(graph, {'name': resize_name + '/max_axes'}).create_node()
- range_node = create_op_with_const_inputs(graph, Range, {0: int64_array(2), 2: int64_array(1)},
- {'name': resize_name + '/axes'})
-
- sizes_ss = create_op_with_const_inputs(graph, StridedSlice,
- {1: int64_array([2]),
- 2: int64_array([0]),
- 3: int64_array([1])},
- {'name': resize_name + '/sizes_ss',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([0]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])})
- scales_ss = create_op_with_const_inputs(graph, StridedSlice,
- {1: int64_array([2]),
- 2: int64_array([0]),
- 3: int64_array([1])},
- {'name': resize_name + '/scales_ss',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([0]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])})
-
- rank_node.out_port(0).connect(range_node.in_port(1))
-
- interpolate_node = Interpolate(graph, {'version': 'opset4',
- 'mode': 'linear_onnx' if resize.mode == 'linear' else 'nearest',
- 'coordinate_transformation_mode': 'asymmetric',
- 'cube_coeff': -0.75,
- 'nearest_mode': 'simple',
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'antialias': 0,
- 'shape_calculation_mode': 'scales',
- 'in_ports_count': 4}).create_node()
-
- range_node.out_port(0).connect(interpolate_node.in_port(3))
- shape_of = Shape(graph, {'name': resize_name + '/ShapeOf'}).create_node()
-
- # When we calculate 'sizes' input as floor(input_shape * scales), we can get incorrect 'sizes' if, e.g.,
- # scales = [1.0, 1.0, 1.33333, 2.0], input_shape = [1, 3, 30, 200], because
- # input_shape * scales = [1, 3, 39.9999, 400], and floor(input_shape * scales)[2] == 39, not 40.
- # Maybe we need to calculate 'sizes' input as floor(input_shape * scales + eps), where eps is some small
- # floating point number, e.g. 1.0e-5. But, in this case, if scales = [1.0, 1.0, 1.333333, 2.0],
- # input_shape = [1, 3, 30, 200], floor(input_shape * scales + eps) = 39, not 40, because
- # input_shape[2] * scales[2] + 1.0e-5 = 39.99991.
- # Hence, we need to calculate 'sizes' as floor(input_shape * (scales + eps)).
- add_node = create_op_with_const_inputs(graph, Add,
- {1: float_array([1.0e-5])},
- {'name': resize_name + '/Add'})
-
- dst_dtype = np.float32 # even if data_type=FP16 use float32 for shape values
-
- cast_shape_to_float = Cast(graph, {'dst_type': dst_dtype}).create_node()
-
- shape_of.out_port(0).connect(cast_shape_to_float.in_port(0))
- mul_node = Mul(graph, {'name': resize_name + '/Mul'}).create_node([cast_shape_to_float, add_node])
- floor_node = Floor(graph, {'name': resize_name + '/Floor'}).create_node([mul_node])
- cast_mul_result_to_int = Cast(graph, {'dst_type': np.int64}).create_node([floor_node])
- cast_mul_result_to_int.out_port(0).connect(sizes_ss.in_port(0))
- sizes_ss.out_port(0).connect(interpolate_node.in_port(1))
-
- scales_ss.out_port(0).connect(interpolate_node.in_port(2))
-
- connection_of_resize_input = resize.in_port(0).get_connection()
- connection_of_resize_input.set_destination(interpolate_node.in_port(0))
-
- connection_of_scales = resize.in_port(1).get_connection()
- connection_of_scales.set_destination(scales_ss.in_port(0))
-
- connection_of_resize_input.get_source().connect(shape_of.in_port(0))
- connection_of_resize_input.get_source().connect(rank_node.in_port(0))
- connection_of_scales.get_source().connect(add_node.in_port(0))
-
- rename_nodes([(resize, resize_name + '/delete'), (interpolate_node, resize_name)])
- resize.out_port(0).get_connection().set_source(interpolate_node.out_port(0))
-
-
-class ONNXResize10ToInterpolate(FrontReplacementOp):
- """
- The transformation replaces ONNX Resize 10 with Interpolate-4.
- """
- op = 'ONNXResize10'
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.InterpolateNormalizer import InterpolateNormalizer
- return [InterpolateNormalizer]
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- resize = match['op']
- replace_resize(graph, resize)
diff --git a/tools/mo/openvino/tools/mo/front/onnx/__init__.py b/tools/mo/openvino/tools/mo/front/onnx/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/front/onnx/activation_ext.py b/tools/mo/openvino/tools/mo/front/onnx/activation_ext.py
deleted file mode 100644
index 8f8ae899159b40..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/activation_ext.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import *
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class AbsExtractor(FrontExtractorOp):
- op = 'Abs'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Abs.update_node_stat(node)
- return cls.enabled
-
-
-class AcosExtractor(FrontExtractorOp):
- op = 'Acos'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Acos.update_node_stat(node)
- return cls.enabled
-
-
-class AcoshExtractor(FrontExtractorOp):
- op = 'Acosh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Acosh.update_node_stat(node)
- return cls.enabled
-
-
-class AsinExtractor(FrontExtractorOp):
- op = 'Asin'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Asin.update_node_stat(node)
- return cls.enabled
-
-
-class AsinhExtractor(FrontExtractorOp):
- op = 'Asinh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Asinh.update_node_stat(node)
- return cls.enabled
-
-
-class AtanExtractor(FrontExtractorOp):
- op = 'Atan'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Atan.update_node_stat(node)
- return cls.enabled
-
-
-class AtanhExtractor(FrontExtractorOp):
- op = 'Atanh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Atanh.update_node_stat(node)
- return cls.enabled
-
-
-class CeilExtractor(FrontExtractorOp):
- op = 'Ceil'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Ceiling.update_node_stat(node)
- return cls.enabled
-
-
-class CosExtractor(FrontExtractorOp):
- op = 'Cos'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Cos.update_node_stat(node)
- return cls.enabled
-
-
-class CoshExtractor(FrontExtractorOp):
- op = 'Cosh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Cosh.update_node_stat(node)
- return cls.enabled
-
-
-class EluExtractor(FrontExtractorOp):
- op = 'Elu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- alpha = onnx_attr(node, 'alpha', 'f', default=1.0)
- Elu.update_node_stat(node, {'alpha': alpha})
- return EluExtractor.enabled
-
-
-class ErfExtractor(FrontExtractorOp):
- op = 'Erf'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Erf.update_node_stat(node)
- return cls.enabled
-
-
-class ExpExtractor(FrontExtractorOp):
- op = 'Exp'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Exp.update_node_stat(node)
- return cls.enabled
-
-
-class FloorExtractor(FrontExtractorOp):
- op = 'Floor'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Floor.update_node_stat(node)
- return cls.enabled
-
-
-class ThresholdedReluExtractor(FrontExtractorOp):
- op = 'ThresholdedRelu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- alpha = onnx_attr(node, 'alpha', 'f', default=1.0)
- ThresholdedRelu.update_node_stat(node, {'alpha': alpha})
- return cls.enabled
-
-
-class LeakyReLUExtractor(FrontExtractorOp):
- op = 'LeakyRelu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- negative_slope = onnx_attr(node, 'alpha', 'f', default=1.0)
- if negative_slope == 0:
- ReLU.update_node_stat(node)
- else:
- LeakyReLU.update_node_stat(node, {'negative_slope': negative_slope})
- return cls.enabled
-
-
-class LogExtractor(FrontExtractorOp):
- op = 'Log'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Log.update_node_stat(node)
- return cls.enabled
-
-
-class NotExtractor(FrontExtractorOp):
- op = 'Not'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalNot.update_node_stat(node)
- return cls.enabled
-
-
-class ReLUExtractor(FrontExtractorOp):
- op = 'Relu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ReLU.update_node_stat(node)
- return cls.enabled
-
-
-class SigmoidExtractor(FrontExtractorOp):
- op = 'Sigmoid'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sigmoid.update_node_stat(node)
- return cls.enabled
-
-
-class SignExtractor(FrontExtractorOp):
- op = 'Sign'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sign.update_node_stat(node)
- return cls.enabled
-
-
-class SinExtractor(FrontExtractorOp):
- op = 'Sin'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sin.update_node_stat(node)
- return cls.enabled
-
-
-class SinhExtractor(FrontExtractorOp):
- op = 'Sinh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sinh.update_node_stat(node)
- return cls.enabled
-
-
-class TanExtractor(FrontExtractorOp):
- op = 'Tan'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Tan.update_node_stat(node)
- return cls.enabled
-
-
-class TanhExtractor(FrontExtractorOp):
- op = 'Tanh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Tanh.update_node_stat(node)
- return cls.enabled
-
-
-class SoftSignExtractor(FrontExtractorOp):
- op = 'Softsign'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- SoftSign.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/affine_ext.py b/tools/mo/openvino/tools/mo/front/onnx/affine_ext.py
deleted file mode 100644
index 491c27d50c02b6..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/affine_ext.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class AffineFrontExtractor(FrontExtractorOp):
- # Affine operation will be transformed to ImageScalar and further will be converted to Mul->Add seq
- op = 'Affine'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- dst_type = lambda x: mo_array(x)
-
- scale = onnx_attr(node, 'alpha', 'f', default=None, dst_type=dst_type)
- bias = onnx_attr(node, 'beta', 'f', default=None, dst_type=dst_type)
-
- node['scale'] = scale
- node['bias'] = bias
- node['op'] = 'ImageScaler'
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/argmax_ext.py b/tools/mo/openvino/tools/mo/front/onnx/argmax_ext.py
deleted file mode 100644
index f21bf86f825b64..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/argmax_ext.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.argmax import ArgMaxOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-class ArgMaxFrontExtractor(FrontExtractorOp):
- op = 'ArgMax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- keepdims = onnx_attr(node, 'keepdims', 'i', default=1)
- axis = onnx_attr(node, 'axis', 'i', default=0)
-
- attrs = {
- 'axis': axis,
-
- # ONNX ArgMax always computes an index of one maximum value
- 'top_k' : 1,
- 'out_max_val' : 0,
-
- # Set attribute to trigger ArgMax replacer in case do not keep the dimension
- 'keepdims': keepdims,
-
- 'remove_values_output': True
- }
-
- ArgMaxOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/argmin_ext.py b/tools/mo/openvino/tools/mo/front/onnx/argmin_ext.py
deleted file mode 100644
index 9aad2ef84da7c3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/argmin_ext.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.argmin import ArgMinOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ArgMinFrontExtractor(FrontExtractorOp):
- op = 'ArgMin'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- keepdims = onnx_attr(node, 'keepdims', 'i', default=1)
- axis = onnx_attr(node, 'axis', 'i', default=0)
-
- attrs = {
- 'axis': axis,
- 'top_k': 1,
- 'keepdims': keepdims,
- 'remove_values_output': True
- }
-
- ArgMinOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/aten_ext.py b/tools/mo/openvino/tools/mo/front/onnx/aten_ext.py
deleted file mode 100644
index 4a36d7676f0dd1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/aten_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.aten import ATen
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ATenFrontExtractor(FrontExtractorOp):
- op = 'ATen'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- mode = onnx_attr(node, 'mode', 'i', default=1)
- operator = onnx_attr(node, 'operator', 's').decode()
-
- ATen.update_node_stat(node, {'operator': operator, 'mode': mode})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/cast_ext.py b/tools/mo/openvino/tools/mo/front/onnx/cast_ext.py
deleted file mode 100644
index ba7a8f5b15b54f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/cast_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import get_onnx_datatype_as_numpy, onnx_attr
-
-
-class CastFrontExtractor(FrontExtractorOp):
- op = 'Cast'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- to = onnx_attr(node, 'to', 'i', default=None)
- Cast.update_node_stat(node, {'dst_type': get_onnx_datatype_as_numpy(to)})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/clip_ext.py b/tools/mo/openvino/tools/mo/front/onnx/clip_ext.py
deleted file mode 100644
index 5ecc7d15ff684a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/clip_ext.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version, onnx_node_has_attr
-from openvino.tools.mo.ops.clamp import Clamp, AttributedClamp
-
-
-class ClipFrontExtractor(FrontExtractorOp):
- op = 'Clip'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- if get_onnx_opset_version(node) < 11:
- attrs = {
- 'min': onnx_attr(node, 'min', 'f', np.finfo(np.float32).min),
- 'max': onnx_attr(node, 'max', 'f', np.finfo(np.float32).max),
- }
- AttributedClamp.update_node_stat(node, attrs)
- else:
- if onnx_node_has_attr(node, 'min') or onnx_node_has_attr(node, 'max'):
- log.error("ONNX Clip-11 operation '{}' shouldn't have attributes 'min' and 'max', this may mean that "
- "this operation created with older opset version.".format(
- node.soft_get('name', node.id)), extra={'is_warning': True})
- Clamp.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/concat_ext.py b/tools/mo/openvino/tools/mo/front/onnx/concat_ext.py
deleted file mode 100644
index 0e0d41a0f87b56..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/concat_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.concat import Concat
-
-class ConcatFrontExtractor(FrontExtractorOp):
- op = 'Concat'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- mapping_rule = {
- 'axis': onnx_attr(node, 'axis', 'i', default=0)
- }
- Concat.update_node_stat(node, mapping_rule)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/const_ext.py b/tools/mo/openvino/tools/mo/front/onnx/const_ext.py
deleted file mode 100644
index 9cb6811cee8192..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/const_ext.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from onnx import numpy_helper
-from onnx.numpy_helper import to_array
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.const import Const
-
-
-class ConstExtractor(FrontExtractorOp):
- op = 'Const'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- value = to_array(node.pb_init)
- attrs = {
- 'data_type': value.dtype,
- 'value': value
- }
- Const.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class ConstantExtractor(FrontExtractorOp):
- op = 'Constant'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb_value = onnx_attr(node, 'value', 't')
- value = numpy_helper.to_array(pb_value)
-
- attrs = {
- 'data_type': value.dtype,
- 'value': value,
- }
- Const.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/constant_fill_ext.py b/tools/mo/openvino/tools/mo/front/onnx/constant_fill_ext.py
deleted file mode 100644
index a1821e3fed6314..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/constant_fill_ext.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.constant_fill import ConstantFill
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ConstantFillFrontExtractor(FrontExtractorOp):
- op = 'ConstantFill'
- enabled = True
-
- @classmethod
- def extract(cls, node):
-
- value = onnx_attr(node, 'value', 'f', default=float(0.0))
- input_as_shape = onnx_attr(node, 'input_as_shape', 'i')
- extra_shape = onnx_attr(node, 'extra_shape', 'ints')
- shape = onnx_attr(node, 'shape', 'ints')
- dtype = onnx_attr(node, 'dtype', 'i', 1)
-
- assert input_as_shape
- assert extra_shape is None
- assert shape is None
- assert dtype == 1
-
- attrs = {
- 'fill_value': value,
- 'input_as_shape': input_as_shape,
- }
-
- ConstantFill.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/constant_of_shape_ext.py b/tools/mo/openvino/tools/mo/front/onnx/constant_of_shape_ext.py
deleted file mode 100644
index 1c297cb1581eb9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/constant_of_shape_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-from onnx import numpy_helper
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.constant_of_shape import ConstantOfShape
-
-
-class ConstantOfShapeExtractor(FrontExtractorOp):
- op = 'ConstantOfShape'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- fill_value = onnx_attr(node, 'value', 't', default=mo_array([0.0]), dst_type=lambda x: numpy_helper.to_array(x))
-
- ConstantOfShape.update_node_stat(node, {'fill_value': fill_value})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/constant_of_shape_to_broadcast.py b/tools/mo/openvino/tools/mo/front/onnx/constant_of_shape_to_broadcast.py
deleted file mode 100644
index 263a76f4c619ef..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/constant_of_shape_to_broadcast.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.const import Const
-
-
-class ConstantOfShapeToBroadcast(FrontReplacementPattern):
- """
- Converts the 'ConstantOfShape' layer to 'Broadcast'.
-
- The 'ConstantOfShape' has one 1D input defining the output constant shape. The value to be filled is defined by the
- 'value' attribute. The transformation creates constant node with value equal to 'value' attribute and connects it to
- the first input of a newly created 'Broadcast' node which defines value to broadcast. Then the input of the
- 'ConstantOfShape' is connected to the second input of the 'Broadcast'.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for const_of_shape_node in graph.get_op_nodes(op='ConstantOfShape'):
- broadcast_node = Broadcast(graph, {'name': const_of_shape_node.name + '/Broadcast'}).create_node()
- const_of_shape_node.in_port(0).get_connection().set_destination(broadcast_node.in_port(1))
- broadcast_node.in_port(0).connect(Const(graph, {'name': broadcast_node.name + '/FillValue',
- 'value': const_of_shape_node.fill_value}
- ).create_node().out_port(0))
- const_of_shape_node.out_port(0).get_connection().set_source(broadcast_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/conv_ext.py b/tools/mo/openvino/tools/mo/front/onnx/conv_ext.py
deleted file mode 100644
index 9d424035d85ac8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/conv_ext.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_autopad
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.utils.error import Error
-
-
-class ConvFrontExtractor(FrontExtractorOp):
- op = 'Conv'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # Extract pads attribute
- # In case if pads is not specified it will be set in default (1) in infer function
- pads = onnx_attr(node, 'pads', 'ints', default=None, dst_type=lambda x: int64_array(x))
- assert pads is None or len(pads) % 2 == 0
- final_pad = None
- if pads is not None:
- pads = pads.reshape([2, -1])
- pads = np.transpose(pads)
- final_pad = int64_array([[0, 0], [0, 0], *pads])
-
- # Extract dilations attribute
- # In case if dilations is not specified it will be set in default (1) in infer function
- dilations = onnx_attr(node, 'dilations', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_dilations = int64_array([1, 1, *dilations]) if dilations is not None else None
-
- # Extract dilations attribute
- # In case if dilations is not specified it will be set in default (1) in infer function
- strides = onnx_attr(node, 'strides', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_strides = int64_array([1, 1, *strides]) if strides is not None else None
-
- kernel_shape = onnx_attr(node, 'kernel_shape', 'ints', default=None)
- auto_pad = onnx_attr(node, 'auto_pad', 's', default=None, dst_type=get_onnx_autopad)
- group = onnx_attr(node, 'group', 'i', default=1, dst_type=lambda x: int64_array(x))
-
- attrs = {
- 'op': __class__.op,
- 'auto_pad': auto_pad,
- 'bias_addable': True,
- 'bias_term': None,
- 'pad': final_pad,
- 'pad_spatial_shape': int64_array(pads) if pads is not None else None,
- 'dilation': final_dilations,
- 'output_spatial_shape': None,
- 'output_shape': None,
- 'stride': final_strides,
- 'group': group,
- 'output': None,
- 'kernel_spatial': int64_array(kernel_shape) if kernel_shape is not None else None,
-
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'kernel_spatial_idx': None, # Will be calculated in infer function (np.array([2, 3]))
-
- 'spatial_dims': None, # Will be calculated in infer function
- 'channel_dims': int64_array([1]),
- 'batch_dims': int64_array([0]),
- 'layout': 'NCHW'
- }
-
- # update the attributes of the node
- Convolution.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class ConvTransposeFrontExtractor(FrontExtractorOp):
- op = 'ConvTranspose'
- enabled = True
-
- @staticmethod
- def get_pad(node, input_shape, kernel_shape):
- # Reference: https://github.com/onnx/onnx/blob/master/docs/Operators.md#ConvTranspose
- input_shape = node.in_node(0).shape
- pad = np.zeros((len(input_shape), 2), dtype=np.int64)
- total_padding = int64_array([node.stride[node.spatial_dims][x] *
- (input_shape[node.spatial_dims][x] - 1) +
- node.output_padding[node.spatial_dims][x] +
- kernel_shape[node.kernel_spatial_idx][x] -
- node.output_spatial_shape[x] for x in range(len(node.spatial_dims))])
- if node.has_valid('auto_pad') and node.auto_pad != 'same_upper':
- pad[node.spatial_dims] = int64_array(
- [[total_padding[x] / 2, total_padding[x] - (total_padding[x] // 2)] for x in
- range(len(node.spatial_dims))])
- else:
- pad[node.spatial_dims] = int64_array(
- [[total_padding[x] - (total_padding[x] // 2), total_padding[x] / 2] for x in
- range(len(node.spatial_dims))])
- return pad
-
- @classmethod
- def extract(cls, node):
- pads = onnx_attr(node, 'pads', 'ints', dst_type=int64_array)
- auto_pad = onnx_attr(node, 'auto_pad', 's', default=None, dst_type=get_onnx_autopad)
-
- if pads is not None:
- if len(pads) % 2 != 0:
- raise Error(
- 'ConvTranspose node {} specifies pads = {} which has odd number of elements. The model is not correct.',
- node.soft_get('name'),
- pads
- )
- pads = pads.reshape([2, -1])
- pads = np.transpose(pads)
-
- final_pads = int64_array([[0, 0], [0, 0], *pads]) if pads is not None else None
-
- dilations = onnx_attr(node, 'dilations', 'ints', default=None)
- final_dilations = int64_array([1, 1, *dilations]) if dilations is not None else None
-
- strides = onnx_attr(node, 'strides', 'ints', default=None)
- final_strides = int64_array([1, 1, *strides]) if strides is not None else None
-
- kernel_shape = onnx_attr(node, 'kernel_shape', 'ints', dst_type=int64_array)
-
- if kernel_shape is None:
- raise Error(
- 'ConvTranspose node {} doesn\'t have explicitly defined kernel_shape. It is not supported.',
- node.soft_get('name')
- )
-
- output_padding = onnx_attr(node, 'output_padding', 'ints', default=None)
- final_output_padding = int64_array([0, 0, *output_padding]) if output_padding is not None else None
-
- output_shape = onnx_attr(node, 'output_shape', 'ints', default=None, dst_type=int64_array)
-
- attrs = {
- 'type': 'Deconvolution',
- 'op': 'Deconv2D',
- 'auto_pad': auto_pad,
- 'bias_addable': True,
- 'bias_term': None, # will be deduced later; not really needed
- 'pad': final_pads,
- 'dilation': final_dilations,
- 'output_spatial_shape': output_shape,
- 'original_output_spatial_shape': output_shape,
- 'output_shape': None,
- 'output_padding': final_output_padding,
- 'stride': final_strides,
- 'group': onnx_attr(node, 'group', 'i', default=1),
- 'output': None,
-
- 'spatial_dims': None, # Will be calculated in infer function
- 'channel_dims': int64_array([1]),
- 'batch_dims': int64_array([0]),
- 'layout': 'NCHW',
-
- 'input_feature_channel': 0,
- 'output_feature_channel': 1,
- 'get_pad': ConvTransposeFrontExtractor.get_pad,
- 'get_output_feature_dim': lambda node: node.kernel_shape[node.output_feature_channel] * node.group,
- }
-
- # update the attributes of the node
- Convolution.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/crop_ext.py b/tools/mo/openvino/tools/mo/front/onnx/crop_ext.py
deleted file mode 100644
index 89baee7499888c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/crop_ext.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.crop import Crop
-
-
-class CropFrontExtractor(FrontExtractorOp):
- op = 'Crop'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # borders: leftBorder, topBorder, rightBorder, bottomBordes
- borders = onnx_attr(node, 'border', 'ints', default=None, dst_type=int64_array)
- scale = onnx_attr(node, 'scale', 'ints', default=None, dst_type=int64_array)
-
- # Crop reference: https://github.com/onnx/onnx/blob/master/docs/Operators.md#Crop
- if len(borders) != 4:
- log.error('ONNX Crop layer {} should take exactly 4 borders instead of {}'.format(node.name, len(borders)))
- return False
-
- attrs = {'axis': int64_array([2, 3])}
- if scale is not None:
- attrs.update({
- 'dim': scale,
- 'offset': int64_array([borders[1], borders[0]])
- })
- else:
- attrs.update({
- 'crop_begin': int64_array([borders[1], borders[0]]),
- 'crop_end': int64_array([borders[3], borders[2]])
- })
-
- Crop.update_node_stat(node, attrs)
- return CropFrontExtractor.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/cumsum_ext.py b/tools/mo/openvino/tools/mo/front/onnx/cumsum_ext.py
deleted file mode 100644
index b43c848d3007a7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/cumsum_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.cumsum import CumSum
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class CumSumFrontExtractor(FrontExtractorOp):
- op = 'CumSum'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- exclusive = onnx_attr(node, 'exclusive', 'i', 0)
- reverse = onnx_attr(node, 'reverse', 'i', 0)
- CumSum.update_node_stat(node, {'exclusive': exclusive, 'reverse': reverse})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/deformable_conv_ext.py b/tools/mo/openvino/tools/mo/front/onnx/deformable_conv_ext.py
deleted file mode 100644
index 1f0a765336aafc..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/deformable_conv_ext.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_autopad
-from openvino.tools.mo.ops.deformable_convolution import DeformableConvolution
-
-
-class DeformableConvExtractor(FrontExtractorOp):
- op = 'DeformableConv2D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # Extract pads attribute
- # In case if pads is not specified it will be set in default (1) in infer function
- pads = onnx_attr(node, 'pads', 'ints', default=None, dst_type=lambda x: int64_array(x))
- assert pads is None or len(pads) % 2 == 0
- final_pad = None
- if pads is not None:
- pads = pads.reshape([2, -1])
- pads = np.transpose(pads)
- final_pad = int64_array([[0, 0], [0, 0], *pads])
-
- # Extract dilations attribute
- # In case if dilations is not specified it will be set in default (1) in infer function
- dilations = onnx_attr(node, 'dilations', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_dilations = int64_array([1, 1, *dilations]) if dilations is not None else None
-
- # Extract dilations attribute
- # In case if dilations is not specified it will be set in default (1) in infer function
- strides = onnx_attr(node, 'strides', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_strides = int64_array([1, 1, *strides]) if strides is not None else None
-
- kernel_shape = onnx_attr(node, 'kernel_shape', 'ints', default=None)
- auto_pad = onnx_attr(node, 'auto_pad', 's', default=None, dst_type=get_onnx_autopad)
- group = onnx_attr(node, 'group', 'i', default=1, dst_type=lambda x: int64_array(x))
- deformable_groups = onnx_attr(node, 'deformable_groups', 'i', default=1)
-
- attrs = {
- 'op': __class__.op,
- 'auto_pad': auto_pad,
- 'bias_addable': False,
- 'bias_term': False,
- 'pad': final_pad,
- 'pad_spatial_shape': int64_array(pads) if pads is not None else None,
- 'dilation': final_dilations,
- 'output_spatial_shape': None,
- 'output_shape': None,
- 'stride': final_strides,
- 'group': group,
- 'deformable_group': deformable_groups,
- 'output': None,
- 'weights_index': 2,
- 'kernel_spatial': int64_array(kernel_shape) if kernel_shape is not None else None,
-
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'kernel_spatial_idx': None, # Will be calculated in infer function (np.array([2, 3]))
-
- 'spatial_dims': None, # Will be calculated in infer function
- 'channel_dims': int64_array([1]),
- 'batch_dims': int64_array([0]),
- 'layout': 'NCHW'
- }
-
- # update the attributes of the node
- DeformableConvolution.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/depth_to_space_ext.py b/tools/mo/openvino/tools/mo/front/onnx/depth_to_space_ext.py
deleted file mode 100644
index 21b817b1b3c9cf..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/depth_to_space_ext.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.depth_to_space import DepthToSpaceOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class DepthToSpaceFrontExtractor(FrontExtractorOp):
- op = 'DepthToSpace'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # update the attributes of the node
- node_name = node.soft_get('name', node.id)
- block_size = onnx_attr(node, 'blocksize', 'i', default=None)
- assert block_size is not None, \
- 'DepthToSpace should have "blocksize" attribute specified for node {}'.format(node_name)
- onnx_mode = onnx_attr(node, 'mode', 's', default=b'DCR').decode()
- assert onnx_mode in ['DCR', 'CRD'], 'Unrecognized mode provided for DepthToSpace node {}'.format(node_name)
- if onnx_mode == 'DCR':
- mode = 'blocks_first'
- else:
- mode = 'depth_first'
-
- DepthToSpaceOp.update_node_stat(node, {'block_size': block_size, 'mode': mode})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/dequantize_linear_ext.py b/tools/mo/openvino/tools/mo/front/onnx/dequantize_linear_ext.py
deleted file mode 100644
index 4fc0ee74defa43..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/dequantize_linear_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.dequantize_linear import DequantizeLinear
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version
-
-
-class DequantizeLinearFrontExtractor(FrontExtractorOp):
- op = 'DequantizeLinear'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {}
- if get_onnx_opset_version(node) >= 13:
- axis = onnx_attr(node, 'axis', 'i', default=None)
- attrs.update(axis=axis)
- DequantizeLinear.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/detection_output.py b/tools/mo/openvino/tools/mo/front/onnx/detection_output.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/openvino/tools/mo/front/onnx/detection_output_ext.py b/tools/mo/openvino/tools/mo/front/onnx/detection_output_ext.py
deleted file mode 100644
index 1f83f72d865da7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/detection_output_ext.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.DetectionOutput import DetectionOutput
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.utils.error import Error
-
-
-class DetectionOutputFrontExtractor(FrontExtractorOp):
- op = 'DetectionOutput'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- nms_threshold = onnx_attr(node, 'nms_threshold', 'f', default=0.0)
- eta = onnx_attr(node, 'eta', 'f', default=0.0)
- top_k = onnx_attr(node, 'top_k', 'i', default=-1)
-
- code_type_values = {
- b"CORNER": "caffe.PriorBoxParameter.CORNER",
- b"CENTER_SIZE": "caffe.PriorBoxParameter.CENTER_SIZE",
- }
-
- code_type = onnx_attr(node, 'code_type', 's', default=code_type_values[b"CORNER"])
- try:
- code_type = code_type_values[code_type]
- except KeyError:
- raise Error("Incorrect value of code_type parameter {}".format(code_type))
-
- resize_mode_values = {
- b"": "",
- b"WARP": "caffe.ResizeParameter.WARP",
- b"FIT_SMALL_SIZE": "caffe.ResizeParameter.FIT_SMALL_SIZE",
- b"FIT_LARGE_SIZE_AND_PAD": "caffe.ResizeParameter.FIT_LARGE_SIZE_AND_PAD",
- }
- resize_mode = onnx_attr(node, 'resize_mode', 's', default=b"")
- try:
- resize_mode = resize_mode_values[resize_mode]
- except KeyError:
- raise Error("Incorrect value of resize_mode parameter {}".format(resize_mode))
-
- pad_mode_values = {
- b"": "",
- b"CONSTANT": "caffe.ResizeParameter.CONSTANT",
- b"MIRRORED": "caffe.ResizeParameter.MIRRORED",
- b"REPEAT_NEAREST": "caffe.ResizeParameter.REPEAT_NEAREST"
- }
- pad_mode = onnx_attr(node, 'pad_mode', 's', default=b"")
- try:
- pad_mode = pad_mode_values[pad_mode]
- except KeyError:
- raise Error("Incorrect value of pad_mode parameter {}".format(pad_mode))
-
- interp_mode_values = {
- b"": "",
- b"LINEAR": "caffe.ResizeParameter.LINEAR",
- b"AREA": "caffe.ResizeParameter.AREA",
- b"NEAREST": "caffe.ResizeParameter.NEAREST",
- b"CUBIC": "caffe.ResizeParameter.CUBIC",
- b"LANCZOS4": "caffe.ResizeParameter.LANCZOS4"
- }
- interp_mode = onnx_attr(node, 'interp_mode', 's', default=b"")
- try:
- interp_mode = interp_mode_values[interp_mode]
- except KeyError:
- raise Error("Incorrect value of interp_mode parameter {}".format(interp_mode))
-
- attrs = {
- 'num_classes': onnx_attr(node, 'num_classes', 'i', default=0),
- 'share_location': onnx_attr(node, 'share_location', 'i', default=0),
- 'background_label_id': onnx_attr(node, 'background_label_id', 'i', default=0),
- 'code_type': code_type,
- 'variance_encoded_in_target': onnx_attr(node, 'variance_encoded_in_target', 'i', default=0),
- 'keep_top_k': onnx_attr(node, 'keep_top_k', 'i', default=0),
- 'confidence_threshold': onnx_attr(node, 'confidence_threshold', 'f', default=0),
- 'visualize_threshold': onnx_attr(node, 'visualize_threshold', 'f', default=0.6),
- # nms_param
- 'nms_threshold': nms_threshold,
- 'top_k': top_k,
- 'eta': eta,
- # save_output_param.resize_param
- 'prob': onnx_attr(node, 'prob', 'f', default=0),
- 'resize_mode': resize_mode,
- 'height': onnx_attr(node, 'height', 'i', default=0),
- 'width': onnx_attr(node, 'width', 'i', default=0),
- 'height_scale': onnx_attr(node, 'height_scale', 'i', default=0),
- 'width_scale': onnx_attr(node, 'width_scale', 'i', default=0),
- 'pad_mode': pad_mode,
- 'pad_value': onnx_attr(node, 'pad_value', 's', default=""),
- 'interp_mode': interp_mode,
- 'input_width': onnx_attr(node, 'input_width', 'i', default=1),
- 'input_height': onnx_attr(node, 'input_height', 'i', default=1),
- 'normalized': onnx_attr(node, 'normalized', 'i', default=1),
- }
-
- # update the attributes of the node
- DetectionOutput.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/detection_output_onnx_ext.py b/tools/mo/openvino/tools/mo/front/onnx/detection_output_onnx_ext.py
deleted file mode 100644
index 58885dd589937b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/detection_output_onnx_ext.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from math import log
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.detection_output_onnx import ExperimentalDetectronDetectionOutput
-
-
-class ExperimentalDetectronDetectionOutputFrontExtractor(FrontExtractorOp):
- op = 'ExperimentalDetectronDetectionOutput'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = dict(class_agnostic_box_regression=onnx_attr(node, 'class_agnostic_box_regression', 'i', 0),
- max_detections_per_image=onnx_attr(node, 'max_detections_per_image', 'i', 100),
- nms_threshold=onnx_attr(node, 'nms_threshold', 'f', 0.5),
- num_classes=onnx_attr(node, 'num_classes', 'i', 81),
- post_nms_count=onnx_attr(node, 'post_nms_count', 'i', 2000),
- score_threshold=onnx_attr(node, 'score_threshold', 'f', 0.05),
- max_delta_log_wh=onnx_attr(node, 'max_delta_log_wh', 'f', log(1000. / 16.)),
- deltas_weights=float32_array(onnx_attr(node, 'deltas_weights', 'floats', [10., 10., 5., 5.]))
- )
- ExperimentalDetectronDetectionOutput.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/dropout_ext.py b/tools/mo/openvino/tools/mo/front/onnx/dropout_ext.py
deleted file mode 100644
index e0a4b209f84ef0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/dropout_ext.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.identity import Identity
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.utils.error import Error
-
-
-class DropoutFrontExtractor(FrontExtractorOp):
- op = 'Dropout'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # some Dropout flavors doesn't have is_test attribute; when it is missing, interpret it as 1
- is_test = onnx_attr(node, 'is_test', 'i', 1)
- if len(node.out_nodes()) > 1:
- raise Error('Dropout node {} has more than one consumer. Unsupported.', node.name)
- if not is_test:
- raise Error('Dropout node {} has is_test: 0. This means training mode which is not supported.', node.name)
- Identity.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/einsum_ext.py b/tools/mo/openvino/tools/mo/front/onnx/einsum_ext.py
deleted file mode 100644
index 86aca737dc6d68..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/einsum_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.einsum import Einsum
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class EinsumExtractor(FrontExtractorOp):
- op = 'Einsum'
- enabled = True
-
- @classmethod
- def extract(cls, einsum_node):
- einsum_name = einsum_node.soft_get('name', einsum_node.id)
- equation = onnx_attr(einsum_node, 'equation', 's').decode(encoding="utf-8")
- normalized_equation = Einsum.normalize_equation(einsum_name, equation)
- Einsum.update_node_stat(einsum_node, {'equation': normalized_equation})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/elementwise_ext.py b/tools/mo/openvino/tools/mo/front/onnx/elementwise_ext.py
deleted file mode 100644
index 00eaabdad524f1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/elementwise_ext.py
+++ /dev/null
@@ -1,217 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.ops.elementwise import Add, Sub, Mul, Div, Pow, Less, Equal, Greater, LogicalAnd, LogicalOr, LogicalXor, \
- Round, GreaterEqual, LessEqual
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.eltwise_n import EltwiseNAdd, EltwiseNMax, EltwiseNMin
-from openvino.tools.mo.ops.power import AttributedPower
-
-
-class AddFrontExtractor(FrontExtractorOp):
- op = 'Add'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- axis = onnx_attr(node, 'axis', 'i', default=None)
- Add.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class SubFrontExtractor(FrontExtractorOp):
- op = 'Sub'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- axis = onnx_attr(node, 'axis', 'i', default=None)
- Sub.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class MulFrontExtractor(FrontExtractorOp):
- op = 'Mul'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- axis = onnx_attr(node, 'axis', 'i', default=None)
- Mul.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class DivFrontExtractor(FrontExtractorOp):
- op = 'Div'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- axis = onnx_attr(node, 'axis', 'i', default=None)
- Div.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class SumFrontExtractor(FrontExtractorOp):
- op = 'Sum'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- axis = onnx_attr(node, 'axis', 'i', default=None)
- EltwiseNAdd.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class PowFrontExtractor(FrontExtractorOp):
- op = 'Pow'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Pow.update_node_stat(node)
- return cls.enabled
-
-
-class NegFrontExtractor(FrontExtractorOp):
- op = 'Neg'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- AttributedPower.update_node_stat(node, {'scale': -1})
- return cls.enabled
-
-
-class SqrtExtractor(FrontExtractorOp):
- op = 'Sqrt'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedPower.update_node_stat(node, {'power': 0.5})
- return cls.enabled
-
-
-class ScaleFrontExtractor(FrontExtractorOp):
- op = 'Scale'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- scale = onnx_attr(node, 'scale', 'f', default=mo_array(1.0), dst_type=lambda x: mo_array(x))
- AttributedPower.update_node_stat(node, {'scale': scale})
- return cls.enabled
-
-
-class MaxExtractor(FrontExtractorOp):
- op = 'Max'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- EltwiseNMax.update_node_stat(node)
- return cls.enabled
-
-
-class MinExtractor(FrontExtractorOp):
- op = 'Min'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- EltwiseNMin.update_node_stat(node)
- return cls.enabled
-
-
-class EqualExtractor(FrontExtractorOp):
- op = 'Equal'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Equal.update_node_stat(node)
- return cls.enabled
-
-
-class LessExtractor(FrontExtractorOp):
- op = 'Less'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Less.update_node_stat(node)
- return cls.enabled
-
-
-class GreaterExtractor(FrontExtractorOp):
- op = 'Greater'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Greater.update_node_stat(node)
- return cls.enabled
-
-
-class GreaterOrEqualExtractor(FrontExtractorOp):
- op = 'GreaterOrEqual'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- GreaterEqual.update_node_stat(node)
- return cls.enabled
-
-
-class LessOrEqualExtractor(FrontExtractorOp):
- op = 'LessOrEqual'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LessEqual.update_node_stat(node)
- return cls.enabled
-
-
-class AndExtractor(FrontExtractorOp):
- op = 'And'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalAnd.update_node_stat(node)
- return cls.enabled
-
-
-class OrExtractor(FrontExtractorOp):
- op = 'Or'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalOr.update_node_stat(node)
- return cls.enabled
-
-
-class XorExtractor(FrontExtractorOp):
- op = 'Xor'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalXor.update_node_stat(node)
- return cls.enabled
-
-
-class RoundFrontExtractor(FrontExtractorOp):
- op = 'Round'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Round.update_node_stat(node, {'mode': 'half_to_even'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/expand_ext.py b/tools/mo/openvino/tools/mo/front/onnx/expand_ext.py
deleted file mode 100644
index b4d1fe8331d4bc..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/expand_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.broadcast import Broadcast
-
-
-class ExpandExtractor(FrontExtractorOp):
- op = 'Expand'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Broadcast.update_node_stat(node, {'mode': 'bidirectional'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/extractor.py b/tools/mo/openvino/tools/mo/front/onnx/extractor.py
deleted file mode 100644
index 80a64d834b949d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/extractor.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node
-
-
-def node_pb_arg(pb_extractor: callable):
- return lambda node: pb_extractor(node.pb)
-
-
-onnx_op_extractors = {}
-
-
-def common_onnx_fields(node: Node):
- return {
- 'kind': 'op',
- 'name': node.id,
- # no reliable name for an onnx node, name can be empty, so we use that surrogate built as ID in the loader
- 'op': node.op if node.has_valid('op') else node.pb.op_type,
- }
-
-
-def onnx_op_extractor(node: Node, lowered_keys_map: dict):
- if not node.has_valid('pb'):
- return True, node.graph.node[node.id]
-
- result = common_onnx_fields(node)
- node.graph.node[node.id].update(result)
- supported = False
- op = result['op'].lower()
- if op in lowered_keys_map:
- op = lowered_keys_map[op]
- assert op in onnx_op_extractors
- attrs = onnx_op_extractors[op](node)
- if attrs:
- result.update(attrs)
- supported = True
- return supported, result
diff --git a/tools/mo/openvino/tools/mo/front/onnx/extractors/__init__.py b/tools/mo/openvino/tools/mo/front/onnx/extractors/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/extractors/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/front/onnx/extractors/utils.py b/tools/mo/openvino/tools/mo/front/onnx/extractors/utils.py
deleted file mode 100644
index 0fc890a399e89b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/extractors/utils.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-
-
-def onnx_node_has_attr(node: Node, name: str):
- attrs = [a for a in node.pb.attribute if a.name == name]
- return len(attrs) != 0
-
-
-def onnx_attr(node: Node, name: str, field: str, default=None, dst_type=None):
- """ Retrieves ONNX attribute with name `name` from ONNX protobuf `node.pb`.
- The final value is casted to dst_type if attribute really exists.
- The function returns `default` otherwise.
- """
- attrs = [a for a in node.pb.attribute if a.name == name]
- if len(attrs) == 0:
- # there is no requested attribute in the protobuf message
- return default
- elif len(attrs) > 1:
- raise Error('Found multiple entries for attribute name {} when at most one is expected. Protobuf message with '
- 'the issue: {}.', name, node.pb)
- else:
- res = getattr(attrs[0], field)
- if dst_type is not None:
- return dst_type(res)
- else:
- return res
-
-
-def onnx_get_num_outputs(node: Node):
- """ Retrieves number of outputs for ONNX operation.
- """
- return len(node.pb.output)
-
-
-def get_backend_pad(pads, spatial_dims, axis):
- return [x[axis] for x in pads[spatial_dims]]
-
-
-def get_onnx_autopad(auto_pad):
- auto_pad = auto_pad.decode().lower()
- if auto_pad == 'notset':
- auto_pad = None
- return auto_pad
-
-
-def get_onnx_opset_version(node: Node):
- return node.graph.graph.get('fw_opset_version', 0)
-
-
-def get_onnx_datatype_as_numpy(value):
- datatype_to_numpy = {
- 1: np.float32,
- 9: bool,
- 11: np.double,
- 10: np.float16,
- 5: np.int16,
- 6: np.int32,
- 7: np.int64,
- 3: np.int8,
- 8: np.ubyte,
- 4: np.uint16,
- 12: np.uint32,
- 13: np.uint64,
- 2: np.uint8,
- }
- try:
- return datatype_to_numpy[value]
- except KeyError:
- raise Error("Incorrect value {} for Datatype enum".format(value))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/faster_rcnn.json b/tools/mo/openvino/tools/mo/front/onnx/faster_rcnn.json
deleted file mode 100644
index c08e094c12cd88..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/faster_rcnn.json
+++ /dev/null
@@ -1,20 +0,0 @@
-[
- {
- "custom_attributes":
- {
- "max_detections_per_image": 100,
- "max_delta_log_wh": 4.135166645050049,
- "score_threshold": 0.05,
- "nms_threshold": 0.5,
- "post_nms_count": 2000,
- "input_fpn_heads": ["486", "454", "422", "390"],
- "do_outputs": ["6371", "6373", "6375"],
- "box_regressions_input_node": "2614",
- "class_predicitons_node": "2615",
- "ROIFeatureExtractor2_input": "2335",
- "ROIFeatureExtractor2_output": "2592"
- },
- "id": "ONNXMaskRCNNReplacement",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/onnx/flattenONNX_to_reshape.py b/tools/mo/openvino/tools/mo/front/onnx/flattenONNX_to_reshape.py
deleted file mode 100644
index 7aeae3ef6e999e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/flattenONNX_to_reshape.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ReduceOps import ReduceProd
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.utils.shape import node_to_get_shape_value_of_indices, new_shape_node_from_shape_nodes
-
-
-class FlattenONNXToReshape(FrontReplacementSubgraph):
- """
- ONNX Flatten operation flattens the input tensor into a 2D matrix by given axis:
-
- Input of shape [d_0, d_1, ... d_n]
- Output of shape [d_0 X d_1 ... d_(axis-1), d_axis X d_(axis+1) ... X dn]
-
- Corner case with axis=0: output shape will be [1, d_0 X d_1 ... X dn]
- """
- enabled = True
-
- def pattern(self):
- return dict(nodes=[('flatten', dict(op='FlattenONNX'))],
- edges=[])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- node = match['flatten']
- name = node.soft_get('name', node.id)
-
- assert node.has_valid('axis'), 'Flatten {} should have `axis` attribute extracted, but it\'s not'.format(name)
- axis = node.axis
-
- reshape_node = Reshape(graph, {'name': node.id + '/Reshape'}).create_node()
-
- if axis == 0:
- dim = Const(graph, {'value': int64_array([1, -1]), 'name': reshape_node.name + '/shape'}).create_node()
- elif axis == 1:
- dim = Const(graph, {'value': int64_array([0, -1]), 'name': reshape_node.name + '/shape'}).create_node()
- else:
- shape = Shape(graph, {'name': name + '/input_shape'}).create_node()
-
- idxs = list(range(axis)) if axis > 0 else list(range(axis, 0))
-
- axis_shape_portion = node_to_get_shape_value_of_indices(shape, idxs)
- first_dims = create_op_node_with_second_input(graph, ReduceProd, int64_array([0]),
- {'name': name + '/first_dims', 'keep_dims': True})
- second_dims = Const(graph, {'value': int64_array([-1]), 'name': name + '/second_dims'}).create_node()
-
- node.in_port(0).get_source().connect(shape.in_port(0))
- axis_shape_portion.out_port(0).connect(first_dims.in_port(0))
-
- order_of_dims = [first_dims, second_dims] if axis > 0 else [second_dims, first_dims]
-
- dim = new_shape_node_from_shape_nodes(order_of_dims)
-
- reshape_node.in_port(1).connect(dim.out_port(0))
-
- node.out_port(0).get_connection().set_source(reshape_node.out_port(0))
- node.in_port(0).get_connection().set_destination(reshape_node.in_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/flatten_ext.py b/tools/mo/openvino/tools/mo/front/onnx/flatten_ext.py
deleted file mode 100644
index 3d001e5a6f33c4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/flatten_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.flatten import FlattenONNX
-
-
-class FlattenFrontExtractor(FrontExtractorOp):
- op = 'Flatten'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', 1)
- attrs = {
- 'axis': axis
- }
-
- FlattenONNX.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/fused_bn_ext.py b/tools/mo/openvino/tools/mo/front/onnx/fused_bn_ext.py
deleted file mode 100644
index d34633e5ac1b9f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/fused_bn_ext.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.BatchNormInference import BatchNormInference
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class BatchNormalizationExtractor(FrontExtractorOp):
- op = 'BatchNormalization'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attr_dict = {
- 'data_format': 'NCHW',
- 'eps': onnx_attr(node, 'epsilon', 'f', 1e-5),
- }
- BatchNormInference.update_node_stat(node, attr_dict)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/gather_ext.py b/tools/mo/openvino/tools/mo/front/onnx/gather_ext.py
deleted file mode 100644
index 8de970e1c6686f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/gather_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.ops.gather import AttributedGather
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class GatherFrontExtractor(FrontExtractorOp):
- op = 'Gather'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'axis': int64_array(onnx_attr(node, 'axis', 'i', default=0))
- }
-
- AttributedGather.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/gatherelements_ext.py b/tools/mo/openvino/tools/mo/front/onnx/gatherelements_ext.py
deleted file mode 100644
index 4640c83dfb6eb4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/gatherelements_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.gatherelements import GatherElements
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class GatherElementsFrontExtractor(FrontExtractorOp):
- op = 'GatherElements'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'axis': onnx_attr(node, 'axis', 'i', default=0)
- }
- GatherElements.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/gathernd_ext.py b/tools/mo/openvino/tools/mo/front/onnx/gathernd_ext.py
deleted file mode 100644
index 5752f1e8ed7631..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/gathernd_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.gathernd import GatherND
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class GatherNDFrontExtractor(FrontExtractorOp):
- op = 'GatherND'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'batch_dims': onnx_attr(node, 'batch_dims', 'i', default=0)
- }
- GatherND.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/gemm_ext.py b/tools/mo/openvino/tools/mo/front/onnx/gemm_ext.py
deleted file mode 100644
index f64de806f7e135..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/gemm_ext.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.ops.MatMul import GemmONNX
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class GemmFrontExtractor(FrontExtractorOp):
- op = 'Gemm'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'alpha': onnx_attr(node, 'alpha', 'f', 1),
- 'beta': onnx_attr(node, 'beta', 'f', 1),
- 'transpose_a': onnx_attr(node, 'transA', 'i', 0),
- 'transpose_b': onnx_attr(node, 'transB', 'i', 0),
- 'broadcast_c': onnx_attr(node, 'broadcast', 'i', 1),
- # TODO: there is no axis in onnx operators.md
- 'axis': int64_array(onnx_attr(node, 'axis', 'i', default=0))
- }
- GemmONNX.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/group_norm_ext.py b/tools/mo/openvino/tools/mo/front/onnx/group_norm_ext.py
deleted file mode 100644
index 8f098d058c259d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/group_norm_ext.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.group_norm import GroupNorm
-
-
-class ExperimentalDetectronGroupNorm(FrontExtractorOp):
- op = 'ExperimentalDetectronGroupNorm'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'eps': mo_array(onnx_attr(node, 'eps', 'f', default=1e-6), dtype=float),
- 'num_groups': int64_array(onnx_attr(node, 'num_groups', 'i', default=1)),
- }
- GroupNorm.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class GroupNormExtractor(FrontExtractorOp):
- op = 'GroupNorm'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'eps': mo_array(onnx_attr(node, 'eps', 'f', default=1e-6), dtype=float),
- 'num_groups': int64_array(onnx_attr(node, 'num_groups', 'i', default=1)),
- }
- GroupNorm.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/gru_ext.py b/tools/mo/openvino/tools/mo/front/onnx/gru_ext.py
deleted file mode 100644
index 887c95b5274155..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/gru_ext.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array, int64_array
-from openvino.tools.mo.ops.GRU import GRU
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class GRUFrontExtractor(FrontExtractorOp):
- op = 'GRU'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- activation_alpha = onnx_attr(node, 'activation_alpha', 'floats',
- default=None, dst_type=lambda x: float32_array(x))
- activation_beta = onnx_attr(node, 'activation_beta', 'floats',
- default=None, dst_type=lambda x: float32_array(x))
- activations = onnx_attr(node, 'activations', 'strings', default=None,
- dst_type=lambda x: list(map(lambda s: s.decode(encoding="utf-8").lower(), list(x))))
- clip = onnx_attr(node, 'clip', 'f', default=None)
- linear_before_reset = onnx_attr(node, 'linear_before_reset', 'i', default=0)
-
- attrs = {
- 'batch_dim': 1,
- 'sequence_dim': 0,
- 'blobs_wrb': True,
- 'has_num_directions': True,
- 'num_layers': 1,
- 'format': 'onnx',
- 'multilayers': False,
- 'gate_order': [0, 1, 2],
-
- # ONNX - specific attrs
- 'activation_alpha': activation_alpha,
- 'activation_beta': activation_beta,
- 'activations': activations,
- 'clip': clip,
- 'direction': onnx_attr(node, 'direction', 's', b'forward').decode().lower(),
- 'hidden_size': int64_array(onnx_attr(node, 'hidden_size', 'i')),
- 'linear_before_reset': linear_before_reset,
- }
-
- GRU.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/hard_sigmoid_ext.py b/tools/mo/openvino/tools/mo/front/onnx/hard_sigmoid_ext.py
deleted file mode 100644
index ba1c2a5b262a7a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/hard_sigmoid_ext.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.ops.hard_sigmoid import HardSigmoid
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-
-
-class HardSigmoidFrontExtractor(FrontReplacementOp):
- op = 'HardSigmoid'
- enabled = True
-
- def replace_op(self, graph: Graph, node: Node):
- alpha = onnx_attr(node, 'alpha', 'f', default=0.2)
- beta = onnx_attr(node, 'beta', 'f', default=0.5)
-
- hard_sigmoid = create_op_with_const_inputs(graph, HardSigmoid, {1: mo_array(alpha), 2: mo_array(beta)},
- {'name': node.name + '/HardSigmoid_'})
-
- node.in_port(0).get_connection().set_destination(hard_sigmoid.in_port(0))
- return [hard_sigmoid.id]
diff --git a/tools/mo/openvino/tools/mo/front/onnx/identity_ext.py b/tools/mo/openvino/tools/mo/front/onnx/identity_ext.py
deleted file mode 100644
index 3c10c9b5f4e0cd..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/identity_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.identity import Identity
-
-
-class IdentityFrontExtractor(FrontExtractorOp):
- op = 'Identity'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Identity.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/image_scaler_ext.py b/tools/mo/openvino/tools/mo/front/onnx/image_scaler_ext.py
deleted file mode 100644
index d33c8cbb46750f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/image_scaler_ext.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ImageScalerFrontExtractor(FrontExtractorOp):
- op = 'ImageScaler'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- dst_type = lambda x: mo_array(x)
-
- scale = onnx_attr(node, 'scale', 'f', default=mo_array(1.0), dst_type=dst_type)
- bias = onnx_attr(node, 'bias', 'floats', default=None, dst_type=dst_type)
-
- # Expand dims for bias in case if it is not scalar
- if bias.ndim != 0:
- broadcast_dims_cnt = 2 if node.graph.graph['layout'] == 'NCHW' else 0
- for idx in range(broadcast_dims_cnt):
- bias = np.expand_dims(bias, axis=-1)
-
- node['scale'] = scale
- node['bias'] = bias
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/instance_normalization_ext.py b/tools/mo/openvino/tools/mo/front/onnx/instance_normalization_ext.py
deleted file mode 100644
index ecd79e253b814f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/instance_normalization_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.instance_normalization import InstanceNormalization
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class InstanceNormalizationExtractor(FrontExtractorOp):
- op = 'InstanceNormalization'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- epsilon = onnx_attr(node, 'epsilon', 'f', default=float(1e-5))
- InstanceNormalization.update_node_stat(node, {'epsilon': epsilon})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/loader.py b/tools/mo/openvino/tools/mo/front/onnx/loader.py
deleted file mode 100644
index 30ea56fc8efb83..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/loader.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import logging as log
-
-import onnx
-
-from openvino.tools.mo.graph.graph import fill_graph_with_nodes, Graph, Node
-from openvino.tools.mo.utils.error import Error, FrameworkError
-
-
-def load_onnx_model(file_name: str):
- try:
- onnx_model = onnx.load(file_name)
- except Exception as e:
- raise FrameworkError(
- 'Cannot read the model file: "{}" is incorrect ONNX model file. Details: {}',
- file_name,
- str(e)
- ) from e
-
- return onnx_model
-
-
-def protobuf_attrs(pb):
- return {'pb': pb}
-
-
-def node_id(pb):
- ''' The result of this function should be passed to unique_id to be used as a unuque ID for new node creation. '''
- if pb.name:
- return str(pb.name)
- elif len(pb.output):
- # node may have multiple outputs, we choose the first one
- return pb.output[0]
- else:
- return 'NoNamed'
-
-
-def protobuf2nx(graph: Graph, pb):
- """
- Convert proto message with ONNX model to equivalent NX representation. All nodes and edges are restored here as
- ONNX model has op/data representation, that means that nodes are connected via tensor names. Name of tensors are
- defined on demand in nodes, so we have a code similar to Caffe here.
-
- :param graph: the Graph object to load the graph into
- :param pb: the ONNX file protobuf message
- :return: None
- """
- # maps a tensor name to a node produced it and the node port: str -> (node_id, node_port)
- data_nodes_map = {}
-
- graph_pb = pb.graph
- add_initializers_and_inputs_to_graph(graph, graph_pb, data_nodes_map)
-
- # Preserve inputs order
- graph.inputs_order = []
- for inp in graph_pb.input:
- name = str(inp.name)
- graph.inputs_order.append(name)
-
- output_ids = []
- for outp in graph_pb.output:
- name = str(outp.name)
- if graph.has_node(name):
- log.error('Name {} of output node already exists in graph. Ignoring this output. If the output is required,'
- ' please rename it.'.format(name), extra={'is_warning': True})
- continue
- else:
- # add fake node on output
- graph.add_node(name, kind='op', op='FakeOutput', pb=outp)
- output_ids.append(name)
-
- # Preserve outputs order
- graph.outputs_order = output_ids
-
- # Go through all nodes in the original model order (because data nodes are defined on-the-fly and order is
- # important)
- for node in graph_pb.node:
- # create an NX node
- fw_name = node_id(node)
- id = graph.unique_id(fw_name)
- graph.add_node(id, pb=node, kind='op')
- if hasattr(graph, 'op_names_statistic') and hasattr(node, 'op_type'):
- graph.op_names_statistic[node.op_type] += 1
-
- # add incoming edges based on data_nodes_map
- for dst_port, inp in enumerate(node.input):
- # should add edge inp --> id
- if inp not in data_nodes_map:
- if inp == '':
- # input is omitted; most likely it corresponds to an optional input for an operator
- continue
- else:
- raise Error(
- 'Reference to {} is not satisfied. A node refer not existing data tensor. ONNX model is not '
- 'consistent. Protobuf fragment: {}', inp, node)
- src_id, src_port = data_nodes_map[inp]
-
- assert (graph.has_node(src_id))
- edge_attrs = {
- 'out': src_port,
- 'in': dst_port,
- 'name': inp,
- 'fw_tensor_debug_info': [(src_id, inp)],
- 'in_attrs': ['in', 'name'],
- 'out_attrs': ['out', 'name'],
- 'data_attrs': ['fw_tensor_debug_info']
- }
- graph.add_edge(src_id, id, **edge_attrs)
-
- # add outgoing edges to data_nodes_map
- for src_port, out in enumerate(node.output):
- if out in output_ids:
- edge_attrs = {
- 'out': src_port,
- 'in': 0,
- 'name': out,
- 'fw_tensor_debug_info': [(fw_name, out)],
- 'in_attrs': ['in', 'name'],
- 'out_attrs': ['out', 'name'],
- 'data_attrs': ['fw_tensor_debug_info']
- }
- graph.add_edge(id, out, **edge_attrs)
- if out in data_nodes_map:
- log.debug("Detected reuse of blob {}.".format(out))
- data_nodes_map[out] = (id, src_port)
-
- graph.graph['tensor_mapping'] = data_nodes_map # save main graph tensor names mapping for Loop op parsing
-
-
-def add_initializers_and_inputs_to_graph(graph: Graph, graph_pb, data_nodes_map: dict):
- """
- The function adds nodes specified in the 'initializer' attribute of the pb and input nodes.
- :param graph: the Graph to add nodes to
- :param graph_pb: the graph protobuf message
- :param data_nodes_map: the dictionary with mapping of tensor names to node id and port
- :return: the list of Parameter nodes
- """
- initializers = Graph()
- fill_graph_with_nodes(initializers, graph_pb.initializer, get_id=lambda pb: pb.name, get_attrs=protobuf_attrs)
-
- parameters = []
- # first go through all inputs and separate constant from placeholders
- for inp in graph_pb.input:
- name = str(inp.name)
- if graph.has_node(name):
- raise Error('Name {} of input node already exists, input names are duplicated.', name)
- elif initializers.has_node(name):
- graph.add_node(name, kind='op', op='Const', pb=inp, pb_init=initializers.node[name]['pb'])
- else:
- graph.add_node(name, kind='op', op='Parameter', pb=inp)
- parameters.append(Node(graph, name))
-
- assert name not in data_nodes_map, 'Inconsistency between data_nodes_map and graph.nodes'
- data_nodes_map[name] = (name, 0)
-
- # go over all initializers and make sure that all of them are added to the graph
- for initializer in initializers.nodes():
- initializer_id = initializer
- if not graph.has_node(initializer_id):
- graph.add_node(initializer_id, kind='op', op='Const', pb=initializers.node[initializer]['pb'],
- pb_init=initializers.node[initializer]['pb'])
- data_nodes_map[initializer] = (initializer_id, 0)
- return parameters
diff --git a/tools/mo/openvino/tools/mo/front/onnx/logsoftmaxONNX_to_logsoftmax.py b/tools/mo/openvino/tools/mo/front/onnx/logsoftmaxONNX_to_logsoftmax.py
deleted file mode 100644
index fcaaa945db3416..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/logsoftmaxONNX_to_logsoftmax.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.ops.flatten import FlattenONNX
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.log_softmax import LogSoftmax
-
-
-class LogSoftmaxONNXFrontReplacer(FrontReplacementOp):
- """
- Replace LogSoftmaxONNX operation with FlattenONNX -> LogSoftmax -> Reshape subgraph
- """
- op = "LogSoftmaxONNX"
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.onnx.flattenONNX_to_reshape import FlattenONNXToReshape
- return [FlattenONNXToReshape]
-
- def replace_op(self, graph: Graph, node: Node):
- node_name = node.soft_get('name', node.id)
- assert node.has_valid('axis'), 'The node "{}" does not have mandatory attribute "axis"'.format(node_name)
-
- flatten_node = FlattenONNX(graph, {'name': node_name + '/FlattenONNX_', 'axis': node.axis}).create_node()
- shape_node = Shape(graph, {'name': node_name + '/ShapeOf_'}).create_node()
- logsoftmax_node = LogSoftmax(graph, {'name': node_name + '/LogSoftmax_', 'axis': 1}).create_node()
- reshape_node = Reshape(graph, {}).create_node()
-
- rename_nodes([(node, node_name + '/delete'), (reshape_node, node_name)])
-
- shape_node.out_port(0).connect(reshape_node.in_port(1))
- logsoftmax_node.out_port(0).connect(reshape_node.in_port(0))
- flatten_node.out_port(0).connect(logsoftmax_node.in_port(0))
-
- source = node.in_port(0).get_source()
-
- flatten_node.in_port(0).connect(source)
- shape_node.in_port(0).connect(source)
-
- return [reshape_node.id]
diff --git a/tools/mo/openvino/tools/mo/front/onnx/loop_ext.py b/tools/mo/openvino/tools/mo/front/onnx/loop_ext.py
deleted file mode 100644
index b170d3c5ec6013..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/loop_ext.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import copy
-import logging as log
-
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.front.common.register_custom_ops import check_for_duplicates
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.extractor import extract_node_attrs
-from openvino.tools.mo.front.onnx.extractor import onnx_op_extractor, onnx_op_extractors
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.front.onnx.loader import node_id, add_initializers_and_inputs_to_graph
-from openvino.tools.mo.graph.graph import Graph, Node, add_opoutput
-from openvino.tools.mo.utils.error import Error
-
-
-def create_edge_with_attrs(graph, src_name, src_internal_id, src_port, dst_id, dst_port):
- # src_name - name of input for edge
- # src_internal_id - input node dst_id. Can be the same as src_name or different if Parameter was created
- assert (graph.has_node(src_internal_id))
- edge_attrs = {
- 'out': src_port,
- 'in': dst_port,
- 'name': src_name,
- 'fw_tensor_debug_info': [(src_internal_id, src_name)],
- 'in_attrs': ['in', 'name'],
- 'out_attrs': ['out', 'name'],
- 'data_attrs': ['fw_tensor_debug_info']
- }
- graph.add_edge(src_internal_id, dst_id, **edge_attrs)
-
-
-def create_parameter_with_empty_attrs(graph, param_name):
- graph.add_node(param_name, kind='op', op='Parameter', name=param_name, pb=None, shape=None)
- parameter_node = Node(graph, param_name)
- # need to manually update necessary attrs for the node because extractor will not be called
- # for it because the node does not have .pb attribute
- Parameter.update_node_stat(parameter_node, {})
- parameter_node['internal_layer_id'] = len(graph.nodes)
-
- return parameter_node
-
-
-def create_cross_body_edge(body_graph, external_edges, additional_params, src_internal_id, dst_id, dst_port):
- cur_graph = body_graph
- counter = 0
- is_finished = False
- transit_parameter = None
- # go through all levels of nested graphs starting from the deepest
- while not is_finished and 'parent_node' in cur_graph.graph:
- parent_graph = cur_graph.graph['parent_node'].graph
- external_edges.append([])
- additional_params.append({})
- assert 0 <= counter < len(additional_params)
- assert 0 <= counter < len(external_edges)
- # if parent graph contains input node, create edge from outer to inner graph
- if src_internal_id in parent_graph.graph['tensor_mapping']:
- log.debug('The edge between outer and inner graphs detected: {} -> {}'.format(src_internal_id, dst_id))
- # if parameter in inner graph already created, use it. Otherwise - create new one
- if parent_graph.graph['tensor_mapping'][src_internal_id] not in additional_params[counter - 1]:
- # possibly we create edge through several levels and have created transit parameter
- if transit_parameter is None:
- # create new Parameter body node and connect the body node with the outer graph using it
- param_id = str(src_internal_id)
- parameter_node = create_parameter_with_empty_attrs(cur_graph, param_id)
- src_id, src_port = param_id, 0
- else:
- parameter_node = transit_parameter
- src_id, src_port = transit_parameter.id, 0
- external_edges[counter].append((parent_graph.graph['tensor_mapping'][src_internal_id],
- parameter_node, src_internal_id))
- additional_params[counter][parent_graph.graph['tensor_mapping'][src_internal_id][0]] = parameter_node
- else:
- src_id, src_port = additional_params[counter - 1][parent_graph.graph['tensor_mapping'][src_internal_id][0]].id, 0
- is_finished = True
- else:
- # check that we are not in process of creating edge through several borders
- # if we have transit node, it becomes destination of edge
- # otherwise create new Parameter
- if transit_parameter is None:
- # create new Parameter in inner graph in hope that we will find node later
- param_id = str(src_internal_id).split(':')[0]
- parameter_node = create_parameter_with_empty_attrs(cur_graph, param_id)
- else:
- parameter_node = transit_parameter
- param_id = transit_parameter.id
-
- # create transit parameter in outer graph in hope that real input will be found later
- parent_param_id = str(src_internal_id).split(':')[0] + "_transit"
- parent_parameter_node = create_parameter_with_empty_attrs(parent_graph, parent_param_id)
-
- external_edges[counter].append(((parent_param_id, 0), parameter_node, parent_param_id))
- src_id, src_port = param_id, 0
- additional_params[counter][parent_param_id + ":0"] = parameter_node
- transit_parameter = parent_parameter_node
-
- if cur_graph.has_node(dst_id):
- create_edge_with_attrs(cur_graph, src_internal_id, src_id, src_port, dst_id, dst_port)
-
- cur_graph = parent_graph
- counter += 1
-
- return is_finished
-
-
-class LoopExtractor(FrontExtractorOp):
- op = 'Loop'
- enabled = True
-
- @classmethod
- def extract(cls, loop_node):
- Loop.update_node_stat(loop_node, {})
-
- body_graph_proto = onnx_attr(loop_node, 'body', 'g', None)
- main_graph = loop_node.graph
-
- # create a Graph object for the body and take graph attributes from the main graph
- body_graph = Graph()
- main_graph_attrs_copy = {}
- for attr_key, attr_value in main_graph.graph.items():
- if attr_key not in ['tensor_mapping', 'parent_node']:
- main_graph_attrs_copy[attr_key] = copy.deepcopy(attr_value)
- body_graph.graph.update(main_graph_attrs_copy)
- loop_node['body'] = body_graph
- # save parent node for nested loops to know which node contains body (and which graph is on upper level)
- body_graph.graph['parent_node'] = loop_node
-
- # maps a tensor name to a node produced it and the node port: str -> (node_id, node_port)
- data_nodes_map = {}
- body_graph.graph['tensor_mapping'] = data_nodes_map # save mapping for possible Loop inside the Loop
-
- body_parameters = add_initializers_and_inputs_to_graph(body_graph, body_graph_proto, data_nodes_map)
-
- external_edges = [] # (src_node, src_out_port), dest_body_parameter_node
- # save additional edges information for graph on each level, the first one is the deepest
- additional_params = [] # (src_node, src_out_port) -> parameter_node (for manually added Parameters)
- # Go through all nodes in the original model order because data nodes are defined on-the-fly and order matters
- for pb_node in body_graph_proto.node:
- # create an NX node
- id = body_graph.unique_id(node_id(pb_node))
- body_graph.add_node(id, pb=pb_node, kind='op')
- if hasattr(body_graph, 'op_names_statistic') and hasattr(pb_node, 'op_type'):
- body_graph.op_names_statistic[pb_node.op_type] += 1
-
- # add incoming edges based on data_nodes_map
- for dst_port, inp in enumerate(pb_node.input):
- # should add edge src_internal_id --> dst_id
- if inp not in data_nodes_map:
- if inp == '':
- # input is omitted; most likely it corresponds to an optional input for an operator
- continue
- else:
- is_finished = create_cross_body_edge(body_graph, external_edges, additional_params,
- inp, id, dst_port)
- if not is_finished:
- raise Error(
- 'Reference to "{}" is not satisfied. A node refer not existing data tensor. ONNX '
- 'model is not consistent. Protobuf fragment: {}', inp, pb_node)
- else:
- src_id, src_port = data_nodes_map[inp]
- create_edge_with_attrs(body_graph, inp, src_id, src_port, id, dst_port)
-
- # add outgoing edges to data_nodes_map
- for src_port, out in enumerate(pb_node.output):
- if out in data_nodes_map:
- log.debug("Detected reuse of blob {}.".format(out))
- data_nodes_map[out] = (id, src_port)
-
- body_results = []
- for output in body_graph_proto.output:
- tensor_name = str(output.name)
- node_name, output_port = data_nodes_map[tensor_name]
- assert body_graph.has_node(node_name), 'The body graph does not contain output with name "{}"'.format(
- node_name)
- body_results.append(Node(body_graph, add_opoutput(body_graph, node_name, output_port, False)))
-
- # add 'internal_layer_id' attribute which is a must have attribute for the loop body node
- for idx, body_node in enumerate(body_graph.get_op_nodes()):
- body_node['internal_layer_id'] = idx
-
- loop_carried_dependencies_count = len(body_graph_proto.input) - 2
- scan_outputs_count = len(body_graph_proto.output) - 1 - loop_carried_dependencies_count
-
- # Loop inputs:
- # 0 - trip count
- # 1 - execution condition
- # 2 .. - loop carried dependencies
-
- # Loop outputs:
- # 0 .. loop_carried_dependencies_count - 1 - loop carried dependencies
- # loop_carried_dependencies_count .. - scan outputs
-
- # Body inputs:
- # 0 - iteration number
- # 1 - execution condition
- # 2 .. - loop carried dependencies
-
- # Body outputs:
- # 0 - execution condition
- # 1 .. loop_carried_dependencies_count - loop carried dependencies
- # loop_carried_dependencies_count + 1 .. - scan outputs
-
- # some of the inputs/outputs may not be connected but the normalization transformation will take care of it
- # connection Loop body nodes with external input edges
- next_loop_input_port_idx = sorted(loop_node.in_edges().keys())[-1] + 1
- cur_graph = body_graph
- for external_edges_subg in external_edges:
- if 'parent_node' not in cur_graph.graph:
- continue
- cur_loop_node = cur_graph.graph['parent_node']
- parent_graph = cur_loop_node.graph
- for (src_node, src_port), body_node, tensor_name in external_edges_subg:
- create_edge_with_attrs(parent_graph, tensor_name, src_node, src_port,
- cur_loop_node.id, next_loop_input_port_idx)
-
- Loop.connect_body_input(cur_loop_node, next_loop_input_port_idx, body_node)
- next_loop_input_port_idx += 1
- cur_graph = parent_graph
-
- # mark current iteration input Parameter node
- Loop.mark_current_iteration_parameter_node(loop_node, body_parameters[0])
-
- # connect initial value for "execution condition" input of the loop
- Loop.connect_body_input(loop_node, 1, body_parameters[1])
- # add back edge with "execution condition"
- Loop.add_back_edge(loop_node, body_parameters[1], body_results[0])
- # mark "execution condition" Result node
- Loop.mark_execution_condition_result_node(loop_node, body_results[0])
-
- # connect initial value for "loop carried" dependencies variables
- for idx in range(loop_carried_dependencies_count):
- Loop.connect_body_input(loop_node, idx + 2, body_parameters[idx + 2])
- # add back edge for "loop carried" dependencies variables
- for idx in range(loop_carried_dependencies_count):
- Loop.add_back_edge(loop_node, body_parameters[idx + 2], body_results[idx + 1])
- # connect final value for "loop carried" dependencies variables
- for idx in range(loop_carried_dependencies_count):
- Loop.connect_body_output(loop_node, idx, body_results[idx + 1])
-
- # connect "scan outputs" and mark axis for concatenation
- for idx in range(loop_carried_dependencies_count, loop_carried_dependencies_count + scan_outputs_count):
- Loop.connect_body_output(loop_node, idx, body_results[idx + 1], axis=0)
-
- # run function to parse body nodes attributes similar to the main graph
- extract_node_attrs(body_graph, lambda node: onnx_op_extractor(node, check_for_duplicates(onnx_op_extractors)))
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/lp_normalization_ext.py b/tools/mo/openvino/tools/mo/front/onnx/lp_normalization_ext.py
deleted file mode 100644
index aa2e4f85136dce..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/lp_normalization_ext.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.normalize_l2 import NormalizeL2Op
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class LPNormalizeExtractor(FrontExtractorOp):
- op = 'LpNormalization'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'p': onnx_attr(node, 'p', 'i', 2),
- 'axis': onnx_attr(node, 'axis', 'i', -1),
- 'eps_mode': 'add', # TODO check ONNX implementation
- 'eps': 1e-6, # TODO check ONNX implementation
- }
- if attrs['p'] == 1:
- log.debug('The node {} has unsupported attribute "p" = {}'.format(node.soft_get('name'), attrs['p']))
- return False
-
- NormalizeL2Op.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/lrn_ext.py b/tools/mo/openvino/tools/mo/front/onnx/lrn_ext.py
deleted file mode 100644
index 0bb5ca278105ad..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/lrn_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.lrn import AttributedLRN
-
-
-class LRNFrontExtractor(FrontExtractorOp):
- op = 'LRN'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'alpha': onnx_attr(node, 'alpha', 'f', 1e-4),
- 'beta': onnx_attr(node, 'beta', 'f', 0.75),
- 'bias': onnx_attr(node, 'bias', 'f', 1.0),
- 'local_size': onnx_attr(node, 'size', 'i', None),
- }
- AttributedLRN.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/lstm_ext.py b/tools/mo/openvino/tools/mo/front/onnx/lstm_ext.py
deleted file mode 100644
index 908ee1b81922a8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/lstm_ext.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array, int64_array
-from openvino.tools.mo.ops.LSTM import LSTM
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class LSTMFrontExtractor(FrontExtractorOp):
- op = 'LSTM'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- activation_alpha = onnx_attr(node, 'activation_alpha', 'floats',
- default=None, dst_type=lambda x: float32_array(x))
- activation_beta = onnx_attr(node, 'activation_beta', 'floats',
- default=None, dst_type=lambda x: float32_array(x))
- activations = onnx_attr(node, 'activations', 'strings', default=None,
- dst_type=lambda x: list(map(lambda s: s.decode(encoding="utf-8").lower(), list(x))))
- clip = onnx_attr(node, 'clip', 'f', default=None)
- input_forget = onnx_attr(node, 'input_forget', 'i', default=0)
-
- attrs = {
- 'batch_dim': 1,
- 'sequence_dim': 0,
- 'blobs_wrb': True,
- 'has_num_directions': True,
- 'num_layers': 1,
- 'format': 'onnx',
- 'multilayers': False,
- 'gate_order': [2, 0, 3, 1], # iofc --> fico
-
- # ONNX attrs
- 'activation_alpha': activation_alpha,
- 'activation_beta': activation_beta,
- 'activations': activations,
- 'clip': clip,
- 'direction': onnx_attr(node, 'direction', 's', b'forward').decode().lower(),
- 'hidden_size': int64_array(onnx_attr(node, 'hidden_size', 'i')),
- 'input_forget': input_forget,
- }
-
- LSTM.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/mask_rcnn.json b/tools/mo/openvino/tools/mo/front/onnx/mask_rcnn.json
deleted file mode 100644
index adc5b02d050f96..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/mask_rcnn.json
+++ /dev/null
@@ -1,21 +0,0 @@
-[
- {
- "custom_attributes":
- {
- "max_detections_per_image": 100,
- "max_delta_log_wh": 4.135166645050049,
- "score_threshold": 0.05,
- "nms_threshold": 0.5,
- "post_nms_count": 2000,
- "input_fpn_heads": ["486", "454", "422", "390"],
- "do_outputs": ["6530", "6532", "6534"],
- "box_regressions_input_node": "2773",
- "class_predicitons_node": "2774",
- "ROIFeatureExtractor1_output": "6795",
- "ROIFeatureExtractor2_input": "2490",
- "ROIFeatureExtractor2_output": "2751"
- },
- "id": "ONNXMaskRCNNReplacement",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/onnx/mask_rcnn_conversion.py b/tools/mo/openvino/tools/mo/front/onnx/mask_rcnn_conversion.py
deleted file mode 100644
index 925d1ed3d4f76e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/mask_rcnn_conversion.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.onnx.softmaxONNX_to_softmax import SoftmaxONNXFrontReplacer
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.detection_output_onnx import ExperimentalDetectronDetectionOutput
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.ops.roifeatureextractor_onnx import ExperimentalDetectronROIFeatureExtractor
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileGeneral
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class ONNXMaskRCNNTransformation(FrontReplacementFromConfigFileGeneral):
- """
- This transformation performs 3 actions:
- 1. Replaces a sub-graph calculating ROIAlign over FPN heads with a single ExperimentalDetectronROIFeatureExtractor
- node.
- 2. Replaces a sub-graph calculating post-processing of background/foreground with a single
- ExperimentalDetectronDetectionOutput node.
- 3. Replaces another sub-graph calculating ROIAlign over FPN heads with a single
- ExperimentalDetectronROIFeatureExtractor node. These ROIAligns get boxes from the
- ExperimentalDetectronDetectionOutput node.
- """
- replacement_id = 'ONNXMaskRCNNReplacement'
-
- def run_before(self):
- # the class_predicitons_node which is used in this transformation is of op SoftMaxONNX. But operations of op SoftMaxONNX
- # will be replaced with a transformation SoftmaxONNXFrontReplacer
- return [SoftmaxONNXFrontReplacer]
-
- def transform_graph(self, graph: Graph, replacement_descriptions: dict):
- insert_ExperimentalDetectronROIFeatureExtractor2(graph, replacement_descriptions)
- insert_do(graph, replacement_descriptions)
- insert_ExperimentalDetectronROIFeatureExtractor1(graph, replacement_descriptions)
-
-
-def insert_do(graph: Graph, replacement_descriptions: dict):
- do_outputs = replacement_descriptions['do_outputs']
- prior_boxes_node = Node(graph, 'ROIFeatureExtractor_2')
- num_classes = 81
- box_regressions_input_node = Node(graph, replacement_descriptions['box_regressions_input_node'])
- box_regressions_node = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 4 * num_classes]),
- dict(name='box_regressions'), box_regressions_input_node)
-
- class_predicitons_node = Node(graph, replacement_descriptions['class_predicitons_node'])
- im_info_node = Parameter(graph, {"name": 'im_info', 'shape': int64_array([1, 3])}).create_node()
-
- do_node = ExperimentalDetectronDetectionOutput(graph, {'name': 'DetectionOutput',
- 'class_agnostic_box_regression': 0,
- 'deltas_weights': mo_array([10.0, 10.0, 5.0, 5.0]),
- 'max_delta_log_wh':
- replacement_descriptions['max_delta_log_wh'],
- 'nms_threshold': replacement_descriptions['nms_threshold'],
- 'score_threshold':
- replacement_descriptions['score_threshold'],
- 'num_classes': num_classes,
- 'max_detections_per_image':
- replacement_descriptions['max_detections_per_image'],
- 'post_nms_count': replacement_descriptions['post_nms_count']
- }).create_node()
- prior_boxes_node.out_port(1).connect(do_node.in_port(0))
- box_regressions_node.out_port(0).connect(do_node.in_port(1))
- class_predicitons_node.out_port(0).connect(do_node.in_port(2))
- im_info_node.out_port(0).connect(do_node.in_port(3))
-
- do_output_ports = [do_node.out_port(0), do_node.out_port(1), do_node.out_port(2)]
- old_do_output_nodes = [Node(graph, node_id) for node_id in do_outputs]
- for old_node, new_port in zip(old_do_output_nodes, do_output_ports):
- old_node.out_port(0).get_connection().set_source(new_port)
- # the consumer of the second output port of the ExperimentalDetectronDetectionOutput is the Mul node which second
- # input is of type int64 so it is necessary to insert Cast to have data types match
- do_node.out_port(1).get_connection().insert_node(Cast(graph, {'dst_type': np.int64}).create_node())
-
-
-def insert_ExperimentalDetectronROIFeatureExtractor1(graph: Graph, replacement_descriptions: dict):
- if 'ROIFeatureExtractor1_output' not in replacement_descriptions:
- # In case of Faster-RCNN this transformation is not needed and this attribute shouldn't be set
- return
- input_fpn_heads = replacement_descriptions['input_fpn_heads']
- old_output_node = Node(graph, replacement_descriptions['ROIFeatureExtractor1_output'])
- input_fpn_head_nodes = [Node(graph, node_id) for node_id in input_fpn_heads]
- fpn_roi_align = ExperimentalDetectronROIFeatureExtractor(graph, {'name': 'ROIFeatureExtractor_1',
- 'output_size': 14,
- 'pyramid_scales': int64_array(
- [4, 8, 16, 32, 64]),
- 'sampling_ratio': 2,
- 'in_ports_count': 5}).create_node()
- fpn_roi_align.in_port(0).connect(Node(graph, 'DetectionOutput').out_port(0))
- for ind, fpn_node in enumerate(input_fpn_head_nodes):
- fpn_roi_align.in_port(ind + 1).connect(fpn_node.out_port(0))
-
- old_output_node.out_port(0).get_connection().set_source(fpn_roi_align.out_port(0))
-
-
-def insert_ExperimentalDetectronROIFeatureExtractor2(graph: Graph, replacement_descriptions: dict):
- input_fpn_heads = replacement_descriptions['input_fpn_heads']
- old_output_node = Node(graph, replacement_descriptions['ROIFeatureExtractor2_output'])
- input_fpn_head_nodes = [Node(graph, node_id) for node_id in input_fpn_heads]
- fpn_roi_align = ExperimentalDetectronROIFeatureExtractor(graph, {'name': 'ROIFeatureExtractor_2',
- 'output_size': 7,
- 'pyramid_scales': int64_array(
- [4, 8, 16, 32, 64]),
- 'sampling_ratio': 2,
- 'in_ports_count': 5}).create_node()
- fpn_roi_align.in_port(0).connect(Node(graph, replacement_descriptions['ROIFeatureExtractor2_input']).out_port(0))
- for ind, fpn_node in enumerate(input_fpn_head_nodes):
- fpn_roi_align.in_port(ind + 1).connect(fpn_node.out_port(0))
-
- old_output_node.out_port(0).get_connection().set_source(fpn_roi_align.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/matmul_ext.py b/tools/mo/openvino/tools/mo/front/onnx/matmul_ext.py
deleted file mode 100644
index fd90f2c95d30b9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/matmul_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.MatMul import MatMul
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class MatMulFrontExtractor(FrontExtractorOp):
- op = 'MatMul'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- MatMul.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/mean_variance_normalization_ext.py b/tools/mo/openvino/tools/mo/front/onnx/mean_variance_normalization_ext.py
deleted file mode 100644
index 9a358de1228d75..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/mean_variance_normalization_ext.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.mvn import MVNOnnx
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class MeanVarianceNormalizationExtractor(FrontExtractorOp):
- op = 'MeanVarianceNormalization'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axes = onnx_attr(node, 'axes', 'ints',
- default=int64_array([0, 2, 3]),
- dst_type=lambda x: int64_array(x))
-
- attrs = {
- 'eps': 1e-9,
- 'normalize_variance': 1,
- 'axes': axes,
- 'eps_mode': 'outside_sqrt',
- }
-
- MVNOnnx.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/non_max_suppression_ext.py b/tools/mo/openvino/tools/mo/front/onnx/non_max_suppression_ext.py
deleted file mode 100644
index 7dc01ee4dde3b3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/non_max_suppression_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.non_max_suppression import NonMaxSuppression
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class NonMaxSuppressionExtractor(FrontExtractorOp):
- op = 'NonMaxSuppression'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- encoding_map = {0: 'corner', 1: 'center'}
- center_point_box = onnx_attr(node, 'center_point_box', 'i', default=0)
- NonMaxSuppression.update_node_stat(node, {'sort_result_descending': 0,
- 'output_type': np.int64,
- 'box_encoding': encoding_map[center_point_box]})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/non_zero_ext.py b/tools/mo/openvino/tools/mo/front/onnx/non_zero_ext.py
deleted file mode 100644
index b4001973d52836..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/non_zero_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.non_zero import NonZero
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class NonZeroExtractor(FrontExtractorOp):
- op = 'NonZero'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- NonZero.update_node_stat(node, {'output_type': np.int64})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/normalize_ext.py b/tools/mo/openvino/tools/mo/front/onnx/normalize_ext.py
deleted file mode 100644
index dc33bb71328982..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/normalize_ext.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.normalize import NormalizeOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class NormalizeFrontExtractor(FrontExtractorOp):
- op = 'Normalize'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- across_spatial = onnx_attr(node, 'across_spatial', 'i', default=0)
- channel_shared = onnx_attr(node, 'channel_shared', 'i', default=0)
- eps = onnx_attr(node, 'eps', 'f', default=0)
-
- attrs = {'across_spatial': bool(across_spatial),
- 'channel_shared': bool(channel_shared),
- 'eps': eps,
- 'layout': 'NCHW'}
-
- # update the attributes of the node
- NormalizeOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/normalize_l2_normalize.py b/tools/mo/openvino/tools/mo/front/onnx/normalize_l2_normalize.py
deleted file mode 100644
index 64f48f660fe00b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/normalize_l2_normalize.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class NormalizeL2Normalize(FrontReplacementPattern):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for normalize_l2 in graph.get_op_nodes(op='NormalizeL2'):
- if normalize_l2.in_port(1).disconnected():
- assert normalize_l2.has_valid('axis'), 'The NormalizeL2 node "{}" misses "axis" attribute.' \
- ''.format(normalize_l2.name)
- axis_node = Const(graph, {'name': normalize_l2.id + '/Axis',
- 'value': int64_array([normalize_l2.axis])}).create_node()
- normalize_l2.in_port(1).connect(axis_node.out_port(0))
- del normalize_l2['axis']
- else:
- log.debug('The NormalizeL2 node input "{}" is already normalized'.format(normalize_l2.name))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/one_hot_ext.py b/tools/mo/openvino/tools/mo/front/onnx/one_hot_ext.py
deleted file mode 100644
index 2f908328481ad4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/one_hot_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.one_hot import OneHot
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class OneHotExtractor(FrontExtractorOp):
- op = 'OneHot'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', default=-1)
- OneHot.update_node_stat(node, {'axis': axis, 'split_values': True})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/one_hot_normalize.py b/tools/mo/openvino/tools/mo/front/onnx/one_hot_normalize.py
deleted file mode 100644
index a430fe938261c3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/one_hot_normalize.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.split_normalizer import SqueezeAxis
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-
-
-class OneHotNormalize(FrontReplacementSubgraph):
- """
- The ONNX OneHot layer has input with values of shape [2] which contains off and on values. This transformation
- splits this input into two and connects them back to the OneHot layer in reverse order because in OV layer the
- on value goes to port 2 and off values goes to port 3.
- """
- enabled = True
-
- def run_before(self):
- return [SqueezeAxis]
-
- def pattern(self):
- return dict(nodes=[('onehot', dict(op='OneHot', split_values=True))],
- edges=[])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- onehot = match['onehot']
- name = onehot.soft_get('name', onehot.id)
-
- split = create_op_with_const_inputs(graph, Split, {1: np.int64(0)},
- {'name': name + '/Split', 'num_splits': 2, 'squeeze_axis': True})
-
- onehot.in_port(2).get_source().connect(split.in_port(0))
- onehot.in_port(2).disconnect()
-
- onehot.in_port(3).connect(split.out_port(0))
- onehot.in_port(2).connect(split.out_port(1))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/pad_converter.py b/tools/mo/openvino/tools/mo/front/onnx/pad_converter.py
deleted file mode 100644
index c1e63fe3f78f09..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/pad_converter.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_node, Node
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.pad import Pad
-
-
-class ONNXPadToPad(FrontReplacementOp):
- """
- This transformation converts ONNXPad operation (ONNX semantic) to Pad operation (OpenVINO semantic).
- Refer to the Op implementation for the operations semantics description.
- """
- op = 'ONNXPad'
- enabled = True
-
- def replace_op(self, graph: Graph, node: Node):
- # save the original node name to use it in the new Pad op instance
- original_name = node.soft_get('name', node.id)
- rename_node(node, original_name + '/TBR')
-
- new_pad = Pad(graph, {'mode': node.soft_get('mode', None)}).create_node()
- rename_node(new_pad, original_name)
-
- node.in_port(0).get_connection().set_destination(new_pad.in_port(0))
-
- if node.soft_get('mode') == 'constant':
- # the input with fill value is an optional third input in ONNX
- if not node.in_port(2).disconnected():
- node.in_port(2).get_connection().set_destination(new_pad.in_port(3))
- else:
- new_pad.in_port(3).connect(Const(graph, {'value': 0.0}).create_node().out_port(0))
-
- # convert ONNX representation of the pads as [2 * N] to MO representation: [N] and [N]
- split_pads = create_op_with_const_inputs(graph, Split, {1: int64_array(0)}, {'num_splits': 2})
- node.in_port(1).get_connection().set_destination(split_pads.in_port(0))
- split_pads.out_port(0).connect(new_pad.in_port(1))
- split_pads.out_port(1).connect(new_pad.in_port(2))
-
- return [new_pad.id]
diff --git a/tools/mo/openvino/tools/mo/front/onnx/pad_ext.py b/tools/mo/openvino/tools/mo/front/onnx/pad_ext.py
deleted file mode 100644
index d6643f17b07ef9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/pad_ext.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version
-from openvino.tools.mo.ops.pad import AttributedPad, ONNXPad
-
-
-class PadFrontExtractor(FrontExtractorOp):
- op = 'Pad'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- mode = onnx_attr(node, 'mode', 's', default='constant', dst_type=lambda x: x.decode())
- # Pytorch 1.3 while converting to opset 11, creates Pad from older opset.
- # To be able to convert such models we have to check if pads attribute exists.
- pads = onnx_attr(node, 'pads', 'ints', dst_type=int64_array)
- if get_onnx_opset_version(node) < 11 or pads is not None:
- value = onnx_attr(node, 'value', 'f', default=0.)
-
- assert pads is not None, 'pads is required attribute for Pad operation'
-
- # MO Pad op and ONNX Pad op have different format for pads values
- # MO Pad has Dx2 where D is the total number of dimensions
- # ONNX Pad pads flat layout, so need to reshape and transpose
-
- pads = np.transpose(pads.reshape([2, -1]))
-
- AttributedPad.update_node_stat(node, {'mode': mode, 'pads': pads, 'fill_value': value})
- else:
- ONNXPad.update_node_stat(node, {'mode': mode})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/parameter_ext.py b/tools/mo/openvino/tools/mo/front/onnx/parameter_ext.py
deleted file mode 100644
index 17feedc1f775d0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/parameter_ext.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from onnx.mapping import TENSOR_TYPE_TO_NP_TYPE
-
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class PlaceholderFrontExtractor(FrontExtractorOp):
- op = 'Parameter'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- t_type = node.pb.type.tensor_type
- attrs = {
- 'shape': shape_array([d.dim_value if (not hasattr(d, 'dim_param') or d.dim_param == '') and d.dim_value != 0
- else dynamic_dimension_value for d in t_type.shape.dim]),
- 'data_type': TENSOR_TYPE_TO_NP_TYPE[t_type.elem_type]
- }
- Parameter.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/person_detection_crossroad.json b/tools/mo/openvino/tools/mo/front/onnx/person_detection_crossroad.json
deleted file mode 100644
index 8fbd55564f6fbb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/person_detection_crossroad.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- {
- "custom_attributes":
- {
- "fpn_heads": ["634", "635", "636", "637"],
- "ROI_feature_extractor_inputs": ["2475", "2834", "3192"],
- "ROI_feature_extractor_outputs": ["2614", "2972", "3330"]
- },
- "id": "ONNXPersonDetectionCrossroadReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/onnx/person_detection_crossroad_conversion.py b/tools/mo/openvino/tools/mo/front/onnx/person_detection_crossroad_conversion.py
deleted file mode 100644
index 6a9acfd0af69eb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/person_detection_crossroad_conversion.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.roifeatureextractor_onnx import ExperimentalDetectronROIFeatureExtractor
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileGeneral
-from openvino.tools.mo.graph.graph import Graph, Node, rename_node
-
-
-class ONNXPersonDetectionCrossroadReplacement(FrontReplacementFromConfigFileGeneral):
- """
- Insert ExperimentalDetectronROIFeatureExtractor layers instead of sub-graphs of the model.
- """
- replacement_id = 'ONNXPersonDetectionCrossroadReplacement'
-
- def transform_graph(self, graph: Graph, replacement_descriptions: dict):
- fpn_heads = replacement_descriptions['fpn_heads']
- for inp, out in zip(replacement_descriptions['ROI_feature_extractor_inputs'],
- replacement_descriptions['ROI_feature_extractor_outputs']):
- insert_experimental_layers(graph, fpn_heads, inp, out)
-
-
-def insert_experimental_layers(graph: Graph, input_fpn_heads: list, inp: str, out: str):
- old_output_node = Node(graph, out)
- output_name = old_output_node.soft_get('name', old_output_node.id)
- old_output_node_name = output_name + '/old'
- rename_node(old_output_node, old_output_node_name)
-
- input_fpn_head_nodes = [Node(graph, node_id) for node_id in input_fpn_heads]
- fpn_roi_align = ExperimentalDetectronROIFeatureExtractor(graph, {'name': output_name,
- 'output_size': 7,
- 'pyramid_scales': int64_array(
- [4, 8, 16, 32, 64]),
- 'sampling_ratio': 2, }).create_node()
- rename_node(fpn_roi_align, output_name)
- fpn_roi_align.in_port(0).connect(Node(graph, inp).out_port(0))
- for ind, fpn_node in enumerate(input_fpn_head_nodes):
- fpn_roi_align.in_port(ind + 1).connect(fpn_node.out_port(0))
-
- old_output_node.out_port(0).get_connection().set_source(fpn_roi_align.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/onnx/pooling_ext.py b/tools/mo/openvino/tools/mo/front/onnx/pooling_ext.py
deleted file mode 100644
index cc272990d40b91..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/pooling_ext.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_autopad
-from openvino.tools.mo.ops.pooling import Pooling
-from openvino.tools.mo.utils.error import Error
-
-
-class AveragePoolFrontExtractor(FrontExtractorOp):
- op = 'AveragePool'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = common_onnx_pool_extractor(node)
-
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class MaxPoolFrontExtractor(FrontExtractorOp):
- op = 'MaxPool'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = common_onnx_pool_extractor(node)
-
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class GlobalAveragePoolFrontExtractor(FrontExtractorOp):
- op = 'GlobalAveragePool'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = common_onnx_pool_extractor(node)
- attrs.update({'pooling_convention': 'full',
- 'global_pool': True,
- })
-
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class GlobalMaxPoolFrontExtractor(FrontExtractorOp):
- op = 'GlobalMaxPool'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = common_onnx_pool_extractor(node)
- attrs.update({'pooling_convention': 'full',
- 'global_pool': True,
- })
-
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-def common_onnx_pool_extractor(node):
- kernel_shape = onnx_attr(node, 'kernel_shape', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_kernel_shape = int64_array([1, 1, *[x for x in kernel_shape]]) if kernel_shape is not None else None
-
- pads = onnx_attr(node, 'pads', 'ints', default=None, dst_type=lambda x: int64_array(x))
-
- if kernel_shape is not None and pads is not None and kernel_shape.size * 2 != pads.size:
- log.warning('Node {} has pad = {} which is ill-formed -- it should have even amount of elements.'.format(
- node.soft_get('name', node.id), pads))
-
- # Try to convert slightly incorrect models with insufficient pad parameters
- assert pads.size == kernel_shape.size
- pads = np.concatenate([pads, pads])
- log.warning('Extended pads to {}'.format(pads))
-
- final_pads = None
- if pads is not None:
- assert len(pads) % 2 == 0
- pads = pads.reshape([2, -1])
- pads = np.transpose(pads)
- final_pads = int64_array([[0, 0], [0, 0], *[p for p in pads]])
-
- # Extract strides attribute
- # In case if strides is not specified it will be set in default (1) in infer function
- strides = onnx_attr(node, 'strides', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_strides = int64_array([1, 1, *[x for x in strides]]) if strides is not None else None
-
- dilation = onnx_attr(node, 'dilations', 'ints', default=None, dst_type=lambda x: int64_array(x))
- final_dilation = int64_array([1, 1, *[x for x in dilation]]) if dilation is not None else None
-
- # exclude_pad = True only when count_include_pad == 0
- exclude_pad = onnx_attr(node, 'count_include_pad', 'i', default=0) == 0
-
- global_pooling = False
- if node.op in ['MaxPool', 'GlobalMaxPool']:
- method = 'max'
- elif node.op in ['AveragePool', 'GlobalAveragePool']:
- method = 'avg'
- else:
- raise Error('Unsupported pooling op {}', node.op)
-
- # TODO check if it is a correct choice for ONNX
- pooling_convention = 'valid' # for Caffe rounding type should be ceil
- rt = 'floor' if onnx_attr(node, 'ceil_mode', 'i', default=0) == 0 else 'ceil'
-
- auto_pad = onnx_attr(node, 'auto_pad', 's', default=None, dst_type=get_onnx_autopad)
- if auto_pad:
- rt = 'ceil'
-
- attrs = {
- 'op': node.op,
- 'auto_pad': auto_pad,
- 'window': final_kernel_shape,
- 'stride': final_strides,
- 'pad': final_pads,
- 'pad_spatial_shape': int64_array(pads) if pads is not None else None,
- 'pool_method': method,
- 'exclude_pad': True if exclude_pad else False,
- 'global_pool': global_pooling,
- 'output_spatial_shape': None,
- 'rounding_type': rt,
- 'dilation': final_dilation,
-
- 'spatial_dims': None,
- 'channel_dims': int64_array([1]),
- 'batch_dims': int64_array([0]),
- 'layout': 'NCHW',
-
- 'pooling_convention': pooling_convention
- }
- return attrs
diff --git a/tools/mo/openvino/tools/mo/front/onnx/priorbox_clustered_ext.py b/tools/mo/openvino/tools/mo/front/onnx/priorbox_clustered_ext.py
deleted file mode 100644
index 75ce3ed75f7da7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/priorbox_clustered_ext.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.ops.priorbox_clustered import PriorBoxClusteredOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class PriorBoxClusteredFrontExtractor(FrontExtractorOp):
- op = 'PriorBoxClustered'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- variance = onnx_attr(node, 'variance', 'floats', default=[], dst_type=lambda x: float32_array(x))
- if len(variance) == 0:
- variance = [0.1]
-
- update_attrs = {
- 'width': onnx_attr(node, 'width', 'floats', dst_type=lambda x: float32_array(x)),
- 'height': onnx_attr(node, 'height', 'floats', dst_type=lambda x: float32_array(x)),
- 'flip': onnx_attr(node, 'flip', 'i', default=0),
- 'clip': onnx_attr(node, 'clip', 'i', default=0),
- 'variance': list(variance),
- 'img_size': onnx_attr(node, 'img_size', 'i', default=0),
- 'img_h': onnx_attr(node, 'img_h', 'i', default=0),
- 'img_w': onnx_attr(node, 'img_w', 'i', default=0),
- 'step': onnx_attr(node, 'step', 'f', default=0.0),
- 'step_h': onnx_attr(node, 'step_h', 'f', default=0.0),
- 'step_w': onnx_attr(node, 'step_w', 'f', default=0.0),
- 'offset': onnx_attr(node, 'offset', 'f', default=0.0),
- }
-
- # update the attributes of the node
- PriorBoxClusteredOp.update_node_stat(node, update_attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/priorbox_ext.py b/tools/mo/openvino/tools/mo/front/onnx/priorbox_ext.py
deleted file mode 100644
index 70eafd746799e7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/priorbox_ext.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.ops.priorbox import PriorBoxOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class PriorBoxFrontExtractor(FrontExtractorOp):
- op = 'PriorBox'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- variance = onnx_attr(node, 'variance', 'floats', default=[], dst_type=lambda x: float32_array(x))
- if len(variance) == 0:
- variance = [0.1]
-
- update_attrs = {
- 'aspect_ratio': onnx_attr(node, 'aspect_ratio', 'floats', dst_type=lambda x: float32_array(x)),
- 'min_size': onnx_attr(node, 'min_size', 'floats', dst_type=lambda x: float32_array(x)),
- 'max_size': onnx_attr(node, 'max_size', 'floats', dst_type=lambda x: float32_array(x)),
- 'flip': onnx_attr(node, 'flip', 'i', default=0),
- 'clip': onnx_attr(node, 'clip', 'i', default=0),
- 'variance': list(variance),
- 'img_size': onnx_attr(node, 'img_size', 'i', default=0),
- 'img_h': onnx_attr(node, 'img_h', 'i', default=0),
- 'img_w': onnx_attr(node, 'img_w', 'i', default=0),
- 'step': onnx_attr(node, 'step', 'f', default=0.0),
- 'step_h': onnx_attr(node, 'step_h', 'f', default=0.0),
- 'step_w': onnx_attr(node, 'step_w', 'f', default=0.0),
- 'offset': onnx_attr(node, 'offset', 'f', default=0.0),
- }
-
- # update the attributes of the node
- PriorBoxOp.update_node_stat(node, update_attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/priorgridgenerator_ext.py b/tools/mo/openvino/tools/mo/front/onnx/priorgridgenerator_ext.py
deleted file mode 100644
index b0efae9164bebc..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/priorgridgenerator_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.priorgridgenerator_onnx import ExperimentalDetectronPriorGridGenerator
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ExperimentalDetectronPriorGridGeneratorFrontExtractor(FrontExtractorOp):
- op = 'ExperimentalDetectronPriorGridGenerator'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = dict(h=onnx_attr(node, 'h', 'i', 0),
- w=onnx_attr(node, 'w', 'i', 0),
- stride_x=onnx_attr(node, 'stride_x', 'f', 0),
- stride_y=onnx_attr(node, 'stride_y', 'f', 0),
- flatten=onnx_attr(node, 'flatten', 'i', 1)
- )
- ExperimentalDetectronPriorGridGenerator.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/proposal_ext.py b/tools/mo/openvino/tools/mo/front/onnx/proposal_ext.py
deleted file mode 100644
index afb58c9be57987..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/proposal_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.proposal_onnx import ExperimentalDetectronGenerateProposalsSingleImage
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ExperimentalDetectronGenerateProposalsSingleImageFrontExtractor(FrontExtractorOp):
- op = 'ExperimentalDetectronGenerateProposalsSingleImage'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = dict(min_size=onnx_attr(node, 'min_size', 'f', 0.0),
- nms_threshold=onnx_attr(node, 'nms_threshold', 'f', 0.7),
- post_nms_count=onnx_attr(node, 'post_nms_count', 'i', 1000),
- pre_nms_count=onnx_attr(node, 'pre_nms_count', 'i', 1000)
- )
- ExperimentalDetectronGenerateProposalsSingleImage.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/quantize_ext.py b/tools/mo/openvino/tools/mo/front/onnx/quantize_ext.py
deleted file mode 100644
index fb97651f6766e5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/quantize_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.fakequantize import FakeQuantize
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class FakeQuantizeFrontExtractor(FrontExtractorOp):
- op = 'FakeQuantize'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- levels = onnx_attr(node, 'levels', 'i')
- FakeQuantize.update_node_stat(node, {'levels': levels})
- return FakeQuantizeFrontExtractor.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/quantize_linear_ext.py b/tools/mo/openvino/tools/mo/front/onnx/quantize_linear_ext.py
deleted file mode 100644
index 60c73faccdfbb8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/quantize_linear_ext.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.quantize_linear import QuantizeLinear
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version
-
-
-class QuantizeLinearFrontExtractor(FrontExtractorOp):
- op = 'QuantizeLinear'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {}
- if get_onnx_opset_version(node) >= 13:
- axis = onnx_attr(node, 'axis', 'i', default=None)
- attrs.update(axis=axis)
- QuantizeLinear.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/random_uniform_ext.py b/tools/mo/openvino/tools/mo/front/onnx/random_uniform_ext.py
deleted file mode 100644
index 3ec1078d3177a2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/random_uniform_ext.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.random_uniform import AttributedRandomUniform
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_datatype_as_numpy
-from openvino.tools.mo.graph.graph import Node
-
-
-class RandomUniformFrontExtractor(FrontExtractorOp):
- op = 'RandomUniform'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- shape = onnx_attr(node, 'shape', 'ints', default=None, dst_type=int64_array)
- out_type = get_onnx_datatype_as_numpy(onnx_attr(node, 'dtype', 'i', default=1))
- seed = onnx_attr(node, 'seed', 'f', default=0.0)
- min_val = onnx_attr(node, 'low', 'f', default=0.0)
- max_val = onnx_attr(node, 'high', 'f', default=1.0)
- AttributedRandomUniform.update_node_stat(node, {'shape': shape,
- 'output_type': out_type,
- 'seed': seed,
- 'min_val': out_type(min_val),
- 'max_val': out_type(max_val)})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/range_ext.py b/tools/mo/openvino/tools/mo/front/onnx/range_ext.py
deleted file mode 100644
index b00c43aced17ba..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/range_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-
-
-class RangeFrontExtractor(FrontExtractorOp):
- op = 'Range'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- # output_type attribute will be deduced during shape infer
- Range.update_node_stat(node, {})
- return cls.enabled
-
diff --git a/tools/mo/openvino/tools/mo/front/onnx/reduce_ext.py b/tools/mo/openvino/tools/mo/front/onnx/reduce_ext.py
deleted file mode 100644
index 0cf3c6f9b90b6c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/reduce_ext.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ReduceOps import ReduceL1, ReduceL2, ReduceMax, ReduceMean, ReduceMin, ReduceProd, ReduceSum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.graph.graph import Node
-
-
-def update_reduce_node_attrs_with(node: Node, c: callable):
- axis = onnx_attr(node, 'axes', 'ints', default=None)
- if axis is not None:
- axis = int64_array(axis)
- keep_dims = onnx_attr(node, 'keepdims', 'i', default=True)
- c.update_node_stat(node, {'axis': axis, 'keep_dims': keep_dims})
-
-
-class ReduceL1Extractor(FrontExtractorOp):
- op = 'ReduceL1'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceL1)
- return cls.enabled
-
-
-class ReduceL2Extractor(FrontExtractorOp):
- op = 'ReduceL2'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceL2)
- return cls.enabled
-
-
-class ReduceMaxFrontExtractor(FrontExtractorOp):
- op = 'ReduceMax'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceMax)
- return cls.enabled
-
-
-class ReduceMeanFrontExtractor(FrontExtractorOp):
- op = 'ReduceMean'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceMean)
- return cls.enabled
-
-
-class ReduceMinFrontExtractor(FrontExtractorOp):
- op = 'ReduceMin'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceMin)
- return cls.enabled
-
-
-class ReduceProdFrontExtractor(FrontExtractorOp):
- op = 'ReduceProd'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceProd)
- return cls.enabled
-
-
-class ReduceSumFrontExtractor(FrontExtractorOp):
- op = 'ReduceSum'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- update_reduce_node_attrs_with(node, ReduceSum)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/register_custom_ops.py b/tools/mo/openvino/tools/mo/front/onnx/register_custom_ops.py
deleted file mode 100644
index 1e2be280b06390..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/register_custom_ops.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp, FrontReplacementPattern, FrontReplacementSubgraph
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileSubGraph, FrontReplacementFromConfigFileOp, \
- FrontReplacementFromConfigFileGeneral
-
-
-def get_front_classes():
- front_classes = [FrontExtractorOp, FrontReplacementOp, FrontReplacementPattern, FrontReplacementSubgraph,
- FrontReplacementFromConfigFileSubGraph, FrontReplacementFromConfigFileOp,
- FrontReplacementFromConfigFileGeneral]
- return front_classes
diff --git a/tools/mo/openvino/tools/mo/front/onnx/reshape_ext.py b/tools/mo/openvino/tools/mo/front/onnx/reshape_ext.py
deleted file mode 100644
index 68bca8f8f33e12..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/reshape_ext.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.reshape import Reshape
-
-class ReshapeFrontExtractor(FrontExtractorOp):
- op = 'Reshape'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- dim = onnx_attr(node, 'shape', 'ints', None)
- if dim is not None:
- dim = int64_array(dim)
- Reshape.update_node_stat(node, {'dim': dim})
- else:
- Reshape.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/resize_ext.py b/tools/mo/openvino/tools/mo/front/onnx/resize_ext.py
deleted file mode 100644
index 189f7314d55e8e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/resize_ext.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ONNXResize10 import ONNXResize10
-from openvino.tools.mo.ops.ONNXResize11 import ONNXResize11Op
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version
-from openvino.tools.mo.graph.graph import Node
-
-
-class ResizeExtractor(FrontExtractorOp):
- op = 'Resize'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- onnx_opset_version = get_onnx_opset_version(node)
- if onnx_opset_version is not None and onnx_opset_version >= 11:
- mode = onnx_attr(node, 'mode', 's', default=b'nearest').decode()
- transformation_mode = onnx_attr(node,
- 'coordinate_transformation_mode',
- 's',
- default=b'half_pixel').decode()
- nearest_mode = onnx_attr(node, 'nearest_mode', 's', default=b'round_prefer_floor').decode()
- cubic_coeff_a = onnx_attr(node, 'cubic_coeff_a', 'f', default=-0.75)
- attrs = {
- 'mode': mode, 'coordinate_transformation_mode': transformation_mode,
- 'nearest_mode': nearest_mode, 'cube_coeff': cubic_coeff_a
- }
- ONNXResize11Op.update_node_stat(node, attrs)
- else:
- mode = onnx_attr(node, 'mode', 's', default=b'nearest').decode()
- ONNXResize10.update_node_stat(node, {'mode': mode})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/reverse_sequence_ext.py b/tools/mo/openvino/tools/mo/front/onnx/reverse_sequence_ext.py
deleted file mode 100644
index 3e94521c68fddb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/reverse_sequence_ext.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.reverse_sequence import ReverseSequence
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ReverseSequenceExtractor(FrontExtractorOp):
- op = 'ReverseSequence'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- batch_axis = onnx_attr(node, 'batch_axis', 'i', default=1)
- time_axis = onnx_attr(node, 'time_axis', 'i', default=0)
-
- attrs = {
- 'batch_axis': batch_axis,
- 'seq_axis': time_axis,
- }
- ReverseSequence.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/rnn_ext.py b/tools/mo/openvino/tools/mo/front/onnx/rnn_ext.py
deleted file mode 100644
index ea7b21f78bcb3c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/rnn_ext.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array, int64_array
-from openvino.tools.mo.ops.RNN import RNN
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class RNNFrontExtractor(FrontExtractorOp):
- op = 'RNN'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- direction = onnx_attr(node, 'direction', 's', b'forward').decode().lower()
-
- activation_alpha = onnx_attr(node, 'activation_alpha', 'floats',
- default=None, dst_type=lambda x: float32_array(x))
- activation_beta = onnx_attr(node, 'activation_beta', 'floats',
- default=None, dst_type=lambda x: float32_array(x))
- activations = onnx_attr(node, 'activations', 'strings',
- default=['tanh', 'tanh'] if direction == 'bidirectional' else ['tanh'],
- dst_type=lambda x: list(map(lambda s: s.decode(encoding="utf-8").lower(), list(x))))
- clip = onnx_attr(node, 'clip', 'f', default=None)
-
- # Since pytorch generates ONNX bidirectional RNN models with only one activation, duplicating activation
- if direction == 'bidirectional' and len(activations) == 1:
- activations.append(activations[0])
-
- attrs = {
- 'batch_dim': 1,
- 'sequence_dim': 0,
- 'blobs_wrb': True,
- 'has_num_directions': True,
- 'num_layers': 1,
- 'format': 'onnx',
- 'multilayers': False,
- 'gate_order': [0],
-
- # ONNX attrs
- 'activation_alpha': activation_alpha,
- 'activation_beta': activation_beta,
- 'activations': activations,
- 'clip': clip,
- 'direction': direction,
- 'hidden_size': int64_array(onnx_attr(node, 'hidden_size', 'i')),
- }
-
- RNN.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/roialign_ext.py b/tools/mo/openvino/tools/mo/front/onnx/roialign_ext.py
deleted file mode 100644
index 134f6a543cc8e5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/roialign_ext.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.roialign import ROIAlign
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version
-
-
-class ROIAlignExtractor(FrontExtractorOp):
- op = 'ROIAlign'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- mode = onnx_attr(node, 'mode', 's', default=b'avg').decode()
- output_height = onnx_attr(node, 'output_height', 'i', default=1)
- output_width = onnx_attr(node, 'output_width', 'i', default=1)
- sampling_ratio = onnx_attr(node, 'sampling_ratio', 'i', default=0)
- spatial_scale = onnx_attr(node, 'spatial_scale', 'f', default=1.0)
- onnx_opset_version = get_onnx_opset_version(node)
- if onnx_opset_version >= 16:
- aligned_mode = onnx_attr(node, 'coordinate_transformation_mode', 's', default=b'half_pixel').decode()
- if aligned_mode == "output_half_pixel":
- aligned_mode = "asymmetric"
- ROIAlign.update_node_stat(node, {'pooled_h': output_height, 'pooled_w': output_width,
- 'sampling_ratio': sampling_ratio, 'spatial_scale': spatial_scale,
- 'mode': mode, 'aligned_mode': aligned_mode})
- else:
- ROIAlign.update_node_stat(node, {'pooled_h': output_height, 'pooled_w': output_width,
- 'sampling_ratio': sampling_ratio, 'spatial_scale': spatial_scale,
- 'mode': mode})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/roifeatureextractor_ext.py b/tools/mo/openvino/tools/mo/front/onnx/roifeatureextractor_ext.py
deleted file mode 100644
index 35f52981852ae5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/roifeatureextractor_ext.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.ops.roifeatureextractor_onnx import ExperimentalDetectronROIFeatureExtractor
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ExperimentalDetectronROIFeatureExtractorFrontExtractor(FrontExtractorOp):
- op = 'ExperimentalDetectronROIFeatureExtractor'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = dict(output_size=onnx_attr(node, 'output_size', 'i', 7),
- sampling_ratio=onnx_attr(node, 'sampling_ratio', 'i', 2),
- aligned=onnx_attr(node, 'aligned', 'i', 0),
- num_classes=onnx_attr(node, 'num_classes', 'i', 81),
- post_nms_count=onnx_attr(node, 'post_nms_count', 'i', 2000),
- score_threshold=onnx_attr(node, 'score_threshold', 'f', 0.05),
- pyramid_scales=int64_array(onnx_attr(node, 'pyramid_scales', 'ints', [4, 8, 16, 32, 64])),
- )
-
- ExperimentalDetectronROIFeatureExtractor.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/scatter_ext.py b/tools/mo/openvino/tools/mo/front/onnx/scatter_ext.py
deleted file mode 100644
index b6627202dcb6a5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/scatter_ext.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.scatter import ScatterElementsUpdate
-from openvino.tools.mo.ops.scatternd import ScatterNDUpdate
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ScatterExtractor(FrontExtractorOp):
- # deprecated ONNX operation
- op = 'Scatter'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', default=0)
- ScatterElementsUpdate.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class ScatterElementsExtractor(FrontExtractorOp):
- op = 'ScatterElements'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', default=0)
- ScatterElementsUpdate.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class ScatterNDExtractor(FrontExtractorOp):
- op = 'ScatterND'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ScatterNDUpdate.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/shape_ext.py b/tools/mo/openvino/tools/mo/front/onnx/shape_ext.py
deleted file mode 100644
index bd6eea52017850..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/shape_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.shape import Shape
-
-
-class ShapeFrontExtractor(FrontExtractorOp):
- op = 'Shape'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Shape.update_node_stat(node, {'output_type': np.int64})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/size_ext.py b/tools/mo/openvino/tools/mo/front/onnx/size_ext.py
deleted file mode 100644
index 7d61482dc8bfc4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/size_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.size import Size
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SizeExtractor(FrontExtractorOp):
- op = 'Size'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Size.update_node_stat(node, {'output_type': np.int64})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/slice_ext.py b/tools/mo/openvino/tools/mo/front/onnx/slice_ext.py
deleted file mode 100644
index 2710e6270f84fe..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/slice_ext.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import get_onnx_opset_version
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.slice import Slice, AttributedSlice
-from openvino.tools.mo.utils.error import Error
-
-
-class SliceFrontExtractor(FrontExtractorOp):
- op = 'Slice'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- if get_onnx_opset_version(node) < 10:
- starts = int64_array(onnx_attr(node, 'starts', 'ints', default=[]))
- ends = int64_array(onnx_attr(node, 'ends', 'ints', default=[]))
- axes = int64_array(onnx_attr(node, 'axes', 'ints', default=[]))
-
- if len(starts) == 0 or len(ends) == 0:
- raise Error("starts or/and ends are not specified for the node {}".format(node.name))
- if len(axes) == 0:
- axes = np.arange(len(starts), dtype=int)
-
- attrs = {'axes': axes, 'starts': starts, 'ends': ends}
- AttributedSlice.update_node_stat(node, attrs)
- else: # onnx_opset_version >= 10
- Slice.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/softmaxONNX_to_softmax.py b/tools/mo/openvino/tools/mo/front/onnx/softmaxONNX_to_softmax.py
deleted file mode 100644
index 2b72cebbcc4a98..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/softmaxONNX_to_softmax.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.ops.flatten import FlattenONNX
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.softmax import Softmax
-
-
-class SoftmaxONNXFrontReplacer(FrontReplacementOp):
- """
- Replace SoftmaxONNX operation with FlattenONNX -> Softmax -> Reshape subgraph
- """
- op = "SoftMaxONNX"
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.onnx.flattenONNX_to_reshape import FlattenONNXToReshape
- return [FlattenONNXToReshape]
-
- def replace_op(self, graph: Graph, node: Node):
- node_name = node.soft_get('name', node.id)
- assert node.has_valid('axis'), 'The node "{}" does not have mandatory attribute "axis"'.format(node_name)
-
- flatten_node = FlattenONNX(graph, {'name': node_name + '/FlattenONNX_', 'axis': node.axis}).create_node()
- shape_node = Shape(graph, {'name': node_name + '/ShapeOf_'}).create_node()
- softmax_node = Softmax(graph, {'name': node_name + '/Softmax_',
- 'axis': 1,
- 'framework_node_name': node_name,
- 'rename_condition': lambda n: len(n.graph.get_op_nodes(name=node_name)) == 0
- }).create_node()
- reshape_node = Reshape(graph, {}).create_node()
-
- rename_nodes([(node, node_name + '/delete'), (reshape_node, node_name)])
-
- flatten_node.out_port(0).connect(softmax_node.in_port(0))
- softmax_node.out_port(0).connect(reshape_node.in_port(0))
- shape_node.out_port(0).connect(reshape_node.in_port(1))
-
- source = node.in_port(0).get_source()
-
- flatten_node.in_port(0).connect(source)
- shape_node.in_port(0).connect(source)
-
- return [reshape_node.id]
diff --git a/tools/mo/openvino/tools/mo/front/onnx/softmax_ext.py b/tools/mo/openvino/tools/mo/front/onnx/softmax_ext.py
deleted file mode 100644
index 2da163a5489bac..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/softmax_ext.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.softmax import SoftmaxONNX
-from openvino.tools.mo.ops.log_softmax import LogSoftmaxONNX
-
-
-class SoftmaxExtractor(FrontExtractorOp):
- op = 'Softmax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', default=1)
- SoftmaxONNX.update_node_stat(node, {'axis': axis})
- return cls.enabled
-
-
-class LogSoftmaxExtractor(FrontExtractorOp):
- op = 'LogSoftmax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', default=1)
- LogSoftmaxONNX.update_node_stat(node, {'axis': axis})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/softplus_ext.py b/tools/mo/openvino/tools/mo/front/onnx/softplus_ext.py
deleted file mode 100644
index d1e41c2b91616a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/softplus_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import SoftPlus
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SoftPlusExtractor(FrontExtractorOp):
- op = 'Softplus'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- SoftPlus.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/space_to_depth_ext.py b/tools/mo/openvino/tools/mo/front/onnx/space_to_depth_ext.py
deleted file mode 100644
index 681b47eef327ea..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/space_to_depth_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.space_to_depth import SpaceToDepth
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class SpaceToDepthFrontExtractor(FrontExtractorOp):
- op = 'SpaceToDepth'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # update the attributes of the node
- block_size = onnx_attr(node, 'blocksize', 'i', default=None)
- SpaceToDepth.update_node_stat(node, {'block_size': block_size})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/split_ext.py b/tools/mo/openvino/tools/mo/front/onnx/split_ext.py
deleted file mode 100644
index ec9ea965101d95..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/split_ext.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.split import AttributedVariadicSplit, AttributedSplit
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, onnx_get_num_outputs
-
-
-class SplitFrontExtractor(FrontExtractorOp):
- op = 'Split'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = onnx_attr(node, 'axis', 'i', default=0, dst_type=np.int64)
- size_splits = onnx_attr(node, 'split', 'ints', default=None, dst_type=int64_array)
- if size_splits is None:
- AttributedSplit.update_node_stat(node, {
- 'axis': axis,
- 'num_splits': onnx_get_num_outputs(node),
- })
- else:
- AttributedVariadicSplit.update_node_stat(node, {
- 'axis': axis,
- 'size_splits': size_splits,
- })
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/squeeze_ext.py b/tools/mo/openvino/tools/mo/front/onnx/squeeze_ext.py
deleted file mode 100644
index 020b9d14ad85bb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/squeeze_ext.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-class SqueezeFrontExtractor(FrontExtractorOp):
- op = 'Squeeze'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = int64_array(onnx_attr(node, 'axes', 'ints', default=[]))
-
- attrs = {
- 'squeeze_dims': axis if len(axis) != 0 else None
- }
-
- # update the attributes of the node
- Squeeze.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/top_k_ext.py b/tools/mo/openvino/tools/mo/front/onnx/top_k_ext.py
deleted file mode 100644
index e0b7ef5b3bc42f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/top_k_ext.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.topk import TopK
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, onnx_node_has_attr
-
-
-class TopKExtractor(FrontExtractorOp):
- op = 'TopK'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- """
- TopK-1 (k as attribute, required)
- TopK-10 (k as input, no sorting manipulations)
- TopK-11 (k as input, sorting manipulations through `sorted` and `largest` attrs)
- """
- attrs = {
- 'axis': onnx_attr(node, 'axis', 'i', default=-1),
- 'index_element_type': np.int64
- }
- if onnx_node_has_attr(node, 'k'):
- attrs['k'] = onnx_attr(node, 'k', 'i')
- attrs['sort'] = 'value' if onnx_attr(node, 'sorted', 'i', default=1) else 'none'
- attrs['mode'] = 'max' if onnx_attr(node, 'largest', 'i', default=1) else 'min'
-
- TopK.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/topkrois_ext.py b/tools/mo/openvino/tools/mo/front/onnx/topkrois_ext.py
deleted file mode 100644
index 616ee4af9d1f73..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/topkrois_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.topkrois_onnx import ExperimentalDetectronTopKROIs
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class ExperimentalDetectronTopKROIsFrontExtractor(FrontExtractorOp):
- op = 'ExperimentalDetectronTopKROIs'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = dict(max_rois=onnx_attr(node, 'max_rois', 'i', 1000))
- ExperimentalDetectronTopKROIs.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/transpose_ext.py b/tools/mo/openvino/tools/mo/front/onnx/transpose_ext.py
deleted file mode 100644
index 061962c336e009..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/transpose_ext.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-
-
-class TransposeFrontExtractor(FrontExtractorOp):
- op = 'Transpose'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # In case of undefined 'perm' attribute, Transpose operation in ONNX reverse the dimensions
- order = onnx_attr(node, 'perm', 'ints', default=None)
- attrs = {
- 'order': int64_array(order) if order is not None else None,
- 'reverse_order': order is None
- }
- Transpose.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/unsqueeze_ext.py b/tools/mo/openvino/tools/mo/front/onnx/unsqueeze_ext.py
deleted file mode 100644
index 62bcccdc00a6b8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/unsqueeze_ext.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr
-from openvino.tools.mo.ops.expand_dims import ExpandDims
-
-
-class UnsqueezeFrontExtractor(FrontExtractorOp):
- """
- Convert Unsqueeze layer to ExpandDims because the ExpandDims layer has fixed attribute with dimensions to unsqueeze.
- """
- op = 'Unsqueeze'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- axis = int64_array(onnx_attr(node, 'axes', 'ints', default=[]))
-
- ExpandDims.update_node_stat(node, {'expand_axis': axis})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/upsample_ext.py b/tools/mo/openvino/tools/mo/front/onnx/upsample_ext.py
deleted file mode 100644
index 7ebe0c36bd4005..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/upsample_ext.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import math
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.ops.ONNXResize10 import ONNXResize10
-from openvino.tools.mo.ops.upsample import UpsampleOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.onnx.extractors.utils import onnx_attr, get_onnx_opset_version
-from openvino.tools.mo.utils.error import Error
-
-
-class UpsampleFrontExtractor(FrontExtractorOp):
- op = 'Upsample'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- onnx_opset_version = get_onnx_opset_version(node)
- if onnx_opset_version is not None and onnx_opset_version >= 9:
- mode = onnx_attr(node, 'mode', 's', default='nearest', dst_type=lambda x: x.decode())
- ONNXResize10.update_node_stat(node, {'mode': mode})
- else:
- mode = onnx_attr(node, 'mode', 's', default='nearest', dst_type=lambda x: x.decode())
- scales = onnx_attr(node, 'scales', 'floats', dst_type=lambda x: float32_array(x))
- width_scale = onnx_attr(node, 'width_scale', 'f')
- height_scale = onnx_attr(node, 'height_scale', 'f')
-
- supported_modes = ['nearest', 'linear']
- if mode not in supported_modes:
- raise Error(
- 'Error decoding Upsample node {}, mode = {} is not in the list of supported modes {}.',
- node.name,
- mode,
- supported_modes
- )
-
- if scales is not None:
- if scales.shape != (4,):
- raise Error(
- 'Upsample scales attribute is wrong for node {}. Only 4D scales are supported.',
- node.name
- )
- if math.fabs(scales[0] - 1) > 1e-5 or math.fabs(scales[1] - 1) > 1e-5:
- raise Error(
- 'Upsampling of batch and feature dimensions is not supported for node {}.',
- node.name
- )
- height_scale = scales[2]
- width_scale = scales[3]
-
- if (width_scale is None or height_scale is None) and len(node.in_nodes()) != 2:
- raise Error(
- 'One/both of widths_scale = {} and height_scale = {} is not defined for Upsample node {}.',
- width_scale,
- height_scale,
- node.name
- )
-
- UpsampleOp.update_node_stat(node, {'mode': mode, 'height_scale': height_scale,
- 'width_scale': width_scale})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/onnx/where_ext.py b/tools/mo/openvino/tools/mo/front/onnx/where_ext.py
deleted file mode 100644
index 247376456b9cbc..00000000000000
--- a/tools/mo/openvino/tools/mo/front/onnx/where_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class WhereExtractor(FrontExtractorOp):
- op = 'Where'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Select.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/output_cut.py b/tools/mo/openvino/tools/mo/front/output_cut.py
deleted file mode 100644
index d1ef11fdce39e0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/output_cut.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.extractor import add_output_ops
-from openvino.tools.mo.graph.graph import Graph, get_edge_attribute_between_nodes, set_edge_attribute_between_nodes
-
-
-class OutputCut(FrontReplacementPattern):
- enabled = True
- run_not_recursively = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.front.user_data_repack import UserDataRepack
- return [UserDataRepack]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- add_output_ops(graph, graph.graph['packed_outputs'], inputs=graph.graph['user_shapes'])
-
- # For keeping tensor names information for output nodes fake outputs are added
- # to graph during the model loading. In the following code fake outputs are removed
- # and tensor names information is moved to output->Result edge.
- for node in graph.get_op_nodes(needs_removal=True):
- fw_info = None
- in_node = None
- out_nodes_ids = {}
- for in_port_idx in node.in_edges():
- node_idx = node.in_edge(in_port_idx)['in']
- if node_idx in node.in_nodes():
- in_node = node.in_node(node_idx)
- fw_info_value = get_edge_attribute_between_nodes(in_node, node, 'fw_tensor_debug_info')
- if fw_info_value:
- fw_info = fw_info_value
- break
- if fw_info is not None and in_node is not None:
- for out_idx in in_node.out_nodes():
- out_node = in_node.out_node(out_idx)
- out_nodes_ids[out_idx] = out_node.id
-
- graph.erase_node(node)
-
- if fw_info is not None and in_node is not None:
- for out_idx in in_node.out_nodes():
- if node.id == out_nodes_ids[out_idx]:
- set_edge_attribute_between_nodes(in_node, in_node.out_node(out_idx),
- 'fw_tensor_debug_info', fw_info)
diff --git a/tools/mo/openvino/tools/mo/front/override_batch.py b/tools/mo/openvino/tools/mo/front/override_batch.py
deleted file mode 100644
index 9079c576dd6370..00000000000000
--- a/tools/mo/openvino/tools/mo/front/override_batch.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.infer import override_batch
-
-
-class OverrideBatch(FrontReplacementPattern):
- enabled = True
- run_not_recursively = True
-
- def find_and_replace_pattern(self, graph: Graph):
- override_batch(graph, graph.graph['cmd_params'].batch)
diff --git a/tools/mo/openvino/tools/mo/front/pass_separator.py b/tools/mo/openvino/tools/mo/front/pass_separator.py
deleted file mode 100644
index 69a5b174b6a028..00000000000000
--- a/tools/mo/openvino/tools/mo/front/pass_separator.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-
-
-class FrontStart(FrontReplacementPattern):
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
-
-class FrontFinish(FrontReplacementPattern):
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
diff --git a/tools/mo/openvino/tools/mo/front/rank_decomposer.py b/tools/mo/openvino/tools/mo/front/rank_decomposer.py
deleted file mode 100644
index 96c61c1961c929..00000000000000
--- a/tools/mo/openvino/tools/mo/front/rank_decomposer.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-class RankDecomposer(FrontReplacementOp):
- op = 'Rank'
- enabled = True
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- node = match['op']
- name = node.soft_get('name', node.id)
-
- assert node.has_valid('output_type'), \
- 'Rank node should have `output_type` attribute, but it`s not for node {}'.format(name)
-
- shape_of = Shape(graph, {'name': name + '/shape_of', 'output_type': node.output_type}).create_node()
- rank_1d = Shape(graph, {'name': name + '/rank_of', 'output_type': node.output_type}).create_node()
- rank_0d = create_op_node_with_second_input(
- graph, Squeeze, int64_array(0), {'name': name + '/0d_rank_of'}, rank_1d)
-
- shape_of.out_port(0).connect(rank_1d.in_port(0))
- node.out_port(0).get_connection().set_source(rank_0d.out_port(0))
- node.in_port(0).get_connection().set_destination(shape_of.in_port(0))
-
- rename_nodes([(node, name + '/ToBeDeleted'), (rank_0d, name)])
diff --git a/tools/mo/openvino/tools/mo/front/reciprocal.py b/tools/mo/openvino/tools/mo/front/reciprocal.py
deleted file mode 100644
index eb6918e3d51d4b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/reciprocal.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.elementwise import Pow
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class ReciprocalReplacer(FrontReplacementOp):
- op = "Reciprocal"
- enabled = True
-
- def replace_op(self, graph: Graph, node: Node):
- const = Const(graph, dict(value=mo_array(-1.), name=node.name + '/reciprocal_pow_const_')).create_node()
- reciprocal = Pow(graph, {'name': node.name + '/reciprocal_pow_'}).create_node()
- node.in_port(0).get_connection().set_destination(reciprocal.in_port(0))
- const.out_port(0).connect(reciprocal.in_port(1))
- return [reciprocal.id]
diff --git a/tools/mo/openvino/tools/mo/front/reduce_axis_normalizer.py b/tools/mo/openvino/tools/mo/front/reduce_axis_normalizer.py
deleted file mode 100644
index 898f696ace01ed..00000000000000
--- a/tools/mo/openvino/tools/mo/front/reduce_axis_normalizer.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ReduceOps import reduce_map
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.ops.rank import Rank
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class ReduceAxisNormalizer(FrontReplacementSubgraph):
- """
- Reduce operation requires information about axis, that is represented in original frameworks differently: as an
- operation attribute or as a 1-st input port value. ReduceAxisNormalizer adds second input to Reduce operations with
- axes to normalize if axes are specified as an attribute.
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('reduce', dict(kind='op', op=lambda op: op in reduce_map))
- ],
- edges=[]
- )
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
- node = match['reduce']
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- if len(connected_in_ports) == 1:
- node_name = node.soft_get('name', node.id)
-
- # if the 'axis' is None then we still add a second input to the layer with a 1D array with 1 element equal
- # to None. The infer function handles this case because the input shape is known at this stage only
- if node.has_valid('axis'):
- const = Const(graph, {'name': node_name + '/axis', 'value': node.axis}).create_node()
- node.add_input_port(1, skip_if_exist=True)
- const.out_port(0).connect(node.in_port(1))
- del graph.node[node.id]['axis']
- else:
- # The default (if there is no 'axis') is to reduce over all the dimensions of the input tensor.
- axes = create_op_with_const_inputs(graph, Range, {0: int64_array(0), 2: int64_array(1)},
- dict(name=node_name + '/axes'))
- end_of_range = Rank(graph, dict(name=node_name + '/range_end')).create_node()
- node.in_port(0).get_connection().get_source().connect(end_of_range.in_port(0))
- end_of_range.out_port(0).connect(axes.in_port(1))
-
- node.add_input_port(1, skip_if_exist=True)
- axes.out_port(0).connect(node.in_port(1))
diff --git a/tools/mo/openvino/tools/mo/front/reshape_dim_normalizer.py b/tools/mo/openvino/tools/mo/front/reshape_dim_normalizer.py
deleted file mode 100644
index 7470289ea80202..00000000000000
--- a/tools/mo/openvino/tools/mo/front/reshape_dim_normalizer.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.pass_separator import FrontStart
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.utils.error import Error
-
-
-class ReshapeDimNormalizer(FrontReplacementSubgraph):
- """
- Reshape operation requires information about output dimensions, that is represented in original frameworks
- differently:
- - by layer parameter
- - by 1-port input value
-
- This transformation reforms Reshape operations to store dim info in 1-port input.
- """
- enabled = True
- force_shape_inference = True
-
- def run_before(self):
- return [FrontStart]
-
- def run_after(self):
- from openvino.tools.mo.front.freeze_placeholder_value import FreezePlaceholderValue
- return [FreezePlaceholderValue]
-
- def pattern(self):
- return dict(
- nodes=[
- ('reshape', dict(kind='op', op='Reshape'))
- ],
- edges=[]
- )
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
- node = match['reshape']
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- if len(connected_in_ports) == 1:
- if node.has('dim'):
- const = Const(graph, {'value': node.dim}).create_node()
- node.add_input_port(1, skip_if_exist=True)
- const.out_port(0).connect(node.in_port(1))
- del node['dim']
- else:
- raise Error('The `dim` attribute for node {} is not set'.format(node.op))
diff --git a/tools/mo/openvino/tools/mo/front/restore_ports.py b/tools/mo/openvino/tools/mo/front/restore_ports.py
deleted file mode 100644
index 9c2c5db21ca6ff..00000000000000
--- a/tools/mo/openvino/tools/mo/front/restore_ports.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-
-
-class RestorePorts(FrontReplacementSubgraph):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.input_cut import InputCut
- return [InputCut]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- for node_id, attrs in graph.nodes(data=True):
- if '_in_ports' not in attrs:
- attrs['_in_ports'] = set()
- if '_out_ports' not in attrs:
- attrs['_out_ports'] = set()
-
- for u, v, k, d in graph.edges(data=True, keys=True):
- from_node_attrs = graph.node[u]
- to_node_attrs = graph.node[v]
- is_control_flow = 'control_flow_edge' in d and d['control_flow_edge'] is True
-
- in_port_id = d['in'] if not is_control_flow else 'control_flow_' + str(d['in'])
- out_port_id = d['out'] if not is_control_flow else 'control_flow_' + str(d['out'])
-
- to_node_attrs['_in_ports'].update({in_port_id: {'control_flow': is_control_flow}})
- from_node_attrs['_out_ports'].update({out_port_id: {'control_flow': is_control_flow}})
-
- graph.stage = 'front'
diff --git a/tools/mo/openvino/tools/mo/front/scatter_normalizer.py b/tools/mo/openvino/tools/mo/front/scatter_normalizer.py
deleted file mode 100644
index 9982247b862b83..00000000000000
--- a/tools/mo/openvino/tools/mo/front/scatter_normalizer.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class ScatterNormalizer(FrontReplacementPattern):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(is_scatter=True):
- name = node.soft_get('name', node.id)
- input_ports_count = len([port for port in node.in_ports().values() if not port.disconnected()])
- has_axis = node.has_valid('axis')
-
- if has_axis:
- assert input_ports_count == 3, \
- '{} node {} has unexpected number of input ports {}'.format(node.op, name, input_ports_count)
- const = Const(graph, {'name': name + '/axis', 'value': np.int64(node.axis)}).create_node()
- node.add_input_port(3, skip_if_exist=True)
- node.in_port(3).connect(const.out_port(0))
- del node['axis']
- else:
- assert input_ports_count == 4, \
- '{} node {} has unexpected number of input ports {}'.format(node.op, name, input_ports_count)
diff --git a/tools/mo/openvino/tools/mo/front/softmax.py b/tools/mo/openvino/tools/mo/front/softmax.py
deleted file mode 100644
index 8bc31506116ba4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/softmax.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.reduce_axis_normalizer import ReduceAxisNormalizer
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.softmax import Softmax
-
-
-class SoftmaxFromKeras(FrontReplacementSubgraph):
- """
- The transformation looks for the pattern that Keras produces for SoftMax layer. The transformation works if the
- softmax is performed over one pre-defined axis.
- """
- enabled = True
-
- def run_after(self):
- return [ReduceAxisNormalizer]
-
- def pattern(self):
- return dict(
- nodes=[
- ('input', dict()),
- ('reduce_max', dict(op='ReduceMax')),
- ('reduce_indices_max', dict(op='Const', value=lambda x: x is not None and x.size != 0)),
- ('sub', dict(op='Sub')),
- ('exp', dict(op='Exp')),
- ('reduce_sum', dict(op='ReduceSum')),
- ('reduce_indices_sum', dict(op='Const', value=lambda x: x is not None and x.size != 0)),
- ('div', dict(op='Div')),
- ],
- edges=[
- ('input', 'sub', {'in': 0}),
- ('input', 'reduce_max', {'in': 0}),
- ('reduce_indices_max', 'reduce_max', {'in': 1}),
- ('reduce_max', 'sub', {'in': 1}),
- ('sub', 'exp', {'in': 0}),
- ('exp', 'div', {'in': 0}),
- ('exp', 'reduce_sum', {'in': 0}),
- ('reduce_indices_sum', 'reduce_sum', {'in': 1}),
- ('reduce_sum', 'div', {'in': 1}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
-
- reduce_max_axis = match['reduce_indices_max'].value
- reduce_sum_axis = match['reduce_indices_sum'].value
-
- if reduce_max_axis.ndim == 0:
- reduce_max_axis = reduce_max_axis.reshape([1])
-
- if reduce_sum_axis.ndim == 0:
- reduce_sum_axis = reduce_sum_axis.reshape([1])
-
- if len(reduce_max_axis) != 1:
- log.info('The reductions indices contain more than 1 element. Cannot convert to Softmax.')
- return
-
- if not np.array_equal(reduce_max_axis, reduce_sum_axis):
- log.info('The reduce indices are not equal: {} vs {}. Cannot convert to Softmax'
- ''.format(reduce_max_axis, reduce_sum_axis))
- return
-
- softmax = Softmax(graph, {'name': match['input'].name + '/Softmax', 'axis': reduce_sum_axis[0]}).create_node()
- match['input'].out_port(0).connect(softmax.in_port(0))
- match['div'].out_port(0).get_connection().set_source(softmax.out_port(0))
-
- log.debug('Successfully created SoftMax node')
diff --git a/tools/mo/openvino/tools/mo/front/split_normalizer.py b/tools/mo/openvino/tools/mo/front/split_normalizer.py
deleted file mode 100644
index 7c17d2f474893e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/split_normalizer.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.split import Split, VariadicSplit
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.utils.error import Error
-
-
-class SqueezeAxis(FrontReplacementOp):
- """
- Split-like operations from original frameworks split tensor by a certain `axis` dimension, removing
- dimension over which splitting is performed. The "Split" layer of OV doesn't do that.
- This replacer inserts Squeeze operation for each output of the Split nodes to remove the dimension.
-
- It is applicable to Unpack from TF operation and MxNet SliceChannel
- """
- enabled = True
-
- def run_before(self):
- return [AttributedSplitToSplit, AttributedVariadicSplitToVariadicSplit]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(squeeze_axis=True):
- name = node.soft_get('name', node.id)
- for out_port in node.out_ports().values():
- if node.has_valid('axis'):
- squeeze_node = create_op_with_const_inputs(graph, Squeeze, {1: mo_array(node.axis)},
- {'name': name + '/Squeeze_'})
- out_port.get_connection().insert_node(squeeze_node)
- elif node.is_in_port_connected(1):
- squeeze_node = Squeeze(graph, {'name': name + '/Squeeze_'}).create_node()
- out_port.get_connection().insert_node(squeeze_node)
- node.in_port(1).get_connection().add_destination(squeeze_node.in_port(1))
- else:
- raise Error('Unknown axis to squeeze for node {}'.format(name))
-
-
-class SplitInputsReconnect(FrontReplacementSubgraph):
- """
- Reconnect input ports to fit IR specification
-
- The Split operation in original frameworks (e.g. TF) may have different semantics than IR specification states:
- IE: 0 - input data to Split, 1 - axis of splitting
- TF: 0 - axis of splitting, 1 - input data to Split
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='Split', input_port=1):
- axis_src = node.in_port(0).get_source()
- node.in_port(0).disconnect()
- node.in_port(1).get_connection().set_destination(node.in_port(0))
- node.in_port(1).connect(axis_src)
- del node['input_port']
-
-
-class AttributedSplitToSplit(FrontReplacementSubgraph):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='AttributedSplit'):
- name = node.soft_get('name', node.id)
-
- axis = node.soft_get('axis', None)
- assert axis is not None, \
- 'AttributedSplit should have `axis` parameter set, but it`s not for node {}'.format(name)
-
- num_splits = node.soft_get('num_splits', None)
- assert num_splits is not None, \
- 'AttributedSplit should have `num_splits` parameter set, but it`s not for node {}'.format(name)
-
- split = create_op_with_const_inputs(graph, Split, {1: np.int64(axis)},
- {'name': name + '/Split', 'num_splits': num_splits})
-
- for idx, port in node.out_ports().items():
- port.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 AttributedVariadicSplitToVariadicSplit(FrontReplacementSubgraph):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='AttributedVariadicSplit'):
- name = node.soft_get('name', node.id)
-
- axis = node.soft_get('axis', None)
- assert axis is not None, \
- 'AttributedVariadicSplit should have `axis` parameter set, but it`s not for node {}'.format(name)
-
- size_splits = node.soft_get('size_splits', None)
- assert size_splits is not None, \
- 'AttributedVariadicSplit should have `size_splits` parameter set, but it`s not for node {}'.format(name)
-
- split = create_op_with_const_inputs(graph, VariadicSplit, {1: np.int64(axis), 2: size_splits},
- {'name': name + '/VariadicSplit', 'out_ports_count': len(size_splits)})
-
- for idx, port in node.out_ports().items():
- port.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 VariadicSplitInputsSwap(FrontReplacementSubgraph):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='VariadicSplit', swap_axis_and_split_size_inputs=True):
- axis_src = node.in_port(2).get_source()
- node.in_port(2).disconnect()
- node.in_port(1).get_connection().set_destination(node.in_port(2))
- node.in_port(1).connect(axis_src)
diff --git a/tools/mo/openvino/tools/mo/front/sub.py b/tools/mo/openvino/tools/mo/front/sub.py
deleted file mode 100644
index c8ee1e2a932b34..00000000000000
--- a/tools/mo/openvino/tools/mo/front/sub.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_node
-
-
-class Sub(FrontReplacementPattern):
- # This transformation is called directly from the 'openvino/tools/mo/middle/fusings.py' transformation
- enabled = False
-
- @staticmethod
- def sub_to_add_replacement(sub: Node):
- # we execute this transformation for V10 IR later on middle phase despite graph_condition
- # so we prevent Sub replacement on shape-calculating sub-graphs
- if sub.in_port(0).data.get_value() is not None and sub.in_port(1).data.get_value() is not None:
- return
-
- graph = sub.graph
- name = sub.soft_get('name', sub.id)
-
- # keep Add name the same as Sub -- because of mathematical equality of output tensors
- rename_node(node=sub, name=name + '/to_be_removed')
-
- # reconnect Sub in(out)puts to Add
- add = Add(graph, {'name': name}).create_node()
- rename_node(add, name)
-
- sub.in_port(0).get_connection().set_destination(add.in_port(0))
- sub.in_port(1).get_connection().set_destination(add.in_port(1))
- sub.out_port(0).get_connection().set_source(add.out_port(0))
-
- # restore mathematical equivalence to Sub operation: Sub(A, B) = Add(A, Mul(B, -1))
- const_dtype = sub.soft_get('data_type', np.float32)
- negate = create_op_with_const_inputs(graph, Mul, {1: mo_array(-1, dtype=const_dtype)}, {'name': name + '/neg_'})
- add.in_port(1).get_connection().insert_node(negate)
-
- def find_and_replace_pattern(self, graph: Graph):
- for sub in graph.get_op_nodes(op='Sub'):
-
- # The attribute zero_point_sub indicates that the node can be used in ConvertQuantizeDequantize
- # transformation (offline transformations). Pattern of such transformation expects Subtract node.
- if sub.has_and_set('zero_point_sub'):
- continue
- self.sub_to_add_replacement(sub)
diff --git a/tools/mo/openvino/tools/mo/front/subgraph_matcher.py b/tools/mo/openvino/tools/mo/front/subgraph_matcher.py
deleted file mode 100644
index 44b81f54399442..00000000000000
--- a/tools/mo/openvino/tools/mo/front/subgraph_matcher.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import re
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils.custom_replacement_config import CustomReplacementDescriptor
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.graph import nodes_matching_name_pattern, sub_graph_between_nodes
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-def find_object_by_pattern(names: list, pattern: str):
- """
- :param names: list of names to find objects from.
- :param pattern: regular expression for the name.
- :return: list of matched objects.
- """
- compiled_pattern = re.compile(pattern)
- return [name for name in names if re.match(compiled_pattern, name)]
-
-
-class SubgraphMatch(object):
- """
- Class providing information about matched sub-graph.
- """
-
- def __init__(self, graph: Graph, replacement_desc: CustomReplacementDescriptor, matched_nodes: list,
- inputs_order: list, outputs_order: list, prefix: str):
- """
- Creates instance of a SubgraphMatch class from the provided configuration.
- :param graph: networkx graph.
- :param replacement_desc: CustomReplacementDescriptor object describing sub-graph.
- :param matched_nodes: list of matched nodes.
- :param inputs_order: nodes description in the format described in the FrontReplacementFromConfigFileSubGraph.
- :param outputs_order: nodes description in the format described in the FrontReplacementFromConfigFileSubGraph.
- :param prefix: optional prefix of the node names. Is not used in the sub-graph match by points.
- """
- self._input_nodes_map = dict()
- self._output_nodes_map = dict()
- self._matched_nodes_names = matched_nodes
- self.graph = graph
- self.custom_replacement_desc = replacement_desc
- self.scope = prefix
-
- for sub_graph_input_port, input_desc in enumerate(inputs_order):
- for node_pattern, node_in_port in input_desc:
- node = self.node_by_pattern(node_pattern)
- if node is not None:
- self._add_input_node(node.id, node_in_port, sub_graph_input_port)
-
- for sub_graph_output_port, (node_pattern, out_port) in enumerate(outputs_order):
- node = self.node_by_pattern(node_pattern)
- if node is not None:
- self._add_output_node(node.id, out_port, sub_graph_output_port)
-
- def matched_nodes_names(self):
- """
- Returns list of node names in the matched sub-graph.
- :return: list of node names in the matched sub-graph.
- """
- return self._matched_nodes_names
-
- def inputs_count(self):
- """
- Returns number of inputs for the matched sub-graph. Only unique input tensors are considered, thus if the same
- tensor is consumed by two or more input nodes of the sub-graph it is counted only once.
- :return: Number or unique input tensors.
- """
- return len(self._input_nodes_map.keys())
-
- def outputs_count(self):
- """
- Returns number of outputs for the matched sub-graph. Only unique output tensors are considered, thus if the same
- tensor is consumed by two or more nodes outside of the sub-graph it is counted only once.
- :return: Number or unique input tensors.
- """
- return len(self._output_nodes_map.keys())
-
- def input_nodes(self, port: int):
- """
- Returns list of tuples where the first element is a Node of the sub-graph and the second is the input port for
- that node. Each node of this list gets the same input tensor through the input port with number 'port' of the
- sub-graph.
-
- For example, if the returned list requested for port 'portSG' is the following: [(NodeA, portA), (nodeB, portB)]
- then the same tensor is passed to node 'NodeA' as input with number 'portA' and node 'nodeB' as input with
- number 'portB' for the sub-graph input with number 'portSG'.
- :param port: input port of the sub-graph.
- :return: list describing nodes of the sub-graph getting tensor through the specified port.
- """
- return self._input_nodes_map[port]
-
- def single_input_node(self, port: int):
- """
- The function does the same as function 'input_nodes' but it relies on fact that there is just one node that
- gets input tensor for sub-graph input with number 'port', so it return just tuple (Node, nodePort) or raises
- exception if the amount of nodes is not equal to 1.
- :param port: input port of the sub-graph.
- :return: tuple describing node of the sub-graph getting tensor through the specified port.
- """
- input_nodes = self.input_nodes(port)
- if len(input_nodes) != 1:
- raise Error('The amount of input nodes for port "{}" is not equal to 1. '.format(port) +
- refer_to_faq_msg(33))
- return input_nodes[0]
-
- def output_node(self, port: int):
- """
- Returns a tuple where the first element is a Node of the sub-graph and the second is the output port of that
- node. Th node produces output tensor through the output port with number 'port' of the sub-graph.
- :param port: output port of the sub-graph.
- :return: tuple describing node of the sub-graph producing sub-graph output tensor through the specified port.
- """
- return self._output_nodes_map[port]
-
- def node_by_pattern(self, pattern: str):
- """
- Returns Node from the list of sub-graph nodes matching node name regular expression 'pattern'. If there are more
- than one nodes matched then the function raises exception.
- :param pattern: the regular expression for the node name.
- :return: matched Node.
- """
- if self.scope != '':
- if self.scope[-1] == '/':
- pattern = self.scope + pattern
- else:
- pattern = self.scope + '/' + pattern
- found_names = find_object_by_pattern(self._matched_nodes_names, pattern)
- if len(found_names) > 1:
- raise Error('The amount of nodes matched pattern "{}" is more than 1. '.format(pattern) +
- refer_to_faq_msg(78))
- if len(found_names) == 0:
- return None
- return Node(self.graph, found_names[0])
-
- def _add_input_node(self, node_name: str, node_port: int, sub_graph_input_port: int):
- self._input_nodes_map.setdefault(sub_graph_input_port, []).append((Node(self.graph, node_name), node_port))
-
- def _add_output_node(self, node_name: str, node_port: int, sub_graph_output_port: int):
- if sub_graph_output_port in self._output_nodes_map:
- raise Error('Output node for port "{}" has already been specified. '.format(sub_graph_output_port) +
- refer_to_faq_msg(34))
- self._output_nodes_map[sub_graph_output_port] = (Node(self.graph, node_name), node_port)
-
-
-# TODO looks like this class is not needed. Can be implemented as pure functions.
-class SubgraphMatcher(object):
- def __init__(self, replacement_descriptor: CustomReplacementDescriptor):
- self.replacement_desc = replacement_descriptor
-
- def _match_sub_graph_for_scope(self, graph: Graph, scope_pattern: str):
- """
- :param graph: networkx graph to find sub-graph in.
- :param scope_pattern: regular expression specifying sub-graph scope.
- :return: an object describing matched sub-graph.
- """
- inputs_order = self.replacement_desc.get_inputs_description()
- outputs_order = self.replacement_desc.get_outputs_description()
-
- for list_nodes in inputs_order:
- for node_name_pattern, port in list_nodes:
- if len(find_object_by_pattern(graph.nodes(), '.*' + node_name_pattern)) == 0:
- log.info('Node "{} does not exist in the graph". Failed to match sub-graph by scope "{}".'.format(
- node_name_pattern, self.replacement_desc.id))
- return None
-
- matched_nodes = nodes_matching_name_pattern(graph, scope_pattern)
- if len(matched_nodes) == 0:
- log.info('There are no instances of the sub-graph by scope "{}"'.format(scope_pattern))
- return None
-
- return SubgraphMatch(graph, self.replacement_desc, matched_nodes, inputs_order, outputs_order, scope_pattern)
-
- def _match_sub_graph_for_points(self, graph: Graph):
- """
- :param graph: networkx graph to find sub-graph in.
- :return: an object describing matched sub-graph.
- """
- start_points = self.replacement_desc.get_internal_input_nodes(graph)
- end_points = self.replacement_desc.get_internal_output_nodes(graph)
- # check that start and end points exist in the graph
- for node_name in start_points + end_points:
- if node_name not in graph.nodes():
- log.info('Node "{}" does not exist in the graph. Failed to match sub-graph by points "{}".'.format(
- node_name, self.replacement_desc.id))
- return None
-
- matched_nodes = sub_graph_between_nodes(graph, start_points, end_points, include_control_flow=False)
- return SubgraphMatch(graph, self.replacement_desc, matched_nodes,
- self.replacement_desc.get_inputs_description(),
- self.replacement_desc.get_outputs_description(), '')
-
- def matched_sub_graph_instances(self, graph: Graph):
- """
- Generator to product all instances of matched sub-graphs.
- :param graph: graph to find instances in.
- :return: generator producing SubGraphMatch objects.
- """
- if self.replacement_desc.match_kind == 'points': # instance is specified with lists of start/end nodes
- match = self._match_sub_graph_for_points(graph)
- if match is not None:
- yield match
- elif self.replacement_desc.match_kind == 'scope': # instance is specified with a node name pattern
- for instance in self.replacement_desc.sub_graph_instances():
- match = self._match_sub_graph_for_scope(graph, instance)
- if match is not None:
- yield match
- else:
- raise Error('Unsupported match kind "{}". Match kinds "points" or "scope" are supported only. '.format(
- self.replacement_desc.match_kind) +
- refer_to_faq_msg(35))
diff --git a/tools/mo/openvino/tools/mo/front/tf/AutomlEfficientDet.py b/tools/mo/openvino/tools/mo/front/tf/AutomlEfficientDet.py
deleted file mode 100644
index b02c54f1627d4e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/AutomlEfficientDet.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.Pack import Pack
-from openvino.tools.mo.front.TransposeOrderNormalizer import TransposeOrderNormalizer
-from openvino.tools.mo.front.eltwise_n import EltwiseNReplacement
-from openvino.tools.mo.front.tf.pad_tf_to_pad import PadTFToPad
-from openvino.tools.mo.ops.DetectionOutput import DetectionOutput
-from openvino.tools.mo.ops.activation_ops import Sigmoid
-from openvino.tools.mo.ops.priorbox_clustered import PriorBoxClusteredOp
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mo_array
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileGeneral
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.result import Result
-
-
-class EfficientDet(FrontReplacementFromConfigFileGeneral):
- replacement_id = 'AutomlEfficientDet'
- run_not_recursively = True
-
- def run_before(self):
- from openvino.tools.mo.front.ExpandDimsToUnsqueeze import ExpandDimsToUnsqueeze
- return [ExpandDimsToUnsqueeze, Pack, TransposeOrderNormalizer, PadTFToPad, EltwiseNReplacement]
-
- class AnchorGenerator:
- def __init__(self, min_level, aspect_ratios, num_scales, anchor_scale):
- self.min_level = min_level
- self.aspect_ratios = aspect_ratios
- self.anchor_scale = anchor_scale
- self.scales = [2 ** (float(s) / num_scales) for s in range(num_scales)]
-
- def get(self, layer_id):
- widths = []
- heights = []
- for s in self.scales:
- for a in self.aspect_ratios:
- base_anchor_size = 2 ** (self.min_level + layer_id) * self.anchor_scale
- heights.append(base_anchor_size * s * a[1])
- widths.append(base_anchor_size * s * a[0])
- return widths, heights
-
- def transform_graph(self, graph: Graph, replacement_descriptions: dict):
- parameter_node = graph.get_op_nodes(op='Parameter')[0]
- parameter_node['data_type'] = data_type_str_to_np(parameter_node.graph.graph['cmd_params'].data_type)
-
- # remove existing Result operations to remove unsupported sub-graph
- graph.remove_nodes_from([node.id for node in graph.get_op_nodes(op='Result')] + ['detections'])
-
- # determine if the op which is a input/final result of mean value and scale applying to the input tensor
- # then connect it to the input of the first convolution of the model, so we remove the image pre-processing
- # which includes padding and resizing from the model
- preprocessing_input_node_id = replacement_descriptions['preprocessing_input_node']
- assert preprocessing_input_node_id in graph.nodes, 'The node with name "{}" is not found in the graph. This ' \
- 'should be a last node before image normalization and is specified' \
- ' in the json file.'.format(preprocessing_input_node_id)
- preprocessing_input_node = Node(graph, preprocessing_input_node_id)
- consumer_node = preprocessing_input_node.out_port(0).get_connection().get_destination().node
- consumer_node.in_port(0).get_connection().set_source(parameter_node.out_port(0))
-
- preprocessing_output_node_id = replacement_descriptions['preprocessing_output_node']
- assert preprocessing_output_node_id in graph.nodes, 'The node with name "{}" is not found in the graph. This ' \
- 'node should provide scaled image output and is specified' \
- ' in the json file.'.format(preprocessing_output_node_id)
- preprocessing_output_node = Node(graph, preprocessing_output_node_id)
- preprocessing_output_node.out_port(0).disconnect()
-
- convolution_nodes = [n for n in graph.pseudo_topological_sort() if n.soft_get('type') == 'Convolution']
- convolution_nodes[0].in_port(0).get_connection().set_source(preprocessing_output_node.out_port(0))
-
- # create prior boxes (anchors) generator
- aspect_ratios = replacement_descriptions['aspect_ratios']
- assert len(aspect_ratios) % 2 == 0
- aspect_ratios = list(zip(aspect_ratios[::2], aspect_ratios[1::2]))
- priors_generator = self.AnchorGenerator(min_level=int(replacement_descriptions['min_level']),
- aspect_ratios=aspect_ratios,
- num_scales=int(replacement_descriptions['num_scales']),
- anchor_scale=replacement_descriptions['anchor_scale'])
-
- prior_boxes = []
- for i in range(100):
- inp_name = 'box_net/box-predict{}/BiasAdd'.format('_%d' % i if i else '')
- if inp_name not in graph:
- break
- widths, heights = priors_generator.get(i)
- prior_box_op = PriorBoxClusteredOp(graph, {'width': mo_array(widths),
- 'height': mo_array(heights),
- 'clip': 0, 'flip': 0,
- 'variance': replacement_descriptions['variance'],
- 'offset': 0.5})
- prior_boxes.append(prior_box_op.create_node([Node(graph, inp_name), parameter_node]))
-
- # concatenate prior box operations
- concat_prior_boxes = Concat(graph, {'axis': -1}).create_node()
- for idx, node in enumerate(prior_boxes):
- concat_prior_boxes.add_input_port(idx)
- concat_prior_boxes.in_port(idx).connect(node.out_port(0))
-
- conf = Sigmoid(graph, dict(name='concat/sigmoid')).create_node([Node(graph, 'concat')])
- reshape_size_node = Const(graph, {'value': int64_array([0, -1])}).create_node([])
- logits = Reshape(graph, dict(name=conf.name + '/Flatten')).create_node([conf, reshape_size_node])
- deltas = Reshape(graph, dict(name='concat_1/Flatten')).create_node([Node(graph, 'concat_1'), reshape_size_node])
-
- # revert convolution boxes prediction weights from yxYX to xyXY (convolutions share weights and bias)
- weights = Node(graph, 'box_net/box-predict/pointwise_kernel')
- weights.value = weights.value.reshape(-1, 4)[:, [1, 0, 3, 2]].reshape(weights.shape)
- bias = Node(graph, 'box_net/box-predict/bias')
- bias.value = bias.value.reshape(-1, 4)[:, [1, 0, 3, 2]].reshape(bias.shape)
-
- detection_output_node = DetectionOutput(graph, dict(
- name='detections',
- share_location=1,
- background_label_id=int(replacement_descriptions['num_classes']) + 1,
- nms_threshold=replacement_descriptions['nms_threshold'],
- confidence_threshold=replacement_descriptions['confidence_threshold'],
- top_k=100,
- keep_top_k=100,
- code_type='caffe.PriorBoxParameter.CENTER_SIZE',
- )).create_node([deltas, logits, concat_prior_boxes])
-
- output_op = Result(graph, dict(name='output'))
- output_op.create_node([detection_output_node])
diff --git a/tools/mo/openvino/tools/mo/front/tf/BatchMatMul_ext.py b/tools/mo/openvino/tools/mo/front/tf/BatchMatMul_ext.py
deleted file mode 100644
index e4b872a15f2250..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/BatchMatMul_ext.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.MatMul import MatMul
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class BatchMatMulExtractor(FrontExtractorOp):
- op = 'BatchMatMul'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attr = node.pb.attr
- attrs = {
- 'transpose_a': int(attr['adj_x'].b),
- 'transpose_b': int(attr['adj_y'].b),
- }
- MatMul.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class BatchMatMulV2Extractor(FrontExtractorOp):
- op = 'BatchMatMulV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attr = node.pb.attr
- attrs = {
- 'transpose_a': int(attr['adj_x'].b),
- 'transpose_b': int(attr['adj_y'].b),
- }
- MatMul.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/BatchToSpaceNDToUpsample.py b/tools/mo/openvino/tools/mo/front/tf/BatchToSpaceNDToUpsample.py
deleted file mode 100644
index 9d2a3fb5ac2568..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/BatchToSpaceNDToUpsample.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.upsample import UpsampleOp
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph, Node
-
-
-class BatchToSpaceToUpsample(FrontReplacementSubgraph):
- """
- The transformation looks for pattern that performs NX upscale of the input image specified in the NHWC layout.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.tf.space_to_batch import BatchToSpaceNormalizer
- return [BatchToSpaceNormalizer]
-
- @staticmethod
- def pattern(**kwargs):
- return dict(
- nodes=[
- ('transpose', dict(op='Transpose')),
- ('expand_dims', dict(op='Unsqueeze')),
- ('tile', dict(op='Tile')),
- ('batch_to_space_nd', dict(op='BatchToSpace')),
- ('strided_slice', dict(op='StridedSlice')),
- ('transpose_back', dict(op='Transpose')),
- ],
- edges=[
- ('transpose', 'expand_dims', {'out': 0}),
- ('expand_dims', 'tile', {'out': 0}),
- ('tile', 'batch_to_space_nd', {'out': 0}),
- ('batch_to_space_nd', 'strided_slice', {'out': 0}),
- ('strided_slice', 'transpose_back', {'out': 0})
- ]
- )
-
- @staticmethod
- def replace_sub_graph(graph: Graph, match: dict, **kwargs):
- def _input_node_value(node: Node, port_ind: int):
- input_node = node.in_port(port_ind).get_source().node
- return input_node.value if input_node.op == 'Const' else None
-
- transpose = match['transpose']
- transpose_order = _input_node_value(transpose, 1)
- if transpose_order is None or not np.all(np.equal(transpose_order, int64_array([1, 2, 3, 0]))):
- log.debug('The transpose order {} for node {} is not equal to [1, 2, 3, 0]. Cannot apply '
- 'BatchToSpaceToUpsample transformation.'.format(transpose_order, transpose.name))
- return
-
- expand_axis = match['expand_dims']
- expand_axis_value = _input_node_value(expand_axis, 1)
- if expand_axis_value != 0:
- log.debug('The expand axis {} for node {} is not equal to 0. Cannot apply BatchToSpaceToUpsample '
- 'transformation.'.format(expand_axis_value, expand_axis.name))
- return
-
- tile = match['tile']
- tile_value = _input_node_value(tile, 1)
- if tile_value is None:
- log.debug('The tile value is not defined for node {}. Cannot apply BatchToSpaceToUpsample '
- 'transformation.'.format(tile.name))
- return
-
- if len(np.where(tile_value != 1)) != 1:
- log.debug('The number of tiles not equal to 1 not equal to 1. Cannot apply BatchToSpaceToUpsample '
- 'transformation.')
- return
- tile_batch = tile_value[0]
-
- batch_to_space_nd = match['batch_to_space_nd']
- block_shape = _input_node_value(batch_to_space_nd, 1)
- if block_shape is None or tile_batch != np.prod(block_shape):
- log.debug('The block shape {} for node {} is not defined or inconsistent with the tile size. Cannot apply '
- 'BatchToSpaceToUpsample transformation.'.format(block_shape, batch_to_space_nd.name))
- return
- if len(block_shape) != 2:
- log.debug('The block shape len is not equal to 2 for node {}. Cannot apply BatchToSpaceToUpsample '
- 'transformation.'.format(batch_to_space_nd.name))
- return
-
- crops = _input_node_value(batch_to_space_nd, 2)
- if crops is None or np.count_nonzero(crops) != 0:
- log.debug('Crops for node {} are non zero. Cannot apply BatchToSpaceToUpsample '
- 'transformation.'.format(batch_to_space_nd.name))
- return
-
- transpose_back = match['transpose_back']
- transpose_back_order = _input_node_value(transpose_back, 1)
- if transpose_back_order is None or not np.all(np.equal(transpose_back_order, int64_array([3, 0, 1, 2]))):
- log.debug('The transpose order {} for node {} is not equal to [3, 0, 1, 2]. Cannot apply '
- 'BatchToSpaceToUpsample transformation.'.format(transpose_back_order, transpose_back.name))
- return
-
- upsample_node = UpsampleOp(graph, {'height_scale': block_shape[0], 'width_scale': block_shape[1],
- 'mode': 'nearest',
- 'name': transpose.name + '/upsample'}).create_node()
-
- match['transpose'].in_port(0).get_connection().set_destination(upsample_node.in_port(0))
- match['transpose_back'].out_port(0).get_connection().set_source(upsample_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/tf/BlockLSTM.py b/tools/mo/openvino/tools/mo/front/tf/BlockLSTM.py
deleted file mode 100644
index bcc81156b54c18..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/BlockLSTM.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.error import Error
-
-
-class BlockLSTM(FrontReplacementPattern):
- """
- We prepare TensorFlow BlockLSTM op to be replaced with LSTMSequence op that will be repacked to TensorIterator later
-
- TensorFlow BlockLSTM op description:
-
- Op parameters:
- cell_clip: Value to clip the 'cs' value to.
- use_peephole: Whether to use peephole weights.
- forget_bias: The forget gate bias.
-
- Inputs:
- 0: seq_len_max: Maximum time length actually used by this input. Outputs are padded with 0s beyond this length
- 1: x: The sequence input to the LSTM, shape (timelen, batch_size, num_inputs)
- 2: cs_prev: Value of the initial cell state
- 3: h_prev: Initial output of cell (to be used for peephole)
- 4: w: The weight matrix
- 5: wci: The weight matrix for input gate peephole connection
- 6: wcf: The weight matrix for forget gate peephole connection
- 7: wco: The weight matrix for output gate peephole connection
- 8: b: The bias vector
-
- Outputs:
- 0: i: The input gate over the whole time sequence
- 1: cs: The cell state before the tanh over the whole time sequence
- 2: f: The forget gate over the whole time sequence
- 3: o: The output gate over the whole time sequence
- 4: ci: The cell input over the whole time sequence
- 5: co: The cell after the tanh over the whole time sequence
- 6: h: The output h vector over the whole time sequence
-
- Limitations:
- - peephole connection, so we check `use_peephole`!=True and cut `wci`, `wco`, `wcf` off
- - cell_clip parameter, so we check `cell_clip==-1`, which means we do not clip
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='BlockLSTM'):
- if node.use_peephole:
- raise Error("BlockLSTM operation is not supported with `use_peephole`==True. Node: {}"
- "".format(node.soft_get('name')))
-
- if node.cell_clip != -1:
- raise Error("Clipping is not supported for BlockLSTM operation. `cell_clip`={!s} for node: {}"
- "".format(node.cell_clip, node.soft_get('name')))
-
- log.debug("Start BlockLSTM->LSTMSequence translation for node: {} with parameters:\n"
- "`cell_clip`={!s}, `use_peephole`=={!s}, `forget_bias`={!s}\n"
- "inputs: {},\noutputs:{}".format(node.soft_get('name'), node.cell_clip, node.use_peephole,
- node.forget_bias, {p: i.id for p, i in node.in_nodes().items()},
- {p: o.id for p, o in node.out_nodes().items()}))
-
- log.debug("Cutting all inputs for peephole connection (5, 6, 7 input ports) off, as `use_peephole`=False")
- log.debug("Cutting seq_len_max input off")
-
- # disconnect all peephole releated inputs and seq_len_max
- for port_idx in [0, 5, 6, 7]:
- if node.is_in_port_connected(port_idx):
- node.in_port(port_idx).disconnect()
-
- assert node.is_in_port_connected(1), "Sequence input to the BlockLSTM is required (1 port). Node {}".format(
- node.id)
- assert node.is_in_port_connected(2), "Value of the initial cell state is required (2 port). Node {}".format(
- node.id)
- assert node.is_in_port_connected(
- 3), "Initial output of cell is required input to BlockLSTM (3 port). Node {}".format(node.id)
- assert node.is_in_port_connected(
- 4), "The weight matrix is required input to BlockLSTM (4 port) . Node {}".format(node.id)
- assert node.is_in_port_connected(
- 8), "The bias vector is required input to BlockLSTM (8 port). Node {}".format(node.id)
-
- # reconnect inputs since OpenVINO LSTMSequence requires different order
- # Reconnecting input edges of LSTMSequence:
- # TF input edges: Description: MO input edges:
- # 1 input 0
- # 4 weights 1
- # 8 biases 2
- # 3 h_prev: initial output of cell 3
- # 2 cs_prev: initial cell state 4
-
- input_source = node.in_port(1).get_source()
- weights_source = node.in_port(4).get_source()
- biases_source = node.in_port(8).get_source()
- h_prev_source = node.in_port(3).get_source()
- cs_prev_source = node.in_port(2).get_source()
-
- node.in_port(0).get_connection().set_source(input_source)
- node.in_port(1).get_connection().set_source(weights_source)
- node.in_port(2).get_connection().set_source(biases_source)
- node.in_port(3).get_connection().set_source(h_prev_source)
- node.in_port(4).get_connection().set_source(cs_prev_source)
- # disconnect original bias input that is no longer needed
- if node.is_in_port_connected(8):
- node.in_port(8).disconnect()
-
- # check that all outputs unsupported by OpenVINO LSTMSequence are absent
- for output_port_idx in [0, 2, 3, 4, 5]:
- if node.is_out_port_connected(output_port_idx):
- raise Error("Output port {} of BlockLSTM node {} is not supported".format(node.id, output_port_idx))
-
- # Reconnecting output edges of LSTMSequence:
- # TF output edges: Description: MO output edges:
- # 6 output h vector 0
- # 1 cell state before the tanh 1
-
- # we need to move only 6-th output port to 0-th port
- if node.is_out_port_connected(6):
- node.add_output_port(0, skip_if_exist=True)
- node.out_port(6).get_connection().set_source(node.out_port(0))
- node.out_port(6).disconnect()
- node.delete_output_port(6, skip_if_absent=True)
diff --git a/tools/mo/openvino/tools/mo/front/tf/BlockLSTM_ext.py b/tools/mo/openvino/tools/mo/front/tf/BlockLSTM_ext.py
deleted file mode 100644
index 57783dec230c73..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/BlockLSTM_ext.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.BlockLSTM import BlockLSTM
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class BlockLSTMExtractor(FrontExtractorOp):
- op = 'BlockLSTM'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'use_peephole': node.pb.attr['use_peephole'].b,
- 'cell_clip': node.pb.attr['cell_clip'].f,
- 'forget_bias': node.pb.attr['forget_bias'].f,
- }
- BlockLSTM.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/CTCGreedyDecoderReplacement.py b/tools/mo/openvino/tools/mo/front/tf/CTCGreedyDecoderReplacement.py
deleted file mode 100644
index 8eeeb86a685485..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/CTCGreedyDecoderReplacement.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.ctc_greedy_decoder_seq_len import CTCGreedyDecoderSeqLenOp
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph, FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.result import Result
-
-
-def replace_ctc_greedy_decoder(graph: Graph, match: dict):
- ctc_greedy_decoder_tf = match['decoder']
- cast = match['cast']
- sparse_to_dense = match['sparse_to_dense']
- sparse_to_dense_name = sparse_to_dense.soft_get('name', sparse_to_dense.id)
- ctc_greedy_decoder_tf_name = ctc_greedy_decoder_tf.soft_get('name', ctc_greedy_decoder_tf.id)
-
- # For normalizing input channel needs to transpose input data from [T, N, C] to [N, T, C]
- # which supported CTCGreedyDecoderSeqLen op.
- ctc_data_permute = create_op_with_const_inputs(graph, Transpose, {1: int64_array([1, 0, 2])},
- {'name': ctc_greedy_decoder_tf_name + '/ctc_data_permute'})
-
- assert ctc_greedy_decoder_tf.has_valid('merge_repeated'), \
- 'The CTCGreedyDecoderSeqLen node "{}" misses "merge_repeated" attribute'.format(ctc_greedy_decoder_tf_name)
-
- ctc_greedy_decoder_tf.in_port(0).get_source().connect(ctc_data_permute.in_port(0))
- merge_repeated_tf = ctc_greedy_decoder_tf.merge_repeated
- ctc_greedy_decoder = CTCGreedyDecoderSeqLenOp(graph, {'name': sparse_to_dense_name,
- 'merge_repeated': merge_repeated_tf}).create_node()
- rename_nodes(
- [(sparse_to_dense, sparse_to_dense_name + '/AbandonedName'), (ctc_greedy_decoder, sparse_to_dense_name)])
- ctc_greedy_decoder.in_port(0).connect(ctc_data_permute.out_port(0))
- ctc_greedy_decoder_tf.in_port(1).get_source().connect(ctc_greedy_decoder.in_port(1))
-
- # Set output of the new sub-graph as a source for SparseToDense consumer
- sparse_to_dense.out_port(0).get_connection().set_source(ctc_greedy_decoder.out_port(0))
-
- # Remove no longer needed nodes
- graph.remove_nodes_from([sparse_to_dense.id, cast.id, ctc_greedy_decoder_tf.id])
-
-
-class CTCGreedyDecoderReplacement(FrontReplacementSubgraph):
- """
- TensorFlow CTCGreedyDecoder produces output in a sparse tensor that is not supported by OpenVINO, and
- OpenVINO's CTCGreedyDecoderSeqLen has a different output that is in a dense format. So this transformation
- intents to replace TF CTCGreedyDecoder+SparseToDense where SparseToDense third input get from input parameter
- to CTCGreedyDecoderSeqLen which compatible with IE.
- """
- enabled = True
-
- @staticmethod
- def pattern(**kwargs):
- return dict(
- nodes=[('decoder', dict(op='CTCGreedyDecoderSeqLen', output_sparse_format=True)),
- ('cast', dict(op='Cast')),
- ('sparse_to_dense', dict(op='SparseToDense'))
- ],
- edges=[('decoder', 'sparse_to_dense', {'out': 0}),
- ('decoder', 'cast', {'out': 1}),
- ('cast', 'sparse_to_dense', {'out': 0})]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- replace_ctc_greedy_decoder(graph, match)
-
-
-class CTCGreedyDecoderWithSparseToDenseShapeReplacement(FrontReplacementSubgraph):
- """
- TensorFlow CTCGreedyDecoder produces output in a sparse tensor that is not supported by OpenVINO, and
- OpenVINO's CTCGreedyDecoderSeqLen has a different output that is in a dense format. So this transformation
- intents to replace TF CTCGreedyDecoder+SparseToDense where SparseToDense third input get from CTCGreedyDecoder
- second output to CTCGreedyDecoderSeqLen which compatible with IE.
- """
- enabled = True
-
- @staticmethod
- def pattern(**kwargs):
- return dict(
- nodes=[('decoder', dict(op='CTCGreedyDecoderSeqLen', output_sparse_format=True)),
- ('cast', dict(op='Cast')),
- ('sparse_to_dense', dict(op='SparseToDense'))
- ],
- edges=[('decoder', 'sparse_to_dense', {'out': 0}),
- ('decoder', 'cast', {'out': 1}),
- ('decoder', 'sparse_to_dense', {'out': 2}),
- ('cast', 'sparse_to_dense', {'out': 0})]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- replace_ctc_greedy_decoder(graph, match)
-
-
-class CTCGreedyDecoderSingleReplacement(FrontReplacementPattern):
- """
- TensorFlow CTCGreedyDecoder produces output in a sparse tensor that is not supported by OpenVINO, and
- OpenVINO's CTCGreedyDecoderSeqLen has a different output that is in a dense format. So this transformation
- handles a single TF CTCGreedyDecoder and warns the user about another format of the output
- """
- enabled = True
-
- def run_after(self):
- return [CTCGreedyDecoderReplacement, CTCGreedyDecoderWithSparseToDenseShapeReplacement]
-
- def find_and_replace_pattern(self, graph: Graph):
- for ctc_greedy_decoder_tf in graph.get_op_nodes(op='CTCGreedyDecoderSeqLen', output_sparse_format=True):
- ctc_greedy_decoder_tf_name = ctc_greedy_decoder_tf.soft_get('name', ctc_greedy_decoder_tf.id)
-
- # TF CTCGreedyDecoder have 4 output tensors. If any of them connected to not Result operation then
- # transformation in not applicable
- for port_num in ctc_greedy_decoder_tf.out_ports():
- if not ctc_greedy_decoder_tf.out_port(port_num).disconnected()\
- and ctc_greedy_decoder_tf.out_port(port_num).get_destination().node.soft_get('op') != 'Result':
- return
-
- # If the first and second output are not connected to Result operations -
- # create Result operation and connect it to appropriate output
- if ctc_greedy_decoder_tf.out_port(0).disconnected():
- first_result = Result(graph,
- {'name': ctc_greedy_decoder_tf_name + '/decoded_classes'}
- ).create_node()
- ctc_greedy_decoder_tf.out_port(0).connect(first_result.in_port(0))
-
- if ctc_greedy_decoder_tf.out_port(1).disconnected():
- second_result = Result(graph,
- {'name': ctc_greedy_decoder_tf_name + '/seq_lengths_output'}
- ).create_node()
- ctc_greedy_decoder_tf.out_port(1).connect(second_result.in_port(0))
-
-
- # For normalizing input channel needs to transpose input data from [T, N, C] to [N, T, C]
- # which supported CTCGreedyDecoderSeqLen op.
- log.warning('Found TF CTCGreedyDecoder operation at the end of network. '
- 'PLEASE NOTE, appropriate network output operation CTCGreedyDecoderSeqLen {} '
- 'will have dense format, not sparse format!'.format(ctc_greedy_decoder_tf_name))
- ctc_data_permute = create_op_with_const_inputs(graph, Transpose, {1: int64_array([1, 0, 2])},
- {'name': ctc_greedy_decoder_tf_name + '/ctc_data_permute'})
-
- assert ctc_greedy_decoder_tf.has_valid('merge_repeated'), \
- 'The CTCGreedyDecoderSeqLen node "{}" misses "merge_repeated" attribute'.format(
- ctc_greedy_decoder_tf_name)
-
- ctc_greedy_decoder_tf.in_port(0).get_source().connect(ctc_data_permute.in_port(0))
- ctc_greedy_decoder_tf.in_port(0).disconnect()
- ctc_data_permute.out_port(0).connect(ctc_greedy_decoder_tf.in_port(0))
-
- del ctc_greedy_decoder_tf['output_sparse_format']
-
- for port_num in [2, 3]: # MO CTCGreedyDecoderSeqLen may have 2 outputs
- if port_num in ctc_greedy_decoder_tf.out_ports():
- if not ctc_greedy_decoder_tf.out_port(port_num).disconnected():
- ctc_greedy_decoder_tf.out_port(port_num).disconnect()
diff --git a/tools/mo/openvino/tools/mo/front/tf/CTCGreedyDecoder_ext.py b/tools/mo/openvino/tools/mo/front/tf/CTCGreedyDecoder_ext.py
deleted file mode 100644
index 99819daa46e909..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/CTCGreedyDecoder_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ctc_greedy_decoder_seq_len import CTCGreedyDecoderSeqLenOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class CTCCGreedyDecoderFrontExtractor(FrontExtractorOp):
- op = 'CTCGreedyDecoder'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'merge_repeated': bool(node.pb.attr['merge_repeated'].b),
- 'output_sparse_format': True, # Special argument for TF CTCGreedyDecoder replacement transformations
- }
- CTCGreedyDecoderSeqLenOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/CTCLossReplacement.py b/tools/mo/openvino/tools/mo/front/tf/CTCLossReplacement.py
deleted file mode 100644
index a6db2a3e1e690f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/CTCLossReplacement.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ctc_greedy_decoder_seq_len import CTCGreedyDecoderSeqLenOp
-from openvino.tools.mo.ops.ctc_loss import CTCLoss
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-
-
-class CTCLossReplacement(FrontReplacementSubgraph):
- """
- The CTCLoss appears along with CTCGreedyDecoder operation in particular. Since the TensorFlow* CTCGreedyDecoder
- outputs sparse tensor format, the OpenVINO CTCGreedyDecoderSeqLen has a different format and the CTCLoss is also affected
- in terms of different format for its inputs. So the corresponding sub-graph with CTCGreedyDecoding and CTCLoss
- must be transformed properly.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.tf.CTCGreedyDecoderReplacement import CTCGreedyDecoderReplacement
- return [CTCGreedyDecoderReplacement]
-
- def pattern(self):
- return dict(
- nodes=[
- ('transpose', dict(op='Transpose')),
- ('ctc_greedy_decoder', dict(op='CTCGreedyDecoderSeqLen', output_sparse_format=True)),
- ('cast', dict(op='Cast')),
- ('sparse_to_dense', dict(op='SparseToDense')),
- ('const', dict(op='Const')),
- ('ctc_loss', dict(op='CTCLoss')),
- ],
- edges=[
- ('transpose', 'ctc_greedy_decoder', {'out': 0, 'in': 0}),
- ('transpose', 'ctc_loss', {'out': 0, 'in': 0}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 2, 'in': 1}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 1, 'in': 2}),
- ('const', 'sparse_to_dense', {'out': 0, 'in': 3}),
- ('ctc_greedy_decoder', 'cast', {'out': 1, 'in': 0}),
- ('ctc_greedy_decoder', 'ctc_loss', {'out': 0, 'in': 1}),
- ('cast', 'ctc_loss', {'out': 0, 'in': 2})
- ])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- transpose_tf = match['transpose']
- ctc_greedy_decoder_tf = match['ctc_greedy_decoder']
- cast_tf = match['cast']
- ctc_loss_tf = match['ctc_loss']
- sparse_to_dense_tf = match['sparse_to_dense']
- output_sparse_to_dense_name = sparse_to_dense_tf.soft_get('name', sparse_to_dense_tf.id)
- ctc_data_permute = create_op_with_const_inputs(graph, Transpose, {1: int64_array([1, 0, 2])},
- {'name': ctc_greedy_decoder_tf.name + '/ctc_data_permute'})
- ctc_data_permute.in_port(0).connect(transpose_tf.out_port(0))
-
- ctc_greedy_decoder_tf_name = ctc_greedy_decoder_tf.soft_get('name', ctc_greedy_decoder_tf.id)
- assert ctc_greedy_decoder_tf.has_valid('merge_repeated'), \
- 'The CTCGreedyDecoderSeqLen node "{}" misses "merge_repeated" attribute'.format(ctc_greedy_decoder_tf_name)
- merge_repeated_tf = ctc_greedy_decoder_tf.merge_repeated
- ctc_greedy_decoder = CTCGreedyDecoderSeqLenOp(graph, {'name': output_sparse_to_dense_name,
- 'merge_repeated': merge_repeated_tf}).create_node()
- rename_nodes([(sparse_to_dense_tf, output_sparse_to_dense_name + '/AbandonedName'),
- (ctc_greedy_decoder, output_sparse_to_dense_name)])
- ctc_greedy_decoder.in_port(0).connect(ctc_data_permute.out_port(0))
- ctc_greedy_decoder.in_port(1).connect(ctc_greedy_decoder_tf.in_port(1).get_connection().get_source())
-
- # set output of the new sub-graph as a source for SparseToDense consumer
- output_ctc_loss_name = ctc_loss_tf.soft_get('name', ctc_loss_tf.id)
- assert ctc_loss_tf.has_valid('preprocess_collapse_repeated'), \
- 'The CTCLoss node "{}" misses "preprocess_collapse_repeated" attribute'.format(output_ctc_loss_name)
- assert ctc_loss_tf.has_valid('ctc_merge_repeated'), \
- 'The CTCLoss node "{}" misses "ctc_merge_repeated" attribute'.format(output_ctc_loss_name)
- assert ctc_loss_tf.has_valid('unique'), \
- 'The CTCLoss node "{}" misses "unique" attribute'.format(output_ctc_loss_name)
- preprocess_collapse_repeated = ctc_loss_tf.preprocess_collapse_repeated
- ctc_merge_repeated = ctc_loss_tf.ctc_merge_repeated
- unique = ctc_loss_tf.unique
- ctc_loss = CTCLoss(graph, {'name': output_ctc_loss_name,
- 'preprocess_collapse_repeated': preprocess_collapse_repeated,
- 'ctc_merge_repeated': ctc_merge_repeated,
- 'unique': unique}).create_node()
- rename_nodes([(ctc_loss_tf, output_ctc_loss_name + '/AbandonedName'), (ctc_loss, output_ctc_loss_name)])
- ctc_loss_tf.out_port(0).get_connection().set_source(ctc_loss.out_port(0))
- if ctc_loss_tf.logits_time_major:
- ctc_loss.in_port(0).connect(ctc_data_permute.out_port(0))
- else:
- ctc_loss.in_port(0).connect(transpose_tf.out_port(0))
- ctc_loss.in_port(1).connect(ctc_greedy_decoder_tf.in_port(1).get_connection().get_source())
- ctc_loss.in_port(2).connect(ctc_greedy_decoder.out_port(0))
- ctc_loss.in_port(3).connect(ctc_greedy_decoder.out_port(1))
-
- # remove no longer needed nodes
- graph.remove_nodes_from([sparse_to_dense_tf.id, cast_tf.id, ctc_loss_tf.id, ctc_greedy_decoder_tf.id])
diff --git a/tools/mo/openvino/tools/mo/front/tf/CTCLoss_ext.py b/tools/mo/openvino/tools/mo/front/tf/CTCLoss_ext.py
deleted file mode 100644
index 526a1de26b3511..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/CTCLoss_ext.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ctc_loss import CTCLoss
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class CTCLossFrontExtractor(FrontExtractorOp):
- op = 'CTCLoss'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # For CTCLoss default value is [N, T]
- logits_time_major = True
- if 'logits_time_major' in node.pb.attr:
- logits_time_major = node.pb.attr['logits_time_major'].b
-
- attrs = {
- 'ctc_merge_repeated': node.pb.attr['ctc_merge_repeated'].b,
- 'preprocess_collapse_repeated': node.pb.attr['preprocess_collapse_repeated'].b,
- 'logits_time_major': logits_time_major,
- # unique is always false for CTCLoss V1
- 'unique': False
- }
-
- CTCLoss.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/Cast_ext.py b/tools/mo/openvino/tools/mo/front/tf/Cast_ext.py
deleted file mode 100644
index ba6d6f568bdca3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/Cast_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.common import tf_data_type_decode
-
-
-class CastFrontExtractor(FrontExtractorOp):
- op = 'Cast'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- cast_dst_type = tf_data_type_decode[node.pb.attr['DstT'].type][0]
- Cast.update_node_stat(node, {'dst_type': cast_dst_type})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/ClipByValueTFTransformation.py b/tools/mo/openvino/tools/mo/front/tf/ClipByValueTFTransformation.py
deleted file mode 100644
index d683fdf24fccfb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ClipByValueTFTransformation.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from openvino.tools.mo.ops.elementwise import Minimum, Maximum
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-
-
-class ClipByValueTFTransformation(FrontReplacementSubgraph):
- """
- The transformation replaces the ClipByValueTF operation which works as Clamp but supports broadcasting of inputs
- with Minimum and Maximum.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for cbv in graph.get_op_nodes(op='ClipByValueTF'):
- cbv_name = cbv.soft_get('name', cbv.id)
- minimum = Minimum(graph, {'name': cbv_name + '/CLipMinimum'}).create_node()
- maximum = Maximum(graph, {'name': cbv_name + '/CLipMaximum'}).create_node()
- minimum.in_port(0).connect(cbv.in_port(0).get_source())
- minimum.in_port(1).connect(cbv.in_port(2).get_source())
- maximum.in_port(0).connect(minimum.out_port(0))
- maximum.in_port(1).connect(cbv.in_port(1).get_source())
- cbv.out_port(0).get_connection().set_source(maximum.out_port(0))
-
- rename_nodes([(cbv, cbv_name + '/TBR'), (maximum, cbv_name)])
- graph.remove_node(cbv.id)
diff --git a/tools/mo/openvino/tools/mo/front/tf/ClipByValue_ext.py b/tools/mo/openvino/tools/mo/front/tf/ClipByValue_ext.py
deleted file mode 100644
index df1ff155244405..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ClipByValue_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.ClipByValueTF import ClibByValueTF
-
-
-class ClipByValueExtractor(FrontExtractorOp):
- op = 'ClipByValue'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ClibByValueTF.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/ComplexAbs.py b/tools/mo/openvino/tools/mo/front/tf/ComplexAbs.py
deleted file mode 100644
index 96fa13a35b9e25..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ComplexAbs.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-from openvino.tools.mo.ops.elementwise import Pow
-from openvino.tools.mo.ops.ReduceOps import ReduceSum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-
-
-class ComplexAbs(FrontReplacementSubgraph):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.tf.ComplexAbsAfterComplex import ComplexAbsAfterComplex
- return [ComplexAbsAfterComplex]
-
- def find_and_replace_pattern(self, graph: Graph):
- for complex_abs in graph.get_op_nodes(op='ComplexAbs'):
- complex_abs_name = complex_abs.soft_get('name', complex_abs.id)
- power_type = data_type_str_to_np(graph.graph['cmd_params'].data_type)
-
- squared = create_op_with_const_inputs(graph, Pow, {1: power_type(2.0)},
- {'name': complex_abs_name + '/squared_parts'})
- complex_abs.in_port(0).get_connection().set_destination(squared.in_port(0))
- sum = create_op_with_const_inputs(graph, ReduceSum, {1: int64_array(-1)},
- {'name': complex_abs_name + '/squared_abs'},
- squared)
- sqrt = create_op_with_const_inputs(graph, Pow, {1: power_type(0.5)}, {}, sum)
-
- complex_abs.out_port(0).get_connection().set_source(sqrt.out_port(0))
-
- rename_nodes([(complex_abs, complex_abs_name + '/to_be_removed'), (sqrt, complex_abs_name)])
diff --git a/tools/mo/openvino/tools/mo/front/tf/ComplexAbsAfterComplex.py b/tools/mo/openvino/tools/mo/front/tf/ComplexAbsAfterComplex.py
deleted file mode 100644
index ec8c4faa5df61b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ComplexAbsAfterComplex.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.ops.elementwise import Add, Pow
-
-
-class ComplexAbsAfterComplex(FrontReplacementSubgraph):
- """
- This transformation converts a sub-graph
-
- SomeOp1 SomeOp2
- | |
- ------------
- |
- Complex
- |
- ComplexAbs
-
- into the sub-graph
-
- SomeOp1 SomeOp2
- | |
- Constant[2]--Pow Pow--Constant[2]
- | |
- -------------
- Add
- |
- Pow--Constant[0.5]
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('complex', dict(op='Complex')),
- ('abs', dict(op='ComplexAbs')),
- ],
- edges=[
- ('complex', 'abs', {'in': 0}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
- cmp = match['complex']
- complex_abs = match['abs']
- complex_abs_name = complex_abs.soft_get('name', complex_abs.id)
-
- power_type = data_type_str_to_np(graph.graph['cmd_params'].data_type)
-
- pow0 = create_op_with_const_inputs(graph, Pow, {1: power_type(2.0)},
- {'name': complex_abs_name + '/real_part_squared'})
- pow1 = create_op_with_const_inputs(graph, Pow, {1: power_type(2.0)},
- {'name': complex_abs_name + '/imag_part_squared'})
-
- cmp.in_port(0).get_connection().set_destination(pow0.in_port(0))
- cmp.in_port(1).get_connection().set_destination(pow1.in_port(0))
-
- add = Add(graph, {'name': complex_abs_name + '/squared_abs'}).create_node([pow0, pow1])
- sqrt = create_op_with_const_inputs(graph, Pow, {1: power_type(0.5)}, {})
- add.out_port(0).connect(sqrt.in_port(0))
-
- complex_abs.out_port(0).get_connection().set_source(sqrt.out_port(0))
-
- rename_nodes([(complex_abs, complex_abs_name + '/to_be_removed'), (sqrt, complex_abs_name)])
diff --git a/tools/mo/openvino/tools/mo/front/tf/CorrectPaddingsForPadAfterComplex.py b/tools/mo/openvino/tools/mo/front/tf/CorrectPaddingsForPadAfterComplex.py
deleted file mode 100644
index f5d82e2e682ac9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/CorrectPaddingsForPadAfterComplex.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.concat import Concat
-
-
-class CorrectPaddingsForPadAfterComplex(FrontReplacementSubgraph):
- """
- There are TF models with the TF operation Complex that has two real tensors as arguments and returns the complex
- tensor with real and imaginary parts given as arguments in port 0 and 1 respectively.
-
- Although TF has a native support of complex numbers, OpenVINO doesn't have such support and emulates a complex
- tensor with the shape [N_0, ..., N_{r - 1}] as a real tensor of the shape [N_0, ..., N_{r - 1}, 2] interpreting
- any complex number as a tuple of the form
- (real part, imaginary part)
- That is, the emulated complex tensor has the rank r + 1, not r as in the TF model.
-
- Hence, when we convert a subgraph of the form
-
- Complex
- |
- |
- Pad
-
- we should correct pads_begin and pads_end adding zero at the end of pads_begin and pads_end.
-
- The transformation performs such corrections.
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.tf.pad_tf_to_pad import PadTFToPad
- return [PadTFToPad]
-
- def pattern(self):
- return dict(
- nodes=[
- ('complex', dict(op='Complex')),
- ('pad', dict(op='Pad')),
- ],
- edges=[
- ('complex', 'pad', {'in': 0}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
- pad_node = match['pad']
- pads_begin_node = pad_node.in_port(1).get_source().node
- pads_end_node = pad_node.in_port(2).get_source().node
-
- pads_begin_node_name = pads_begin_node.soft_get('name', pads_begin_node.id)
- pads_end_node_name = pads_end_node.soft_get('name', pads_end_node.id)
-
- concat_for_pads_begin = create_op_with_const_inputs(graph, Concat,
- {1: int64_array([0])},
- {
- 'name': pads_begin_node_name + '/additional',
- 'in_ports_count': 2,
- 'axis': 0,
- })
- concat_for_pads_end = create_op_with_const_inputs(graph, Concat,
- {1: int64_array([0])},
- {
- 'name': pads_end_node_name + '/additional',
- 'in_ports_count': 2,
- 'axis': 0,
- })
- pad_node.in_port(1).get_connection().insert_node(concat_for_pads_begin)
- pad_node.in_port(2).get_connection().insert_node(concat_for_pads_end)
diff --git a/tools/mo/openvino/tools/mo/front/tf/CropAndResizeReplacement.py b/tools/mo/openvino/tools/mo/front/tf/CropAndResizeReplacement.py
deleted file mode 100644
index 8f4176a539df38..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/CropAndResizeReplacement.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import add_convolution_to_swap_xy_coordinates, create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class CropAndResizeReplacement(FrontReplacementOp):
- """
- The CropAndResize operation from TF gets separate input with boxes coordinates and image batch indices. But
- ROIPooling operation in the OpenVINO receives them as a single concatenated input. This replacer
- concatenates two inputs into a new one.
- """
- op = "CropAndResize"
- enabled = True
-
- def nodes_to_remove(self, graph: Graph, match: dict):
- # do not remove matched node
- return []
-
- def replace_op(self, graph: Graph, node: Node):
- if node.has_and_set('inputs_preprocessed'):
- log.debug('Node "{}" has already been preprocessed'.format(node.soft_get('name')))
- return []
- # reshape tensor with batch indices to 2d
- unsqueeze_node = create_op_node_with_second_input(graph, Unsqueeze, int64_array([1]),
- {'name': node.name + '/Unsqueeze'}, node.in_node(2))
-
- convert_node = Cast(graph, {'name': unsqueeze_node.name + '/ToFloat',
- 'dst_type': data_type_str_to_np(graph.graph['cmd_params'].data_type)}).create_node()
-
- convert_node.in_port(0).connect(unsqueeze_node.out_port(0))
-
- concat_op = Concat(graph, {'axis': 1, 'name': node.name + '/concat_batch_indices_and_boxes',
- 'in_ports_count': 2})
- concat_node = concat_op.create_node([convert_node, node.in_node(1)])
-
- # do not remove edge with crop_size because it is needed in the partial infer
- graph.remove_edge(node.in_node(1).id, node.id)
-
- # input to the CropAndResize contains boxes coordinates in YXYX layout. But OV layer ROIPooling expects
- # coordinates in the XYXY layout, so convolution is added here to swap coordinates
- swapped_box_coordinates_node = add_convolution_to_swap_xy_coordinates(graph, concat_node, 5)
-
- # reshape locations tensor to 2D so it could be passed to Eltwise which will be converted to ScaleShift
- reshape_2d_node = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 5]),
- dict(name=swapped_box_coordinates_node.id + '/reshape_2d_'),
- swapped_box_coordinates_node)
- graph.create_edge(reshape_2d_node, node, 0, 1)
-
- # do not replace any output edge
- return []
diff --git a/tools/mo/openvino/tools/mo/front/tf/FakeQuantWithMinMaxVars_ext.py b/tools/mo/openvino/tools/mo/front/tf/FakeQuantWithMinMaxVars_ext.py
deleted file mode 100644
index 979f851de6cf41..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/FakeQuantWithMinMaxVars_ext.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.op import Op
-
-
-class FakeQuantWithMinMaxVarsExtractor(FrontExtractorOp):
- op = 'FakeQuantWithMinMaxVars'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- narrow_range = node.pb.attr['narrow_range'].b
- num_bits = node.pb.attr['num_bits'].i
- levels = 2 ** num_bits - int(narrow_range)
-
- # we prepare this operation to be converted to FakeQuantize op,
- # but input reconnection is needed, so we don't set infer function and type attribute
- Op.update_node_stat(node, {'op': 'FakeQuantWithMinMaxVars', 'levels': levels,
- 'narrow_range': narrow_range, 'num_bits': num_bits})
-
- return cls.enabled
-
-
-class FakeQuantWithMinMaxVarsPerChannelExtractor(FrontExtractorOp):
- op = 'FakeQuantWithMinMaxVarsPerChannel'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- narrow_range = node.pb.attr['narrow_range'].b
- num_bits = node.pb.attr['num_bits'].i
- levels = 2 ** num_bits - int(narrow_range)
-
- # we prepare this operation to be converted to FakeQuantize op,
- # but input reconnection is needed, so we don't set infer function and type attribute
- Op.update_node_stat(node, {'op': 'FakeQuantWithMinMaxVars', 'levels': levels,
- 'narrow_range': narrow_range, 'num_bits': num_bits})
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/FlattenToReshape.py b/tools/mo/openvino/tools/mo/front/tf/FlattenToReshape.py
deleted file mode 100644
index c502c0c958822a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/FlattenToReshape.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.Pack import Pack
-from openvino.tools.mo.front.tf.nearest_neighbor_upsampling import NearestNeighborUpsampling
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-def is_value_is_constant(val: np.ndarray, const: [int, float]):
- if val.ndim > 1:
- return False
- if val.ndim == 1 and len(val) > 1:
- return False
- return val.item() == const
-
-
-class FlattenToReshapeableReshape(FrontReplacementSubgraph):
- """
- The TensorFlow implementation of the Flatten operation is not reshape-able because the batch size is hardcoded
- during the constant propagation. This transform sets the 'dim' attribute for the Reshape to [0, -1].
- """
- enabled = True
-
- def run_after(self):
- return [NearestNeighborUpsampling]
-
- def run_before(self):
- return [Pack]
-
- def pattern(self):
- return dict(
- nodes=[
- ('shape', dict(op='ShapeOf')),
- ('strided_slice', dict(op='StridedSlice')),
- ('pack', dict(op='Pack')),
- ('const', dict(op='Const')),
- ('reshape', dict(op='Reshape')),
- ],
- edges=[
- ('shape', 'strided_slice', {'in': 0}),
- ('strided_slice', 'pack', {'in': 0}),
- ('const', 'pack', {'in': 1}),
- ('pack', 'reshape', {'in': 1}),
- ])
-
- @staticmethod
- def replace_sub_graph(graph: Graph, match: dict):
- strided_slice_node = match['strided_slice']
- const_node = match['const']
- reshape_node = match['reshape']
- pack_node = match['pack']
-
- if not const_node.has_valid('value') or not is_value_is_constant(const_node.value, -1):
- log.debug('The pattern does not correspond to flatten. The second reshape dimension is not -1. It is {}'.
- format(const_node.soft_get('value')))
- return
- if len(pack_node.in_nodes()) != 2:
- log.debug('The pattern does not correspond to flatten. The "Pack" operation produces tensor with 3 items '
- 'but should produce just 2.')
- return
-
- expected_values = [0, 1, 1] # expected values to a StridedSlice to get the batch size
- for ind in range(3):
- if not strided_slice_node.in_node(ind + 1).has_valid('value') or \
- not is_value_is_constant(strided_slice_node.in_node(ind + 1).value, expected_values[ind]):
- log.debug('The pattern does not correspond to flatten because of the input with index {}. The value is '
- '"{}".'.format(ind, strided_slice_node.soft_get('value')))
- return
-
- reshape_node.in_port(1).disconnect()
- reshape_const_node = Const(graph, {'value': int64_array([0, -1]),
- 'name': reshape_node.soft_get('name', reshape_node.id) + '/shape'}).create_node()
- reshape_node.in_port(1).connect(reshape_const_node.out_port(0))
- reshape_node['special_zero'] = True
- log.debug('The node "{}" is actually a Flatten node'.format(reshape_node.soft_get('name')))
diff --git a/tools/mo/openvino/tools/mo/front/tf/GNMT_DynamicSequenceLengths.py b/tools/mo/openvino/tools/mo/front/tf/GNMT_DynamicSequenceLengths.py
deleted file mode 100644
index 41891f923b247d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/GNMT_DynamicSequenceLengths.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.middle.TensorIteratorCondition import looking_for_op_in_list
-from openvino.tools.mo.ops.elementwise import Mul
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class GNMT_sequence_lengths(FrontReplacementPattern):
- """
- This pass matching GNMT-like condition (like in DynamicDecoderConditionMatcher) with path for sequence lengths
- calculation:
- Seq_len_data -> Max -> Cast -> Mul -> Round -> Cast.
-
- After matching this pattern:
- 1. This replacer looking for encoder sequence lengths node (using information about encoder condition structure)
- 2. Create node for multiplying Encoder sequence lengths by 2 (as it works in GNMT).
- 3. Connect Encoder sequence lengths value multiplied by 2 with decoder TensorArrays as size.
- """
- enabled = True
-
- @staticmethod
- def pattern():
- log.debug('+++++++++++++++ GNMT Sequence Lengths ConditionMatching ++++++++++++++++')
- return dict(
- nodes=[
- ('loop_cond', dict(kind='op', op='LoopCond')),
- ('logical_not', dict(kind='op', op='LogicalNot')),
-
- ('all', dict(kind='op', op='ReduceAnd')),
-
- ('Merge_16', dict(kind='op', op='Merge')),
-
- ('NextIteration_16', dict(kind='op', op='NextIteration')),
-
- ('Switch', dict(kind='op', op='Switch')),
-
- ('Identity', dict(kind='op', op='Identity')),
-
- ('Switch_1', dict(kind='op', op='Switch')),
-
- ('Identity_1', dict(kind='op', op='Identity')),
-
- ('add', dict(kind='op', op='Add')),
-
- ('Less_enter', dict(kind='op', op='Enter')),
-
- ('And', dict(kind='op', op='LogicalAnd')),
-
- ('Less', dict(kind='op', op='Less')),
- ('TensorArrayWrite', dict(kind='op', op='TensorArrayWriteV3')),
- ('TensorArrayWrite_1', dict(kind='op', op='TensorArrayWriteV3')),
-
- ('Max', dict(kind='op', op='ReduceMax')),
- ('ToFloat', dict(kind='op', op='Cast')),
- ('Mul', dict(kind='op', op='Mul')),
- ('Round', dict(kind='op', op='Round')),
- ('ToInt', dict(kind='op', op='Cast')),
- ],
- edges=[
- ('NextIteration_16', 'Merge_16'),
- ('Merge_16', 'all'),
-
- ('all', 'logical_not'),
-
- ('Less_enter','Less'),
-
- ('Less', 'And'),
-
- ('logical_not', 'And'),
- ('And', 'loop_cond'),
-
- ('loop_cond', 'Switch'),
- ('Switch', 'Identity'),
- ('Identity', 'add'),
-
- ('loop_cond', 'Switch_1'),
- ('Switch_1', 'Identity_1'),
-
- ('Identity_1', 'TensorArrayWrite'),
- ('Identity_1', 'TensorArrayWrite_1'),
-
- ('Max', 'ToFloat'),
- ('ToFloat', 'Mul'),
- ('Mul', 'Round'),
- ('Round', 'ToInt'),
- ('ToInt', 'Less_enter'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== GNMTBeforeConditionFind ==================')
- input_sequence_lengths = match['Max'].in_port(0).get_source().node
- encoder_sequence_lengths = looking_for_op_in_list([port.node for port in input_sequence_lengths.out_port(0).get_destinations()],
- 'Identity')
-
- # Looking for Sequence_length node in encoder looks like:
- # Sequence_length -> CheckSeqLen -> Max -> Maximum -> Minimum
-
- check_seq_len = looking_for_op_in_list([port.node for port in encoder_sequence_lengths.out_port(0).get_destinations()],
- 'Identity')
- max = looking_for_op_in_list([port.node for port in check_seq_len.out_port(0).get_destinations()], 'ReduceMax')
- maximum = max.out_port(0).get_destinations()[0].node
- assert maximum.op == 'Maximum'
- minimum = maximum.out_port(0).get_destinations()[0].node
- assert minimum.op == 'Minimum'
-
- tensor_seq_len = looking_for_op_in_list([minimum.in_port(port).get_source().node for port in minimum.in_ports()], 'StridedSlice')
-
- # Create node for multiplying seq_len by 2
- const = Const(graph, {'name': 'FakeSeqLenMultiplyer', 'value': mo_array(2)}).create_node()
- mul_op = Mul(graph, {'name': 'FakeSeqLen'}).create_node()
-
- const.out_port(0).get_connection().set_destination(mul_op.in_port(1))
- tensor_seq_len.out_port(0).get_connection().add_destination(mul_op.in_port(0))
-
- # Connect seq_len * 2 to TensorArray from GNMT loop
- ta_writes = [port.node for port in match['Identity_1'].out_port(0).get_destinations() if port.node.op == 'TensorArrayWriteV3']
-
- for ta_write in ta_writes:
- ta = ta_write.in_port(0).get_source().node.in_port(0).get_source().node
-
- ta.in_port(0).disconnect()
- ta.in_port(0).get_connection().set_source(mul_op.out_port(0))
-
- if not graph.graph['cmd_params'].static_shape:
- log.error(
- "Model can not be translated in a reshape-able way.\n"
- "Model Optimizer key static_shape was turned on to prevent related errors.\n"
- "There will be no success changing input shapes of the model with the help of "
- "OpenVINO reshape method", extra={'is_warning': True})
- graph.graph['cmd_params'].static_shape = True
diff --git a/tools/mo/openvino/tools/mo/front/tf/GRUBlockCellReplacement.py b/tools/mo/openvino/tools/mo/front/tf/GRUBlockCellReplacement.py
deleted file mode 100644
index 5f5a8867506678..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/GRUBlockCellReplacement.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.GRUCell import GRUCell
-from openvino.tools.mo.ops.split import AttributedSplit
-from openvino.tools.mo.ops.transpose import Transpose
-
-
-class GRUBlockCellToGRUCell(FrontReplacementPattern):
- """
- This transformation converts TF GRUBlockCell to mo.ops.GRUCell
- by alignment of weights and bias inputs.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for tf_gru_block_cell in graph.get_op_nodes(op='GRUBlockCell'):
- original_name = tf_gru_block_cell.soft_get('name', tf_gru_block_cell.id)
- new_gru_cell = GRUCell(graph, {}).create_node()
- rename_nodes([(tf_gru_block_cell, original_name + '/to_be_removed'), (new_gru_cell, original_name)])
-
- # Connect X data port
- tf_gru_block_cell.in_port(0).get_connection().set_destination(new_gru_cell.in_port(0))
- # Connect hidden state port
- tf_gru_block_cell.in_port(1).get_connection().set_destination(new_gru_cell.in_port(1))
-
- # W (Weights)
- # z - update, r - reset, h - hidden
- # Convert gate order W_rz, W_h -> W_zrh
- split_rz_w = AttributedSplit(graph, {'name': original_name + '/Split_W_rz', 'axis': 1, 'num_splits': 2}).create_node()
-
- # Split W_rz to W_r and W_z
- tf_gru_block_cell.in_port(2).get_connection().set_destination(split_rz_w.in_port(0))
-
- concat_zrh_w = Concat(graph, {'name': original_name + '/Concat_W_zrh', 'in_ports_count': 3,
- 'axis': 1}).create_node()
-
- # Swap and concat gates: W_rz -> W_zr
- split_rz_w.out_port(0).connect(concat_zrh_w.in_port(1))
- split_rz_w.out_port(1).connect(concat_zrh_w.in_port(0))
-
- # Conncat W_h gate: W_zr -> W_zrh
- tf_gru_block_cell.in_port(3).get_connection().set_destination(concat_zrh_w.in_port(2))
-
- # B (Bias)
- # z - update, r - reset, h - hidden
- # Convert gate order B_rz, B_h -> B_zrh
- split_rz_b = AttributedSplit(graph, {'name': original_name + '/Split_B_rz', 'axis': 0, 'num_splits': 2}).create_node()
-
- # Split B_rz to B_r and B_z
- tf_gru_block_cell.in_port(4).get_connection().set_destination(split_rz_b.in_port(0))
-
- concat_zrh_b = Concat(graph, {'name': original_name + '/Concat_B_zrh', 'in_ports_count': 3,
- 'axis': 0}).create_node()
-
- # Swap and concat gates: B_rz -> B_zr
- split_rz_b.out_port(0).connect(concat_zrh_b.in_port(1))
- split_rz_b.out_port(1).connect(concat_zrh_b.in_port(0))
-
- # Concat B_h gate: B_zr -> B_zrh
- tf_gru_block_cell.in_port(5).get_connection().set_destination(concat_zrh_b.in_port(2))
-
- # Transpose W Shape [input_size + hidden_size, 3 * hidden_size] to [3 * hidden_size, input_size + hidden_size]
- permute_order = int64_array([1, 0])
- transpose_w = create_op_node_with_second_input(graph, Transpose, permute_order,
- dict(name=original_name + '/Transpose_W'), concat_zrh_w)
-
- transpose_w.out_port(0).connect(new_gru_cell.in_port(2))
- concat_zrh_b.out_port(0).connect(new_gru_cell.in_port(3))
-
- tf_gru_block_cell.out_port(3).get_connection().set_source(new_gru_cell.out_port(0))
- graph.remove_nodes_from([tf_gru_block_cell.id])
diff --git a/tools/mo/openvino/tools/mo/front/tf/GRUBlockCell_ext.py b/tools/mo/openvino/tools/mo/front/tf/GRUBlockCell_ext.py
deleted file mode 100644
index dd69fc9576d6a7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/GRUBlockCell_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.GRUBlockCell import GRUBlockCell
-
-
-class GRUBlockCellExtractor(FrontExtractorOp):
- op = 'GRUBlockCell'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- GRUBlockCell.update_node_stat(node, {'format': 'tf'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/GatherTree_ext.py b/tools/mo/openvino/tools/mo/front/tf/GatherTree_ext.py
deleted file mode 100644
index 976dbce4797d67..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/GatherTree_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.GatherTree import GatherTree
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class GatherTreeFrontExtractor(FrontExtractorOp):
- op = 'GatherTree'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- GatherTree.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/IteratorGetNextCut.py b/tools/mo/openvino/tools/mo/front/tf/IteratorGetNextCut.py
deleted file mode 100644
index 9f0429cd27bdac..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/IteratorGetNextCut.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from collections import defaultdict
-
-from openvino.tools.mo.front.extractor import add_input_ops
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.convert_data_type import SUPPORTED_DATA_TYPES, np_data_type_to_precision
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-
-
-class IteratorGetNextCut(FrontReplacementPattern):
- """
- Cuts OneShotIterator -> IteratorGetNext pattern
- in order to enable Out Of the Box (OOB) usage.
- Pass is run only if user didn't specify any inputs names and shapes.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['cmd_params'].input is None]
-
- def run_before(self):
- from openvino.tools.mo.front.output_cut import OutputCut
- from openvino.tools.mo.front.input_cut import InputCut
- return [OutputCut, InputCut]
-
- def run_after(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- iter_get_next_shapes = defaultdict(list)
- for iter_get_next in graph.get_op_nodes(op='IteratorGetNext'):
- iter_get_next_name = iter_get_next.soft_get('name', iter_get_next.id)
- for port_idx, port in iter_get_next.out_ports().items():
- if port.disconnected():
- continue
-
- if not np_data_type_to_precision(iter_get_next.types[port_idx]) in SUPPORTED_DATA_TYPES:
- raise Error("In IteratorGetNext node '{}' data type '{}' is not supported".format(
- iter_get_next_name, iter_get_next.types[port_idx]))
-
- iter_get_next_shapes[iter_get_next_name].append(dict(
- shape=iter_get_next.shapes[port_idx],
- out=port_idx,
- data_type=iter_get_next.types[port_idx]
- ))
-
- add_input_ops(graph, iter_get_next_shapes, True)
diff --git a/tools/mo/openvino/tools/mo/front/tf/IteratorGetNext_ext.py b/tools/mo/openvino/tools/mo/front/tf/IteratorGetNext_ext.py
deleted file mode 100644
index eb359ddaa192c1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/IteratorGetNext_ext.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape
-from openvino.tools.mo.ops.op import Op
-
-
-class IteratorGetNextExtractor(FrontExtractorOp):
- op = 'IteratorGetNext'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- shapes = node.pb.attr['output_shapes'].list.shape
- tf_types = node.pb.attr['output_types'].list.type
- extracted_types = []
- for t in tf_types:
- extracted_types.append(tf_dtype_extractor(t))
- result_shapes = []
- for shape_pb in shapes:
- result_shapes.append(tf_tensor_shape(shape_pb))
- Op.update_node_stat(node, {'shapes': result_shapes, 'types': extracted_types, 'out_ports_count': len(result_shapes)})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/LookupTableInsert_ext.py b/tools/mo/openvino/tools/mo/front/tf/LookupTableInsert_ext.py
deleted file mode 100644
index 007125689fb337..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/LookupTableInsert_ext.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.LookupTableInsert import LookupTableInsert
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class LookupTableInsertFrontExtractor(FrontExtractorOp):
- op = 'LookupTableInsert'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LookupTableInsert.update_node_stat(node, {})
- return cls.enabled
-
-
-class LookupTableInsertV2FrontExtractor(FrontExtractorOp):
- op = 'LookupTableInsertV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LookupTableInsert.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/LoopCond_ext.py b/tools/mo/openvino/tools/mo/front/tf/LoopCond_ext.py
deleted file mode 100644
index 4ac722f9683e57..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/LoopCond_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import single_output_infer
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class LoopCondFrontExtractor(FrontExtractorOp):
- op = 'LoopCond'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- node['infer'] = lambda node: single_output_infer(
- node,
- lambda node: node.in_node(0).shape,
- lambda node: node.in_node(0).value
- )
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/MapFNTransformation.py b/tools/mo/openvino/tools/mo/front/tf/MapFNTransformation.py
deleted file mode 100644
index f3f0df9ec07504..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/MapFNTransformation.py
+++ /dev/null
@@ -1,396 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mo_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.WhileNormalize import WhileNormalize
-from openvino.tools.mo.front.tf.custom_subgraph_call import skip_nodes_by_condition
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.middle.pattern_match import find_pattern_matches, inverse_dict
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-def find_subgraph_match_to_pattern(graph: Graph, body_pattern: dict):
- """
- Finds sub-graph matches corresponding pattern in graph
- :param graph: a graph where to search for matched sub-graph
- :param body_pattern: a pattern
- :return: a list of sub-graph matches
- """
- matches = []
- for match in find_pattern_matches(graph, **body_pattern):
- match = inverse_dict(match)
- for k in match:
- match[k] = Node(graph, match[k])
- matches.append(match)
-
- return matches
-
-
-class MapFNInputSlicing(FrontReplacementSubgraph):
- """
- The transformation handles inputs slicing in While loop created by TensorFlow 2 Map Function primitive
- (see tf.map_fn). It avoids TensorListFromTensor and TensorFlowGetItem operations and replaces the original
- sub-graph by adding axis attribute in Loop node for slicing inputs.
- The transformation is also applicable to TensorFlow 2 Keras Simple RNN, GRU, and LSTM layers.
- """
- enabled = True
-
- def run_before(self):
- return [WhileNormalize]
-
- @staticmethod
- def get_body_pattern():
- return dict(
- nodes=[('tensor_list', dict(op='Parameter')),
- ('current_iteration', dict(op='Parameter')),
- ('slicing', dict(op='TensorListGetItem')),
- ('const_increment', dict(op='Const')),
- ('increment_iteration', dict(op='Add')),
- ('increment_iteration_identity', dict(op='Identity')),
- ('increment_iteration_result', dict(op='Result'))],
- edges=[('tensor_list', 'slicing', {'in': 0}),
- ('current_iteration', 'slicing', {'in': 1}),
- ('const_increment', 'increment_iteration', {'in': 1}),
- ('current_iteration', 'increment_iteration', {'in': 0}),
- ('increment_iteration', 'increment_iteration_identity', {'in': 0}),
- ('increment_iteration_identity', 'increment_iteration_result', {'in': 0})]
- )
-
- @staticmethod
- def get_body_pattern_without_identity():
- return dict(
- nodes=[('tensor_list', dict(op='Parameter')),
- ('current_iteration', dict(op='Parameter')),
- ('slicing', dict(op='TensorListGetItem')),
- ('const_increment', dict(op='Const')),
- ('increment_iteration', dict(op='Add')),
- ('increment_iteration_result', dict(op='Result'))],
- edges=[('tensor_list', 'slicing', {'in': 0}),
- ('current_iteration', 'slicing', {'in': 1}),
- ('const_increment', 'increment_iteration', {'in': 1}),
- ('current_iteration', 'increment_iteration', {'in': 0}),
- ('increment_iteration', 'increment_iteration_result', {'in': 0})]
- )
-
- @staticmethod
- def transform_map_fn_input_slicing(external_match: dict, internal_match: dict):
- """
- Transforms TensorFlow 2 input slicing into use of axis attribute for input port of Loop node
- :param external_match: a match used for handling a part of the main graph responsible for input slicing
- :param internal_match: a match used for handling a part of the body graph responsible for input slicing
- """
- loop_node = external_match['while']
- unstack_node = external_match['unstack']
- body_graph = loop_node['body']
-
- tensor_list_get_item_node = internal_match['slicing']
- unstack_placeholder = internal_match['tensor_list']
- tensor_list_get_item_node_name = tensor_list_get_item_node.soft_get('name', tensor_list_get_item_node.id)
-
- # 1. process the body graph to avoid unsupported operations: TensorListGetItem and TensorListSetItem
- # replace TensorListGetItem with Squeeze node and iterate through slices using axis for input port
- squeeze_list_element = create_op_with_const_inputs(body_graph, Squeeze, {1: int64_array(0)},
- {'name': 'TensorListGetItemSqueeze'})
- tensor_list_get_item_node.in_port(0).get_connection().set_destination(squeeze_list_element.in_port(0))
- tensor_list_get_item_node.out_port(0).get_connection().set_source(squeeze_list_element.out_port(0))
- rename_nodes([(tensor_list_get_item_node, tensor_list_get_item_node_name + '/AbandonedName'),
- (squeeze_list_element, tensor_list_get_item_node_name)])
- unstack_placeholder_layer_id = unstack_placeholder.internal_layer_id
- Loop.update_port_map_value_ext(loop_node.input_port_map, 'internal_layer_id', unstack_placeholder_layer_id,
- 'axis', 0)
-
- # 2. process locality of Loop node in the main graph to avoid unsupported operations:
- # TensorListFromTensor, TensorListReserve, and TensorListStack
- # remove TensorListFromTensor and pass a tensor to Loop as is
- unstack_node.out_port(0).get_connection().set_source(unstack_node.in_port(0).get_connection().get_source())
-
- def find_and_replace_pattern(self, graph: Graph):
- for loop_node in graph.get_op_nodes(op='Loop'):
- loop_name = loop_node.soft_get('name', loop_node.id)
- body_graph = loop_node['body']
- body_pattern = MapFNInputSlicing.get_body_pattern()
- body_pattern_without_identity = MapFNInputSlicing.get_body_pattern_without_identity()
- internal_matches = find_subgraph_match_to_pattern(body_graph, body_pattern)
- internal_matches += find_subgraph_match_to_pattern(body_graph, body_pattern_without_identity)
-
- for internal_match in internal_matches:
- # check if TensorListGetItem from the body graph is connected with TensorListFromTensor
- # from the main graph. If yes, the transformation detects input slicing by this port
- # and can use Loop axis attribute
- unstack_node = Loop.get_external_nodes_by_internal_id(loop_node,
- internal_match['tensor_list'].internal_layer_id)
- unstack_node = unstack_node[0] if (len(unstack_node) == 1
- and unstack_node[0].op == 'TensorListFromTensor') else None
- if unstack_node is None:
- log.info("A sub-graph around the loop node {} does not match "
- "TensorFlow 2 MapFN pattern for input slicing".format(loop_name))
- continue
-
- external_match = {'while': loop_node,
- 'unstack': unstack_node}
- # check that back edges connect correct Parameter and Result nodes in the body
- # check connections between body input ports and external inputs ports of Loop node
- if Loop.back_edge_exists(loop_node.back_edges,
- internal_match['increment_iteration_result'].internal_layer_id,
- internal_match['current_iteration'].internal_layer_id):
- MapFNInputSlicing.transform_map_fn_input_slicing(external_match, internal_match)
-
-
-class MapFNOutputConcatenation(FrontReplacementSubgraph):
- """
- The transformation handles inputs slicing in While loop created by TensorFlow 2 Map Function primitive
- (see tf.map_fn). It avoids TensorListReserve, TensorListStack, and TensorListSetItem operations and replaces
- the original sub-graph by adding axis attribute in Loop node for concatenation of intermediate output results.
- The transformation is also applicable to TensorFlow 2 Keras Simple RNN, GRU, and LSTM layers.
- """
- enabled = True
-
- def run_before(self):
- return [WhileNormalize]
-
- @staticmethod
- def get_body_pattern():
- return dict(
- nodes=[('container', dict(op='Parameter')),
- ('current_iteration', dict(op='Parameter')),
- ('const_increment', dict(op='Const')),
- ('increment_iteration', dict(op='Add')),
- ('increment_iteration_identity', dict(op='Identity')),
- ('increment_iteration_result', dict(op='Result')),
- ('concatenation', dict(op='TensorListSetItem')),
- ('concatenation_identity', dict(op='Identity')),
- ('concatenation_result', dict(op='Result')),
- ],
- edges=[('const_increment', 'increment_iteration', {'in': 1}),
- ('current_iteration', 'increment_iteration', {'in': 0}),
- ('container', 'concatenation', {'in': 0}),
- ('current_iteration', 'concatenation', {'in': 1}),
- ('concatenation', 'concatenation_identity', {'in': 0}),
- ('concatenation_identity', 'concatenation_result', {'in': 0}),
- ('increment_iteration', 'increment_iteration_identity', {'in': 0}),
- ('increment_iteration_identity', 'increment_iteration_result', {'in': 0})]
- )
-
- @staticmethod
- def get_body_pattern_without_identity():
- return dict(
- nodes=[('container', dict(op='Parameter')),
- ('current_iteration', dict(op='Parameter')),
- ('const_increment', dict(op='Const')),
- ('increment_iteration', dict(op='Add')),
- ('increment_iteration_result', dict(op='Result')),
- ('concatenation', dict(op='TensorListSetItem')),
- ('concatenation_result', dict(op='Result'))
- ],
- edges=[('const_increment', 'increment_iteration', {'in': 1}),
- ('current_iteration', 'increment_iteration', {'in': 0}),
- ('container', 'concatenation', {'in': 0}),
- ('current_iteration', 'concatenation', {'in': 1}),
- ('concatenation', 'concatenation_result', {'in': 0}),
- ('increment_iteration', 'increment_iteration_result', {'in': 0})
- ]
- )
-
- @staticmethod
- def transform_map_fn_output_concatenation(external_match: dict, internal_match: dict):
- """
- Transforms TensorFlow 2 output concatenation into use of axis attribute for output port of Loop node
- :param external_match: a match used for handling a part of the main graph responsible for output concatenation
- :param internal_match: a match used for handling a part of the body graph responsible for output concatenation
- """
- loop_node = external_match['while']
- stack_node = external_match['stack']
- list_reserve_node = external_match['reserve']
- body_graph = loop_node['body']
-
- tensor_list_set_item_node = internal_match['concatenation']
- tensor_list_set_item_node_name = tensor_list_set_item_node.soft_get('name', tensor_list_set_item_node.id)
- list_result_node = internal_match['concatenation_result']
-
- # replace TensorListSetItem with Unsqueeze and use axis attribute for corresponding Result node
- # to concatenate results from different iterations
- unsqueeze_list_element = create_op_with_const_inputs(body_graph, Unsqueeze, {1: int64_array(0)},
- {'name': 'TensorListSetItemUnsqueeze'})
- tensor_list_set_item_node.in_port(2).get_connection().set_destination(unsqueeze_list_element.in_port(0))
- tensor_list_set_item_node.out_port(0).get_connection().set_source(unsqueeze_list_element.out_port(0))
- rename_nodes([(tensor_list_set_item_node, tensor_list_set_item_node_name + '/AbandonedName'),
- (unsqueeze_list_element, tensor_list_set_item_node_name)])
- list_result_node_layer_id = list_result_node.internal_layer_id
- Loop.update_port_map_value_ext(loop_node.output_port_map, 'internal_layer_id', list_result_node_layer_id,
- 'axis', 0)
-
- # remove TensorListStack to by-pass the node since the result from the Loop node is already concatenated
- stack_node.out_port(0).get_connection().set_source(stack_node.in_port(0).get_connection().get_source())
-
- # disconnect ListReserve node because it is no longer needed for Loop
- list_reserve_node.out_port(0).disconnect()
-
- # connect a number of iterations with trip count that can be received from the second input of ListReserve
- # create a constant network with True value for execution_condition so that OV can ignore execution condition
- # and perform trip_counts iterations. This approach with known trip count value allows to avoid dynamism.
- loop_node.in_port(1).disconnect()
- list_reserve_node.in_port(1).get_source().connect(loop_node.in_port(1))
- for record in loop_node.output_port_map:
- if 'purpose' in record and record['purpose'] == 'execution_condition':
- exec_cond_layer_id = record['internal_layer_id']
- exec_cond_node = Loop.get_body_node_by_internal_id(loop_node, exec_cond_layer_id)
- const_true = Const(body_graph, {'value': mo_array(True, dtype=bool)}).create_node()
- exec_cond_node.in_port(0).get_connection().set_source(const_true.out_port(0))
-
- # remove back edge
- for record in loop_node.back_edges:
- if 'from_layer' in record and record['from_layer'] == list_result_node_layer_id:
- loop_node.back_edges.remove(record)
-
- def find_and_replace_pattern(self, graph: Graph):
- for loop_node in graph.get_op_nodes(op='Loop'):
- loop_name = loop_node.soft_get('name', loop_node.id)
- body_graph = loop_node['body']
- body_pattern = MapFNOutputConcatenation.get_body_pattern()
- body_pattern_without_identity = MapFNOutputConcatenation.get_body_pattern_without_identity()
- internal_matches = find_subgraph_match_to_pattern(body_graph, body_pattern)
- internal_matches += find_subgraph_match_to_pattern(body_graph, body_pattern_without_identity)
-
- for internal_match in internal_matches:
- # check if TensorListReserve from the main graph is connected with Parameter node from the body graph
- # that is assigned for storing intermediate output results of While Loop. If yes, the transformation
- # detects intermediate outputs concatenation by this port and can use Loop axis attribute
- reserve_node = Loop.get_external_nodes_by_internal_id(loop_node,
- internal_match['container'].internal_layer_id)
- reserve_node = reserve_node[0] if (len(reserve_node) == 1 and
- reserve_node[0].op == 'TensorListReserve') else None
- if reserve_node is None:
- log.info("A sub-graph around the loop node {} does not match "
- "TensorFlow 2 MapFN pattern for intermediate outputs concatenation".format(loop_name))
- continue
- stack_node = Loop.get_external_nodes_by_internal_id(
- loop_node, internal_match['concatenation_result'].internal_layer_id)
- stack_node = stack_node[0] if len(stack_node) == 1 else None
-
- if stack_node is None:
- log.info("A sub-graph around the loop node {} does not match "
- "TensorFlow 2 MapFN pattern for intermediate outputs concatenation".format(loop_name))
- continue
-
- # skip StopGradient node if it exists between While loop output port and TensorListStack operation
- stack_node = skip_nodes_by_condition(stack_node, lambda x: x.has_and_set('identity'), True)
- stack_node = stack_node if stack_node.op == 'TensorListStack' else None
- if stack_node is None:
- log.info("A sub-graph around the loop node {} does not match "
- "TensorFlow 2 MapFN pattern for intermediate outputs concatenation".format(loop_name))
- continue
-
- external_match = {'while': loop_node,
- 'reserve': reserve_node,
- 'stack': stack_node}
- # check that back edges connect Parameter node (or container with intermediate output results)
- # and concatenation result produced by TensorListSetItem node
- if Loop.back_edge_exists(loop_node.back_edges, internal_match['concatenation_result'].internal_layer_id,
- internal_match['container'].internal_layer_id) and \
- Loop.back_edge_exists(loop_node.back_edges,
- internal_match['increment_iteration_result'].internal_layer_id,
- internal_match['current_iteration'].internal_layer_id):
- MapFNOutputConcatenation.transform_map_fn_output_concatenation(external_match, internal_match)
-
-
-class TensorListOutputConcatenation(FrontReplacementSubgraph):
- """
- The transformation handles inputs slicing in While loop. It avoids TensorListPushBack, and EmptyTensorList
- operations and replaces the original sub-graph by adding axis attribute in Loop node for concatenation of
- intermediate output results.
- """
- enabled = True
-
- def run_before(self):
- return [WhileNormalize]
-
- @staticmethod
- def get_body_pattern():
- return dict(
- nodes=[('container', dict(op='Parameter')),
- ('concatenation', dict(op='TensorListPushBack')),
- ('concatenation_result', dict(op='Result'))
- ],
- edges=[
- ('container', 'concatenation', {'in': 0}),
- ('concatenation', 'concatenation_result', {'in': 0}),
- ]
- )
-
- @staticmethod
- def transform_tensor_list_output_concatenation(external_match: dict, internal_match: dict):
- """
- Transforms TensorFlow 2 output concatenation into use of axis attribute for output port of Loop node
- :param external_match: a match used for handling a part of the main graph responsible for output concatenation
- :param internal_match: a match used for handling a part of the body graph responsible for output concatenation
- """
- loop_node = external_match['while']
- empty_tensor_list_node = external_match['reserve']
- body_graph = loop_node['body']
-
- tensor_list_push_back_node = internal_match['concatenation']
- tensor_list_push_back_node_name = tensor_list_push_back_node.soft_get('name', tensor_list_push_back_node.id)
- list_result_node = internal_match['concatenation_result']
-
- # replace TensorListPushBack with Unsqueeze and use axis attribute for corresponding Result node
- # to concatenate results from different iterations
- unsqueeze_list_element = create_op_with_const_inputs(body_graph, Unsqueeze, {1: int64_array(0)},
- {'name': tensor_list_push_back_node_name +
- '/TensorListPushBackUnsqueeze'})
- tensor_list_push_back_node.in_port(1).get_connection().set_destination(unsqueeze_list_element.in_port(0))
- tensor_list_push_back_node.out_port(0).get_connection().set_source(unsqueeze_list_element.out_port(0))
- rename_nodes([(tensor_list_push_back_node, tensor_list_push_back_node_name + '/AbandonedName'),
- (unsqueeze_list_element, tensor_list_push_back_node_name)])
- list_result_node_layer_id = list_result_node.internal_layer_id
- Loop.update_port_map_value_ext(loop_node.output_port_map, 'internal_layer_id', list_result_node_layer_id,
- 'axis', 0)
-
- # disconnect EmptyTensorList node because it is no longer needed for Loop
- empty_tensor_list_node.out_port(0).disconnect()
-
- loop_node.in_port(1).disconnect()
- empty_tensor_list_node.in_port(1).get_source().connect(loop_node.in_port(1))
-
- # remove back edge
- for record in loop_node.back_edges:
- if 'from_layer' in record and record['from_layer'] == list_result_node_layer_id:
- loop_node.back_edges.remove(record)
-
- def find_and_replace_pattern(self, graph: Graph):
- for loop_node in graph.get_op_nodes(op='Loop'):
- loop_name = loop_node.soft_get('name', loop_node.id)
- body_graph = loop_node['body']
- body_pattern = TensorListOutputConcatenation.get_body_pattern()
- internal_matches = find_subgraph_match_to_pattern(body_graph, body_pattern)
-
- for internal_match in internal_matches:
- # check if EmptyTensorList from the main graph is connected with Parameter node from the body graph
- # that is assigned for storing intermediate output results of While Loop. If yes, the transformation
- # detects intermediate outputs concatenation by this port and can use Loop axis attribute
- reserve_node = Loop.get_external_nodes_by_internal_id(loop_node,
- internal_match['container'].internal_layer_id)
- reserve_node = reserve_node[0] if (len(reserve_node) == 1 and
- reserve_node[0].op == 'EmptyTensorList') else None
- if reserve_node is None:
- log.info("A sub-graph around the loop node {} does not match "
- "TensorFlow 2 EmptyTensorList->TensorListPushBack pattern for intermediate "
- "outputs concatenation".format(loop_name))
- continue
-
- external_match = {'while': loop_node,
- 'reserve': reserve_node}
- # check that back edges connect Parameter node (or container with intermediate output results)
- # and concatenation result produced by TensorListPushBack node
- if Loop.back_edge_exists(loop_node.back_edges, internal_match['concatenation_result'].internal_layer_id,
- internal_match['container'].internal_layer_id):
- TensorListOutputConcatenation.transform_tensor_list_output_concatenation(external_match,
- internal_match)
diff --git a/tools/mo/openvino/tools/mo/front/tf/NonConstBeginStridedSliceReplacement.py b/tools/mo/openvino/tools/mo/front/tf/NonConstBeginStridedSliceReplacement.py
deleted file mode 100644
index 1b5c7cd10e8daf..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/NonConstBeginStridedSliceReplacement.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class NonConstBeginStridedSliceReplacement(FrontReplacementSubgraph):
- r"""
- The transformation handles StridedSlice operation with dynamic begin and end values
- when slicing performs along just one dimension with a dynamic index.
- For example, StridedSlice with begin=(0,idx,0), end=(0,idx+1,0),
- and begin_mask=end_mask=shrink_mask=(0, 1, 0) can be replaced with Squeeze(axis=1;Gather(axis=1; Unsqueeze(idx))).
- The transformation attempts to match to following sub-graph:
-
- Input ----> StridedSlice(begin_mask, end_mask, and shrink_mask where only element for axis equal to 1) --> OTHER OPS
- /\ /\ /\
- | | |
- ---------> Pack(Begin) Pack(End) Const(Step) = (1,..,1)
- | /\ /\ /\
- | | | |
- | | | Const(All others)
- | Const(All others) |
- Index ---------------------------> Add
- /\
- Const(SliceSize)=1------------------|
-
- And the original sub-graph is transformed as follows:
-
- Input --------> Gather(axis) ---> Squeeze(axis) ---> OTHER OPS
- /\
- |
- Index -----> Unsqueeze(axis=1)
-
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.Pack import Pack
- return [Pack]
-
- @staticmethod
- def pattern(**kwargs):
- return dict(
- nodes=[('begin', dict(op='Pack')),
- ('end', dict(op='Pack')),
- ('step', dict(op='Const')),
- ('strided_slice', dict(op='StridedSlice')),
- ],
- edges=[('begin', 'strided_slice', {'in': 1}),
- ('end', 'strided_slice', {'in': 2}),
- ('step', 'strided_slice', {'in': 3})])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- strided_slice_node = match['strided_slice']
- begin_node = match['begin']
- end_node = match['end']
- step_node = match['step']
-
- # retrieve attribute values
- begin_mask = strided_slice_node.soft_get('begin_mask')
- end_mask = strided_slice_node.soft_get('end_mask')
- shrink_mask = strided_slice_node.soft_get('shrink_axis_mask', int64_array([0]))
-
- # check applicability of this transformation to the given sub-graph:
- # 1. check that slicing is performed along just one axis
- if np.sum(begin_mask) != 1 or np.sum(end_mask) != 1 or np.sum(shrink_mask) != 1:
- return
- # 2. check that shrink axis is equal to slicing axis
- if not np.array_equal(np.argwhere(begin_mask == 1), np.argwhere(end_mask == 1)) or \
- not np.array_equal(np.argwhere(begin_mask == 1), np.argwhere(shrink_mask == 1)):
- return
- sliced_axis = np.argwhere(begin_mask == 1)[0][0]
- # 3. check constant nodes for begin and end correspond to non-slicing axes
- for idx_port, in_port in begin_node.in_ports().items():
- if idx_port != sliced_axis and in_port.get_source().node.soft_get('type') != 'Const' or \
- idx_port == sliced_axis and in_port.get_source().node.soft_get('type') == 'Const':
- return
- for idx_port, in_port in end_node.in_ports().items():
- if idx_port != sliced_axis and in_port.get_source().node.soft_get('type') != 'Const' or \
- idx_port == sliced_axis and in_port.get_source().node.soft_get('type') == 'Const':
- return
- # 4. check that offset of begin and end values for slicing axis is constant
- add_node = end_node.in_port(sliced_axis).get_source().node
- slice_start_index_node = begin_node.in_port(sliced_axis).get_source().node
- if add_node.soft_get('type') != 'Add':
- return
-
- if add_node.in_port(1).get_source().node.soft_get('type') == 'Const':
- slice_size_node = add_node.in_port(1).get_source().node
- if add_node.in_port(0).get_source().node.id != slice_start_index_node.id:
- return
- elif add_node.in_port(0).get_source().node.soft_get('type') == 'Const':
- slice_size_node = add_node.in_port(0).get_source().node
- if add_node.in_port(1).get_source().node.id != slice_start_index_node.id:
- return
- else:
- return
- slice_size = slice_size_node.value
- step_value = step_node.value[sliced_axis]
-
- # 5. check that step_value equal to 1 and step_value equal to 1
- # TODO: support other cases when slice_size not equal to 1 and step_value not equal to 1
- if slice_size != 1 or step_value != 1:
- return
-
- # unsqueeze a scalar by which to slice input tensor
- strided_slice_name = strided_slice_node.soft_get('name', strided_slice_node.id)
- unsqueeze_node = create_op_with_const_inputs(graph, Unsqueeze, {1: int64_array(0)},
- {'name': strided_slice_name + '/Unsqueeze'})
- add_node.in_port(0).get_connection().add_destination(unsqueeze_node.in_port(0))
-
- # replace StridedSlice with Gather operation that supports dynamic indices for slicing
- gather_node = create_op_with_const_inputs(graph, Gather, {2: int64_array(sliced_axis)},
- {'name': strided_slice_name + '/Gather'})
- strided_slice_node.in_port(0).get_connection().set_destination(gather_node.in_port(0))
- unsqueeze_node.out_port(0).connect(gather_node.in_port(1))
-
- # squeeze Gather output since sliced axis is shrinked
- squeeze_node = create_op_with_const_inputs(graph, Squeeze, {1: int64_array(sliced_axis)},
- {'name': strided_slice_name + '/Squeeze'})
- squeeze_node.in_port(0).connect(gather_node.out_port(0))
- rename_nodes(
- [(strided_slice_node, strided_slice_name + '/AbandonedName'), (squeeze_node, strided_slice_name)])
-
- # preserve a name of original StridedSlice node
- strided_slice_node.out_port(0).get_connection().set_source(squeeze_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/tf/ObjectDetectionAPI.py b/tools/mo/openvino/tools/mo/front/tf/ObjectDetectionAPI.py
deleted file mode 100644
index 3c94f408884218..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ObjectDetectionAPI.py
+++ /dev/null
@@ -1,1865 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-"""
-The file contains necessary transformations to convert models created with a TensorFlow Object Detection framework from
-the https://github.com/tensorflow/models/blob/master/research/object_detection/ repository. There is a dedicated
-OpenVINO document describing overall procedure of conversion these models with the Model Optimizer:
-https://docs.openvino.ai/2023.0/openvino_docs_MO_DG_prepare_model_convert_model_tf_specific_Convert_Object_Detection_API_Models.html
-
-Conversion of most of the TF OD API models requires execution of several transformations defined in this file. The list
-of transformations to be executed for a particular model type (meta-architecture) is defined in the transformation
-configuration JSON file located in the "openvino/tools/mo/front/tf/" directory. A file should be specified using the
-"--transformations_config" command line parameter. An additional parameter
-"--tensorflow_object_detection_api_pipeline_config" should be specified with the path to the pipeline.config used for
-the model training.
-
-Refer to the code comments of a particular transformation for the explanation of its purpose and low-level
-implementation details.
-"""
-import collections
-import logging as log
-from math import sqrt
-
-import numpy as np
-
-from openvino.tools.mo.front.Pack import Pack
-from openvino.tools.mo.front.TransposeOrderNormalizer import TransposeOrderNormalizer
-from openvino.tools.mo.front.split_normalizer import SqueezeAxis
-from openvino.tools.mo.front.tf.CropAndResizeReplacement import CropAndResizeReplacement
-from openvino.tools.mo.front.FakeQuantWithMinMaxVars import FakeQuantWithMinMaxVarsToQuantize
-from openvino.tools.mo.front.tf.MapFNTransformation import MapFNInputSlicing, MapFNOutputConcatenation,\
- TensorListOutputConcatenation
-from openvino.tools.mo.front.tf.TFSliceToSlice import TFSliceToSliceReplacer
-from openvino.tools.mo.front.tf.pad_tf_to_pad import PadTFToPad
-from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import mark_as_correct_data_layout, \
- mark_input_as_in_correct_layout, mark_output_as_in_correct_layout
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.DetectionOutput import DetectionOutput
-from openvino.tools.mo.ops.ReduceOps import ReduceMean
-from openvino.tools.mo.ops.activation_ops import Sigmoid
-from openvino.tools.mo.ops.elementwise import Mul, Sub, Add, Div
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.ops.priorbox_clustered import PriorBoxClusteredOp
-from openvino.tools.mo.ops.proposal import ProposalOp
-from openvino.tools.mo.ops.psroipooling import PSROIPoolingOp
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.layout import get_batch_dim, get_height_dim, get_width_dim
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension, mo_array, dynamic_dimension_value
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.extractor import output_user_data_repack, add_output_ops
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.custom_subgraph_call import skip_nodes_by_condition
-from openvino.tools.mo.front.tf.graph_utils import add_activation_function_after_node, add_convolution_to_swap_xy_coordinates, \
- add_fake_background_loc, create_op_node_with_second_input, create_op_with_const_inputs
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileSubGraph, FrontReplacementFromConfigFileGeneral
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.clamp import AttributedClamp
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.op import PermuteAttrs
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.ops.roipooling import ROIPooling
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.softmax import Softmax
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.tile import Tile
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.graph import backward_bfs_for_operation, bfs_search, clear_tensor_names_info, sub_graph_between_nodes
-from openvino.tools.mo.utils.pipeline_config import PipelineConfig
-from openvino.tools.mo.utils.shape import node_to_get_shape_value_of_indices
-
-missing_param_error = 'To convert the model specify path to the pipeline configuration file which was used to ' \
- 'generate the model. Please use "--tensorflow_object_detection_api_pipeline_config" option:\n' \
- '--tensorflow_object_detection_api_pipeline_config ""\nIf you have ' \
- 'downloaded the model file from the Object Detection Model zoo repository then this file is ' \
- 'located in the archive with frozen model and called "pipeline.config".\nIf you did not use ' \
- 'this command line parameter before that means that you are using currently deprecated ' \
- 'TensorFlow* Object Detection API models conversion mechanism.'
-
-
-def _value_or_raise(match: SubgraphMatch, pipeline_config: PipelineConfig, key: str):
- """
- Returns value from the 'custom_attributes' of the 'match' object or pipeline_config associated with a key 'key'.
- If the value doesn't exist then raise error.
- :param match: SubgraphMatch object containing 'custom_attributes'.
- :param pipeline_config: PipelineConfig object with parsed values.
- :param key: key to search for.
- :return: the requested value.
- """
- if match and key in match.custom_replacement_desc.custom_attributes:
- return match.custom_replacement_desc.custom_attributes[key]
- value = pipeline_config.get_param(key)
- if value is None:
- raise Error('The sub-graph replacer "[REPLACEMENT_ID]" was not able to find the value for key "{}" in the '
- 'pipeline configuration file specified with the --tensorflow_object_detection_api_pipeline_config '
- 'command line parameter. Update the sub-graph replacement configuration file specified with the '
- '--transformations_config command line parameter by adding key "{}" with required '
- 'value to the "custom_attributes" dictionary of the "[REPLACEMENT_ID]" replacer.'.format(key, key))
- return value
-
-
-def _find_ssd_head_node(graph: Graph, ssd_head_index: int, head_type: str):
- """
- Finds the SSD head node with index 'ssd_head_index' in the topology. The parameter 'head_type' specifies what type
- of the head is requested: with box predictions or class predictions.
- :param graph: graph with the topology.
- :param ssd_head_index: index of the SSD head.
- :param head_type: either 'box' or 'class' string specifying type of the SSD head node.
- :return: the requested Node or None if node is not found.
- """
- if head_type == 'box':
- possible_node_names = ['BoxPredictor_%d/BoxEncodingPredictor/BiasAdd' % ssd_head_index,
- 'WeightSharedConvolutionalBoxPredictor/BoxPredictor/BiasAdd' if ssd_head_index == 0 else
- 'WeightSharedConvolutionalBoxPredictor_%d/BoxPredictor/BiasAdd' % ssd_head_index]
- elif head_type == 'class':
- possible_node_names = ['BoxPredictor_%d/ClassPredictor/BiasAdd' % ssd_head_index,
- 'WeightSharedConvolutionalBoxPredictor/ClassPredictor/BiasAdd' if ssd_head_index == 0
- else 'WeightSharedConvolutionalBoxPredictor_%d/ClassPredictor/BiasAdd' % ssd_head_index]
- else:
- raise Error('SSD heads can be of type "box" and "class" only.')
-
- head_node = None
- for head_node_name in possible_node_names:
- if head_node_name in graph.nodes():
- assert (head_node is None) # only one of the possible node names should exist in the graph
- head_node = Node(graph, head_node_name)
- return head_node
-
-
-def _variance_from_pipeline_config(pipeline_config: PipelineConfig):
- """
- Generates a numpy array with variances values from the pipeline_config object. The order of the elements is the
- following: variance x, variance y, variance box width, variance box height.
- :param pipeline_config: pipeline_config object to get variances from.
- :return: the numpy array with variances.
- """
- return 1.0 / mo_array([pipeline_config.get_param('frcnn_variance_x'),
- pipeline_config.get_param('frcnn_variance_y'),
- pipeline_config.get_param('frcnn_variance_width'),
- pipeline_config.get_param('frcnn_variance_height')])
-
-
-def _skip_node_of_type(node: Node, node_ops_to_skip: list):
- """
- Skips nodes of specified ops starting from node 'node'.
- :param node: node to start skipping Identity nodes.
- :return: node of the op
- """
- # skip the Identity node
- while len(node.out_edges()) == 1 and node.op in node_ops_to_skip:
- node = node.out_node()
- return node
-
-
-def _relax_reshape_nodes(graph: Graph, pipeline_config: PipelineConfig):
- """
- Finds the 'Reshape' operations following the SSD head nodes which have hard-coded output dimensions and replaces
- them with new ones with one of the dimensions sizes equal to -1. This function is used to make TF OD API SSD models
- reshape-able.
- :param graph: graph with the topology.
- :param pipeline_config: PipelineConfig object with parsed values.
- :return: None
- """
- num_classes = pipeline_config.get_param('num_classes')
- num_layers = pipeline_config.get_param('ssd_anchor_generator_num_layers')
- if num_layers is None:
- num_layers = pipeline_config.get_param('multiscale_anchor_generator_max_level') - \
- pipeline_config.get_param('multiscale_anchor_generator_min_level') + 1
- for ssd_head_ind in range(num_layers):
- input_node = _find_ssd_head_node(graph, ssd_head_ind, 'box')
- assert (input_node is not None)
- old_reshape_node = _skip_node_of_type(input_node.out_node(),
- ['Identity', 'FakeQuantWithMinMaxVars', 'FakeQuantize'])
- assert old_reshape_node.op == 'Reshape'
- reshape_size_node = Const(graph, {'value': int64_array([0, -1, 1, 4])}).create_node([])
- new_reshape_op = Reshape(graph, {'name': input_node.id + '/Reshape'})
- new_reshape_node = new_reshape_op.create_node([input_node, reshape_size_node])
- old_reshape_node.replace_node(new_reshape_node)
-
- # fix hard-coded value for the number of items in tensor produced by the convolution to make topology reshapable
- input_node = _find_ssd_head_node(graph, ssd_head_ind, 'class')
- assert (input_node is not None)
- old_reshape_node = _skip_node_of_type(input_node.out_node(),
- ['Identity', 'FakeQuantWithMinMaxVars', 'FakeQuantize'])
-
- assert old_reshape_node.op == 'Reshape'
- reshape_size_node_2 = Const(graph, {'value': int64_array([0, -1, num_classes + 1])}).create_node([])
- new_reshape_op_2 = Reshape(graph, {'name': input_node.id + '/Reshape'})
- new_reshape_node_2 = new_reshape_op_2.create_node([input_node, reshape_size_node_2])
- old_reshape_node.replace_node(new_reshape_node_2)
-
-
-def _create_prior_boxes_node(graph: Graph, pipeline_config: PipelineConfig):
- """
- The function creates one or several PriorBoxClustered nodes based on information from the pipeline configuration
- files. The PriorBoxClustered nodes get input data from SSD 'heads' and from the placeholder node (just to get
- input image size).
- :param graph: graph with the topology.
- :param pipeline_config: PipelineConfig object with parsed values.
- :return: node generating prior boxes.
- """
- min_scale = pipeline_config.get_param('ssd_anchor_generator_min_scale')
- max_scale = pipeline_config.get_param('ssd_anchor_generator_max_scale')
- num_layers = pipeline_config.get_param('ssd_anchor_generator_num_layers')
- aspect_ratios = pipeline_config.get_param('ssd_anchor_generator_aspect_ratios')
- if not isinstance(aspect_ratios, list):
- aspect_ratios = [aspect_ratios]
-
- # prior boxes have to be generated using the image size used for training
- image_height = pipeline_config.get_param('resizer_image_height')
- image_width = pipeline_config.get_param('resizer_image_width')
- min_im_shape = min(image_height, image_width)
- _base_anchor_height = pipeline_config.get_param('ssd_anchor_generator_base_anchor_height')
- _base_anchor_width = pipeline_config.get_param('ssd_anchor_generator_base_anchor_width')
- base_anchor_size = [min_im_shape / image_height * _base_anchor_height,
- min_im_shape / image_width * _base_anchor_width]
- reduce_boxes_in_lowest_layer = True
- if pipeline_config.get_param('ssd_anchor_generator_reduce_lowest') is not None:
- reduce_boxes_in_lowest_layer = pipeline_config.get_param('ssd_anchor_generator_reduce_lowest')
-
- if pipeline_config.get_param('ssd_anchor_generator_scales') is not None:
- scales = pipeline_config.get_param('ssd_anchor_generator_scales') + [1.0]
- else:
- scales = [min_scale + (max_scale - min_scale) * i / (num_layers - 1) for i in range(num_layers)] + [1.0]
-
- prior_box_nodes = []
- for ssd_head_ind in range(num_layers):
- ssd_head_node = _find_ssd_head_node(graph, ssd_head_ind, 'box')
- assert (ssd_head_node is not None)
-
- if ssd_head_ind == 0 and reduce_boxes_in_lowest_layer:
- widths = [0.1, min_scale * sqrt(2.0), min_scale * sqrt(0.5)]
- heights = [0.1, min_scale / sqrt(2.0), min_scale / sqrt(0.5)]
- else:
- widths = [scales[ssd_head_ind] * sqrt(ar) for ar in aspect_ratios]
- heights = [scales[ssd_head_ind] / sqrt(ar) for ar in aspect_ratios]
-
- interpolated_scale_ar = pipeline_config.get_param('ssd_anchor_generator_interpolated_scale_aspect_ratio')
- if interpolated_scale_ar > 0.0:
- widths += [sqrt(scales[ssd_head_ind] * scales[ssd_head_ind + 1]) * interpolated_scale_ar]
- heights += [sqrt(scales[ssd_head_ind] * scales[ssd_head_ind + 1]) / interpolated_scale_ar]
- widths = [w * image_width * base_anchor_size[1] for w in widths]
- heights = [h * image_height * base_anchor_size[0] for h in heights]
-
- variance = _variance_from_pipeline_config(pipeline_config)
- prior_box_op = PriorBoxClusteredOp(graph, {'width': mo_array(widths), 'height': mo_array(heights),
- 'clip': 0, 'flip': 0, 'variance': variance, 'offset': 0.5,
- })
- # connect the PriorBoxClustered node with the "Cast" node of the Placeholder node because the pass that removes
- # Cast operations is executed in the middle phase and it will fail when there are several consumers of the
- # Placeholder
- input_node_name = 'image_tensor' if 'image_tensor' in graph.nodes else 'input_tensor'
- prior_box_node = prior_box_op.create_node([ssd_head_node, Node(graph, input_node_name).out_node(0)],
- {'name': 'PriorBoxClustered_{}'.format(ssd_head_ind)})
- prior_box_nodes.append(prior_box_node)
- if len(prior_box_nodes) == 1:
- return prior_box_nodes[0]
- else:
- concat_prior_boxes_op = Concat(graph, {'axis': -1, 'in_ports_count': len(prior_box_nodes)})
- return concat_prior_boxes_op.create_node(prior_box_nodes, {'name': 'ConcatPriorBoxesClustered'})
-
-
-def _create_multiscale_prior_boxes_node(graph: Graph, pipeline_config: PipelineConfig):
- """
- The function creates one or several PriorBoxClustered nodes based on information from the pipeline configuration
- files. The PriorBoxClustered nodes get input data from SSD 'heads' and from the placeholder node (just to get
- input image size).
- :param graph: graph with the topology.
- :param pipeline_config: PipelineConfig object with parsed values.
- :return: node generating prior boxes.
- """
- min_level = pipeline_config.get_param('multiscale_anchor_generator_min_level')
- max_level = pipeline_config.get_param('multiscale_anchor_generator_max_level')
- anchor_scale = pipeline_config.get_param('multiscale_anchor_generator_anchor_scale')
- aspect_ratios = pipeline_config.get_param('multiscale_anchor_generator_aspect_ratios')
- scales_per_octave = pipeline_config.get_param('multiscale_anchor_generator_scales_per_octave')
-
- prior_box_nodes = []
- scales = [2 ** (float(scale) / scales_per_octave) for scale in range(scales_per_octave)]
- for level in range(min_level, max_level + 1):
- base_anchor_size = 2 ** level * anchor_scale
-
- ssd_head_ind = level - min_level
- ssd_head_node = _find_ssd_head_node(graph, ssd_head_ind, 'box')
- assert (ssd_head_node is not None)
-
- widths = [base_anchor_size * scale * sqrt(ar) for ar in aspect_ratios for scale in scales]
- heights = [base_anchor_size * scale / sqrt(ar) for ar in aspect_ratios for scale in scales]
-
- variance = _variance_from_pipeline_config(pipeline_config)
- prior_box_op = PriorBoxClusteredOp(graph, {'width': mo_array(widths), 'height': mo_array(heights),
- 'clip': 0, 'flip': 0, 'variance': variance,
- 'offset': 0.5,
- })
- # connect the PriorBoxClustered node with the "Cast" node of the Placeholder node because the pass that removes
- # Cast operations is executed in the middle phase and it will fail when there are several consumers of the
- # Placeholder
- prior_box_node = prior_box_op.create_node([ssd_head_node, Node(graph, 'image_tensor').out_node(0)],
- {'name': 'PriorBoxClustered_{}'.format(ssd_head_ind)})
- prior_box_nodes.append(prior_box_node)
- if len(prior_box_nodes) == 1:
- return prior_box_nodes[0]
- else:
- concat_prior_boxes_op = Concat(graph, {'axis': -1, 'in_ports_count': len(prior_box_nodes)})
- return concat_prior_boxes_op.create_node(prior_box_nodes, {'name': 'ConcatPriorBoxesClustered'})
-
-
-def insert_weights_swap_xy_sub_graph(graph: Graph, connection):
- """
- Inserts a sub-graph of operations which does the following:
- 1. Reshapes the input tensor (should be convolution weights/biases) to [-1, 2].
- 2. Swaps slices of data [:, 0] and [:, 1].
- 3. Reshapes tensor to the initial shape.
- """
- weights_producer = connection.get_source()
- name = weights_producer.node.soft_get('name', weights_producer.node.id)
-
- # this Shape operation must be inferred and constant folded
- origin_shape = Shape(graph, {'name': name + '/OriginShape', 'force_dead_node': True}).create_node()
- origin_shape.in_port(0).connect(weights_producer)
-
- reshaped = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 2]), {'name': name + '/Reshape2D'})
- reshaped.in_port(0).connect(weights_producer)
-
- swapped_weight = Gather(graph, {'name': name + '/SwappedWeights'}).create_node()
- gather_indices = Const(graph,
- {'name': swapped_weight.name + '/Indices', 'value': int64_array([1, 0])}).create_node()
- gather_axis = Const(graph, {'name': swapped_weight.name + '/Axis', 'value': int64_array(1)}).create_node()
- swapped_weight.in_port(0).connect(reshaped.out_port(0))
- swapped_weight.in_port(1).connect(gather_indices.out_port(0))
- swapped_weight.in_port(2).connect(gather_axis.out_port(0))
-
- reshape_back = Reshape(graph, {'name': name + '/ReshapeBack'}).create_node()
- reshape_back.in_port(0).connect(swapped_weight.out_port(0))
- reshape_back.in_port(1).connect(origin_shape.out_port(0))
-
- connection.set_source(reshape_back.out_port(0))
-
-
-def swap_weights_xy(graph: Graph, nodes: list):
- """
- The function changes weights of the nodes from the 'nodes' list which are used with calculations with coordinates of
- some objects. The function should be used when it is necessary to virtually change the layout of data from XY to YX.
- The node from the 'nodes' list should be some sort of convolution node or matrix multiplication.
- The function also swaps weights in the following Add and BiasAdd operations.
- :param graph: graph with the topology.
- :param nodes: list of Node objects to change the weights in them.
- :return: None
- """
- producers_ports = set()
- for node in nodes:
- # need to skip the FakeQuantize node if it exists
- weights_producer = node.in_port(1).get_source()
- if weights_producer.node.soft_get('type') == 'FakeQuantize':
- weights_producer = weights_producer.node.in_port(0).get_source()
- producers_ports.add(weights_producer)
-
- for producers_port in producers_ports:
- log.debug('Swapping weights for node "{}"'.format(producers_port.node.name))
- insert_weights_swap_xy_sub_graph(graph, producers_port.get_connection())
-
- for node in nodes:
- # swap biases
- for m in [n.node for n in node.out_port(0).get_destinations()]:
- if m.soft_get('type') in ['Add', 'BiasAdd']:
- insert_weights_swap_xy_sub_graph(graph, m.in_port(1).get_connection())
-
-
-def calculate_shape_keeping_aspect_ratio(height: int, width: int, min_size: int, max_size: int):
- """
- The function changes spatial sizes of the image keeping aspect ratio to satisfy provided requirements.
- The behavior of this function is equivalent to the output shape calculation of the pre-processor block of TensorFlow
- Object Detection API models with keep aspect ratio resizer.
-
- :param height: input height.
- :param width: input width.
- :param min_size: size limit.
- :param max_size: size limit.
- :return: the tuple with scaled image height, width.
- """
- ratio_min = min_size / min(height, width)
- ratio_max = max_size / max(height, width)
- ratio = min(ratio_min, ratio_max)
- return int(round(height * ratio)), int(round(width * ratio))
-
-
-def calculate_placeholder_spatial_shape(graph: Graph, match: SubgraphMatch, pipeline_config: PipelineConfig):
- """
- The function calculates the preprocessed shape of the input image for a TensorFlow Object Detection API model.
- It uses various sources to calculate it:
- 1. The shape passed using the '--input_shape' command line parameter.
- 2. The values from the pipeline configuration file describing Preprocessor block of the topology:
- a. If the fixed size resizer is used then size passed via '--input_shape' can override them, but Model Optimizer
- prints warning. If the '--input_shape' is not defined then use values from the pipeline configuration file.
- b. If the keep aspect ratio resizer is used then scale the size passed via '--input_shape' using the provided
- limits. If the '--input_shape' is not defined then use shape as (min_dimension_size, min_dimension_size)
- defined in the pipeline configuration file. If the "pad_to_max_dimension" attribute is set to true then the
- output shape will always be (max_dimension_size, max_dimension_size).
-
- :param graph: graph with the topology.
- :param match: the object containing matching sub-graph and custom attributes from the sub-graph replacement file.
- :param pipeline_config: the object contain information from the pipeline configuration file.
- :return: tuple (height, width) of the placeholder shape.
- """
- height = None
- width = None
- user_shapes = graph.graph['user_shapes']
-
- if match and ('preprocessed_image_height' in match.custom_replacement_desc.custom_attributes or
- 'preprocessed_image_width' in match.custom_replacement_desc.custom_attributes):
- log.error('The "preprocessed_image_height" or "preprocessed_image_width" is specified in the sub-graph '
- 'replacement configuration file but they are ignored. Please, specify desired input shape using the '
- '"--input_shape" command line parameter.', extra={'is_warning': True})
-
- user_defined_height = None
- user_defined_width = None
- input_name = 'input_tensor' if 'input_tensor' in graph.nodes else 'image_tensor'
- if user_shapes and input_name in user_shapes and user_shapes[input_name]:
- user_defined_shape = user_shapes[input_name][0]['shape']
- if user_defined_shape is not None:
- user_defined_height = user_defined_shape[1].get_min_length() if user_defined_shape[1].is_static else dynamic_dimension_value
- user_defined_width = user_defined_shape[2].get_min_length() if user_defined_shape[2].is_static else dynamic_dimension_value
-
- # the parameters below are set if the fixed_shape_resizer is used
- resizer_height = pipeline_config.get_param('resizer_image_height')
- resizer_width = pipeline_config.get_param('resizer_image_width')
- if resizer_height and resizer_width:
- log.debug('The model resizes image to a fixed shape: ({}, {})'.format(resizer_height, resizer_width))
- if user_defined_height and user_defined_width:
- if user_defined_width != resizer_width or user_defined_width != resizer_width:
- log.error('The model expects that the input image is resized to a fixed shape ({}, {}), but the shape '
- 'provided with the "--input_shape" command line parameter is different ({}, {}).'.format(
- resizer_height, resizer_width, user_defined_height, user_defined_width), extra={'is_warning': True})
- height = user_defined_height
- width = user_defined_width
- else:
- height = resizer_height
- width = resizer_width
-
- # the parameters below are set if keep_aspect_ratio_resizer is used
- resizer_min_dimension = pipeline_config.get_param('resizer_min_dimension')
- resizer_max_dimension = pipeline_config.get_param('resizer_max_dimension')
- pad_to_max_dimension = pipeline_config.get_param('pad_to_max_dimension')
- if resizer_min_dimension and resizer_max_dimension:
- log.debug('The model resizes image using keep aspect ratio with minimum size {}, maximum size {}, pad {}.'
- ''.format(resizer_min_dimension, resizer_max_dimension, pad_to_max_dimension))
- if pad_to_max_dimension:
- if user_defined_height and user_defined_width:
- log.error('The model contains pre-processing block which resizes image keeping aspect ratio with a '
- 'padding to max dimension. The only valid model input image spatial shape after '
- 'pre-processing is ({}, {}). Ignoring the user provided input shapes.'
- ''.format(resizer_max_dimension, resizer_max_dimension), extra={'is_warning': True})
- height = width = resizer_max_dimension
- else:
- log.error('Model Optimizer removes pre-processing block of the model which resizes image keeping aspect '
- 'ratio. OpenVINO does not support dynamic image size so the Intermediate Representation '
- 'file is generated with the input image size of a fixed size.', extra={'is_warning': True})
- if user_defined_height and user_defined_width:
- scaled_height, scaled_width = calculate_shape_keeping_aspect_ratio(user_defined_height,
- user_defined_width,
- resizer_min_dimension,
- resizer_max_dimension)
- if scaled_height != user_defined_height or scaled_width != user_defined_width:
- log.error('The model resizes the input image keeping aspect ratio with min dimension {}, max '
- 'dimension {}. The provided input height {}, width {} is transformed to height {}, width '
- '{}.'.format(resizer_min_dimension, resizer_max_dimension, user_defined_height,
- user_defined_width, scaled_height, scaled_width), extra={'is_warning': True})
- height = scaled_height
- width = scaled_width
- else:
- height = width = resizer_min_dimension
- log.error('Specify the "--input_shape" command line parameter to override the default shape which is '
- 'equal to ({}, {}).'.format(height, width), extra={'is_warning': True})
-
- if height is None or width is None:
- raise Error('Failed to determine the placeholder shape. Unsupported image resizer from the pipeline.config was '
- 'used to create the model.')
- return height, width
-
-
-def update_parameter_shape(graph: Graph, match: [SubgraphMatch, None]):
- """
- Updates the shape of the model Parameter node based on the user provided input shape or values provided in the
- pipeline.config configuration file used for model training.
- :param graph: model graph
- :param match: Match object with information about matched sub-graph
- :return: tuple with input node names and Parameter Node
- """
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
-
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
-
- initial_input_node_name = 'input_tensor' if 'input_tensor' in graph.nodes else 'image_tensor'
- if initial_input_node_name not in graph.nodes():
- raise Error('Input node "{}" of the graph is not found. Do not run the Model Optimizer with '
- '"--input" command line parameter.'.format(initial_input_node_name))
- parameter_node = Node(graph, initial_input_node_name)
-
- # set default value of the batch size to 1 if user didn't specify batch size and input shape
- layout = graph.graph['layout']
- batch_dim = get_batch_dim(layout, 4)
- if argv.batch is None and parameter_node.shape[batch_dim] is dynamic_dimension:
- parameter_node.shape[batch_dim] = 1
- height, width = calculate_placeholder_spatial_shape(graph, match, pipeline_config)
- parameter_node.shape[get_height_dim(layout, 4)] = height
- parameter_node.shape[get_width_dim(layout, 4)] = width
- return initial_input_node_name, parameter_node
-
-
-def mark_squeeze_reshape_concat_before_detection_output(start_nodes: list):
- """
- The function looks for Reshape, Concat and Squeeze ops after the 'start_nodes' with 4D output and marks them with
- proper attributes to infer them in original NHWC layout. This is a case of the TensorFlow Object Detection API
- models for the SSD heads output which produces 4D tensor with bounding box deltas.
-
- :param start_nodes: list of nodes to start search from.
- :return: None
- """
- q = collections.deque()
- visited = set()
- q.extend(start_nodes)
- while len(q) != 0:
- cur_node = q.popleft()
- visited.add(cur_node.id)
- if cur_node.has_valid('type'):
- if cur_node.soft_get('type') == 'DetectionOutput': # do not go beyond the DetectionOutput node
- continue
- # the input to Reshape comes from Convolution so it will be converted from NCHW to NHWC layout in the
- # InsertLayoutPropagationTransposes transformation. But the output should be kept in the original layout
- if cur_node.soft_get('type') == 'Reshape':
- mark_output_as_in_correct_layout(cur_node, 0)
-
- # Concat should be inferred in the original layout so the input with concatenation axis should not be
- # updated from NHWC to NCHW layout
- if cur_node.soft_get('type') == 'Concat':
- cur_node.in_port(1).__setattr__('input_permutation', None)
- cur_node['nchw_layout'] = True
- cur_node.out_node(0)['nchw_layout'] = True
-
- # Squeeze should be inferred in the original layout so the input with squeeze axis should not be updated
- # from NHWC to NCHW layout. The input is marked as in correct layout to prevent from inserting Transpose
- # from NHWC to NCHW.
- if cur_node.soft_get('type') == 'Squeeze':
- cur_node.in_port(1).__setattr__('input_permutation', None)
- mark_input_as_in_correct_layout(cur_node, 0)
-
- if cur_node.has_port('out', 0):
- [q.append(port.node) for port in cur_node.out_port(0).get_destinations() if port.node.id not in visited]
-
-
-class ObjectDetectionAPITransformationsStart(FrontReplacementPattern):
- """
- This is a anchor transformation which is used to distinguish TF OD API models related transformations.
- All transformations have a dependency to be executed after this transformation (or some other TF OD API
- transformation which is executed after this one).
- Some transformation which swap convolution weights using the "swap_weights_xy" function relies on the fact that the
- "FakeQuantWithMinMaxVars" operations are decomposed into "FakeQuantize"s.
- """
- enabled = True
-
- def run_after(self):
- return [FakeQuantWithMinMaxVarsToQuantize]
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
-
-class ObjectDetectionAPITransformationsFinish(FrontReplacementPattern):
- """
- This is a anchor transformation which is used to separate TF OD API models related transformations.
- All transformations have a dependency to be executed before this transformation (or some other TF OD API
- transformation which is executed before this one).
- 1. This anchor transformation is executed before any other standard MO transformations which may break the model
- conversion. For example, PadTFToPad replaces PadTF operation nodes with the Pad operation nodes and re-uses an
- input node defining the pad value. The scope pattern matcher will remove the node defining the pad value and the
- newly created Pad operation become invalid.
- 2. Another common issue that some transformations should be executed after TF OD API transformations is that these
- transformations replace some nodes with new nodes but different "id" attribute. Since the pattern matcher is based
- on node "id" (not "name") attribute the matching will be broken.
- 3. Some TF OD API transformations mark TF CropAndResize nodes with specific flag which is then handled in the
- CropAndResizeReplacement transformation that is why latter one should be executed after this transformation.
- """
- enabled = True
- # cleanup the graph after applying of TF OD API transformations to remove a lot of unconnected nodes to avoid issues
- # with shape inference
- force_clean_up = True
-
- def run_before(self):
- return [Pack, TransposeOrderNormalizer, PadTFToPad, SqueezeAxis, TFSliceToSliceReplacer, MapFNInputSlicing,
- MapFNOutputConcatenation, TensorListOutputConcatenation, CropAndResizeReplacement]
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
-
-def get_specific_ops_with_const_inputs(first_node: Node, allowed_ops: list, forward: bool = True):
- """
- Returns the list with information about consecutive nodes of operation from "allowed_ops".
-
- :param first_node: The first node (not included) to start looking for nodes from the "allowed_ops" list
- :param allowed_ops: list of allowed operations
- :param forward: flag specifying direction of search
- :return: list of triplets (Node, const_port_index, const_value)
- """
- node = first_node.out_port(0).get_destination().node if forward else first_node.in_port(0).get_source().node
- result = [] # (Node, port # with constant input, value)
- while node.soft_get('op') in allowed_ops:
- num_in_ports = len(node.in_ports())
- assert num_in_ports == 2, 'The node "{}" should have exactly 2 inputs, but it has only {}.' \
- ''.format(node.soft_get('name', node.id), num_in_ports)
- for port in (0, 1):
- if node.in_port(port).get_source().node.has_valid('value'): # this is a constant input to the node
- result.append((node, port, node.in_port(port).get_source().node.value.copy()))
- node = node.out_port(0).get_destination().node if forward else node.in_port(1 - port).get_source().node
- break
- return result
-
-
-def get_preprocessing_ops(graph: Graph, start_node_id_suffix: str, end_node_id_suffix: str):
- """
- Finds a sequence of pre-processing nodes (Sub, Mul, Div and Add) after the node with the id suffix
- 'end_node_id_suffix' or ending with the node with id suffix 'end_node_id_suffix'.
-
- :param graph: graph to look for pre-processing ops
- :param start_node_id_suffix: suffix of the start node name
- :param end_node_id_suffix: suffix of the end node name
- :return: the list with pre-processing nodes information and flag specifying nodes position
- """
- start_node = None
- end_node = None
- for node in graph.get_op_nodes():
- if node.id.endswith(start_node_id_suffix):
- start_node = node
- if node.id.endswith(end_node_id_suffix):
- end_node = node
-
- assert start_node is not None and end_node is not None, \
- 'Failed to find start/end nodes of the pre-processing block. The section of the transformation JSON ' \
- 'configuration file related to "ObjectDetectionAPIPreprocessor2Replacement" transformation should be updated ' \
- 'for this particular model.'
- allowed_ops = ['Sub', 'Mul', 'Div', 'Add']
- preprocessing_nodes = get_specific_ops_with_const_inputs(start_node, allowed_ops, False)
- trailing = False # switch to apply newly created pre-processing nodes after/before start_node/end_node
- if len(preprocessing_nodes) == 0:
- preprocessing_nodes = get_specific_ops_with_const_inputs(end_node, allowed_ops, True)
- trailing = True
-
- # try to detect floating-point casting inside the body graph
- # that also needs to stay in the resulted graph
- casting = False
- cast_nodes = backward_bfs_for_operation(start_node, ['Cast'])
- if len(cast_nodes) == 1 and cast_nodes[0].dst_type == np.float32:
- casting = True
-
- return preprocessing_nodes, trailing, casting
-
-
-"""
-Object Detection API models contain the sub-graph that performs some (not necessarily all) of the following tasks
-(possibly in different order):
-* Resizes image according to the constraints defined in the pipeline.config file.
-* Applies mean and scale values.
-* Pads the resized image to the size specified in the pipeline.config file.
-This sub-graph is called "Preprocessor" in TF1 OD API models and early versions of the TF2 OD API models. Starting from
-version 2.4 the block is called "map". The sub-graph has one output with the pre-processed input image and optionally
-has a second output which contains either the original image size or the resized image size (before padding). When the
-second output exists it is used to map predicted bounding boxes of the resized image to the original image coordinates.
-
-Model Optimizer removes nodes performing image resize and padding, but keeps nodes applying mean and scale values.
-Historically, Model Optimizer didn't support converting TF sub-graphs into TensorIterator/Loop from TF 1 models so this
-was the only option to convert the model and avoid dynamism which occurs when keep_aspect_ratio resizer is used. And the
-user should resize the image the same way as it is implemented in the model before feeding the data to the Inference
-Engine.
-
-If the "keep_aspect_ratio" resizer with "pad_to_max_dimension" parameter equal to "true" is used and mean/scale
-operations are applied before the resize like this:
-
-input_tensor -> mean/scale -> resize -> pad -> ...
-
-then it is not allowed to remove the resize and padding operations and pre-process the input data before feeding the
-model like this:
-
-resized_padded_input_data -> mean/scale -> ...
-
-because the output results will be different because mean/scale operations will be applied for padding area as well. So
-the only option in this case is to remove all pre-processing operations from the model and expect that user perform them
-before feeding the model.
-"""
-
-
-class ObjectDetectionAPIPreprocessorReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- The transformation is triggered for the pre-processing block which resizes the input image and applies mean/scale
- values in the TF1 OD API models.
- """
- replacement_id = 'ObjectDetectionAPIPreprocessorReplacement'
- run_not_recursively = True
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- def run_after(self):
- return [ObjectDetectionAPITransformationsStart]
-
- def nodes_to_remove(self, graph: Graph, match: SubgraphMatch):
- new_nodes_to_remove = match.matched_nodes_names()
- # do not remove nodes that perform input image scaling and mean value subtraction
- for node_to_keep in ('Preprocessor/sub', 'Preprocessor/sub/y', 'Preprocessor/mul', 'Preprocessor/mul/x'):
- if node_to_keep in new_nodes_to_remove:
- new_nodes_to_remove.remove(node_to_keep)
- return new_nodes_to_remove
-
- def is_preprocessing_applied_before_resize(self, to_float: Node, mul: Node, sub: Node):
- """
- The function checks if the output of 'to_float' operation is consumed by 'mul' or 'sub'. If this is true then
- the pre-processing (mean/scale) is applied before the image resize. The image resize was applied first in the
- original version of the TF OD API models, but in the recent versions it is applied after.
-
- :param to_float: the Cast node which converts the input tensor to Float
- :param mul: the Mul node (can be None)
- :param sub: the Sub node
- :return: the result of the check
- """
- assert sub is not None, 'The Sub node should not be None. Check the caller function.'
- if mul is not None:
- return any([port.node.id == mul.id for port in to_float.out_port(0).get_destinations()])
- else:
- return any([port.node.id == sub.id for port in to_float.out_port(0).get_destinations()])
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- sub_node = match.output_node(0)[0]
- # sanity check whether this is really TF OD API model. The Sub operation always exists in TF1 OD API models
- # pre-processing sub-graph
- if sub_node.soft_get('op') != 'Sub':
- raise Error('The output op of the Preprocessor sub-graph is not of type "Sub". Looks like the topology is '
- 'not created with TensorFlow Object Detection API.')
-
- # identify the node performing scale (if it exists)
- mul_node = None
- if sub_node.in_port(0).get_source().node.soft_get('op') == 'Mul':
- log.info('There is image scaling node in the Preprocessor block.')
- mul_node = sub_node.in_port(0).get_source().node
-
- # update the model Parameter node shape based on MO command line parameters and values in the pipeline.config
- initial_input_node_name, placeholder_node = update_parameter_shape(graph, match)
-
- to_float_node = placeholder_node.out_port(0).get_destination().node
- # one more sanity check
- if to_float_node.soft_get('op') != 'Cast':
- raise Error('The output of the node "{}" is not Cast operation. Cannot apply transformation.'.format(
- initial_input_node_name))
-
- if self.is_preprocessing_applied_before_resize(to_float_node, mul_node, sub_node):
- # connect sub node directly to nodes which consume resized image
- resize_output_node_id = 'Preprocessor/map/TensorArrayStack/TensorArrayGatherV3'
- if resize_output_node_id not in graph.nodes:
- raise Error('There is no expected node "{}" in the graph.'.format(resize_output_node_id))
- resize_output = Node(graph, resize_output_node_id)
- for dst_port in resize_output.out_port(0).get_destinations():
- dst_port.get_connection().set_source(sub_node.out_port(0))
- else:
- # connect to_float_node directly with node performing scale on mean value subtraction
- if mul_node is None:
- to_float_node.out_port(0).connect(sub_node.in_port(0))
- else:
- to_float_node.out_port(0).connect(mul_node.in_port(1))
-
- log.error('The Preprocessor block has been removed. Only nodes performing mean value subtraction and scaling '
- '(if applicable) are kept.', extra={'is_warning': True})
- # the pre-processing sub-graph is connected with the main graph, so there is no need to return new nodes mapping
- # dictionary
- return {}
-
-
-class ObjectDetectionAPIPreprocessor2Replacement(FrontReplacementFromConfigFileGeneral):
- """
- The transformation is triggered for the pre-processing block which resizes the input image and applies mean/scale
- values in the TF2 OD API model. Only nodes related to applying mean/scaling values are kept.
- If the mean/scale values are applied before the resize and the pre-processing includes padding then mean/scale
- values are removed as well. Refer to the comments section before the ObjectDetectionAPIPreprocessorReplacement
- transformation.
-
- There are 6 possible cases:
- 1. ... -> Scale -> Start -> Resize -> End -> ...
- 2. ... -> Start -> Resize -> End -> Scale -> ...
- 3. ... -> Start -> Resize -> End -> ...
- 4. ... -> Start -> While (... -> Scale -> Resize -> ...) -> End -> ...
- 5. ... -> Start -> While (... -> Resize -> Scale -> ...) -> End -> ...
- 6. ... -> Start -> While (... -> Resize -> ...) -> End -> ...
-
- Where:
- - "Start" - is the node name specified in the transformation configuration file
- - "End" - is the node name specified in the transformation configuration file
- - "Scale" - a node or a sequence of element-wise nodes like Mul, Add, Sub or Div with Const input
- - "While" (... nodes ... ) - a Loop operation with body nodes specified in parentheses
- - "Resize" - the Resize sub-graph being removed
-
- The transformation creates a new sub-graph of pre-processing nodes if in the original model it is inside the Loop,
- or keeps the existing one if they are in the main graph already.
- """
- replacement_id = 'ObjectDetectionAPIPreprocessor2Replacement'
- run_not_recursively = True
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- def run_after(self):
- return [ObjectDetectionAPITransformationsStart]
-
- def transform_graph(self, graph: Graph, replacement_descriptions: dict):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
-
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
- pad_to_max_dimension = pipeline_config.get_param('pad_to_max_dimension')
-
- # update the model Parameter node shape based on MO command line parameters and values in the pipeline.config
- update_parameter_shape(graph, None)
-
- # NOTE: this transformation can be implemented as a "scope" or "points" transformation since we need to match
- # some sub-graph between specific nodes
- start_nodes = replacement_descriptions['start_nodes']
- end_nodes = replacement_descriptions['end_nodes']
-
- start_nodes = [node_id for node_id in start_nodes if node_id in graph.nodes]
- end_nodes = [node_id for node_id in end_nodes if node_id in graph.nodes]
-
- assert len(start_nodes) >= 1
- start_node = Node(graph, start_nodes[0])
-
- assert len(end_nodes) >= 1
- end_node = Node(graph, end_nodes[0])
-
- # determine nodes between specified input and output nodes to check if there is a Loop op among them
- sub_graph_node_ids = sub_graph_between_nodes(graph, start_nodes, end_nodes, include_control_flow=False,
- allow_non_reachable_end_nodes=True)
-
- pre_processing_in_loop = False
- # If the pre-processing block contains Loop operation then mean and scale value should be obtained from it using
- # some pre-defined marker nodes existing for all pre-processing blocks.
- # If there is no Loop then pre-processing nodes are in the main graph and they should be obtained from it
- loop_nodes_ids = [node_id for node_id in sub_graph_node_ids if graph.nodes[node_id].get('op') == 'Loop']
- if len(loop_nodes_ids):
- assert len(loop_nodes_ids) == 1, 'There should be exactly one Loop node in the pre-processor block.'
- pre_processing_in_loop = True
- loop_node = Node(graph, loop_nodes_ids[0])
- body_graph = loop_node.body
- # we stick to the nodes with ids 'map/while/Preprocessor/unstack' and 'map/while/Preprocessor/stack' as they
- # "wrap" nodes performing image resize. The scale/mean values nodes are located strictly before or after
- # them
- pre_processing_ops, trailing, casting = get_preprocessing_ops(body_graph,
- 'map/while/Preprocessor/unstack',
- 'map/while/Preprocessor/stack')
- else:
- pre_processing_ops, trailing, casting = get_preprocessing_ops(graph, start_node.id, end_node.id)
-
- mean_scale_kept = True
- if len(pre_processing_ops):
- # if the pre-processing is applied before the resize then reverse them to be in the topological order
- if not trailing:
- pre_processing_ops = list(reversed(pre_processing_ops))
-
- if pre_processing_in_loop: # case 4 and 5
- # build a sub-graph containing a sequence of pre_processing_ops if they came from the Loop
- new_preprocessing_ops = []
-
- # cast data before start pre-processing with mean/scale values
- if casting:
- cast_node = Cast(graph, {'dst_type': np.float32}).create_node()
- new_preprocessing_ops.append(cast_node)
-
- ops_mapping = {'Add': Add, 'Div': Div, 'Mul': Mul, 'Sub': Sub}
- for idx in range(len(pre_processing_ops)):
- origin_node, const_port_ind, value = pre_processing_ops[idx]
- new_node = create_op_with_const_inputs(graph, ops_mapping[origin_node.op], {const_port_ind: value})
- if len(new_preprocessing_ops):
- new_node.in_port(1 - const_port_ind).connect(new_preprocessing_ops[-1].out_port(0))
- new_preprocessing_ops.append(new_node)
-
- # replace sub-graph between start and end nodes (including them) with new_preprocessing_ops nodes
- end_node.out_port(0).get_connection().set_source(new_preprocessing_ops[-1].out_port(0))
- start_node.in_port(0).get_connection().set_destination(
- new_preprocessing_ops[0].in_port(int(new_preprocessing_ops[0].is_in_port_connected(0))))
- else:
- if trailing: # case 2
- # change output of the end_node to be produced with the start node producer
- source_port = start_node.in_port(0).get_source()
- source_port.disconnect()
- end_node.out_port(0).get_connection().set_source(source_port)
- else: # case 1
- # if padding is specified then need to remove mean/scale as well. Refer to the transformation
- # comments for more details
- if pad_to_max_dimension:
- # change output of the end_node to be produced with the node producing data for the first
- # preprocessing op
- mean_scale_kept = False
- first_pre_processing_node = pre_processing_ops[0][0]
- consumer_port = first_pre_processing_node.in_port(int(not pre_processing_ops[0][1]))
- end_node.out_port(0).get_connection().set_source(consumer_port.get_connection().get_source())
- else:
- # change output of the end_node to be produced with the last preprocessing op
- end_node.out_port(0).get_connection().set_source(pre_processing_ops[-1][0].out_port(0))
- start_node.in_port(0).disconnect()
- else: # simply remove the nodes in between start_node and end_node (including them). Case 3 and 6
- end_node.out_port(0).get_connection().set_source(start_node.in_port(0).get_source())
-
- if mean_scale_kept:
- log.error('The pre-processing block has been removed. Only nodes performing mean value subtraction and '
- 'scaling (if applicable) are kept. It is necessary to resize an input image using the same '
- 'algorithm as in the original model before feeding it to the OpenVINO.',
- extra={'is_warning': True})
- else:
- log.error('The Preprocessor block has been removed including mean value subtraction and scaling (if '
- 'applicable). It is necessary to resize, scale and pad an input image using the same algorithm '
- 'as in the original model before feeding it to the OpenVINO.', extra={'is_warning': True})
-
-
-class ObjectDetectionAPIDetectionOutputReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- Replaces the sub-graph that is equal to the DetectionOutput layer from OpenVINO (similarly to the
- ObjectDetectionAPISSDPostprocessorReplacement). This transformation is used for Faster R-CNN, R-FCN and Mask R-CNN
- topologies conversion.
- Refer to the code for more details.
- """
- replacement_id = 'ObjectDetectionAPIDetectionOutputReplacement'
- run_not_recursively = True
-
- def run_before(self):
- return [ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement]
-
- def run_after(self):
- return [ObjectDetectionAPIProposalReplacement]
-
- def nodes_to_remove(self, graph: Graph, match: SubgraphMatch):
- new_nodes_to_remove = match.matched_nodes_names().copy()
- outputs = ['detection_boxes', 'detection_scores', 'num_detections']
- for output in outputs:
- if output in graph.nodes:
- children = Node(graph, output).out_nodes()
- if len(children) != 1:
- log.warning('Output {} has {} children. It should have only one output: with op==`Result`'
- ''.format(output, len(children)))
- elif children[list(children.keys())[0]].op == 'Result':
- new_nodes_to_remove.append(children[list(children.keys())[0]].id)
- new_nodes_to_remove.extend(outputs)
- return new_nodes_to_remove
-
- def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict):
- # the DetectionOutput in OV produces single tensor, but in TF it produces four tensors, so we need to create
- # only one output edge match
- if match.outputs_count() >= 1:
- return {match.output_node(0)[0].id: new_sub_graph['detection_output_node'].id}
- else:
- return {list(graph.graph.get("packed_outputs").keys())[0]: new_sub_graph['detection_output_node'].id}
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
- custom_attributes = match.custom_replacement_desc.custom_attributes
-
- num_classes = _value_or_raise(match, pipeline_config, 'num_classes')
- max_proposals = _value_or_raise(match, pipeline_config, 'first_stage_max_proposals')
- activation_function = _value_or_raise(match, pipeline_config, 'postprocessing_score_converter')
-
- activation_conf_node = add_activation_function_after_node(graph, match.single_input_node(1)[0].in_node(0),
- activation_function)
-
- # OV DetectionOutput operation consumes flattened tensors so need add a Reshape layer.
- # The batch value of the input tensor is not equal to the batch of the topology, so it is not possible to use
- # "0" value in the Reshape layer attribute to refer to the batch size, but we know how to
- # calculate the second dimension so the batch value will be deduced from it with help of "-1".
- reshape_conf_node = create_op_node_with_second_input(graph, Reshape,
- int64_array([-1, (num_classes + 1) * max_proposals]),
- dict(name='do_reshape_conf'), activation_conf_node)
- mark_as_correct_data_layout(reshape_conf_node)
-
- # We looking for first not Reshape-typed node before match.single_input_node(0)[0].in_node(0).
- # And add reshape_offsets node after this first not Reshape-typed node to avoid issues with Reshape-like
- # operations which may trigger insert of Transpose operations before/after them
- current_node = skip_nodes_by_condition(match.single_input_node(0)[0].in_node(0),
- lambda x: x['kind'] == 'op' and x.has_and_set('reinterp_shape'))
-
- # if share_box_across_classes=1 then the same set of bounding boxes shape offsets is used for all classes,
- # otherwise per-class set of shape offsets is used and we need to use appropriate Reshape output shape
- share_box_across_classes = _value_or_raise(match, pipeline_config, 'share_box_across_classes')
- if share_box_across_classes:
- reshape_offsets_shape = int64_array([-1, 1, 1, 4])
- else:
- reshape_offsets_shape = int64_array([-1, num_classes, 1, 4])
- reshape_offsets = create_op_node_with_second_input(graph, Reshape, reshape_offsets_shape,
- dict(name='reshape_loc'), current_node)
- mark_as_correct_data_layout(reshape_offsets)
-
- if share_box_across_classes:
- offsets = reshape_offsets
- else:
- # TF produces shape offsets tensor without boxes corresponding to "background" class
- # OpenVINO DetectionOutput layer requires "background" class data be included so we generate them
- offsets = add_fake_background_loc(graph, reshape_offsets)
- PermuteAttrs.set_permutation(reshape_offsets, offsets, None)
-
- # reshape offsets tensor to 2D so it could be multiplied with variances
- reshape_offsets_2d = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 4]),
- dict(name='reshape_locs_2d'), offsets)
- mark_as_correct_data_layout(reshape_offsets_2d)
-
- # multiply bounding boxes shape offsets with variances as it is expected when variance_encoded_in_target=1 for
- # the DetectionOutput operation
- variances = Const(graph, dict(value=_variance_from_pipeline_config(pipeline_config))).create_node([])
- scaled_offsets = Mul(graph, dict()).create_node([reshape_offsets_2d, variances], dict(name='scale_locs'))
-
- # there are Convolution/MatMul nodes before the post-processing block in all models except RFCN. So for most of
- # the models we can just update Convolution/MatMul weights to perform swapping of coordinates. But for the RFCN
- # models we use approach with adding special Convolution node which perform the same swap. Previously we used a
- # dedicated parameter in the transformation config but now it is not needed and the get this information from
- # the model automatically by performing graph traversal until CropAndResize (RFCN case) or Conv/MatMul nodes are
- # found
- if 'coordinates_swap_method' in custom_attributes:
- log.error('The "coordinates_swap_method" parameter is not needed anymore. Consider removing it from the '
- '"ObjectDetectionAPIDetectionOutputReplacement" transformation custom attributes.',
- extra={'is_warning': True})
- matmul_or_conv_nodes = backward_bfs_for_operation(scaled_offsets, ['MatMul', 'Conv2D'], ['ShapeOf',
- 'CropAndResize'])
- if len(matmul_or_conv_nodes) == 0:
- swapped_offsets = add_convolution_to_swap_xy_coordinates(graph, scaled_offsets, 4)
- flattened_offsets = Reshape(graph, dict(name='do_reshape_locs')).create_node([swapped_offsets])
- else:
- swap_weights_xy(graph, matmul_or_conv_nodes)
- flattened_offsets = Reshape(graph, dict(name='do_reshape_locs')).create_node([scaled_offsets])
-
- # OV DetectionOutput layer consumes flattened tensors so need add a Reshape layer.
- # The batch value of the input tensor is not equal to the batch of the topology, so it is not possible to use
- # "0" value in the Reshape layer attribute to refer to the batch size, but we know how to
- # calculate the second dimension so the batch value will be deduced from it with help of "-1".
- if share_box_across_classes:
- reshape_shape = int64_array([-1, max_proposals * 4])
- else:
- reshape_shape = int64_array([-1, (num_classes + 1) * max_proposals * 4])
- Const(graph, {'value': reshape_shape, 'name': flattened_offsets.name + '/Dim'}).create_node().out_port(0).\
- connect(flattened_offsets.in_port(1))
- mark_as_correct_data_layout(flattened_offsets)
-
- # find Proposal output which has the data layout as in TF: YXYX coordinates without batch indices.
- proposal_nodes_ids = [node_id for node_id, attrs in graph.nodes(data=True)
- if 'name' in attrs and attrs['name'] == 'crop_proposals']
- if len(proposal_nodes_ids) != 1:
- raise Error("Found the following nodes '{}' with name 'crop_proposals' but there should be exactly 1. "
- "Looks like ObjectDetectionAPIProposalReplacement transformation didn't work."
- "".format(proposal_nodes_ids))
- proposal = Node(graph, proposal_nodes_ids[0])
-
- # Need to swap proposals coordinates before passing them to the DetectionOutput for the RFCN topologies
- if len(matmul_or_conv_nodes) == 0:
- proposal = add_convolution_to_swap_xy_coordinates(graph, proposal, 4)
-
- # reshape priors boxes as Detection Output expects
- reshape_priors = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 1, max_proposals * 4]),
- dict(name='DetectionOutput_reshape_priors_'), proposal)
- mark_as_correct_data_layout(reshape_priors)
-
- detection_output_op = DetectionOutput(graph, {})
- for key in ('clip_before_nms', 'clip_after_nms'):
- if key in match.custom_replacement_desc.custom_attributes:
- detection_output_op.attrs[key] = int(match.custom_replacement_desc.custom_attributes[key])
-
- detection_output = detection_output_op.create_node([flattened_offsets, reshape_conf_node, reshape_priors], dict(
- name=detection_output_op.attrs['type'],
- share_location=int(share_box_across_classes),
- variance_encoded_in_target=1,
- background_label_id=int(custom_attributes.get('background_label_id', 0)),
- code_type='caffe.PriorBoxParameter.CENTER_SIZE',
- pad_mode='caffe.ResizeParameter.CONSTANT',
- resize_mode='caffe.ResizeParameter.WARP',
- confidence_threshold=_value_or_raise(match, pipeline_config, 'postprocessing_score_threshold'),
- top_k=_value_or_raise(match, pipeline_config, 'postprocessing_max_detections_per_class'),
- keep_top_k=_value_or_raise(match, pipeline_config, 'postprocessing_max_total_detections'),
- nms_threshold=_value_or_raise(match, pipeline_config, 'postprocessing_iou_threshold')))
- # sets specific name to the node so we can find it in other transformations
- detection_output.name = 'detection_output'
-
- # when the use_matmul_crop_and_resize = True then the prior boxes were not swapped and we need to swap them from
- # YXYX to XYXY before passing to the DetectionOutput operation
- if pipeline_config.get_param('use_matmul_crop_and_resize'):
- insert_weights_swap_xy_sub_graph(graph, detection_output.in_port(2).get_connection())
-
- # create Result since after the transformation other Results are removed
- Result(graph, dict(name='do_OutputOp')).create_node([detection_output])
-
- log.error('The graph output nodes have been replaced with a single layer of type "DetectionOutput". Refer to '
- 'the operation set specification documentation for more information about the operation.',
- extra={'is_warning': True})
- return {'detection_output_node': detection_output}
-
-
-class ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- There are two TensorFlow CropAndResize (corresponding to OpenVINO ROIPooling with bilinear interpolation
- mode) operations in the Mask-RCNN model. The second CropAndResize gets bounding boxes coordinates as input from the
- part of the model which is replaced with the DetectionOutput operation using the transformation
- ObjectDetectionAPIDetectionOutputReplacement. DetectionOutput operation produces tensor with 7-element tuples
- [batch_id, class_id, confidence, x_1, y_1, x_2, y_2]. The ROIPooling operation expects input defining bounding boxes
- with the following format [batch_id, x_1, y_1, x_2, y_2]. The ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement
- transformation inserts ROIPooling operation instead of the CropAndResize and crops slices of data from the
- DetectionOutput operation and concatenates them to produce a tensor with correct content.
- """
- replacement_id = 'ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement'
- run_not_recursively = True
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- def run_after(self):
- return [ObjectDetectionAPIProposalReplacement]
-
- def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict):
- return {match.output_node(0)[0].id: new_sub_graph['roi_pooling_node'].id}
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
-
- # the output spatial dimensions of the ROIPooling operation are defined in the pipeline.config
- roi_pool_size = _value_or_raise(match, pipeline_config, 'initial_crop_size')
-
- # find the DetectionOutput operation by name to get tensor with information about bounding boxes from it.
- # the layout of bounding boxes is XYXY already, so no need to swap them
- detection_output_nodes_ids = [node_id for node_id, attrs in graph.nodes(data=True)
- if 'name' in attrs and attrs['name'] == 'detection_output']
- if len(detection_output_nodes_ids) != 1:
- raise Error("Found the following nodes '{}' with name 'detection_output' but there should be exactly 1.".
- format(detection_output_nodes_ids))
- detection_output = Node(graph, detection_output_nodes_ids[0])
- do_outputs = [port.node for port in detection_output.out_port(0).get_destinations() if port.node.op == 'Result']
- if len(do_outputs) == 1:
- graph.remove_node(do_outputs[0].id)
-
- # add reshape of Detection Output so it can be an output of the topology.
- # this looks like some legacy not relevant constraint anymore
- flatten_do = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 7]), dict(name='reshape_do_2d'),
- detection_output)
- mark_as_correct_data_layout(flatten_do)
-
- # adds "Result" node so this output is returned by OV by default for the backward compatibility
- do_result = Result(graph, dict(name='do_reshaped_OutputOp')).create_node([flatten_do])
-
- # add attribute 'output_sort_order' so it will be used as a key to sort output nodes before generation of IR
- do_result.in_edge()['data_attrs'].append('output_sort_order')
- do_result.in_edge()['output_sort_order'] = [('detection_boxes', 0)]
-
- # creates two Crop operations which get input from the DetectionOutput, cuts off slices of data with class ids
- # and probabilities and produces a tensor with batch ids and bounding boxes only (as it is expected by the
- # ROIPooling operation)
- batch_ids = Crop(graph, dict(axis=int64_array([1]), offset=int64_array([0]), dim=int64_array([1]))).create_node(
- [flatten_do], dict(name='crop_do_batch_ids'))
- coords = Crop(graph, dict(axis=int64_array([1]), offset=int64_array([3]), dim=int64_array([4]))).create_node(
- [flatten_do], dict(name='crop_do_coords'))
- batch_and_coords = Concat(graph, dict(axis=1)).create_node([batch_ids, coords], dict(name='batch_and_coords'))
-
- roi_pooling = ROIPooling(graph, dict(method="bilinear", spatial_scale=1, pooled_h=roi_pool_size,
- pooled_w=roi_pool_size)).create_node(
- [match.single_input_node(0)[0].in_node(), batch_and_coords], dict(name='ROI_pooling_2'))
- return {'roi_pooling_node': roi_pooling}
-
-
-class ObjectDetectionAPIMaskRCNNSigmoidReplacement(FrontReplacementFromConfigFileGeneral):
- """
- The transformation is used to convert Mask R-CNN topologies only.
-
- The post-processing part of Mask-RCNN models is to select masks from the output tensor which correspond to bounding
- boxes with probability exceeding specific threshold. The final step of the post-processing is to apply Sigmoid
- activation function to the tensor with selected masks so the values become in range [0, 1]. The post-processing part
- of the model is not supported so it is removed using the transformation ObjectDetectionAPIOutputReplacement.
- This transformation adds back the activation function to the end of the network producing masks tensors. So the
- post-processing with selecting masks corresponding to bounding boxes with high probabilities should be implemented
- in the application.
- """
- replacement_id = 'ObjectDetectionAPIMaskRCNNSigmoidReplacement'
- run_not_recursively = True
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- def run_after(self):
- return [ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement]
-
- def transform_graph(self, graph: Graph, replacement_descriptions):
- # there could be multiple Result nodes in the graph. We identify the one containing masks data using the node
- # name prefix
- masks_node_prefix_name = replacement_descriptions.get('masks_node_prefix_name', 'SecondStageBoxPredictor')
- op_outputs = graph.get_op_nodes(op='Result')
- for op_output in op_outputs:
- last_node = op_output.in_port(0).get_source().node
- if last_node.name.startswith(masks_node_prefix_name):
- sigmoid_node = Sigmoid(graph, dict(name='masks')).create_node()
- op_output.in_port(0).get_connection().insert_node(sigmoid_node)
-
- # the line below is needed to keep layout as is, istead of default NCHW->NHWC changing
- sigmoid_node['nchw_layout'] = True
-
- # adding op name to tensor names list is needed for compatiblity with old api configs
- op_output.in_port(0).get_connection().get_source().add_tensor_names([sigmoid_node['name']])
-
- log.error('The predicted masks are produced by the "masks" layer for each bounding box generated with a '
- '"detection_output" operation.\n Refer to operation specification in the documentation for the '
- 'information about the DetectionOutput operation output data interpretation.\nThe model can be '
- 'inferred using the dedicated demo "mask_rcnn_demo" from the OpenVINO Open Model Zoo.',
- extra={'is_warning': True})
-
-
-class ObjectDetectionAPIProposalReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- The outputs of the Region Proposal Network which produces shape offsets and probabilities whether anchors contain
- object or not is fed to the part of the model which decodes bounding boxes and performs non-maximum suppression.
- There are two operations in the OpenVINO which can perform such calculations: Proposal and DetectionOutput.
- Historically, the Proposal operation was inserted by this transformation, but now a DetectionOutput can be inserted
- instead if the "operation_to_add" parameter in the JSON configuration file is set to "DetectionOutput". There was a
- model for which inserting DetectionOutput instead of Proposal operation results in generation more accurate results.
- Another reason why Proposal operation is not preferable is that it requires addition model input which defines
- original image size and special scale value (refer to the operation specification for more details). So even though
- the original TensorFlow model has one input (actual image), the generated IR contains two inputs (actual image and
- a special input for the Proposal operation). It is not possible to switch to inserting DetectionOutput operation
- by default because it is not backward compatible change and some customer script may start to fail since one input
- disappears.
- Refer to the code for details on the conversion process and operations inserted.
- """
- replacement_id = 'ObjectDetectionAPIProposalReplacement'
- run_not_recursively = True
- matched_input_nodes_to_keep = 2 # number of matched input nodes to keep
-
- def run_after(self):
- return [ObjectDetectionAPIPreprocessorReplacement, ObjectDetectionAPIPreprocessor2Replacement]
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- 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}
-
- def nodes_to_remove(self, graph: Graph, match: SubgraphMatch):
- new_list = match.matched_nodes_names().copy()
- # do not remove nodes that produce box predictions and class predictions and optionally generated anchors
- for port in range(self.matched_input_nodes_to_keep):
- new_list.remove(match.single_input_node(port)[0].id)
- return new_list
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
-
- # the transformation configuration file specifies what operations should be included with this transformation
- if match.custom_replacement_desc.custom_attributes.get('operation_to_add', 'Proposal') == 'DetectionOutput':
- self.matched_input_nodes_to_keep = 3 # keep the third input with prior boxes (anchors)
- return self.insert_detection_output_instead_of_proposal(graph, match, pipeline_config)
-
- max_proposals = _value_or_raise(match, pipeline_config, 'first_stage_max_proposals')
- proposal_ratios = _value_or_raise(match, pipeline_config, 'anchor_generator_aspect_ratios')
- proposal_scales = _value_or_raise(match, pipeline_config, 'anchor_generator_scales')
- anchors_count = len(proposal_ratios) * len(proposal_scales)
-
- # Find Convolution/MatMul node that produces classes confidence
- class_conf = backward_bfs_for_operation(match.single_input_node(1)[0], ['Add'])[0]
-
- # size of 'C' dimension of the tensor with class predictions is equal to base_anchors_count * 2, where 2
- # corresponds to a number of classes (background and foreground) and base_anchors_count is equal to number of
- # anchors applied to each position of 'H' and 'W' dimensions. Therefore, there are H * W * base_anchors_count
- # bounding boxes. OpenVINO Proposal operation interprets the input tensor as a tensor
- # [batch, 2 * base_anchors_count, H, W] but in TensorFlow model it is calculated as
- # [batch, base_anchors_count, H, W] (after NHWC->NCHW layout conversion), so it is necessary to decompose the
- # 'C' dimension into base_anchors_count and 2 and swap these two dimensions
- reshape_class_conf = create_op_node_with_second_input(graph, Reshape, int64_array([0, anchors_count, 2, -1]),
- dict(name='predictions/Reshape'))
- class_conf.insert_node_after(reshape_class_conf, 0)
- mark_as_correct_data_layout(reshape_class_conf)
-
- # the part of the sub-graph being removed contains the SoftMax operation, so here we insert it back
- softmax_conf_op = Softmax(graph, dict(axis=2, nchw_layout=True, name=reshape_class_conf.id + '/Softmax'))
- softmax_conf = softmax_conf_op.create_node([reshape_class_conf])
-
- order_const = Const(graph, dict(value=int64_array([0, 2, 1, 3]),
- name=softmax_conf.name + '/TransposeOrder')).create_node()
- permute_reshape_softmax_op = Transpose(graph, dict())
- permute_reshape_softmax = permute_reshape_softmax_op.create_node([softmax_conf, order_const], dict(
- name=softmax_conf.name + '/Transpose'))
- mark_input_as_in_correct_layout(permute_reshape_softmax, 1)
- mark_output_as_in_correct_layout(permute_reshape_softmax, 0)
-
- initial_shape = Shape(graph, dict(name=class_conf.id + '/Shape')).create_node([class_conf])
-
- reshape_conf_initial = Reshape(graph, dict(name='Reshape_Transpose_Class')).create_node(
- [permute_reshape_softmax, initial_shape])
- mark_input_as_in_correct_layout(reshape_conf_initial, 0)
- mark_output_as_in_correct_layout(reshape_conf_initial, 0)
-
- variance_height = pipeline_config.get_param('frcnn_variance_height')
- variance_width = pipeline_config.get_param('frcnn_variance_width')
- variance_x = pipeline_config.get_param('frcnn_variance_x')
- variance_y = pipeline_config.get_param('frcnn_variance_y')
- anchor_generator_height_stride = pipeline_config.get_param('anchor_generator_height_stride')
- anchor_generator_width_stride = pipeline_config.get_param('anchor_generator_width_stride')
- anchor_generator_height = pipeline_config.get_param('anchor_generator_height')
- anchor_generator_width = pipeline_config.get_param('anchor_generator_width')
-
- if variance_height != variance_width:
- log.error('The values for variance for height "{}" is not equal to variance for width "{}". The detection '
- 'results will be inaccurate.'.format(variance_height, variance_width))
- if variance_x != variance_y:
- log.error('The values for variance for x "{}" is not equal to variance for y "{}". The detection '
- 'results will be inaccurate.'.format(variance_x, variance_y))
- if anchor_generator_height_stride != anchor_generator_width_stride:
- log.error('The values for the anchor generator height stride "{}" is not equal to the anchor generator '
- 'width stride "{}". The detection results will be inaccurate.'
- ''.format(anchor_generator_height_stride, anchor_generator_width_stride))
- if anchor_generator_height != anchor_generator_width:
- log.error('The values for the anchor generator height "{}" is not equal to the anchor generator width '
- 'stride "{}". The detection results will be inaccurate.'.format(anchor_generator_height,
- anchor_generator_width))
-
- proposal_op = ProposalOp(graph, dict(min_size=1,
- framework='tensorflow',
- pre_nms_topn=2 ** 31 - 1,
- box_size_scale=variance_height,
- box_coordinate_scale=variance_x,
- post_nms_topn=max_proposals,
- feat_stride=anchor_generator_height_stride,
- ratio=proposal_ratios,
- scale=proposal_scales,
- normalize=1,
- base_size=anchor_generator_height,
- nms_thresh=_value_or_raise(match, pipeline_config,
- 'first_stage_nms_iou_threshold')))
- for key in ('clip_before_nms', 'clip_after_nms'):
- if key in match.custom_replacement_desc.custom_attributes:
- proposal_op.attrs[key] = int(match.custom_replacement_desc.custom_attributes[key])
-
- bboxes_offsets = backward_bfs_for_operation(match.single_input_node(0)[0], ['Add'])[0]
-
- # creates input to store input image height, width and scales (usually 1.0s) which is a mandatory input to the
- # Proposal operation. The batch size for this input is fixed because it is allowed to pass images of the same
- # size only as input
- im_info = Parameter(graph, dict(shape=int64_array([1, 3]), fixed_batch=True)).create_node(
- [], dict(name='image_info'))
-
- proposal = proposal_op.create_node([reshape_conf_initial, bboxes_offsets, im_info], dict(name='proposals'))
- return {'proposal_node': ObjectDetectionAPIProposalReplacement.ie_to_tf_proposals(graph, proposal, match,
- pipeline_config,
- max_proposals)}
-
- @staticmethod
- def insert_detection_output_instead_of_proposal(graph: Graph, match: SubgraphMatch,
- pipeline_config: PipelineConfig):
- """
- The function inserts DetectionOutput operation instead of Proposal operation which may result in an increase of
- the accuracy for some models. The function is enabled with the custom attribute "operation_to_insert" with
- value "DetectionOutput" in the transformation configuration file section for the
- "ObjectDetectionAPIProposalReplacement" transformation.
-
- :param graph: the graph to operate on
- :param match: the object containing information about the matched sub-graph
- :param pipeline_config: object containing information from the pipeline.config file of the model
- :return: the dictionary with mapping information needed for other transformations
- """
- max_proposals = _value_or_raise(match, pipeline_config, 'first_stage_max_proposals')
-
- # Convolution/matmul node that produces classes confidence
- # Transpose result of the tensor with classes confidences so it will be in a correct layout for Softmax
- class_conf_nodes = backward_bfs_for_operation(match.single_input_node(1)[0], ['Add'])
- assert len(class_conf_nodes) >= 1, 'Expected to find nodes of type "Add" starting from the node "{}" in ' \
- 'backward direction'.format(match.single_input_node(1)[0].id)
- class_conf = class_conf_nodes[0]
-
- # prepare input with class confidences. The DetectionOutput operation which will consume this tensor as a
- # second input expects probabilities to be normalized with SoftMax operation per each bounding box class. In
- # order to do this we first reshape the tensor so the last dimension contains probability for 2 classes
- # (background and foreground) for each bounding box. Before feeding this tensor to the DO operation the tensor
- # is flattened to the shape [num_batches, num_classes * num_bounding_boxes]
- reshape_conf = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1, 2]),
- dict(name='predictions/Reshape'))
- # transpose from NCHW to NHWC will be inserted as input to the Reshape automatically. This is expected
- class_conf.out_port(0).disconnect()
- class_conf.out_port(0).connect(reshape_conf.in_port(0))
- softmax_conf = Softmax(graph, dict(axis=2, name=reshape_conf.id + '/Softmax')).create_node([reshape_conf])
- flattened_conf = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1]),
- dict(name=softmax_conf.name + '/Flatten'), softmax_conf)
- # prepare input with bounding boxes shape offsets
- offsets = backward_bfs_for_operation(match.single_input_node(0)[0], ['Add'])[0]
- flatten_offsets = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1]),
- dict(name=offsets.soft_get('name', offsets.id) + '/Flatten'),
- offsets)
-
- # TensorFlow produces anchor boxes in absolute coordinates in YXYX order. Need to normalize them to [0, 1]
- # interval and append a tensor with variances. Refer to the ObjectDetectionAPISSDPostprocessorReplacement
- # transformation comments about variances. The YXYX->XYXY order change will be performed with the output of the
- # inserted DetectionOutput operation
- yxyx_anchors = match.single_input_node(2)[0]
-
- # get the input image height and width to divide the anchors values by it
- initial_input_node_name = 'input_tensor' if 'input_tensor' in graph.nodes else 'image_tensor'
- if initial_input_node_name not in graph.nodes():
- raise Error('Input node "{}" of the graph is not found. Do not run the Model Optimizer with '
- '"--input" command line parameter.'.format(initial_input_node_name))
- parameter_node = Node(graph, initial_input_node_name)
-
- input_shape = Shape(graph, {'name': parameter_node.name}).create_node([parameter_node])
- input_image_hw = node_to_get_shape_value_of_indices(input_shape, [1, 2]) # NHWC layout
- hwhw = create_op_with_const_inputs(graph, Tile, {1: int64_array([2])}, {'name': 'image_hwhw'}, input_image_hw)
-
- hwhw_float = Cast(graph, {'dst_type': np.float32}).create_node([hwhw])
- scaled_anchors = Div(graph, {'name': 'scaled_anchors'}).create_node([yxyx_anchors, hwhw_float])
-
- flattened_anchors = create_op_with_const_inputs(graph, Reshape, {1: int64_array([1, 1, -1])},
- {'name': 'flattened_anchors'}, scaled_anchors)
- cropped_anchors = AttributedClamp(graph, {'min': 0.0, 'max': 1.0, 'name': 'clamped_yxyx',
- 'nchw_layout': True}).create_node([flattened_anchors])
- # the input tensor "scaled_anchors" for the "flattened_anchors" may be 4D. In order to avoid inserting Transpose
- # operation mark the "flattened_anchors" with the correct data layout
- mark_as_correct_data_layout(flattened_anchors)
-
- # create tensor of shape [4] with variance values which then are tiled by the number of boxes which is obtained
- # from the 'yxyx_anchors' node
- variances = Const(graph, {'value': _variance_from_pipeline_config(pipeline_config)}).create_node()
-
- anchors_shape = Shape(graph, {'name': 'anchors_shape'}).create_node([yxyx_anchors])
- anchors_count = node_to_get_shape_value_of_indices(anchors_shape, [0])
- tiled_variances = Tile(graph, {'name': 'tiled_variances'}).create_node([variances, anchors_count])
- reshaped_tiled_variances = create_op_with_const_inputs(graph, Reshape, {1: int64_array([1, 1, -1])},
- {'name': 'flattened_variances'}, tiled_variances)
-
- # now we can merge actual anchors coordinates with a tensor with variances as it is expected by the
- # DetectionOutput operation
- duplicate_anchors = Concat(graph, {'axis': 1, 'name': 'anchors_with_variances'}).create_node(
- [cropped_anchors, reshaped_tiled_variances])
-
- do = DetectionOutput(graph,
- {'background_label_id': 0,
- 'clip_after_nms': True,
- 'clip_before_nms': False,
- 'code_type': 'caffe.PriorBoxParameter.CENTER_SIZE',
- 'confidence_threshold': 0.0,
- 'decrease_label_id': False,
- 'input_height': 1,
- 'input_width': 1,
- 'keep_top_k': max_proposals,
- 'normalized': True,
- 'objectness_score': 0,
- 'share_location': True,
- 'top_k': 6000,
- 'variance_encoded_in_target': False,
- 'nms_threshold': _value_or_raise(match, pipeline_config, 'first_stage_nms_iou_threshold'),
- 'name': 'first_do',
- }).create_node([flatten_offsets, flattened_conf, duplicate_anchors])
- # DetectionOutput output tensor has YXYX box coordinates order
- # switch to 3D to avoid issues that part of the model with 4D shapes should be inferred in NCHW layout
- do_3d = create_op_with_const_inputs(graph, Squeeze, {1: int64_array(0)}, {'name': do.name + '/SqueezeDO'}, do)
- mark_as_correct_data_layout(do_3d)
-
- # DetectionOutput output tensor produces a tensor of tuples with the following 7 elements:
- # [batch_id, class_id, confidence, x1, y1, x2, y2]. Here we split the DetectionOutput result into the 7
- # tensors with each of these elements for predictions. Then we crop predicted box coordinates (scaled) to be
- # within [0, 1] range (as it is predicted in the TF model) and then combine tensors back to the Proposal
- # operation output format: [batch_id, x1, y1, x2, y2].
- do_split = create_op_node_with_second_input(graph, Split, int64_array(2), {'num_splits': 7,
- 'name': do.name + '/Split'}, do_3d)
-
- coords = Concat(graph, {'axis': -1, 'in_ports_count': 4, 'name': do_split.name + '/coords'}).create_node()
- # concat bounding boxes with the same order (XYXY) as Proposal produces
- for port_idx in range(4):
- do_split.out_port(3 + port_idx).connect(coords.in_port(port_idx))
-
- clamped_coords = AttributedClamp(graph, {'min': 0.0, 'max': 1.0, 'name': 'clamped_xyxy'}).create_node([coords])
-
- # prepare final proposal boxes [batch_id, x1, y1, x2, y2]
- proposal_node = Concat(graph, {'axis': -1, 'in_ports_count': 2, 'name': 'proposals'}).create_node()
- do_split.out_port(0).connect(proposal_node.in_port(0))
- clamped_coords.out_port(0).connect(proposal_node.in_port(1))
- return {'proposal_node': ObjectDetectionAPIProposalReplacement.ie_to_tf_proposals(graph, proposal_node, match,
- pipeline_config,
- max_proposals)}
-
- @staticmethod
- def ie_to_tf_proposals(graph: Graph, proposal: Node, match: SubgraphMatch, pipeline_config: PipelineConfig,
- max_proposals: int):
- """
- Builds a graph which converts the proposals data in OV format to the format of TensorFlow. This includes
- cropping the OV output of format [batch, x1, y1, x2, y2] to simply [x1, y1, x2, y2] and reshaping tensor to an
- appropriate shape. Swapping of the Proposal output is performed when necessary.
-
- :param graph: the graph to operate on
- :param proposal: the node producing OV proposals
- :param match: the object containing information about matched sub-graph
- :param pipeline_config: object containing information from the pipeline.config file of the model
- :param max_proposals: maximum number of proposal boxes. Needed for the reshaping of the tensor
- :return: the node producing output in the TF format.
- """
- # models with use_matmul_crop_and_resize = True should not swap order of elements (YX to XY) after the Proposal
- # because the TF output has XYXY layout originally.
- # Also old version of RFCN model (1.9) does not require proposal swap since the output has proper layout
- # already. The swap is controlled with the 'do_not_swap_proposals' parameter from the transformation file
- swap_proposals = not match.custom_replacement_desc.custom_attributes.get('do_not_swap_proposals', False) and \
- not pipeline_config.get_param('use_matmul_crop_and_resize')
- if swap_proposals:
- proposal = add_convolution_to_swap_xy_coordinates(graph, proposal, 5)
-
- # the "reshape_swap_proposals_2d" is used in the ObjectDetectionAPIPSROIPoolingReplacement transformation. It
- # is important that this input may be swapped several lines above
- proposal_reshape_2d = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 5]),
- dict(name="reshape_swap_proposals_2d"), proposal)
- mark_input_as_in_correct_layout(proposal_reshape_2d, 0)
-
- # Find closest CropAndResize in topological order
- start_node = match.single_input_node(0)[0]
- crop_and_resize_nodes_ids = [node.id for node in graph.pseudo_topological_sort_with_start_node(start_node) if
- graph.nodes[node.id]['op'] == 'CropAndResize']
-
- if len(crop_and_resize_nodes_ids) != 0 and swap_proposals:
- # feed the CropAndResize node with a correct boxes information produced with the Proposal layer
- # find the first CropAndResize node in the BFS order. This is needed in the case when we already swapped
- # box coordinates data after the Proposal node
- crop_and_resize_node = Node(graph, crop_and_resize_nodes_ids[0])
- # set a marker that an input with box coordinates has been pre-processed so the CropAndResizeReplacement
- # transform doesn't try to merge the second and the third inputs
- crop_and_resize_node['inputs_preprocessed'] = True
- crop_and_resize_node.in_port(1).disconnect()
- proposal_reshape_2d.out_port(0).connect(crop_and_resize_node.in_port(1))
-
- tf_proposal_reshape_4d = create_op_node_with_second_input(graph, Reshape,
- int64_array([-1, 1, max_proposals, 5]),
- dict(name="reshape_proposal_4d"), proposal)
- mark_as_correct_data_layout(tf_proposal_reshape_4d)
-
- crop_op = Crop(graph, dict(axis=int64_array([3]), offset=int64_array([1]), dim=int64_array([4]),
- nchw_layout=True))
- # the crop_proposals node is used in the ObjectDetectionAPIDetectionOutputReplacement transformation
- crop = crop_op.create_node([tf_proposal_reshape_4d], dict(name='crop_proposals'))
-
- tf_proposals_crop_reshape_3d_node = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1, 4]),
- dict(name="reshape_crop_3d"), crop)
- mark_input_as_in_correct_layout(tf_proposals_crop_reshape_3d_node, 0)
- return tf_proposals_crop_reshape_3d_node
-
-
-"""
-An important part of many object detection models is an operation DetectionOutput which decodes final detection boxes
-using predicted bounding boxes shape offsets and prior boxes inputs. And finally performs non-maximum-suppression based
-on decoded boxes and their confidences (scores). There is no DetectionOutput operation in TensorFlow operation set, it
-is implemented as a sub-graph of primitive operations instead. There are two transformations which replace the sub-graph
-implementing DetectionOutput operation in this file: ObjectDetectionAPISSDPostprocessorReplacement and
-ObjectDetectionAPIDetectionOutputReplacement. The first one is used for SSD models, the second one for Faster-RCNN,
-Mask-RCNN and RFCN models. These transformations also prepare input data for the DetectionOutput operation because the
-layout and shape of the data is different between the TensorFlow and the OpenVINO. The most notable difference
-is that bounding boxes and deltas are calculated with YXYX order in the TensorFlow model whilst OpenVINO
-operation DetectionOutput, ROIPooling and Proposal expects them and produce the output with XYXY order. Refer to the
-transformation code and operations specifications for more details.
-"""
-
-
-class ObjectDetectionAPISSDPostprocessorReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- The transformation replaces the TensorFlow sub-graph performing DetectionOutput with the DetectionOutput operation
- and adds some nodes to prepare input data in correct layout and shape.
- """
- replacement_id = 'ObjectDetectionAPISSDPostprocessorReplacement'
- run_not_recursively = True
-
- def run_after(self):
- return [ObjectDetectionAPIPreprocessorReplacement, ObjectDetectionAPIPreprocessor2Replacement]
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict):
- # the DetectionOutput in OV produces single tensor, but in TF it produces two tensors, so create only one output
- # edge match
- return {match.output_node(0)[0].id: new_sub_graph['detection_output_node'].id}
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
-
- has_background_class = _value_or_raise(match, pipeline_config, 'add_background_class')
- num_classes = _value_or_raise(match, pipeline_config, 'num_classes') + has_background_class
-
- # reshapes confidences to 4D before applying activation function and do not convert from NHWC to NCHW this node.
- # the add_activation_function_after_node function may insert the Softmax operation which is performed over the
- # last dimension which should have a specific size = num_classes. In the original model the last dimension may
- # be different, so this Reshape is absolutely necessary
- reshape_conf_before_ac = create_op_node_with_second_input(graph, Reshape, int64_array([0, 1, -1, num_classes]),
- {'name': 'do_ExpandDims_conf'})
- reshape_conf_before_ac.in_port(0).connect(match.input_nodes(1)[0][0].in_node(0).out_port(0))
- mark_as_correct_data_layout(reshape_conf_before_ac)
-
- # the transformation nodes are selected such a way that the confidences/scores post-processing activation
- # function is removed. This was done in order to support several versions of the model using one JSON config
- # file. Therefore, it is necessary to manually add this operation back to the graph
- activation_function = _value_or_raise(match, pipeline_config, 'postprocessing_score_converter')
- activation_conf_node = add_activation_function_after_node(graph, reshape_conf_before_ac, activation_function)
-
- # OV DetectionOutput operation expects flattened tensor with bounding boxes shape offsets, so reshaping it
- reshape_offsets = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1]),
- {'name': 'do_reshape_offsets'})
-
- # skip all Identity nodes and Reshape/Squeeze/Unsqueeze ops which may break the conversion because add or split
- # unnecessary dimensions
- current_node = skip_nodes_by_condition(match.input_nodes(0)[0][0].in_node(0),
- lambda x: x.op == 'Identity' or x.has_and_set('reinterp_shape'))
- reshape_offsets.in_port(0).connect(current_node.out_port(0))
- mark_as_correct_data_layout(reshape_offsets)
-
- # OV DetectionOutput operation expects flattened tensor with class confidences, so reshaping it
- reshape_conf_node = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1]),
- {'name': 'do_reshape_conf'}, activation_conf_node)
- mark_as_correct_data_layout(reshape_conf_node)
-
- need_swap_priors = False
- # the SSD model is a fully convolutional model so it can perform detection for the arbitrary input shape image
- # if the input with prior boxes is properly generated based on the input image size. There were some TensorFlow
- # models where this input was hardcoded as a constant and so the model can predict images of the specific input
- # size only. The code below inserts PriorBox or PriorBoxClustered operations which generate prior boxes and a
- # function call "_relax_reshape_nodes" to fix hardcoded output shapes specified for some Reshape operations in
- # the original model. These workarounds can be disabled by specifying parameter
- # 'disable_prior_boxes_layers_generator' in the JSON transformation configuration file or is automatically
- # disabled if necessary information about prior box generators is not known
- if not match.custom_replacement_desc.custom_attributes.get('disable_prior_boxes_layers_generator', False) and \
- (pipeline_config.get_param('ssd_anchor_generator_num_layers') is not None or
- pipeline_config.get_param('multiscale_anchor_generator_min_level') is not None):
- # change the Reshape operations with hardcoded number of output elements of the convolution nodes to be
- # reshape-able
- _relax_reshape_nodes(graph, pipeline_config)
-
- # create PriorBoxClustered nodes instead of a constant value with prior boxes so the model could be reshaped
- if pipeline_config.get_param('ssd_anchor_generator_num_layers') is not None:
- priors_node = _create_prior_boxes_node(graph, pipeline_config)
- else:
- priors_node = _create_multiscale_prior_boxes_node(graph, pipeline_config)
- else:
- log.info('The anchor generator is not known. Save constant with prior-boxes to IR.')
- tf_priors_node = match.input_nodes(2)[0][0].in_node(0)
- # original prior boxes are stored as YXYX while DetectionOutput expects them to be represented as XYXY.
- # also variances should be encoded into this input. Variances are the values which are used during decoding
- # of bounding boxes from prior boxes and shape offsets. Refer to the DetectionOutput operation
- # implementation for more details
- flattened_priors = create_op_with_const_inputs(graph, Reshape, {1: int64_array([1, 1, -1])},
- {'name': 'flattened_priors'}, tf_priors_node)
- mark_as_correct_data_layout(flattened_priors)
-
- # create tensor of shape [4] with variance values which then are tiled by the number of boxes which is
- # obtained from the 'priors_node' node
- priors_shape = Shape(graph, {'name': 'priors_shape'}).create_node([tf_priors_node])
- priors_count = node_to_get_shape_value_of_indices(priors_shape, [-2])
-
- # replicating the variance values for all prior-boxes
- variances = Const(graph, {'value': _variance_from_pipeline_config(pipeline_config)}).create_node()
- tiled_variances = Tile(graph, {'name': 'tiled_variances'}).create_node([variances, priors_count])
- flattened_tiled_variances = create_op_with_const_inputs(graph, Reshape, {1: int64_array([1, 1, -1])},
- {'name': 'flattened_tiled_variances'},
- tiled_variances)
- # now we can concatenate priors with a tensor with variances as it is expected by the DetectionOutput
- priors_node = Concat(graph, {'axis': 1, 'name': 'priors_with_variances'}).create_node(
- [flattened_priors, flattened_tiled_variances])
-
- # set a flag that priors should we swapped from YXYX to XYXY
- need_swap_priors = True
-
- detection_output_op = DetectionOutput(graph, match.custom_replacement_desc.custom_attributes)
- # during the bounding boxes detection the intermediate boxes are clipped to be in range [0, 1]. Different
- # versions of the TF OD API SSD models have this clipping at different stages. Special attributes
- # "clip_before_nms" and "clip_after_nms" were introduced to the operation DetectionOutput to handle these cases.
- # These attributes are specified in the JSON transformation configuration file
- detection_output_node = detection_output_op.create_node(
- [reshape_offsets, reshape_conf_node, priors_node],
- dict(name=detection_output_op.attrs['type'],
- background_label_id=0 if has_background_class else -1,
- variances_encoded_in_target=False,
- confidence_threshold=_value_or_raise(match, pipeline_config, 'postprocessing_score_threshold'),
- top_k=_value_or_raise(match, pipeline_config, 'postprocessing_max_detections_per_class'),
- keep_top_k=_value_or_raise(match, pipeline_config, 'postprocessing_max_total_detections'),
- nms_threshold=_value_or_raise(match, pipeline_config, 'postprocessing_iou_threshold')))
-
- # the TensorFlow model keeps the bounding boxes shape offsets as YXYX, while OV DetectionOutput expects them to
- # be specified as XYXY. The solution is to update last convolutions weights and biases to produce XY->YX swapped
- # bounding boxes offsets
- conv_nodes = backward_bfs_for_operation(detection_output_node.in_node(0), ['Conv2D'], ['ShapeOf'])
- swap_weights_xy(graph, conv_nodes)
-
- # also need to swap priors from YXYX to XYXY if this input was used from the original model. If the input was
- # not with PriorBox or PriorBoxClustered operations above then the layout will be XYXY
- if need_swap_priors:
- insert_weights_swap_xy_sub_graph(graph, detection_output_node.in_port(2).get_connection())
-
- # need to mark some Squeeze, Reshape and Concat operations to not change the layout
- mark_squeeze_reshape_concat_before_detection_output(conv_nodes)
-
- # As outputs are replaced with a postprocessing node, outgoing tensor names are no longer correspond to the
- # original tensors and should be removed from output->Result edges
- clear_tensor_names_info([match.output_node(out)[0] for out in range(match.outputs_count())])
-
- # return dictionary with mapping of nodes that is used in the `output_edges_match` function to finish sub-graph
- # replacement by re-connecting output from the original matched output node to the DetectionOutput node
- return {'detection_output_node': detection_output_node}
-
-
-class ObjectDetectionAPIOutputReplacement(FrontReplacementFromConfigFileGeneral):
- """
- This replacer is used to cut-off the network by specified nodes for models generated with Object Detection API.
- The custom attribute for the replacer contains one value for key "outputs". This string is a comma separated list
- of outputs alternatives. Each output alternative is a '|' separated list of node name which could be outputs. The
- first node from each alternative group that exits in the graph is chosen. Others are ignored.
- For example, if the "outputs" is equal to the following string:
-
- "Reshape_16,SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
-
- then the "Reshape_16" will be an output if it exists in the graph. The second output will be
- SecondStageBoxPredictor_1/Conv_3/BiasAdd if it exist in the graph, if not then
- SecondStageBoxPredictor_1/Conv_1/BiasAdd will be output if it exists in the graph.
- """
- replacement_id = 'ObjectDetectionAPIOutputReplacement'
- run_not_recursively = True
-
- def run_after(self):
- return [ObjectDetectionAPITransformationsStart]
-
- def run_before(self):
- return [ObjectDetectionAPIPreprocessorReplacement, ObjectDetectionAPIPreprocessor2Replacement]
-
- def transform_graph(self, graph: Graph, replacement_descriptions: dict):
- if graph.graph['cmd_params'].output is not None:
- log.warning('User defined output nodes are specified. Skip the graph cut-off by the '
- 'ObjectDetectionAPIOutputReplacement.')
- return
- outputs = []
- outputs_string = replacement_descriptions['outputs']
- for alternatives in outputs_string.split(','):
- for out_node_name in alternatives.split('|'):
- if graph.has_node(out_node_name):
- outputs.append(out_node_name)
- break
- else:
- log.debug('A node "{}" does not exist in the graph. Do not add it as output'.format(out_node_name))
- _outputs = output_user_data_repack(graph, outputs)
- add_output_ops(graph, _outputs, graph.graph['inputs'])
-
-
-class ObjectDetectionAPIPSROIPoolingReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- RFCN models contain a unique block ("SecondStageBoxPredictor") performing bounding boxes predictions which is
- called Position Sensitive ROI Pooling (PSROIPooling). The combination of "CropAndResize operations located in the
- "while" loop forms a single PSROIPooling operation with bilinear interpolation. The transformation matches two
- "while" loops with PSROIPooling layers applied to the tensors with box coordinates and classes predictions. The
- sub-graph being replaced also contains a Reduce operation performing mean calculation over the spatial dimensions,
- so the transformation adds this operation as well.
- """
- replacement_id = 'ObjectDetectionAPIPSROIPoolingReplacement'
- run_not_recursively = True
-
- def run_after(self):
- return [ObjectDetectionAPIProposalReplacement]
-
- def run_before(self):
- return [ObjectDetectionAPITransformationsFinish]
-
- def output_edges_match(self, graph: Graph, match: SubgraphMatch, new_sub_graph: dict):
- return {match.output_node(0)[0].id: new_sub_graph['output_node'].id}
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
- num_classes = _value_or_raise(match, pipeline_config, 'num_classes')
-
- input_node = match.input_nodes(0)[0][0].in_node(0)
- if 'class_predictions' in input_node.id:
- psroipooling_output_dim = num_classes + 1
- else:
- psroipooling_output_dim = num_classes * 4
-
- num_spatial_bins_height = pipeline_config.get_param('num_spatial_bins_height')
- num_spatial_bins_width = pipeline_config.get_param('num_spatial_bins_width')
- crop_height = pipeline_config.get_param('crop_height')
- crop_width = pipeline_config.get_param('crop_width')
- if crop_height != crop_width:
- raise Error('Different "crop_height" and "crop_width" parameters from the pipeline config are not '
- 'supported: {} vs {}'.format(crop_height, crop_width))
-
- proposal_nodes = graph.get_op_nodes(name='reshape_swap_proposals_2d')
- if len(proposal_nodes) != 1:
- raise Error("Found the following nodes '{}' with name 'reshape_swap_proposals_2d' but there should be "
- "exactly 1. Looks like ObjectDetectionAPIProposalReplacement transformation didn't work."
- "".format(proposal_nodes))
- reshape_swap_proposals_node = proposal_nodes[0]
-
- psroipooling_node = PSROIPoolingOp(graph, {'name': input_node.soft_get('name') + '/PSROIPooling',
- 'output_dim': psroipooling_output_dim,
- 'group_size': crop_width // num_spatial_bins_width,
- 'spatial_bins_x': num_spatial_bins_width,
- 'spatial_bins_y': num_spatial_bins_height,
- 'mode': 'bilinear',
- 'spatial_scale': 1,
- }).create_node([input_node, reshape_swap_proposals_node])
-
- # add Reduce operation which is a part of the graph being removed
- reduce_node = create_op_node_with_second_input(graph, ReduceMean, int64_array([1, 2]),
- {'name': 'mean', 'keep_dims': True}, psroipooling_node)
-
- output_node = match.output_node(0)[0].out_node()
- if len(output_node.in_ports()) == 2 and not output_node.in_port(1).disconnected():
- output_node.in_port(1).disconnect() # disconnect the second input to make "erase_node" function work
- graph.erase_node(match.output_node(0)[0].out_node())
-
- return {'output_node': reduce_node}
-
-
-class ObjectDetectionAPIConstValueOverride(FrontReplacementFromConfigFileGeneral):
- """
- Transforms allows to override specific constant values in the topology. The replacement description configuration
- file contains list of tuples describing the desired replacements specified in the "replacements" key of the
- "custom_attributes". The first element in the tuple is the initial node name of the graph with constant value. The
- second element is the name of the parameter from the pipeline configuration file which stores new value.
-
- Usage example. The Faster-RCNNs topologies has constant node with the number specifying maximum generated proposals.
- This value is specified in the pipeline configuration file in the parameter 'first_stage_max_proposals' and is
- saved as a constant node in the generated topology. If the parameter is modified from it's original value then the
- topology will be incorrect because the number 'first_stage_max_proposals' is used in the transforms of this file is
- no more equal to the 'first_stage_max_proposals' saved as a constant.
- """
- replacement_id = 'ObjectDetectionAPIConstValueOverride'
- run_not_recursively = True
-
- def run_after(self):
- return [ObjectDetectionAPITransformationsStart]
-
- def run_before(self):
- return [ObjectDetectionAPIPreprocessorReplacement, ObjectDetectionAPIPreprocessor2Replacement]
-
- def transform_graph(self, graph: Graph, replacement_descriptions: dict):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_object_detection_api_pipeline_config is None:
- raise Error(missing_param_error)
- pipeline_config = PipelineConfig(argv.tensorflow_object_detection_api_pipeline_config)
- for (node_id, pipeline_config_name) in replacement_descriptions['replacements']:
- if node_id not in graph.nodes():
- log.debug('Node with id {} does not exist in the graph'.format(node_id))
- continue
- node = Node(graph, node_id)
- if not node.has_valid('value'):
- log.debug('Node with id {} does not have value'.format(node_id))
- continue
- node.value = mo_array(pipeline_config.get_param(pipeline_config_name))
- node.value = node.value.reshape(node.shape)
diff --git a/tools/mo/openvino/tools/mo/front/tf/QueueDequeue_ext.py b/tools/mo/openvino/tools/mo/front/tf/QueueDequeue_ext.py
deleted file mode 100644
index e9b336daf486cd..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/QueueDequeue_ext.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.op import Op
-
-
-def get_attrs(node: Node):
- shapes = node.pb.attr["_output_shapes"].list.shape
- tf_types = node.pb.attr["component_types"].list.type
- extracted_types = []
- for t in tf_types:
- extracted_types.append(tf_dtype_extractor(t))
- result_shapes = []
- for shape_pb in shapes:
- result_shapes.append(tf_tensor_shape(shape_pb))
- assert len(result_shapes) == len(extracted_types), "Output shapes do not match output" \
- "types in the node {}".format(node.soft_get('name', node.id))
- attrs = {"shapes": result_shapes, "types": extracted_types, 'out_ports_count': len(result_shapes)}
- return attrs
-
-
-class QueueDequeueV1Extractor(FrontExtractorOp):
- op = "QueueDequeue"
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = get_attrs(node)
- Op.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class QueueDequeueV2Extractor(FrontExtractorOp):
- op = "QueueDequeueV2"
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = get_attrs(node)
- Op.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/RFFTRealImagToRFFTSplit.py b/tools/mo/openvino/tools/mo/front/tf/RFFTRealImagToRFFTSplit.py
deleted file mode 100644
index 0cf3894ae3186a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/RFFTRealImagToRFFTSplit.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-class RFFTRealImagToRDFTSplit(FrontReplacementSubgraph):
- """
- This transformation converts the operation TFRFFT into OpenVINO RDFT.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.tf.TFFFTToDFT import TFFFTToDFT
- return [TFFFTToDFT]
-
- def pattern(self):
- return dict(
- nodes=[
- ('rfft', dict(op='TFFFT', fft_kind='RDFT')),
- ('real', dict(op='Real')),
- ('imag', dict(op='Imag')),
- ],
- edges=[
- ('rfft', 'real', {'in': 0}),
- ('rfft', 'imag', {'in': 0}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
- rfft_node = match['rfft']
- real_node = match['real']
- imag_node = match['imag']
-
- rfft_name = rfft_node.soft_get('name', rfft_node.id)
- real_name = rfft_node.soft_get('name', real_node.id)
- imag_name = rfft_node.soft_get('name', imag_node.id)
- split_node = create_op_with_const_inputs(graph, Split, {1: int64_array(-1)},
- {
- 'name': rfft_name + '/split',
- 'num_splits': 2,
- 'out_ports_count': 2
- })
- squeeze_real = create_op_with_const_inputs(graph, Squeeze, {1: int64_array(-1)},
- {'name': rfft_name + '/squeeze_real'})
- squeeze_imag = create_op_with_const_inputs(graph, Squeeze, {1: int64_array(-1)},
- {'name': rfft_name + '/squeeze_imag'})
-
- split_node.out_port(0).connect(squeeze_real.in_port(0))
- split_node.out_port(1).connect(squeeze_imag.in_port(0))
- real_node.out_port(0).get_connection().set_source(squeeze_real.out_port(0))
- imag_node.out_port(0).get_connection().set_source(squeeze_imag.out_port(0))
-
- rfft_node.out_port(0).connect(split_node.in_port(0))
-
- rename_nodes([(real_node, real_name + '/to_be_removed'), (squeeze_real, real_name)])
- rename_nodes([(imag_node, imag_name + '/to_be_removed'), (squeeze_imag, imag_name)])
-
- real_node.in_port(0).disconnect()
- imag_node.in_port(0).disconnect()
diff --git a/tools/mo/openvino/tools/mo/front/tf/RetinaNetFilteredDetectionsReplacement.py b/tools/mo/openvino/tools/mo/front/tf/RetinaNetFilteredDetectionsReplacement.py
deleted file mode 100644
index c279c2da9138c4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/RetinaNetFilteredDetectionsReplacement.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.DetectionOutput import DetectionOutput
-from openvino.tools.mo.ops.elementwise import Mul, Sub, Pow
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.split import VariadicSplit
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array, mo_array
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input, create_op_with_const_inputs
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileSubGraph
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.graph import clear_tensor_names_info
-
-
-class RetinaNetFilteredDetectionsReplacement(FrontReplacementFromConfigFileSubGraph):
- """
- The class replaces the sub-graph that performs boxes post-processing and NMS with the DetectionOutput layer.
-
- The post-processing in the RetinaNet topology is performed differently from the DetectionOutput layer implementation
- in the OpenVINO. The first one calculates (d_x1, d_y1, d_x2, d_y2) which are a factor of the prior box width
- and height. The DetectionOuput with "code_type" equal to "caffe.PriorBoxParameter.CORNER" just adds predicted deltas
- to the prior box coordinates. This replacer add nodes which calculate prior box widths and heights, apply variances
- to the predicated box coordinates and multiply them. With this approach the DetectionOutput layer with "code_type"
- equal to "caffe.PriorBoxParameter.CORNER" produces the same result as the post-processing in the original topology.
- """
- replacement_id = 'RetinaNetFilteredDetectionsReplacement'
-
- 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}
-
- def nodes_to_remove(self, graph: Graph, match: SubgraphMatch):
- new_nodes_to_remove = match.matched_nodes_names()
- new_nodes_to_remove.remove(match.single_input_node(0)[0].id)
- new_nodes_to_remove.remove(match.single_input_node(1)[0].id)
- new_nodes_to_remove.remove(match.single_input_node(2)[0].id)
- return new_nodes_to_remove
-
- @staticmethod
- def append_variances(priors_scale_node: Node, variance: list):
- graph = priors_scale_node.graph
- name = priors_scale_node.name
-
- sp_shape = Shape(graph, {'name': name + '/shape'}).create_node()
- priors_scale_node.out_port(0).connect(sp_shape.in_port(0))
-
- begin = Const(graph, {'value': int64_array([-2])}).create_node()
- end = Const(graph, {'value': int64_array([-1])}).create_node()
- stride = Const(graph, {'value': int64_array([1])}).create_node()
- shape_part_for_tiling = StridedSlice(graph, {'name': name + '/get_-2_dim', 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]), 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])}).create_node()
-
- sp_shape.out_port(0).connect(shape_part_for_tiling.in_port(0))
- begin.out_port(0).connect(shape_part_for_tiling.in_port(1))
- end.out_port(0).connect(shape_part_for_tiling.in_port(2))
- stride.out_port(0).connect(shape_part_for_tiling.in_port(3))
-
- shape_concat = create_op_node_with_second_input(graph, Concat, int64_array([4]),
- {'name': name + '/shape_for_tiling', 'in_ports_count': 2,
- 'axis': int64_array(0)},
- shape_part_for_tiling)
-
- variance = Const(graph, {'name': name + '/variance', 'value': float32_array(variance)}).create_node()
- tile = Broadcast(graph, {'name': name + '/variance_tile'}).create_node()
- variance.out_port(0).connect(tile.in_port(0))
- shape_concat.out_port(0).connect(tile.in_port(1))
-
- reshape_dim = Const(graph, {'value': int64_array([-1, 4])}).create_node()
- sp_reshape = Reshape(graph, {'name': name + '/reshape'}).create_node()
- sp_reshape.in_port(0).connect(priors_scale_node.out_port(0))
- sp_reshape.in_port(1).connect(reshape_dim.out_port(0))
-
- concat = Concat(graph,
- {'name': name + '/priors_concat', 'axis': int64_array(0), 'in_ports_count': 2}).create_node()
- sp_reshape.out_port(0).connect(concat.in_port(0))
- tile.out_port(0).connect(concat.in_port(1))
-
- output_dims = Const(graph, {'value': int64_array([1, 2, -1])}).create_node()
- output_node = Reshape(graph, {'name': name + '/3D_priors_wth_variances'}).create_node()
- concat.out_port(0).connect(output_node.in_port(0))
- output_dims.out_port(0).connect(output_node.in_port(1))
-
- return output_node
-
- def placeholder_scales(self, placeholder: Node):
- """
- Helper function to get scales for prior boxes out of input image size:
- [1 / im_width, 1 / im_height, 1 / im_width, 1 / im_height]
- """
- graph = placeholder.graph
- name = placeholder.soft_get('name', placeholder.id)
-
- shape_value = placeholder.soft_get('shape', None)
- assert shape_value is not None, \
- "[ {} replacer ] Placeholder `{}` should have shape attribute".format(self.replacement_id, name)
- assert isinstance(shape_value, np.ndarray), \
- "[ {} replacer ] Placeholder `{}` shape attribute should be np.ndarray".format(self.replacement_id, name)
- assert shape_value.size == 4, \
- "[ {} replacer ] Placeholder `{}` should be 4D. Shape: {}".format(self.replacement_id, name, shape_value)
-
- shape = Shape(graph, {'name': 'input_image_shape'}).create_node()
- shape.in_port(0).connect(placeholder.out_port(0))
-
- begin = Const(graph, {'value': int64_array([1])}).create_node()
- end = Const(graph, {'value': int64_array([3])}).create_node()
- stride = Const(graph, {'value': int64_array([1])}).create_node()
- spatial = StridedSlice(graph, {'name': name + '/get_h_w', 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]), 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]), 'ellipsis_mask': int64_array([0])}).create_node()
-
- spatial.in_port(0).connect(shape.out_port(0))
- spatial.in_port(1).connect(begin.out_port(0))
- spatial.in_port(2).connect(end.out_port(0))
- spatial.in_port(3).connect(stride.out_port(0))
-
- power = Const(graph, {'value': float32_array([-1.])}).create_node()
- spatial_scale = Pow(graph, {}).create_node()
-
- spatial_scale.in_port(0).connect(spatial.out_port(0))
- spatial_scale.in_port(1).connect(power.out_port(0))
-
- # Power `type_infer` requires inputs to have equal data type
- convert_to_fp32 = Cast(graph, {'dst_type': np.float32}).create_node()
- spatial_scale.in_port(0).get_connection().insert_node(convert_to_fp32)
-
- order = Const(graph, {'value': int64_array([1, 0])}).create_node()
- axis_const = Const(graph, {'value': int64_array(0)}).create_node()
- reverse = Gather(graph, {}).create_node()
-
- reverse.in_port(0).connect(spatial_scale.out_port(0))
- reverse.in_port(1).connect(order.out_port(0))
- axis_const.out_port(0).connect(reverse.in_port(2))
-
- priors_scale_node = Concat(graph, {'axis': 0, 'in_ports_count': 2}).create_node()
- priors_scale_node.add_input_port(0, skip_if_exist=True)
- priors_scale_node.add_input_port(1, skip_if_exist=True)
-
- priors_scale_node.in_port(0).connect(reverse.out_port(0))
- priors_scale_node.in_port(1).connect(reverse.out_port(0))
- return priors_scale_node
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- reshape_classes_node = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1]),
- dict(name='do_reshape_classes'),
- match.single_input_node(1)[0])
-
- initial_priors_node = match.single_input_node(2)[0]
- priors_name = initial_priors_node.soft_get('name', initial_priors_node.id)
- # model calculates identical prior boxes for each batch, so we take first slice of them
- begin = Const(graph, {'value': mo_array([0, 0, 0], dtype=np.int32)}).create_node()
- end = Const(graph, {'value': mo_array([1, 0, 0], dtype=np.int32)}).create_node()
- stride = Const(graph, {'value': mo_array([1, 1, 1], dtype=np.int32)}).create_node()
-
- priors_node = StridedSlice(graph, {'name': priors_name + '/0_batch_slice',
- 'begin_mask': int64_array([1, 1, 1]),
- 'end_mask': int64_array([1, 0, 0]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])}).create_node()
-
- initial_priors_node.out_port(0).connect(priors_node.in_port(0))
- begin.out_port(0).connect(priors_node.in_port(1))
- end.out_port(0).connect(priors_node.in_port(2))
- stride.out_port(0).connect(priors_node.in_port(3))
-
- placeholders = graph.get_op_nodes(type='Parameter')
- assert len(placeholders) == 1, "{} replacer requires model to have one Placeholder, but current model has " \
- "{} placeholders".format(self.replacement_id, len(placeholders))
- placeholder = placeholders[0]
-
- # scale prior boxes to the [0, 1] interval
- node_with_scales_for_prior_boxes = self.placeholder_scales(placeholder)
- priors_scale_node = Mul(graph, {'name': 'scale_priors'}).create_node()
-
- broadcast = Broadcast(graph, {'name': 'scales_broadcast'}).create_node()
- shape_of_priors = Shape(graph, {'name': 'priors_shape'}).create_node()
- priors_node.out_port(0).connect(shape_of_priors.in_port(0))
- broadcast.in_port(1).connect(shape_of_priors.out_port(0))
- broadcast.in_port(0).connect(node_with_scales_for_prior_boxes.out_port(0))
-
- priors_scale_node.in_port(0).connect(priors_node.out_port(0))
- priors_scale_node.in_port(1).connect(broadcast.out_port(0))
-
- try:
- variance = match.custom_replacement_desc.custom_attributes['variance']
- except:
- raise Error('There is no variance attribute in {} replacement config file `custom_attributes`'
- ''.format(self.replacement_id))
-
- priors = self.append_variances(priors_scale_node, variance)
-
- # calculate prior boxes widths and heights
- split_node = create_op_with_const_inputs(
- graph, VariadicSplit, {1: int64_array(2), 2: int64_array([1, 1, 1, 1])}, {'out_ports_count': 4},
- priors_scale_node)
-
- priors_width_node = Sub(graph, dict(name=split_node.name + '/sub_2-0_')
- ).create_node([(split_node, 2), (split_node, 0)])
- priors_height_node = Sub(graph, dict(name=split_node.name + '/sub_3-1_')
- ).create_node([(split_node, 3), (split_node, 1)])
-
- # concat weights and heights into a single tensor and multiple with the box coordinates regression values
- # WA with 3 Concats instead of 1 for keeping model reshapable
- # concat_width_height_node = Concat(graph, {'name': 'concat_priors_width_height', 'axis': -1,
- # 'in_ports_count': 4}).create_node(
- # [priors_width_node, priors_height_node, priors_width_node, priors_height_node])
-
- concat_1 = Concat(graph, {'name': 'concat_width_height',
- 'axis': -1, 'in_ports_count': 2}).create_node([priors_width_node, priors_height_node])
- concat_2 = Concat(graph, {'name': 'concat_width_height_width',
- 'axis': -1, 'in_ports_count': 2}).create_node([concat_1, priors_width_node])
- concat_width_height_node = Concat(graph, {'name': 'concat_priors_width_height', 'axis': -1, 'in_ports_count': 2}
- ).create_node([concat_2, priors_height_node])
-
- applied_width_height_regressions_node = Mul(graph, {'name': 'final_regressions'}).create_node(
- [concat_width_height_node, match.single_input_node(0)[0]])
-
- # reshape to 2D tensor as OpenVINO Detection Output layer expects
- reshape_regression_node = create_op_node_with_second_input(graph, Reshape, int64_array([0, -1]),
- dict(name='reshape_regression'),
- applied_width_height_regressions_node)
-
- detection_output_op = DetectionOutput(graph, match.custom_replacement_desc.custom_attributes)
- # get nms from the original network
- iou_threshold = None
- nms_nodes = graph.get_op_nodes(op='NonMaxSuppression')
- if len(nms_nodes) > 0:
- # it is highly unlikely that for different classes NMS has different
- # moreover DetectionOutput accepts only scalar values for iou_threshold (nms_threshold)
- iou_threshold = nms_nodes[0].in_node(3).value
- if iou_threshold is None:
- raise Error('During {} `iou_threshold` was not retrieved from RetinaNet graph'.format(self.replacement_id))
-
- detection_output_node = detection_output_op.create_node(
- [reshape_regression_node, reshape_classes_node, priors],
- dict(name=detection_output_op.attrs['type'], nms_threshold=iou_threshold, clip_after_nms=1, normalized=1,
- variance_encoded_in_target=0, background_label_id=1000))
-
- # As outputs are replaced with a postprocessing node, outgoing tensor names are no longer
- # correspond to original tensors and should be removed from output->Result edges
- out_nodes = []
- for out in range(match.outputs_count()):
- out_nodes.append(match.output_node(out)[0])
- clear_tensor_names_info(out_nodes)
-
- return {'detection_output_node': detection_output_node}
diff --git a/tools/mo/openvino/tools/mo/front/tf/RollRealImagPack.py b/tools/mo/openvino/tools/mo/front/tf/RollRealImagPack.py
deleted file mode 100644
index 89fbf10bb434c8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/RollRealImagPack.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.graph_utils import add_constant_to_negative_values
-from openvino.tools.mo.graph.graph import Graph
-
-
-class RollRealImagPack(FrontReplacementSubgraph):
- """
- Some TF models contain Roll for complex data, as a part of the sub-graph
-
- input shift axes
- | | |
- -------------------
- Roll
- |
- -------------------
- | |
- Real Imag
- | |
- ------- -------
- | |
- Pack
- |
- SomeOp
-
- This sub-graph can be replaced with the sub-graph
-
- input shift axes
- | | |
- -------------------
- Roll
- |
- SomeOp
-
- But after such replacement, we should correct axes of Roll, because input data are real now. Namely, if
- there are negative axes for Roll, we need subtract 1 from such axes indices.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.Pack import Pack
- return [Pack]
-
- def pattern(self):
- return dict(
- nodes=[
- ('unroll', dict(op='Roll')),
- ('real', dict(op='Real')),
- ('imag', dict(op='Imag')),
- ('pack', dict(op='Pack')),
- ],
- edges=[
- ('unroll', 'real', {'in': 0}),
- ('unroll', 'imag', {'in': 0}),
- ('real', 'pack', {'in': 0}),
- ('imag', 'pack', {'in': 1}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: [dict, SubgraphMatch]):
- unroll = match['unroll']
- add_constant_to_negative_values(unroll, 2, int64_array(-1))
- pack = match['pack']
- pack.out_port(0).get_connection().set_source(unroll.out_port(0))
- graph.remove_nodes_from([match['real'].id, match['imag'].id])
diff --git a/tools/mo/openvino/tools/mo/front/tf/SSDToolboxDetectionOutput.py b/tools/mo/openvino/tools/mo/front/tf/SSDToolboxDetectionOutput.py
deleted file mode 100644
index d3a8febee2cb82..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/SSDToolboxDetectionOutput.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.DetectionOutput import DetectionOutput
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileSubGraph
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import PermuteAttrs
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.result import Result
-
-
-class SSDToolboxDetectionOutputReplacement(FrontReplacementFromConfigFileSubGraph):
- replacement_id = 'SSDToolboxDetectionOutput'
-
- def nodes_to_remove(self, graph: Graph, match: SubgraphMatch):
- return []
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- # OV DetectionOutput layer consumes flattened confidences and locations tensors.
- # That is why we add reshapes before them.
- locs_node = match.single_input_node(0)
- conf_node = match.single_input_node(1)
- prior_boxes_node = match.single_input_node(2)
-
- locs_out_nodes = locs_node[0].out_nodes()
- assert len(locs_out_nodes) == 1
- locs_out_node = locs_out_nodes[list(locs_out_nodes.keys())[0]]
- assert locs_out_node.op == "Result", locs_out_node.op
- graph.remove_node(locs_out_node.id)
-
- conf_out_nodes = conf_node[0].out_nodes()
- assert len(conf_out_nodes) == 1
- conf_out_node = conf_out_nodes[list(conf_out_nodes.keys())[0]]
- assert conf_out_node.op == "Result", conf_out_node.op
- graph.remove_node(conf_out_node.id)
-
- # reshape operation to flatten confidence tensor
- const = Const(graph, {'value': int64_array([0, -1])}).create_node()
- reshape_loc_node = Reshape(graph, {}).create_node([locs_node, const], dict(name='DetectionOutput_Reshape_loc_'))
-
- # reshape operation to flatten confidence tensor
- reshape_conf_node = Reshape(graph, {}).create_node([conf_node, const], dict(name='DetectionOutput_Reshape_conf_'))
-
- # remove the Result node after the priors node
- assert prior_boxes_node[0].out_node().op == "Result"
- graph.remove_node(prior_boxes_node[0].out_node().id)
-
- # reshape operation for prior boxes tensor
- const = Const(graph, {'value': int64_array([1, 2, -1])}).create_node()
- reshape_priors_node = Reshape(graph, {}).create_node([prior_boxes_node, const],
- dict(name='DetectionOutput_Reshape_priors_'))
- # create Detection Output node with three inputs: locations, confidences and prior boxes
- detection_output_op = DetectionOutput(graph, match.custom_replacement_desc.custom_attributes)
- detection_output_node = detection_output_op.create_node(
- [reshape_loc_node, reshape_conf_node, reshape_priors_node],
- dict(name=detection_output_op.attrs['type'] + '_'))
- PermuteAttrs.set_permutation(reshape_priors_node, detection_output_node, None)
-
- # create Output node to mark DetectionOutput as a graph output operation
- output_op = Result(graph)
- output_op.create_node([detection_output_node], dict(name='sink_'))
- return {}
diff --git a/tools/mo/openvino/tools/mo/front/tf/SwitchMergeOptimization.py b/tools/mo/openvino/tools/mo/front/tf/SwitchMergeOptimization.py
deleted file mode 100644
index 02d357deff0c2d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/SwitchMergeOptimization.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-
-
-class SwitchMergeOptimization(FrontReplacementSubgraph):
- """
- Optimization for case, when combination of Switches have one common condition and can be expressed as Select node.
-
- This transformation matches too big number of instances for models with many BatchNorm layers with the same input
- from the model input data node with training/inference flag. So the transformation is implemented as a simple graph
- traversal instead of regular pattern-based approach.
-
- The following pattern is checked:
- nodes=[('Merge', dict(kind='op', op='Merge')),
- ('Switch_2_input', dict(kind='data')),
- ('Switch_2', dict(kind='op', op='Switch')),
- ('Switch_2_data', dict(kind='data')),
- ('op', dict(kind='op')),
- ('op_data', dict(kind='data')),
- ('Switch', dict(kind='op', op='Switch')),
- ('Switch_data', dict(kind='data')),
- ('Switch_1', dict(kind='op', op='Switch')),
- ('Switch_1_data', dict(kind='data')),
- ('cond_data', dict(kind='data')),
- ('identity', dict(kind='op', op='Identity')),
- ('identity_data', dict(kind='data')),
- ],
- edges=[
- ('Switch_2_input', 'Switch_2', {'in': 0}),
- ('Switch_2', 'Switch_2_data', {'out': 1}),
- ('Switch_2_data', 'Merge'),
- ('cond_data', 'Switch_2', {'in': 1}),
- ('cond_data', 'Switch_1', {'in': 1}),
- ('cond_data', 'Switch', {'in': 1}),
- ('Switch_1', 'Switch_1_data', {'out': 0}),
- ('Switch', 'Switch_data', {'out': 0}),
- ('Switch_1_data', 'op', {'in': 1}),
- ('Switch_data', 'op', {'in': 0}),
- ('op', 'op_data'),
- ('op_data', 'identity'),
- ('identity', 'identity_data'),
- ('identity_data', 'Merge'),
- ],
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for merge in graph.get_op_nodes(op='Merge'):
- for merge_switch_in_port in range(2):
- if merge.in_port(merge_switch_in_port).disconnected() or \
- merge.in_port(merge_switch_in_port).get_source().node.op != 'Switch':
- continue
- switch_2 = merge.in_port(merge_switch_in_port).get_source().node
-
- if merge.in_port(1 - merge_switch_in_port).disconnected() or \
- merge.in_port(1 - merge_switch_in_port).get_source().node.op != 'Identity':
- continue
- false_value_port = merge.in_port(1 - merge_switch_in_port).get_source()
-
- true_value_port = switch_2.in_port(0).get_source()
- op = false_value_port.node.in_port(0).get_source().node
-
- if op.in_port(0).disconnected() or op.in_port(0).get_source().node.op != 'Switch':
- continue
- switch = op.in_port(0).get_source().node
-
- if op.in_port(1).disconnected() or op.in_port(1).get_source().node.op != 'Switch':
- continue
- switch_1 = op.in_port(1).get_source().node
-
- if switch.in_port(1).get_source() == switch_1.in_port(1).get_source() and \
- switch.in_port(1).get_source() == switch_2.in_port(1).get_source():
- select = Select(graph, dict(name=merge.soft_get('name') + '/Select/', format='tf')).create_node()
- select.in_port(0).connect(switch.in_port(1).get_source())
- select.in_port(1).connect(true_value_port)
- select.in_port(2).connect(false_value_port)
-
- merge.out_port(0).get_connection().set_source(select.out_port(0))
-
- assert 1 in op.in_ports() and 0 in op.in_ports()
-
- op.in_port(0).disconnect()
- op.in_port(1).disconnect()
-
- switch.in_port(0).get_connection().set_destination(op.in_port(0))
- switch_1.in_port(0).get_connection().set_destination(op.in_port(1))
-
- graph.remove_nodes_from(nodes=[switch_1.id, switch.id, switch_2.id, merge.id])
- # need to exit from the inner for loop because the Merge op has been removed
- break
diff --git a/tools/mo/openvino/tools/mo/front/tf/TFFFTToDFT.py b/tools/mo/openvino/tools/mo/front/tf/TFFFTToDFT.py
deleted file mode 100644
index baefa191b8d60a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/TFFFTToDFT.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.dft import DFT, IDFT, IRDFT, RDFT
-
-
-class TFFFTToDFT(FrontReplacementSubgraph):
- """
- This transformation converts the operation TFFFT into OpenVINO operations DFT, RDFT, IDFT, or IRDFT,
- according to the following rules:
- 1) FFT, FFT2D, FFT3D are converted into DFT;
- 2) IFFT, IFFT2D, IFFT3D are converted into IDFT;
- 3) RFFT, RFFT2D, RFFT3D are converted into RDFT;
- 4) IRFFT, IRFFT2D, IRFFT3D are converted into IRDFT.
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.tf.RollRealImagPack import RollRealImagPack
- return [RollRealImagPack]
-
- def find_and_replace_pattern(self, graph: Graph):
- for tf_fft in graph.get_op_nodes(op='TFFFT'):
- tf_fft_name = tf_fft.soft_get('name', tf_fft.id)
-
- num_of_dims = tf_fft.soft_get('num_of_dimensions', 1)
- axes = int64_array(range(-num_of_dims, 0))
-
- fft_kind = tf_fft['fft_kind']
- assert fft_kind in ['DFT', 'IDFT', 'RDFT', 'IRDFT'], \
- 'Node {} with the operation TFFFT supports only the following FFT-like operations: ' \
- 'DFT, IDFT, RDFT, IRDFT. Got: {}'.format(tf_fft_name, fft_kind)
-
- op = {'DFT': DFT, 'IDFT': IDFT, 'RDFT': RDFT, 'IRDFT': IRDFT}[fft_kind]
-
- if fft_kind in ['DFT', 'IDFT'] or not tf_fft.is_in_port_connected(1):
- dft_node = create_op_with_const_inputs(graph, op, {1: axes}, {'in_ports_count': 2},
- tf_fft.in_port(0).get_source().node)
- else:
- dft_node = create_op_with_const_inputs(graph, op, {1: axes}, {'in_ports_count': 3},
- tf_fft.in_port(0).get_source().node)
- tf_fft.in_port(1).get_source().connect(dft_node.in_port(2))
-
- tf_fft.out_port(0).get_connection().set_source(dft_node.out_port(0))
-
- rename_nodes([(tf_fft, tf_fft_name + '/to_be_removed'), (dft_node, tf_fft_name)])
-
- if graph.graph['layout'] == 'NHWC':
- dft_node['need_insert_transposes_for_dft'] = True
diff --git a/tools/mo/openvino/tools/mo/front/tf/TFResizeToInterpolate.py b/tools/mo/openvino/tools/mo/front/tf/TFResizeToInterpolate.py
deleted file mode 100644
index dc8a4b6742ed08..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/TFResizeToInterpolate.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Div
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-def replace_tf_resize(graph: Graph, resize: Node, interpolation_mode: str):
- resize_name = resize.soft_get('name', resize.id)
- log.debug("Converting of {} to Interpolate-4 is triggered for node {}.".format(resize.op, resize_name))
-
- num_of_inputs = len([port for port in resize.in_ports().values() if not port.disconnected()])
- assert num_of_inputs == 2, \
- "Number of inputs of {} (with name {}) should be equal to 2".format(resize.op, resize_name)
-
- attrs_msg = "If half_pixel_centers attribute of the node {} with op {} is True, " \
- "the attribute align_corners must be False"
- assert not resize.half_pixel_centers or (resize.half_pixel_centers and not resize.align_corners), \
- attrs_msg.format(resize_name, resize.op)
-
- if resize.has_valid('data_type') and not np.issubdtype(resize.data_type, np.floating):
- input_cast = Cast(graph, {'name': resize_name + '/to_f32', 'dst_type': np.float32}).create_node()
- resize.in_port(0).get_connection().insert_node(input_cast, "source")
- # casted tensor is not present in TF model, we don't need to propagate any name to output of this Convert
- # therefore we use "source" attributes_save_mode for insert_node
-
- shape = Shape(graph, {'name': resize_name + '/shapeof'}).create_node()
-
- ss = create_op_with_const_inputs(graph, StridedSlice,
- {1: int64_array([1]),
- 2: int64_array([3]),
- 3: int64_array([1])
- },
- {'name': resize_name + '/StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])
- })
-
- div_node = Div(graph, {'name': resize_name + '/Div'}).create_node()
-
- shape_to_float = Cast(graph, dict(dst_type=np.float32)).create_node()
- size_to_float = Cast(graph, dict(dst_type=np.float32)).create_node()
-
- size_to_float.out_port(0).connect(div_node.in_port(0))
- shape_to_float.out_port(0).connect(div_node.in_port(1))
- ss.out_port(0).connect(shape_to_float.in_port(0))
- shape.out_port(0).connect(ss.in_port(0))
-
- align_corners = resize.align_corners
- half_pixel_centers = resize.half_pixel_centers
-
- nearest_mode = 'floor' if interpolation_mode == 'nearest' else 'round_prefer_floor'
- if align_corners:
- coordinate_transformation_mode = 'align_corners'
- if interpolation_mode == 'nearest':
- nearest_mode = 'round_prefer_ceil'
- elif half_pixel_centers:
- coordinate_transformation_mode = 'tf_half_pixel_for_nn' if interpolation_mode == 'nearest' else 'half_pixel'
- else:
- coordinate_transformation_mode = 'asymmetric'
-
- interpolate4 = create_op_with_const_inputs(graph, Interpolate,
- {
- 3: int64_array([1, 2])
- },
- {
- 'name': resize_name + '/interpolate_4',
- 'mode': interpolation_mode,
- 'antialias': False,
- 'coordinate_transformation_mode': coordinate_transformation_mode,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'nearest_mode': nearest_mode,
- 'cube_coeff': -0.75,
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4',
- 'in_ports_count': 4,
- })
-
- resize_input_connection = resize.in_port(0).get_connection()
- resize_input_connection.set_destination(interpolate4.in_port(0))
- resize_input_connection.get_source().connect(shape.in_port(0))
-
- div_node.out_port(0).connect(interpolate4.in_port(2))
-
- sizes_connection = resize.in_port(1).get_connection()
- sizes_connection.set_destination(interpolate4.in_port(1))
- sizes_connection.get_source().connect(size_to_float.in_port(0))
-
- resize.out_port(0).get_connection().set_source(interpolate4.out_port(0))
- rename_nodes([(resize, resize_name + '/delete'), (interpolate4, resize_name)])
-
-
-class TFResizeToInterpolate(FrontReplacementOp):
- """
- The transformation replaces TFResize with Interpolate-4.
- """
- op = 'TFResize'
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.InterpolateNormalizer import InterpolateNormalizer
- return [InterpolateNormalizer]
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- resize = match['op']
- replace_tf_resize(graph, resize, resize.mode)
diff --git a/tools/mo/openvino/tools/mo/front/tf/TFScatterNDDecomposition.py b/tools/mo/openvino/tools/mo/front/tf/TFScatterNDDecomposition.py
deleted file mode 100644
index eb558d359a783b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/TFScatterNDDecomposition.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array, int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.scatternd import ScatterNDUpdate
-from openvino.tools.mo.ops.ConvertLike import ConvertLike
-
-
-class TFScatterNDDecomposition(FrontReplacementSubgraph):
- """
- Replaces TensorFlow ScatterND with OpenVINO ScatterNDUpdate. TF ScatterND does not have input data, so
- instead of this argument it expects its shape
-
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for tf_scatter_nd in graph.get_op_nodes(op='TFScatterND'):
- if not tf_scatter_nd.is_in_port_connected(0) or not tf_scatter_nd.is_in_port_connected(1) \
- or not tf_scatter_nd.is_in_port_connected(2):
- continue
- name = tf_scatter_nd.soft_get('name', tf_scatter_nd.soft_get('id'))
- indices_port = tf_scatter_nd.in_port(0).get_source()
- updates_port = tf_scatter_nd.in_port(1).get_source()
- shape_port = tf_scatter_nd.in_port(2).get_source()
- # need get type of const type
- zero_const = Const(graph, {'value': int64_array(0.0), 'name': name + '/zero_const'}).create_node()
-
- # Convert zero value to type of updates node
- convert_to_type = ConvertLike(graph, {'name': name + '/convert_like'}).create_node()
- convert_to_type.in_port(0).connect(zero_const.out_port(0))
- convert_to_type.in_port(1).connect(updates_port)
-
- broad_cast_node = Broadcast(graph, {'name': name + '/broadcast'}).create_node()
- broad_cast_node.in_port(0).connect(convert_to_type.out_port(0))
- broad_cast_node.in_port(1).connect(shape_port)
-
- scatter_nd_node = ScatterNDUpdate(graph, {'name': name + '/replaced'}).create_node()
- scatter_nd_node.in_port(0).connect(broad_cast_node.out_port(0))
- scatter_nd_node.in_port(1).connect(indices_port)
- scatter_nd_node.in_port(2).connect(updates_port)
-
- rename_nodes([(tf_scatter_nd, name + '/TBD'), (scatter_nd_node, name)])
-
- tf_scatter_nd.out_port(0).get_connection().set_source(scatter_nd_node.out_port(0))
- tf_scatter_nd.in_port(0).disconnect()
- tf_scatter_nd.in_port(1).disconnect()
- tf_scatter_nd.in_port(2).disconnect()
diff --git a/tools/mo/openvino/tools/mo/front/tf/TFSliceToSlice.py b/tools/mo/openvino/tools/mo/front/tf/TFSliceToSlice.py
deleted file mode 100644
index 36a913cb6fd984..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/TFSliceToSlice.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Add, Equal
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.slice import Slice
-
-
-class TFSliceToSliceReplacer(FrontReplacementOp):
- """
- This transformation converts TFSlice to internal Slice operation.
- TFSlice has 'size' on the second input while Slice has 'ends', therefore we insert Add(begin, size).
- size[i] == -1 is a magic number that means take the whole range along axis i up to the end.
- To process the case when size[i] == -1 we insert subgraph with ShapeOf.
- """
- op = 'TFSlice'
- enabled = True
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- tf_slice_node = match['op']
- slice_name = tf_slice_node.soft_get('name', tf_slice_node.id)
- slice_node = Slice(graph).create_node()
- rename_nodes([(tf_slice_node, slice_name + '/to_be_removed'), (slice_node, slice_name)])
- ends_node = Add(graph, {'name': slice_name + '/ends'}).create_node()
-
- # reconnect input, begin, and size from TFSlice to the subgraph with Slice
- tf_slice_node.in_port(0).get_connection().set_destination(slice_node.in_port(0))
- tf_slice_node.in_port(1).get_connection().set_destination(slice_node.in_port(1))
- tf_slice_node.in_port(2).get_connection().set_destination(ends_node.in_port(0))
- slice_node.in_port(1).get_connection().add_destination(ends_node.in_port(1))
-
- max_ends = Shape(graph, {'name': slice_name + '/ShapeOf'}).create_node()
- slice_node.in_port(0).get_connection().add_destination(max_ends.in_port(0))
-
- # check if size[i] == -1, will be applied elementwisely: len(size) = len(begin) = input_rank
- where_max_ends_is_needed = create_op_with_const_inputs(graph, Equal, {0: int64_array(-1)},
- {'name': slice_name + '/where_max_ends_is_needed'})
- ends_node.in_port(0).get_connection().add_destination(where_max_ends_is_needed.in_port(1))
- # select requires equal dtypes, need to convert ends to I64
- ends_casted_to_i64 = Cast(graph, {'name': slice_name + '/CastToI64',
- 'dst_type': np.int64}).create_node([ends_node])
- # if size[i] == 1 then take max_ends values
- correct_ends = Select(graph, {'name': slice_name + '/chosen_ends'}).create_node([where_max_ends_is_needed,
- max_ends, ends_casted_to_i64])
- correct_ends.out_port(0).connect(slice_node.in_port(2))
-
- tf_slice_node.out_port(0).get_connection().set_source(slice_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/tf/TensorArrayExtractors.py b/tools/mo/openvino/tools/mo/front/tf/TensorArrayExtractors.py
deleted file mode 100644
index 7a88d31f12b273..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/TensorArrayExtractors.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.TensorArray import TensorArray
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_tensor_shape
-from openvino.tools.mo.graph.graph import Node
-
-
-class TensorArrayExtractor(FrontExtractorOp):
- op = "TensorArrayV3"
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- attrs = {
- 'op': __class__.op,
- 'element_shape': tf_tensor_shape(node.pb.attr["element_shape"].shape),
- }
- TensorArray.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/TensorArrayGatherV3.py b/tools/mo/openvino/tools/mo/front/tf/TensorArrayGatherV3.py
deleted file mode 100644
index c83bd298709839..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/TensorArrayGatherV3.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.TensorArrayGather import TensorArrayGather
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_tensor_shape
-from openvino.tools.mo.graph.graph import Node
-
-
-class TensorArrayGatherV3Extractor(FrontExtractorOp):
- op = "TensorArrayGatherV3"
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- attrs = {
- 'op': __class__.op,
- 'element_shape': tf_tensor_shape(node.pb.attr["element_shape"].shape),
- }
- TensorArrayGather.update_node_stat(node, attrs)
- return cls.enabled
-
diff --git a/tools/mo/openvino/tools/mo/front/tf/UnpackPackReverseInputChannels.py b/tools/mo/openvino/tools/mo/front/tf/UnpackPackReverseInputChannels.py
deleted file mode 100644
index 0ce572d39fa617..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/UnpackPackReverseInputChannels.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.back.ReverseInputChannels import ReverseChannels
-from openvino.tools.mo.front.Pack import Pack
-from openvino.tools.mo.front.split_normalizer import AttributedSplitToSplit, SqueezeAxis
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-
-
-class UnpackPackReverseInputChannels(FrontReplacementSubgraph):
- r"""
- Unpack - Pack nodes sequence from TensorFlow connected like it shown below is a way to ReverseChannels
-
- / 0 - 2 \
- Unpack - 1 - 1 - Pack
- \ 2 - 0 /
-
- Converting it to internal ReverseChannels node to be fused to Convolution while running ApplyReverseChannels on back
- """
- enabled = True
-
- def run_before(self):
- # ordering transformations to keep matching pattern as small as possible
-
- # Unpack from TensorFlow is extracted as AttributedSplit with squeeze_axis=True attribute,
- # so we should execute current transformation before AttributedSplitToSplit and SqueezeAxis
-
- # Pack from TensorFlow is an operation that creates new dimension, which we add by inserting Unsqueeze on all
- # inputs at Pack transform, so we should execute current transformation before it
- return [AttributedSplitToSplit, Pack, SqueezeAxis]
-
- def pattern(self):
- return dict(
- nodes=[
- ('unpack', dict(op='AttributedSplit')),
- ('pack', dict(op='Pack')),
- ],
- edges=[
- ('unpack', 'pack', {'out': 0, 'in': 2}),
- ('unpack', 'pack', {'out': 1, 'in': 1}),
- ('unpack', 'pack', {'out': 2, 'in': 0}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- unpack = match['unpack']
- pack = match['pack']
-
- if unpack.soft_get('axis', None) is None or unpack.axis != pack.soft_get('axis', None):
- # axes doesn't match - not ReverseChannels case
- return
-
- axis = unpack.axis
-
- connected_unpack_ports_count = len([port for port in unpack.out_ports().values() if not port.disconnected()])
- connected_pack_ports_count = len([port for port in pack.in_ports().values() if not port.disconnected()])
- if connected_pack_ports_count != connected_unpack_ports_count or connected_unpack_ports_count != 3:
- # number of connected input ports of Concat and output ports of Split mismatch - not ReverseChannels case
- return
-
- name = pack.soft_get('name', pack.id)
- log.debug('Unpack - Pack sequence was detected `{}`'.format(name))
-
- reverse_channels = ReverseChannels(graph, {
- 'name': pack.soft_get('name', pack.id) + '/ReverseChannels',
- 'axis': int64_array(axis), 'order': int64_array([2, 1, 0])}).create_node()
-
- pack.out_port(0).get_connection().set_source(reverse_channels.out_port(0))
- unpack.in_port(0).get_connection().set_destination(reverse_channels.in_port(0))
- log.debug('Unpack - Pack was converted to ReverseChannels {}'.format(name))
diff --git a/tools/mo/openvino/tools/mo/front/tf/WhereDecomposition.py b/tools/mo/openvino/tools/mo/front/tf/WhereDecomposition.py
deleted file mode 100644
index f9fde8ae8a0fec..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/WhereDecomposition.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Node, Graph, rename_nodes
-from openvino.tools.mo.ops.non_zero import NonZero
-from openvino.tools.mo.ops.transpose import Transpose
-
-
-class WhereDecomposition(FrontReplacementOp):
- """
- This transformation decomposes the TF layer Where (when x = None, y = None) using the formula
- Where(condition) = Transpose(NonZero(condition), [1, 0])
- """
- op = 'Where'
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.tf.embedding_segments_operation_fusing import \
- EmbeddingSegmentsOperationMultipleFeaturesFusing, EmbeddingSegmentsOperationSingleFeatureFusing
- from openvino.tools.mo.front.TransposeOrderNormalizer import TransposeOrderNormalizer
- return [EmbeddingSegmentsOperationMultipleFeaturesFusing, EmbeddingSegmentsOperationSingleFeatureFusing,
- TransposeOrderNormalizer]
-
- def replace_op(self, graph: Graph, node: Node):
- node_name = node.soft_get('name', node.id)
- non_zero_node = NonZero(graph, {'name': node_name + '/NonZero_', 'output_type': np.int64}).create_node()
- transpose_node = create_op_node_with_second_input(graph, Transpose, int64_array([1, 0]), op_attrs={})
- non_zero_node.out_port(0).connect(transpose_node.in_port(0))
- rename_nodes([(node, node_name + '/delete'), (transpose_node, node_name)])
-
- non_zero_node.in_port(0).connect(node.in_port(0).get_source())
- return [transpose_node.id]
diff --git a/tools/mo/openvino/tools/mo/front/tf/WhileNormalize.py b/tools/mo/openvino/tools/mo/front/tf/WhileNormalize.py
deleted file mode 100644
index ad97ace0901c18..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/WhileNormalize.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.const import Const
-
-
-class WhileNormalize(FrontReplacementSubgraph):
- """
- Normalize inputs for Loop replacing TensorFlow 2 While operation:
- 1) Remove external input port for current iteration
- 2) Move trip count from port #1 to port #0
- 3) Occupy port #1 for execution condition
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='Loop'):
- self.normalize_loop_node(graph, node)
-
- @staticmethod
- def normalize_loop_node(graph: Graph, loop_node: Node):
- loop_name = loop_node.soft_get('name', loop_node.id)
-
- # disconnect current iteration from external port #0 and move trip count to this port
- loop_node.in_port(0).disconnect()
- loop_node.in_port(1).get_connection().add_destination(loop_node.in_port(0))
- Loop.update_port_map_value(loop_node.input_port_map, 'external_port_id', 1, 0)
-
- # connect execution condition port
- exec_cond_node = Const(graph, {'name': loop_name + '/ExecutionConditionValue',
- 'value': mo_array(True, dtype=bool)}).create_node()
- loop_node.in_port(1).get_connection().set_source(exec_cond_node.out_port(0))
-
- loop_node.body.clean_up()
- Loop.normalize_input_output_ports(loop_node)
diff --git a/tools/mo/openvino/tools/mo/front/tf/__init__.py b/tools/mo/openvino/tools/mo/front/tf/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/front/tf/activation_ext.py b/tools/mo/openvino/tools/mo/front/tf/activation_ext.py
deleted file mode 100644
index 61a9eb38d87c1d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/activation_ext.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import *
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class AbsExtractor(FrontExtractorOp):
- op = 'Abs'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Abs.update_node_stat(node)
- return cls.enabled
-
-
-class EluFrontExtractor(FrontExtractorOp):
- op = 'Elu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Elu.update_node_stat(node)
- return cls.enabled
-
-
-class ErfFrontExtractor(FrontExtractorOp):
- op = 'Erf'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Erf.update_node_stat(node)
- return cls.enabled
-
-
-class ExpExtractor(FrontExtractorOp):
- op = 'Exp'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Exp.update_node_stat(node)
- return cls.enabled
-
-
-class LeakyReLUFrontExtractor(FrontExtractorOp):
- op = 'LeakyRelu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- negative_slope = node.pb.attr['alpha'].f
- if negative_slope == 0:
- ReLU.update_node_stat(node)
- else:
- LeakyReLU.update_node_stat(node, {'negative_slope': negative_slope})
- return cls.enabled
-
-
-class LogicalNotFrontExtractor(FrontExtractorOp):
- op = 'LogicalNot'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalNot.update_node_stat(node)
- return cls.enabled
-
-
-class Relu6FrontExtractor(FrontExtractorOp):
- op = 'Relu6'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ReLU6.update_node_stat(node)
- return cls.enabled
-
-
-class ReluFrontExtractor(FrontExtractorOp):
- op = 'Relu'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ReLU.update_node_stat(node)
- return cls.enabled
-
-
-class SigmoidFrontExtractor(FrontExtractorOp):
- op = 'Sigmoid'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sigmoid.update_node_stat(node)
- return cls.enabled
-
-
-class CosFrontExtractor(FrontExtractorOp):
- op = 'Cos'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Cos.update_node_stat(node)
- return cls.enabled
-
-
-class CoshFrontExtractor(FrontExtractorOp):
- op = 'Cosh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Cosh.update_node_stat(node)
- return cls.enabled
-
-
-class AcoshFrontExtractor(FrontExtractorOp):
- op = 'Acosh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Acosh.update_node_stat(node)
- return cls.enabled
-
-
-class SinFrontExtractor(FrontExtractorOp):
- op = 'Sin'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sin.update_node_stat(node)
- return cls.enabled
-
-
-class SinhFrontExtractor(FrontExtractorOp):
- op = 'Sinh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sinh.update_node_stat(node)
- return cls.enabled
-
-
-class AsinhFrontExtractor(FrontExtractorOp):
- op = 'Asinh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Asinh.update_node_stat(node)
- return cls.enabled
-
-
-class TanFrontExtractor(FrontExtractorOp):
- op = 'Tan'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Tan.update_node_stat(node)
- return cls.enabled
-
-
-class TanhFrontExtractor(FrontExtractorOp):
- op = 'Tanh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Tanh.update_node_stat(node)
- return cls.enabled
-
-
-class AtanhFrontExtractor(FrontExtractorOp):
- op = 'Atanh'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Atanh.update_node_stat(node)
- return cls.enabled
-
-
-class CeilExtractor(FrontExtractorOp):
- op = 'Ceil'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Ceiling.update_node_stat(node)
- return cls.enabled
-
-
-class MishExtractor(FrontExtractorOp):
- op = 'Mish'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Mish.update_node_stat(node)
- return cls.enabled
-
-
-class LogExtractor(FrontExtractorOp):
- op = 'Log'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Log.update_node_stat(node)
- return cls.enabled
-
-
-class AsinExtractor(FrontExtractorOp):
- op = 'Asin'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Asin.update_node_stat(node)
- return cls.enabled
-
-
-class AcosExtractor(FrontExtractorOp):
- op = 'Acos'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Acos.update_node_stat(node)
- return cls.enabled
-
-
-class AtanExtractor(FrontExtractorOp):
- op = 'Atan'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Atan.update_node_stat(node)
- return cls.enabled
-
-
-class SoftSignExtractor(FrontExtractorOp):
- op = 'Softsign'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- SoftSign.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/argmax_ext.py b/tools/mo/openvino/tools/mo/front/tf/argmax_ext.py
deleted file mode 100644
index e14dfb109e15a7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/argmax_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.argmax import ArgMaxOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class ArgMaxFrontExtractor(FrontExtractorOp):
- op = 'ArgMax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ArgMaxOp.update_node_stat(node, {'out_max_val': 0, 'top_k': 1, 'axis': None,
- 'dim_attrs': ['axis'], 'keepdims': 0, 'remove_values_output': True,
- 'output_type': tf_dtype_extractor(node.pb.attr['output_type'].type, np.int64),
- })
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/argmin_ext.py b/tools/mo/openvino/tools/mo/front/tf/argmin_ext.py
deleted file mode 100644
index 5e1773fb22090b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/argmin_ext.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.argmin import ArgMinOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class ArgMinFrontExtractor(FrontExtractorOp):
- op = 'ArgMin'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'top_k': 1,
- 'axis': None,
- 'keepdims': 0,
- 'remove_values_output': True,
- 'output_type': tf_dtype_extractor(node.pb.attr['output_type'].type, np.int64)
- }
- ArgMinOp.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/assign_elimination.py b/tools/mo/openvino/tools/mo/front/tf/assign_elimination.py
deleted file mode 100644
index 20230117fecb1a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/assign_elimination.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-
-
-class AssignAndAssertElimination(FrontReplacementPattern):
- # The solution with removal of Assign and Assert operations is temporary.
- # The proper solution is to keep these operations until the partial inference
- # phase when control flow edges are properly handled and later unnecessary ones are eliminated.
- # In order to achieve this we need to implement control flow inference function
- # for these operations similar to "Merge" and "Switch" operations.
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes():
- if node.soft_get('op') in ["Assign", "AssignSub", "AssignAdd", "Assert"]:
- log.debug('"{}" op with id="{}" was removed'.format(node.op, node.id))
- graph.remove_node(node.id)
diff --git a/tools/mo/openvino/tools/mo/front/tf/automl_efficientdet.json b/tools/mo/openvino/tools/mo/front/tf/automl_efficientdet.json
deleted file mode 100644
index ebf13c68ab0495..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/automl_efficientdet.json
+++ /dev/null
@@ -1,18 +0,0 @@
-[
- {
- "id": "AutomlEfficientDet",
- "custom_attributes": {
- "preprocessing_input_node": "strided_slice_1",
- "preprocessing_output_node": "truediv",
- "aspect_ratios": [1.0, 1.0, 1.4, 0.7, 0.7, 1.4],
- "variance": [1.0, 1.0, 1.0, 1.0],
- "min_level": 3,
- "num_scales": 3,
- "anchor_scale": 4.0,
- "num_classes": 90,
- "nms_threshold": 0.6,
- "confidence_threshold": 0.2
- },
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/basic_lstm_cell.py b/tools/mo/openvino/tools/mo/front/tf/basic_lstm_cell.py
deleted file mode 100644
index 9e4e0b47e03083..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/basic_lstm_cell.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.split_normalizer import SplitInputsReconnect
-from openvino.tools.mo.ops.lstm_cell import LSTMCell
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.result import Result
-
-
-class BasicLSTMCell(FrontReplacementSubgraph):
- enabled = True
-
- # list of names of all original nodes that are supported by IE
- # this list is collected gradually by a separate transformation
- # original name in this case is a selected node in the pattern
- # that is returned from anchor() function
- instances_supported_by_IE = []
-
- def __init__(self):
-
- super().__init__()
-
- # Inputs that are required by LSTMCell operation definition
- __class__.inputs = ['input_op', 'input_hidden_state', 'input_cell_state', 'weights', 'biases']
-
- # Extra inputs that are not expected by LSTMCell but required for extra checks
- # at middle-end partial inference stage. They are consumed by the extended infer function
- # and then removed.
- __class__.extra_inputs = ['concat_axis', 'split_axis', 'shift_const']
-
- __class__.outputs = ['mul_2', 'add_1']
-
- def run_after(self):
- from openvino.tools.mo.front.split_normalizer import AttributedSplitToSplit
- return [AttributedSplitToSplit, SplitInputsReconnect]
-
- def pattern(self):
- return dict(
- nodes=[
- ('concat_axis', dict()),
- ('concat', dict(op='ConcatV2')),
- ('weights', dict()),
- ('matmul', dict(op='MatMul')),
- ('biases', dict()),
- ('biasadd', dict(op='Add')),
- ('split_axis', dict()),
- ('split', dict(op='Split')),
- ('shift_const', dict()),
- ('shift', dict(op='Add')),
- ('sigmoid_0', dict(op='Sigmoid')),
- ('mul_0', dict(op='Mul')),
- ('sigmoid_1', dict(op='Sigmoid')),
- ('tanh_0', dict(op='Tanh')),
- ('mul_1', dict(op='Mul')),
- ('add_1', dict(op='Add')),
- ('tanh_1', dict(op='Tanh')),
- ('sigmoid_2', dict(op='Sigmoid')),
- ('mul_2', dict(op='Mul'))
- ],
- edges=[
- # This important block specifies how input/hidden are concatenated
- ('concat_axis', 'concat', {'in': 2}),
-
- ('concat', 'matmul', {'in': 0}),
- ('weights', 'matmul', {'in': 1}),
- ('matmul', 'biasadd', {'in': 0}),
- ('biases', 'biasadd', {'in': 1}),
-
- ('split_axis', 'split', {'in': 1}),
- ('biasadd', 'split', {'in': 0}),
-
- # This important block specifies how gates are ordered in TF graph
- ('split', 'sigmoid_1', {'out': 0}), # i
- ('split', 'tanh_0', {'out': 1}), # c
- ('split', 'shift', {'out': 2}), # f (this is unbiased f, there is an extra addition here)
- ('split', 'sigmoid_2', {'out': 3}), # o
-
- ('shift_const', 'shift', {}),
- ('shift', 'sigmoid_0', {}),
- ('sigmoid_0', 'mul_0', {}),
-
- ('sigmoid_1', 'mul_1', {}),
- ('tanh_0', 'mul_1', {}),
-
- ('mul_0', 'add_1', {}),
- ('mul_1', 'add_1', {}),
-
- ('add_1', 'tanh_1', {}),
- ('tanh_1', 'mul_2', {}),
- ('sigmoid_2', 'mul_2', {}),
- ])
-
- @staticmethod
- def anchor():
- """ Mnemonic name in the pattern that is used as an anchor name for this pattern in the original graph.
- Used for the second round of the pattern application when only a part of instances is allowed for conversion.
- """
- return 'concat'
-
- def replace_sub_graph(self, graph: Graph, match: dict):
-
- # node that is used to identify this pattern application instance for switching between supported
- # and not supported LSTMCell sub-graphs; this value will be searched in __class__.instances_supported_by_IE.
- anchor_node = match[__class__.anchor()]
- assert anchor_node.has_valid('name'), \
- 'LSTMCell anchor node {} does\'t have attribute name; such nodes are not supported.'
-
- match['input_op'] = match['concat'].in_node(0)
- match['input_hidden_state'] = match['concat'].in_node(1)
- match['input_cell_state'] = match['mul_0'].in_node(0) \
- if match['mul_0'].in_node(0).id != match['sigmoid_0'].id else match['mul_0'].in_node(1)
-
- pattern_edges = self.pattern()['edges']
- pattern_edges.extend([('input_op', 'concat'), ('input_cell_state', 'mul_0'), ('input_hidden_state', 'concat')])
- inputs = graph.get_inputs_with_ports(match, pattern_edges, __class__.inputs + __class__.extra_inputs)
-
- lstm_op = LSTMCell(graph, dict(
- name=match['concat'].name + '/LSTMCell', activations=None,
- ))
- lstm_node = lstm_op.create_node(inputs)
- lstm_node['old_infer'] = lstm_node.infer
- lstm_node.infer = __class__.infer
-
- # this node consumes one of the resulting LSTMCell outputs,
- # it should be removed before reconnecting the nodes,
- # otherwise it will be reconnected to the new cell output
- graph.remove_node(match['tanh_1'].id)
-
- for i, output in enumerate(__class__.outputs):
- match[output].replace_node(lstm_node, i)
-
- # Because of LSTMCell specification, this layer MUST have 2 outputs.
- # => we need to create fake consumers for LSTMCell
- # when this node haven't some outputs.
- for i in [0, 1]:
- if i not in lstm_node.out_nodes():
- fake_output_node = Result(graph, dict(name=lstm_node.name + "/Output_{}".format(i)))
- fake_output_node.create_node(inputs=[lstm_node], edge_attrs={'out': i, 'in': 0})
-
- lstm_node['tf'] = True
- lstm_node['extra_inputs'] = {name: match[name].id for name in __class__.extra_inputs}
- lstm_node['inputs'] = {name: match[name].id for name in __class__.inputs}
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) == len(__class__.inputs) + len(__class__.extra_inputs)
-
- for axis in ['concat_axis', 'split_axis']:
- axis_node = __class__.extra_inputs.index(axis) + len(__class__.inputs)
- assert node.in_node(axis_node).has_valid('value')
- assert node.in_node(axis_node).value == 1
-
- shift_const = node.in_node(__class__.extra_inputs.index('shift_const') + len(__class__.inputs))
- assert shift_const.has_valid('value')
- shift_const = shift_const.value
- assert shift_const.ndim == 0 # expect scalar value
- node['shift_const'] = shift_const.copy()
-
- weights_node = node.in_node(__class__.inputs.index('weights'))
- biases_node = node.in_node(__class__.inputs.index('biases'))
-
- assert weights_node.has_valid('value')
- assert biases_node.has_valid('value')
-
- # Restore original infer function (to avoid calling previous code twice) and call it
- node.infer = node.old_infer
- node.infer(node)
diff --git a/tools/mo/openvino/tools/mo/front/tf/batch_to_space_ext.py b/tools/mo/openvino/tools/mo/front/tf/batch_to_space_ext.py
deleted file mode 100644
index 5d87f971db7cc5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/batch_to_space_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.space_to_batch import BatchToSpace
-
-
-class SpaceToBatchFrontExtractor(FrontExtractorOp):
- op = 'BatchToSpaceND'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- BatchToSpace.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/broadcast_ext.py b/tools/mo/openvino/tools/mo/front/tf/broadcast_ext.py
deleted file mode 100644
index e7ec62e1d2cf1b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/broadcast_ext.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.broadcast import Broadcast
-
-
-class BroadcastExtractor(FrontExtractorOp):
- op = 'BroadcastTo'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Broadcast.update_node_stat(node, attrs={'mode': 'numpy'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/bucketize.py b/tools/mo/openvino/tools/mo/front/tf/bucketize.py
deleted file mode 100644
index 7ea131936e15f0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/bucketize.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class BucketizeFrontReplacer(FrontReplacementSubgraph):
- """
- Moves the boundaries data from attribute to the second input tensor.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for bucketize in graph.get_op_nodes(op='Bucketize'):
- if bucketize.in_port(1).disconnected():
- assert bucketize.has_valid('boundaries'), 'The Bucketize node "{}" misses "boundaries" attribute'.format(bucketize.name)
- boundaries_node = Const(graph, {'name': bucketize.name + '/Bucketize_boundaries_', 'value': bucketize.boundaries}).create_node()
- bucketize.in_port(1).connect(boundaries_node.out_port(0))
- del bucketize['boundaries']
- else:
- log.debug('The Bucketize node input "{}" is already normalized'.format(bucketize.name))
diff --git a/tools/mo/openvino/tools/mo/front/tf/bucketize_ext.py b/tools/mo/openvino/tools/mo/front/tf/bucketize_ext.py
deleted file mode 100644
index 90476a87d9d32b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/bucketize_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.ops.bucketize import Bucketize
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class BucketizeFrontExtractor(FrontExtractorOp):
- op = 'Bucketize'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- boundaries = float32_array(node.pb.attr['boundaries'].list.f)
- Bucketize.update_node_stat(node, {'boundaries': boundaries, 'with_right_bound': False, 'output_type': np.int32})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/common.py b/tools/mo/openvino/tools/mo/front/tf/common.py
deleted file mode 100644
index 74c9662369c1c7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/common.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-from tensorflow.core.framework import types_pb2 as tf_types # pylint: disable=no-name-in-module,import-error
-
-# Suppress false positive pylint warning about function with too many arguments
-# pylint: disable=E1121
-# mapping between TF data type and numpy data type and function to extract data from TF tensor
-_tf_np_mapping = [('DT_BOOL', bool, lambda pb: pb.bool_val, lambda x: bool_cast(x)),
- ('DT_INT8', np.int8, lambda pb: pb.int_val, lambda x: np.int8(x)),
- ('DT_INT16', np.int16, lambda pb: pb.int_val, lambda x: np.int16(x)),
- ('DT_INT32', np.int32, lambda pb: pb.int_val, lambda x: np.int32(x)),
- ('DT_INT64', np.int64, lambda pb: pb.int64_val, lambda x: np.int64(x)),
- ('DT_UINT8', np.uint8, lambda pb: pb.uint8_val, lambda x: np.uint8(x)),
- ('DT_UINT16', np.uint16, lambda pb: pb.int_val, lambda x: np.uint16(x)),
- ('DT_UINT32', np.uint32, lambda pb: pb.uint32_val, lambda x: np.uint32(x)),
- ('DT_UINT64', np.uint64, lambda pb: pb.uint64_val, lambda x: np.uint64(x)),
- ('DT_HALF', np.float16, lambda pb: np.uint16(pb.half_val).view(np.float16), lambda x: np.float16(x)),
- ('DT_FLOAT', np.float32, lambda pb: pb.float_val, lambda x: np.float32(x)),
- ('DT_DOUBLE', np.double, lambda pb: pb.double_val, lambda x: np.double(x)),
- ('DT_STRING', str, lambda pb: pb.string_val, lambda x: str(x)),
- ]
-
-tf_data_type_decode = {getattr(tf_types, tf_dt): (np_type, func) for tf_dt, np_type, func, _ in _tf_np_mapping if
- hasattr(tf_types, tf_dt)}
-
-tf_data_type_cast = {np_type: cast for tf_dt, np_type, _, cast in _tf_np_mapping if hasattr(tf_types, tf_dt)}
-
-
-def bool_cast(x):
- if isinstance(x, str):
- return False if x.lower() in ['false', '0'] else True if x.lower() in ['true', '1'] else 'unknown_boolean_cast'
- else:
- return bool(x)
diff --git a/tools/mo/openvino/tools/mo/front/tf/complex_ext.py b/tools/mo/openvino/tools/mo/front/tf/complex_ext.py
deleted file mode 100644
index e93921e34e3339..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/complex_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.Complex import Complex
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class ComplexOpFrontExtractor(FrontExtractorOp):
- op = 'Complex'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Complex.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/concat.py b/tools/mo/openvino/tools/mo/front/tf/concat.py
deleted file mode 100644
index f28fdbc3ecd227..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/concat.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-
-
-class Concat(FrontReplacementSubgraph):
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[('concat', dict(op='Concat', simple_concat=True))],
- edges=[]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- """
- There are Concat and ConcatV2 operations in TensorFlow
- The main difference is incoming port of tensor representing axis of concatenation
- In Concat it is the 0 port, in ConcatV2 it is the last port
- To reuse ConcatV2 logic (infer) that already exists in the Model Optimizer here we renumber ports of Concat
- """
- in_edges = list(graph.in_edges(match['concat'].id, data=True))
- for u, v, attrs in in_edges:
- in_port = attrs['in']
- attrs['in'] = len(in_edges) - 1 if in_port == 0 else attrs['in'] - 1
- if match['concat'].has('axis'):
- # we delete axis parameter here (it was set by default by Concat Op) to carefully get it from the last
- # input in Concat infer function
- del graph.node[match['concat'].id]['axis']
diff --git a/tools/mo/openvino/tools/mo/front/tf/concat_ext.py b/tools/mo/openvino/tools/mo/front/tf/concat_ext.py
deleted file mode 100644
index 3c44e1745d6108..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/concat_ext.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.concat import Concat
-
-
-class ConcatFrontExtractor(FrontExtractorOp):
- op = 'Concat'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'N': node.pb.attr["N"].i, 'simple_concat': True}
- Concat.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/const_ext.py b/tools/mo/openvino/tools/mo/front/tf/const_ext.py
deleted file mode 100644
index 017f8d54c7eb0b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/const_ext.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape, tf_tensor_content
-from openvino.tools.mo.ops.const import Const
-
-
-class ConstExtractor(FrontExtractorOp):
- op = 'Const'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb_tensor = node.pb.attr["value"].tensor
- shape = tf_tensor_shape(pb_tensor.tensor_shape)
- attrs = {
- 'shape': shape,
- 'value': tf_tensor_content(pb_tensor.dtype, shape, pb_tensor),
- 'data_type': tf_dtype_extractor(pb_tensor.dtype),
- }
- Const.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/conv_ext.py b/tools/mo/openvino/tools/mo/front/tf/conv_ext.py
deleted file mode 100644
index dd2964e7bdb16a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/conv_ext.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import convert_tf_padding_to_str, int64_array, dynamic_dimension
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_data_format_channel, tf_data_format_batch, \
- tf_int_list
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.op import PermuteAttrs
-
-
-class Conv2DFrontExtractor(FrontExtractorOp):
- op = 'Conv2D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = tf_create_attrs(node, 2, 3)
-
- def get_num_groups(node):
- if 'group' in node:
- return node.group
- elif node.in_node(0).shape is not None and node.kernel_shape is not None \
- and node.in_node(0).shape[node.channel_dims[0]] is not dynamic_dimension \
- and node.kernel_shape[node.input_feature_channel] is not dynamic_dimension:
- # if group attribute is not defined, number of groups is calculated
- # from number of input channels and filter channel size
- return node.in_node(0).shape[node.channel_dims] // node.kernel_shape[node.input_feature_channel]
- else:
- return 1
-
- attrs.update({'op': __class__.op,
- 'get_group': get_num_groups,
- 'get_output_feature_dim': lambda node: node.kernel_shape[node.output_feature_channel],
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([3, 2, 0, 1]),
- inv=int64_array([2, 3, 1, 0]))
- })
-
- # update the attributes of the node
- Convolution.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class DepthwiseConv2dNativeFrontExtractor(FrontExtractorOp):
- op = 'DepthwiseConv2dNative'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = tf_create_attrs(node, 2, 2)
- attrs.update({'op': __class__.op,
- 'kernel_spatial_idx': int64_array([0, 1]),
- 'get_group': lambda node: node.kernel_shape[node.output_feature_channel],
- 'get_output_feature_dim': lambda node: node.kernel_shape[-1] * node.kernel_shape[-2],
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([2, 3, 0, 1]),
- inv=int64_array([2, 3, 0, 1]))
- })
-
- # update the attributes of the node
- Convolution.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class Conv3DFrontExtractor(FrontExtractorOp):
- op = 'Conv3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = tf_create_attrs(node, 3, 4)
- attrs.update({'op': __class__.op,
- 'get_group': lambda node: 1,
- 'get_output_feature_dim': lambda node: node.kernel_shape[node.output_feature_channel],
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([4, 3, 0, 1, 2]),
- inv=int64_array([2, 3, 4, 1, 0]))
- })
-
- # update the attributes of the node
- Convolution.update_node_stat(node, attrs)
- return cls.enabled
-
-
-def tf_create_attrs(node, input_feature_channel, output_feature_channel):
- data_format = node.pb.attr["data_format"]
- dilations = tf_int_list(node.pb.attr["dilations"].list)
- if len(dilations) == 0:
- dilations = None
-
- attrs = {
- 'type': 'Convolution',
- 'auto_pad': convert_tf_padding_to_str(node.pb.attr['padding'].s.decode()),
- 'bias_addable': True,
- 'bias_term': False,
- 'dilation': dilations,
- 'stride': tf_int_list(node.pb.attr["strides"].list),
-
- 'channel_dims': tf_data_format_channel(data_format),
- 'batch_dims': tf_data_format_batch(data_format),
-
- 'input_feature_channel': input_feature_channel,
- 'output_feature_channel': output_feature_channel,
- 'layout': data_format.s.decode(),
-
- # get_group and get_output_feature_dim are special attrs that stores lambdas ( lambda node, kernel_shape:...)
- # this attrs calls in infer function to calculate output feature dimension and group attr
- 'get_group': None, # lambda should return group attr for given node
- 'get_output_feature_dim': None, # lamda should return output feature dimension
- }
-
- return attrs
diff --git a/tools/mo/openvino/tools/mo/front/tf/crop_and_resize_ext.py b/tools/mo/openvino/tools/mo/front/tf/crop_and_resize_ext.py
deleted file mode 100644
index 06f6d127c5310b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/crop_and_resize_ext.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.roipooling import ROIPooling
-
-
-class CropAndResizeFrontExtractor(FrontExtractorOp):
- op = 'CropAndResize'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # update the attributes of the node and force 'op' to be 'CropAndResize' so extension that merges two of its
- # inputs would be called
- method = node.pb.attr['method'].s.decode('utf-8')
- if method != 'bilinear':
- log.warning(
- 'The crop and resize method "{}" for node "{}" is not supported.'.format(method, node.soft_get('name')))
- return False
- ROIPooling.update_node_stat(node, {'spatial_scale': 1, 'op': 'CropAndResize', 'method': method})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/cumsum_ext.py b/tools/mo/openvino/tools/mo/front/tf/cumsum_ext.py
deleted file mode 100644
index 0457af59c91c3a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/cumsum_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.cumsum import CumSum
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class CumSumExtractor(FrontExtractorOp):
- op = 'Cumsum'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- exclusive = node.pb.attr['exclusive'].b
- reverse = node.pb.attr['reverse'].b
- CumSum.update_node_stat(node, {'exclusive': exclusive, 'reverse': reverse})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/custom_subgraph_call.py b/tools/mo/openvino/tools/mo/front/tf/custom_subgraph_call.py
deleted file mode 100644
index 56ba139f53fcb6..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/custom_subgraph_call.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from re import findall
-
-from openvino.tools.mo.front.extractor import update_ie_fields
-from openvino.tools.mo.graph.graph import Node, merge_edge_props, Graph
-from openvino.tools.mo.utils.graph import is_connected_component
-
-
-def internal_output_name_for_node(node_name: str, output_port: int):
- return node_name + ":" + str(output_port)
-
-
-def add_node_pb_if_not_yet_added(node: Node, mega_node: Node):
- if node.has_valid('pb') and node.pb.name not in mega_node.pbs.keys():
- mega_node.pbs[node.pb.name] = node.pb
-
-
-def find_input_port(node: Node, input_desc: list, search_node_name: str, search_node_port: int):
- if input_desc is None:
- return len(node.in_nodes())
-
- for in_port, tensor_desc in enumerate(input_desc):
- for node_pattern, node_port in tensor_desc:
- if findall(node_pattern, search_node_name) and node_port == search_node_port:
- return in_port
- raise Exception('Did not find input port of the node "{}" with port "{}"'.format(search_node_name,
- search_node_port))
-
-
-def find_output_port(node: Node, output_desc: list, search_node_name: str, search_node_port: int):
- if output_desc is None:
- return len(node.out_nodes())
-
- for out_port, (node_pattern, node_port) in enumerate(output_desc):
- if findall(node_pattern, search_node_name) and node_port == search_node_port:
- return out_port
- raise Exception('Did not find output port of the node "{}" with port "{}"'.format(search_node_name,
- search_node_port))
-
-
-def merge_nodes(graph: Graph, nodes_to_merge_names: list, inputs_desc: list = None,
- outputs_desc: list = None):
- """
- Merges nodes specified in the set 'nodes_to_merge_names' into one mega-node, creating new edges between mega-node
- and inputs/outputs nodes of the mega-node. The added edges contain name of input/output nodes which will be used for
- generation of placeholders and will be saved to the IR xml so OV plug-in know how to map input/output data for the
- layer. Also the function adds protobufs of the nodes of the sub-graph and 'Const' ops consumed by nodes in the
- sub-graph to the node's attribute 'pbs'.
- :param graph: the graph object to operate on.
- :param nodes_to_merge_names: list of nodes names that should be merged into a single node.
- :param inputs_desc: optional list describing input nodes order.
- :param outputs_desc: optional list describing output nodes order.
- """
- if not is_connected_component(graph, nodes_to_merge_names):
- log.warning("The following nodes do not form connected sub-graph: {}".format(nodes_to_merge_names))
- # graph.dump_graph_for_graphviz(nodes_to_dump=nodes_to_merge_names)
-
- new_node_name = graph.unique_id("TFSubgraphCall_")
- log.info("Create new node with name '{}' for nodes '{}'".format(new_node_name, ', '.join(nodes_to_merge_names)))
- graph.add_node(new_node_name)
- new_node_attrs = graph.node[new_node_name]
-
- new_node_attrs['name'] = new_node_name
- set_tf_custom_call_node_attrs(new_node_attrs)
- new_node = Node(graph, new_node_name)
-
- added_input_tensors_names = set() # set of tensors that are were added as input to the sub-graph
- added_new_node_output_tensors = dict() # key - tensor name, value - out port
-
- for node_name in nodes_to_merge_names:
- node = Node(graph, node_name)
- add_node_pb_if_not_yet_added(node, new_node)
- # TODO: any improvements?
- for in_node_name, edge_attrs in Node(graph, node_name).get_inputs():
- in_node = Node(graph, in_node_name)
-
- # internal edges between nodes of the sub-graph
- if in_node_name in nodes_to_merge_names:
- add_node_pb_if_not_yet_added(in_node, new_node)
- continue
-
- # edge outside of sub-graph into sub-graph
- if in_node_name not in nodes_to_merge_names:
- # we cannot use the 'in_node_name' as a protobuf operation name here
- # because the 'in_node_name' could be a sub-graph matched before.
- input_tensor_name = node.pb.input[edge_attrs['in']]
- if input_tensor_name not in added_input_tensors_names:
- if not new_node.has_port('in', edge_attrs['in']):
- new_node.add_input_port(edge_attrs['in'])
- graph.add_edge(in_node_name, new_node_name,
- **merge_edge_props(
- {'in': find_input_port(new_node, inputs_desc, node_name, edge_attrs['in']),
- 'out': edge_attrs['out'],
- 'internal_input_node_name': input_tensor_name,
- 'original_dst_node_name': node_name,
- 'original_dst_port': edge_attrs['in'],
- 'in_attrs': ['in', 'internal_input_node_name', 'original_dst_node_name',
- 'original_dst_port', 'placeholder_name'],
- 'out_attrs': ['out']},
- edge_attrs)
- )
- log.debug("Creating edge from outside of sub-graph to inside sub-graph: {} -> {}".format(
- in_node_name, new_node_name))
- added_input_tensors_names.add(input_tensor_name)
-
- # edge from inside sub-graph to outside sub-graph
- for out_node_name, edge_attrs in Node(graph, node_name).get_outputs():
- if out_node_name not in nodes_to_merge_names:
- log.debug("Creating edge from inside of sub-graph to outside sub-graph: {} -> {}".format(
- new_node_name, out_node_name))
- out_name = internal_output_name_for_node(node_name, edge_attrs['out'])
- if out_name not in added_new_node_output_tensors.keys():
- added_new_node_output_tensors[out_name] = find_output_port(new_node, outputs_desc, node_name,
- edge_attrs['out'])
- if not new_node.has_port('out', added_new_node_output_tensors[out_name]):
- new_node.add_output_port(added_new_node_output_tensors[out_name])
- graph.add_edge(new_node_name, out_node_name,
- **merge_edge_props(
- {'in': edge_attrs['in'],
- 'out': added_new_node_output_tensors[out_name],
- 'internal_output_node_name': out_name,
- 'in_attrs': ['in', 'internal_input_node_name'],
- 'out_attrs': ['out', 'internal_output_node_name']},
- edge_attrs)
- )
- new_node['output_tensors_names'] = [val for val in
- {v: k for k, v in added_new_node_output_tensors.items()}.values()]
-
- # add nodes using the same order as in initial GraphDef so we can dump them to IR in "correct" order
- new_node['nodes_order'] = [node for node in graph.graph['initial_nodes_order'] if node in new_node['pbs'].keys()]
-
- for n in nodes_to_merge_names:
- if graph.has_node(n): # check if not deleted by another (similar) pattern
- graph.remove_node(n)
- return Node(graph, new_node_name)
-
-
-def set_tf_custom_call_node_attrs(node_attrs: dict):
- from openvino.tools.mo.front.tf.partial_infer.tf import tf_subgraph_infer
- update_ie_fields(node_attrs)
- node_attrs['input_nodes_names'] = list()
- node_attrs['output_tensors_names'] = list()
- node_attrs['real_input_dims'] = list()
- node_attrs['pbs'] = dict()
- node_attrs['type'] = 'TFCustomSubgraphCall'
- node_attrs['op'] = 'TFCustomSubgraphCall'
- node_attrs['infer'] = tf_subgraph_infer
- node_attrs['kind'] = 'op'
-
-
-def skip_nodes_by_condition(current_node: Node, condition: callable, forward: bool = False):
- if forward:
- while condition(current_node):
- current_node = current_node.out_node()
- else:
- while condition(current_node):
- current_node = current_node.in_node()
- return current_node
diff --git a/tools/mo/openvino/tools/mo/front/tf/deconv_ext.py b/tools/mo/openvino/tools/mo/front/tf/deconv_ext.py
deleted file mode 100644
index 0dd16a58d2d30a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/deconv_ext.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import convert_deconv_tf_padding_to_str, int64_array, \
- dynamic_dimension
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_data_format_spatial, tf_data_format_channel, \
- tf_data_format_batch, \
- tf_int_list
-from openvino.tools.mo.ops.deconvolution import Deconvolution
-from openvino.tools.mo.ops.op import PermuteAttrs
-
-
-class Conv2DBackpropInputFrontExtractor(FrontExtractorOp):
- op = 'Conv2DBackpropInput'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = tf_create_attrs(node, 3, 2)
- attrs.update({'op': cls.op,
- 'get_group': get_conv_backprop_groups,
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([3, 2, 0, 1]),
- inv=int64_array([2, 3, 1, 0])),
- 'swap_0_and_2_inputs': True,
- 'shape_input': True,
- })
-
- # update the attributes of the node
- Deconvolution.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class Conv3DBackpropInputV2InputFrontExtractor(FrontExtractorOp):
- op = 'Conv3DBackpropInputV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = tf_create_attrs(node, 4, 3)
- attrs.update({'op': cls.op,
- 'get_group': get_conv_backprop_groups,
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([4, 3, 0, 1, 2]),
- inv=int64_array([2, 3, 4, 1, 0])),
- 'swap_0_and_2_inputs': True,
- 'shape_input': True,
- })
-
- # update the attributes of the node
- Deconvolution.update_node_stat(node, attrs)
- return cls.enabled
-
-
-def tf_create_attrs(node, input_feature_channel, output_feature_channel):
- data_format = node.pb.attr["data_format"]
-
- return {
- 'auto_pad': convert_deconv_tf_padding_to_str(node.pb.attr['padding'].s.decode()),
- 'bias_addable': True,
- 'bias_term': False,
- 'spatial_dims': tf_data_format_spatial(data_format),
- 'channel_dims': tf_data_format_channel(data_format),
- 'batch_dims': tf_data_format_batch(data_format),
- 'pad': None, # will be inferred when input shape is known
- 'pad_spatial_shape': None,
- 'output_spatial_shape': None,
- 'output_shape': None,
- 'output': None,
- 'stride': tf_int_list(node.pb.attr["strides"].list),
- 'type': None, # don't set type until we are sure it is really translated to correct IR; see infer function
- 'group': None,
- 'layout': data_format.s.decode(),
- 'input_feature_channel': input_feature_channel,
- 'output_feature_channel': output_feature_channel,
- }
-
-
-def get_conv_backprop_groups(node):
- # output shape is required input for TensorFlow ConvBackpropInput operation and contains output shape values
- # in the form [batch_size, output_height, output_width, output_channel], so that
- # groups number = output_channel // kernel_out_channels, where
- # kernel shape is given as [kernel_height, kernel_width, kernel_out_channels, in_channels]
- output_shape = node.in_port(2).data.get_value()
- kernel_shape = node.in_port(1).data.get_shape()
- if node.has_and_set('group'):
- return node.group
- elif output_shape is not None and kernel_shape is not None \
- and output_shape[node.channel_dims[0]] is not dynamic_dimension \
- and kernel_shape[node.output_feature_channel] is not dynamic_dimension:
- return output_shape[node.channel_dims] // kernel_shape[node.output_feature_channel]
- else:
- return 1
diff --git a/tools/mo/openvino/tools/mo/front/tf/depth_to_space.py b/tools/mo/openvino/tools/mo/front/tf/depth_to_space.py
deleted file mode 100644
index ca914cec748cf6..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/depth_to_space.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.depth_to_space import DepthToSpaceOp
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class DepthToSpaceFrontExtractor(FrontExtractorOp):
- op = 'DepthToSpace'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # update the attributes of the node
- block_size = node.pb.attr['block_size'].i
- data_format = node.pb.attr['data_format'].s.decode('utf-8')
- DepthToSpaceOp.update_node_stat(node, {'block_size': block_size, 'data_format': data_format})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/efficient_det_support_api_v2.0.json b/tools/mo/openvino/tools/mo/front/tf/efficient_det_support_api_v2.0.json
deleted file mode 100644
index f1333461f9d0b3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/efficient_det_support_api_v2.0.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/Preprocessor/unstack"],
- "end_nodes": ["StatefulPartitionedCall/Preprocessor/stack",
- "StatefulPartitionedCall/Preprocessor/stack_1"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true,
- "disable_prior_boxes_layers_generator": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/Identity",
- "StatefulPartitionedCall/Identity_1",
- "StatefulPartitionedCall/Identity_2",
- "StatefulPartitionedCall/Identity_3",
- "StatefulPartitionedCall/Identity_4",
- "StatefulPartitionedCall/Identity_5",
- "StatefulPartitionedCall/Identity_6",
- "StatefulPartitionedCall/Identity_7"
- ],
- "start_points": [
- "StatefulPartitionedCall/Postprocessor/Reshape_1",
- "StatefulPartitionedCall/Postprocessor/scale_logits",
- "StatefulPartitionedCall/Postprocessor/Tile",
- "StatefulPartitionedCall/Postprocessor/Cast_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/Identity,StatefulPartitionedCall/Identity_1,StatefulPartitionedCall/Identity_2,StatefulPartitionedCall/Identity_3,StatefulPartitionedCall/Identity_4,StatefulPartitionedCall/Identity_5,StatefulPartitionedCall/Identity_6,StatefulPartitionedCall/Identity_7"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/efficient_det_support_api_v2.4.json b/tools/mo/openvino/tools/mo/front/tf/efficient_det_support_api_v2.4.json
deleted file mode 100644
index e1826d8b45fd2b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/efficient_det_support_api_v2.4.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/map/TensorArrayUnstack/TensorListFromTensor"],
- "end_nodes": ["StatefulPartitionedCall/map/TensorArrayV2Stack/TensorListStack",
- "StatefulPartitionedCall/map/TensorArrayV2Stack_1/TensorListStack"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true,
- "disable_prior_boxes_layers_generator": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/Identity",
- "StatefulPartitionedCall/Identity_1",
- "StatefulPartitionedCall/Identity_2",
- "StatefulPartitionedCall/Identity_3",
- "StatefulPartitionedCall/Identity_4",
- "StatefulPartitionedCall/Identity_5",
- "StatefulPartitionedCall/Identity_6",
- "StatefulPartitionedCall/Identity_7"
- ],
- "start_points": [
- "StatefulPartitionedCall/Postprocessor/Reshape_1",
- "StatefulPartitionedCall/Postprocessor/scale_logits",
- "StatefulPartitionedCall/Postprocessor/Tile",
- "StatefulPartitionedCall/Postprocessor/Cast_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/Identity,StatefulPartitionedCall/Identity_1,StatefulPartitionedCall/Identity_2,StatefulPartitionedCall/Identity_3,StatefulPartitionedCall/Identity_4,StatefulPartitionedCall/Identity_5,StatefulPartitionedCall/Identity_6,StatefulPartitionedCall/Identity_7"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/einsum_ext.py b/tools/mo/openvino/tools/mo/front/tf/einsum_ext.py
deleted file mode 100644
index 3c622e20483275..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/einsum_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.einsum import Einsum
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class EinsumExtractor(FrontExtractorOp):
- op = 'Einsum'
- enabled = True
-
- @classmethod
- def extract(cls, einsum_node):
- einsum_name = einsum_node.soft_get('name', einsum_node.id)
- equation = einsum_node.pb.attr['equation'].s.decode('utf-8')
- normalized_equation = Einsum.normalize_equation(einsum_name, equation)
- Einsum.update_node_stat(einsum_node, {'equation': normalized_equation})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/elementwise_ext.py b/tools/mo/openvino/tools/mo/front/tf/elementwise_ext.py
deleted file mode 100644
index 1f244a708a421f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/elementwise_ext.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.elementwise import Add, Mul, Sub, Div, Maximum, Minimum, Pow, LogicalAnd, LogicalOr, Equal, \
- GreaterEqual, Greater, Less, LessEqual, NotEqual, FloorMod, BiasAdd, SquaredDifference, Round, Mod
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-from openvino.tools.mo.ops.eltwise_n import EltwiseNAdd
-from openvino.tools.mo.ops.power import AttributedPower
-
-
-class AddExtractor(FrontExtractorOp):
- op = 'Add'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Add.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class AddV2Extractor(FrontExtractorOp):
- op = 'AddV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Add.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class AddNExtractor(FrontExtractorOp):
- op = 'AddN'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- EltwiseNAdd.update_node_stat(node)
- return cls.enabled
-
-
-class BiasAddExtractor(FrontExtractorOp):
- op = 'BiasAdd'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- BiasAdd.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type),
- 'data_format': node.pb.attr["data_format"].s.decode()})
- return cls.enabled
-
-
-class MulExtractor(FrontExtractorOp):
- op = 'Mul'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Mul.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class SubExtractor(FrontExtractorOp):
- op = 'Sub'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sub.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class ModExtractor(FrontExtractorOp):
- op = 'Mod'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Mod.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class DivExtractor(FrontExtractorOp):
- op = 'RealDiv'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Div.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class SquaredDifferenceExtractor(FrontExtractorOp):
- op = 'SquaredDifference'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- SquaredDifference.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class SqrtExtractor(FrontExtractorOp):
- op = 'Sqrt'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedPower.update_node_stat(node, {'power': 0.5})
- return cls.enabled
-
-
-class RsqrtExtractor(FrontExtractorOp):
- op = 'Rsqrt'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedPower.update_node_stat(node, {'power': -0.5})
- return cls.enabled
-
-
-class SquareExtractor(FrontExtractorOp):
- op = 'Square'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- data_type = tf_dtype_extractor(node.pb.attr["T"].type)
- AttributedPower.update_node_stat(node, {'power': data_type(2), 'data_type': data_type})
- return cls.enabled
-
-
-class NegExtractor(FrontExtractorOp):
- op = 'Neg'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedPower.update_node_stat(node, {'scale': -1})
- return cls.enabled
-
-
-class ZerosLike(FrontExtractorOp):
- op = 'ZerosLike'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedPower.update_node_stat(node, {'scale': 0})
- return cls.enabled
-
-
-class MaximumExtractor(FrontExtractorOp):
- op = 'Maximum'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Maximum.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class MinimumExtractor(FrontExtractorOp):
- op = 'Minimum'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Minimum.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class PowExtractor(FrontExtractorOp):
- op = 'Pow'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Pow.update_node_stat(node, {'data_type': tf_dtype_extractor(node.pb.attr["T"].type)})
- return cls.enabled
-
-
-class LogicalAndFrontExtractor(FrontExtractorOp):
- op = 'LogicalAnd'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalAnd.update_node_stat(node)
- return cls.enabled
-
-
-class LogicalOrFrontExtractor(FrontExtractorOp):
- op = 'LogicalOr'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LogicalOr.update_node_stat(node)
- return cls.enabled
-
-
-class EqualExtractor(FrontExtractorOp):
- op = 'Equal'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Equal.update_node_stat(node)
- return cls.enabled
-
-
-class LessEqualExtractor(FrontExtractorOp):
- op = 'LessEqual'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- LessEqual.update_node_stat(node)
- return cls.enabled
-
-
-class LessExtractor(FrontExtractorOp):
- op = 'Less'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Less.update_node_stat(node)
- return cls.enabled
-
-
-class GreaterExtractor(FrontExtractorOp):
- op = 'Greater'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Greater.update_node_stat(node)
- return cls.enabled
-
-
-class GreaterEqualExtractor(FrontExtractorOp):
- op = 'GreaterEqual'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- GreaterEqual.update_node_stat(node)
- return cls.enabled
-
-
-class NotEqualExtractor(FrontExtractorOp):
- op = 'NotEqual'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- NotEqual.update_node_stat(node)
- return cls.enabled
-
-
-class FloorModFrontExtractor(FrontExtractorOp):
- op = 'FloorMod'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- FloorMod.update_node_stat(node)
- return cls.enabled
-
-
-class RoundExtractor(FrontExtractorOp):
- op = 'Round'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Round.update_node_stat(node, {'mode': 'half_to_even'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/embedding_segments_mean_decomposition.py b/tools/mo/openvino/tools/mo/front/tf/embedding_segments_mean_decomposition.py
deleted file mode 100644
index ab151dd5c1735d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/embedding_segments_mean_decomposition.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.ConvertLike import ConvertLike
-from openvino.tools.mo.ops.ReduceOps import ReduceSum
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.elementwise import Div, Equal
-from openvino.tools.mo.ops.embedding_bag import EmbeddingSegmentsSum
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class EmbeddingSegmentsMeanDecomposition(FrontReplacementPattern):
- """
- This transformation decomposes EmbeddingSegmentsMean operation into EmbeddingSegmentSum operations taking into
- account that summed up embedding vectors for each vector must be normalized appropriately by a coefficient
- equal to a number of gathered embedding vectors for each object. If there is no gathered embedding vector
- for an object, the coefficient equals one.
-
- Approximate computation scheme (Cast operations omitted) for the normalization coefficients:
-
- Const(0)
- segment_ids -> Unsqueeze(axis=1) -----------------\ |
- \ \/
- ---> Equal() --> Select --> ReduceSum(axis=0) --> Norm. Coeff.
- / /\
- Range(0, num_segments) -> Unsqueeze(axis=0)------ / |
- Const(1)
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.tf.embedding_segments_operation_fusing import \
- EmbeddingSegmentsOperationMultipleFeaturesFusing, EmbeddingSegmentsOperationSingleFeatureFusing
- return [EmbeddingSegmentsOperationMultipleFeaturesFusing, EmbeddingSegmentsOperationSingleFeatureFusing]
-
- def find_and_replace_pattern(self, graph: Graph):
- for embedding_segments_mean in graph.get_op_nodes(op='EmbeddingSegmentsMean'):
- embedding_segments_mean_name = embedding_segments_mean.soft_get('name',
- embedding_segments_mean.id)
- embedding_table_input = embedding_segments_mean.in_port(0)
- segment_ids_input = embedding_segments_mean.in_port(2)
- num_segments_input = embedding_segments_mean.in_port(3)
-
- # TODO: support EmbeddingSegmentsMean with specified weights vector.
- # now this case has not appeared in models so far so EmbeddingSegmentsOperation fusion
- # transformations do not handle it either
- if embedding_segments_mean.is_in_port_connected(5):
- return
-
- # 1. compute indices membership matrix, i.e. which indices belong to some object
- # the shape of this matrix is [num_segments, num_indices]
- non_norm_range_1_to_num_segments = create_op_with_const_inputs(graph, Range,
- {0: int64_array(0),
- 2: int64_array(1)},
- {'name': embedding_segments_mean_name +
- '/Range1ToNumSegments',
- 'output_type': np.int64})
- num_segments_input.get_connection().add_destination(non_norm_range_1_to_num_segments.in_port(1))
-
- range_1_to_num_segments = ConvertLike(graph, {'name': embedding_segments_mean_name +
- '/Range1ToNumSegmentsNorm'}
- ).create_node()
- range_1_to_num_segments.in_port(0).connect(non_norm_range_1_to_num_segments.out_port(0))
- num_segments_input.get_connection().add_destination(range_1_to_num_segments.in_port(1))
-
- unsqueeze_range_1_to_num_segments = create_op_with_const_inputs(graph, Unsqueeze, {1: int64_array(1)},
- {'name': embedding_segments_mean_name +
- '/Range1ToNumSegmentsUnsqueeze'})
- unsqueeze_range_1_to_num_segments.in_port(0).connect(range_1_to_num_segments.out_port(0))
- unsqueeze_segment_ids = create_op_with_const_inputs(graph, Unsqueeze, {1: int64_array(0)},
- {'name': embedding_segments_mean_name +
- '/SegmentIdsUnsqueeze'})
- segment_ids_input.get_connection().add_destination(unsqueeze_segment_ids.in_port(0))
- boolean_membership_matrix = Equal(graph, {'name': embedding_segments_mean_name +
- '/BooleanMembershipMatrix'}
- ).create_node()
- boolean_membership_matrix.in_port(0).connect(unsqueeze_range_1_to_num_segments.out_port(0))
- boolean_membership_matrix.in_port(1).connect(unsqueeze_segment_ids.out_port(0))
- shape_of_membership_matrix = Shape(graph, {'name': embedding_segments_mean_name +
- '/ShapeOfMembershipMatrix'}
- ).create_node([boolean_membership_matrix])
- one_scalar_constant = Const(graph, {'name': embedding_segments_mean_name + '/OneScalar',
- 'value': int64_array([1])}).create_node()
- one_constant = Broadcast(graph, {'name': embedding_segments_mean_name + '/One'}
- ).create_node([one_scalar_constant,
- shape_of_membership_matrix])
- zero_constant = Const(graph, {'name': embedding_segments_mean_name + '/Zero',
- 'value': int64_array(0)}).create_node()
- membership_matrix = Select(graph, {'name': embedding_segments_mean_name + '/MembershipMatrix',
- 'auto_broadcast': 'numpy'}).create_node([boolean_membership_matrix,
- one_constant,
- zero_constant])
-
- # 2. compute a number of indices belong to each object from the batch
- # it computes the normalization coefficients
- num_indices_per_object = create_op_with_const_inputs(graph, ReduceSum,
- {1: int64_array(1)},
- {'name': embedding_segments_mean_name +
- '/NumIndicesPerObject'})
- num_indices_per_object.in_port(0).connect(membership_matrix.out_port(0))
-
- # 3. replace zero coefficient (zero number of indices belong to an object) with one
- # because for such object the single default embedding vector is used
- where_zero_number = Equal(graph, {'name': embedding_segments_mean_name +
- '/WhereZeroIndicesNumber'}
- ).create_node([num_indices_per_object, zero_constant])
- normalized_num_indices_per_object = Select(graph, {'name': embedding_segments_mean_name +
- '/NormNumIndicesPerObject',
- 'auto_broadcast': 'numpy'}
- ).create_node([where_zero_number,
- one_scalar_constant,
- num_indices_per_object])
-
- # 4. cast normalized_num_indices_per_object to the same type as embedding vector table
- norm_coefficients = ConvertLike(graph, {'name': embedding_segments_mean_name +
- '/NormCoefficients'}
- ).create_node()
- norm_coefficients.in_port(0).connect(normalized_num_indices_per_object.out_port(0))
- embedding_table_input.get_connection().add_destination(norm_coefficients.in_port(1))
-
- # 5. replace EmbeddingSegmentMean with EmbeddingSegmentSum
- embedding_segments_sum = EmbeddingSegmentsSum(graph, {'name': embedding_segments_mean_name +
- '/EmbeddingSegmentsSum'}
- ).create_node()
- for in_port in embedding_segments_mean.in_ports():
- if embedding_segments_mean.is_in_port_connected(in_port):
- embedding_segments_mean.in_port(in_port).get_connection().set_destination(
- embedding_segments_sum.in_port(in_port))
-
- # 6. normalize EmbeddingSegmentSum results by computed coefficients
- result_node = Div(graph, {'name': embedding_segments_mean_name +
- '/Div'}
- ).create_node([embedding_segments_sum, norm_coefficients])
- embedding_segments_mean.out_port(0).get_connection().set_source(result_node.out_port(0))
-
- rename_nodes([(embedding_segments_mean, embedding_segments_mean_name + '/AbandonedName'),
- (result_node, embedding_segments_mean_name)])
- graph.remove_nodes_from([embedding_segments_mean.id])
diff --git a/tools/mo/openvino/tools/mo/front/tf/embedding_segments_operation_fusing.py b/tools/mo/openvino/tools/mo/front/tf/embedding_segments_operation_fusing.py
deleted file mode 100644
index a70219307d8ed4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/embedding_segments_operation_fusing.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.embedding_bag import EmbeddingSegmentsMean, EmbeddingSegmentsSum
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-class EmbeddingSegmentsOperationSingleFeatureFusing(FrontReplacementSubgraph):
- """
- The transformation looks for pattern (sub-graph) that performs extraction of embedding vectors from the parameters
- table for object feature values, and sum up these embedding vectors for every object or compute their mean value.
- Such sub-graph is met in the Wide and Deep model in case of the SINGLE categorical feature.
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('identity_spw', dict(op='Identity')),
- ('gather0_1', dict(type='Gather')),
- ('gather0_2', dict(type='Gather')),
- ('reshape0', dict(op='Reshape')),
- ('where0', dict(op='Where')),
- ('greaterequal0', dict(op='GreaterEqual')),
- ('sparse_fill_empty_rows', dict(op='SparseFillEmptyRows')),
- ('unique', dict(op='Unique')),
- ('strided_slice', dict(op='StridedSlice')),
- ('cast', dict(op='Cast')),
- ('gather', dict(type='Gather')),
- ('sparse_segment_op', dict(op=lambda op: op in ['SparseSegmentSum', 'SparseSegmentMean'])),
- ('reshape', dict(op='Reshape')),
- ('tile', dict(type='Tile')),
- ('select', dict(op='Select'))
- ],
- edges=[
- ('identity_spw', 'sparse_fill_empty_rows', {'out': 0, 'in': 2}),
- ('gather0_1', 'sparse_fill_empty_rows', {'out': 0, 'in': 0}),
- ('gather0_2', 'sparse_fill_empty_rows', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_1', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_2', {'out': 0, 'in': 1}),
- ('where0', 'reshape0', {'out': 0, 'in': 0}),
- ('greaterequal0', 'where0', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'unique', {'out': 1, 'in': 0}),
- ('sparse_fill_empty_rows', 'strided_slice', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'reshape', {'out': 2, 'in': 0}),
- ('unique', 'sparse_segment_op', {'out': 1, 'in': 1}),
- ('unique', 'gather', {'out': 0, 'in': 1}),
- ('strided_slice', 'cast', {'out': 0, 'in': 0}),
- ('gather', 'sparse_segment_op', {'out': 0, 'in': 0}),
- ('cast', 'sparse_segment_op', {'out': 0, 'in': 2}),
- ('sparse_segment_op', 'select', {'out': 0, 'in': 2}),
- ('reshape', 'tile', {'out': 0, 'in': 0}),
- ('tile', 'select', {'out': 0, 'in': 0})
- ])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- identity_spw = match['identity_spw']
- gather0_1 = match['gather0_1']
- gather0_2 = match['gather0_2']
- greaterequal0 = match['greaterequal0']
- sparse_fill_empty_rows = match['sparse_fill_empty_rows']
- gather = match['gather']
- select = match['select']
- where0 = match['where0']
- sparse_segment_op = match['sparse_segment_op']
- output_node_name = select.soft_get('name', select.id)
-
- log.debug('Found EmbeddingSparseSegmentsSingleFeature pattern after {} with name {}'.format(
- sparse_fill_empty_rows.op,
- sparse_fill_empty_rows.name))
-
- split_for_indices = create_op_with_const_inputs(graph, Split, {1: int64_array(1)}, {'num_splits': 2})
- squeeze_for_indices = create_op_with_const_inputs(graph, Squeeze, {1: int64_array([1])})
- split_for_dense_shape = create_op_with_const_inputs(graph, Split, {1: int64_array(0)}, {'num_splits': 2})
- squeeze_to_scalar = create_op_with_const_inputs(graph, Squeeze, {1: int64_array([0])})
-
- # TODO: remove Cast nodes once we start to support EmbeddingSegmentSum (new version) with segment_ids,
- # indices, and num_segments of different integer type.
- # Because the real cases show that it is possible to have it in TensorFlow
- cast_indices = Cast(graph, {'name': output_node_name + '/CastIndices', 'dst_type': np.int32}).create_node()
- cast_segment_ids = Cast(graph, {'name': output_node_name + '/CastSegmentIds',
- 'dst_type': np.int32}).create_node()
- cast_default_value = Cast(graph, {'name': output_node_name + '/CastDefaultValue',
- 'dst_type': np.int32}).create_node()
- cast_num_segments = Cast(graph, {'name': output_node_name + '/CastSegmentsNumber',
- 'dst_type': np.int32}).create_node()
- if sparse_segment_op.op == 'SparseSegmentSum':
- embedding_segments_op = EmbeddingSegmentsSum(graph, {'name': output_node_name}).create_node()
- else:
- embedding_segments_op = EmbeddingSegmentsMean(graph, {'name': output_node_name}).create_node()
- rename_nodes([(select, output_node_name + '/AbandonedName'), (embedding_segments_op, output_node_name)])
-
- # connect parameters table
- gather.in_port(0).get_connection().set_destination(embedding_segments_op.in_port(0))
- # connect indices values
- greaterequal0.in_port(0).get_connection().set_destination(cast_indices.in_port(0))
- embedding_segments_op.in_port(1).connect(cast_indices.out_port(0))
- # split and connect segment ids
- gather0_1.in_port(0).get_connection().set_destination(split_for_indices.in_port(0))
- squeeze_for_indices.in_port(0).connect(split_for_indices.out_port(0))
- cast_segment_ids.in_port(0).connect(squeeze_for_indices.out_port(0))
- embedding_segments_op.in_port(2).connect(cast_segment_ids.out_port(0))
- # split and connect number of segments
- identity_spw.in_port(0).get_connection().set_destination(split_for_dense_shape.in_port(0))
- squeeze_to_scalar.in_port(0).connect(split_for_dense_shape.out_port(0))
- cast_num_segments.in_port(0).connect(squeeze_to_scalar.out_port(0))
- embedding_segments_op.in_port(3).connect(cast_num_segments.out_port(0))
- # connect default value
- sparse_fill_empty_rows.in_port(3).get_connection().set_destination(cast_default_value.in_port(0))
- embedding_segments_op.in_port(4).connect(cast_default_value.out_port(0))
- # no input port for per_sample_weight
-
- identity_spw.in_port(0).disconnect()
- gather0_1.in_port(0).disconnect()
- gather0_2.in_port(0).disconnect()
- greaterequal0.in_port(0).disconnect()
- sparse_fill_empty_rows.in_port(2).disconnect()
- gather.in_port(0).disconnect()
-
- select.out_port(0).get_connection().set_source(embedding_segments_op.out_port(0))
- graph.remove_nodes_from(
- [gather0_1.id, gather0_2.id, greaterequal0.id, sparse_fill_empty_rows.id, select.id, where0.id])
-
-
-class EmbeddingSegmentsOperationMultipleFeaturesFusing(FrontReplacementSubgraph):
- """
- The transformation looks for pattern (sub-graph) that performs extraction of embedding vectors from the parameters
- table for object feature values, and sum up these embedding vectors for every object or compute their mean value.
- Such sub-graph is met in the Wide and Deep model in case of MULTIPLE categorical features.
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('identity_spw', dict(op='Identity')),
- ('gather0_1', dict(type='Gather')),
- ('gather0_2', dict(type='Gather')),
- ('reshape0', dict(op='Reshape')),
- ('where0', dict(op='Where')),
- ('greaterequal0', dict(op='GreaterEqual')),
- ('sparse_fill_empty_rows', dict(op='SparseFillEmptyRows')),
- ('unique', dict(op='Unique')),
- ('strided_slice', dict(op='StridedSlice')),
- ('cast', dict(op='Cast')),
- ('gather', dict(type='Gather')),
- ('identity', dict(op='Identity')),
- ('identity_1', dict(op='Identity')),
- ('sparse_segment_op', dict(op=lambda op: op in ['SparseSegmentSum', 'SparseSegmentMean'])),
- ('reshape', dict(op='Reshape')),
- ('tile', dict(type='Tile')),
- ('select', dict(op='Select'))
- ],
- edges=[
- ('identity_spw', 'sparse_fill_empty_rows', {'out': 0, 'in': 2}),
- ('gather0_1', 'sparse_fill_empty_rows', {'out': 0, 'in': 0}),
- ('gather0_2', 'sparse_fill_empty_rows', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_1', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_2', {'out': 0, 'in': 1}),
- ('where0', 'reshape0', {'out': 0, 'in': 0}),
- ('greaterequal0', 'where0', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'unique', {'out': 1, 'in': 0}),
- ('sparse_fill_empty_rows', 'strided_slice', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'reshape', {'out': 2, 'in': 0}),
- ('unique', 'sparse_segment_op', {'out': 1, 'in': 1}),
- ('unique', 'gather', {'out': 0, 'in': 1}),
- ('strided_slice', 'cast', {'out': 0, 'in': 0}),
- ('gather', 'identity', {'out': 0, 'in': 0}),
- ('identity', 'identity_1', {'out': 0, 'in': 0}),
- ('identity_1', 'sparse_segment_op', {'out': 0, 'in': 0}),
- ('cast', 'sparse_segment_op', {'out': 0, 'in': 2}),
- ('sparse_segment_op', 'select', {'out': 0, 'in': 2}),
- ('reshape', 'tile', {'out': 0, 'in': 0}),
- ('tile', 'select', {'out': 0, 'in': 0})
- ])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- identity_spw = match['identity_spw']
- gather0_1 = match['gather0_1']
- gather0_2 = match['gather0_2']
- greaterequal0 = match['greaterequal0']
- sparse_fill_empty_rows = match['sparse_fill_empty_rows']
- gather = match['gather']
- select = match['select']
- where0 = match['where0']
- sparse_segment_op = match['sparse_segment_op']
- output_node_name = select.soft_get('name', select.id)
-
- log.debug('Found EmbeddingSparseSegmentsMultipleFeatures pattern after {} with name {}'.format(
- sparse_fill_empty_rows.op,
- sparse_fill_empty_rows.name))
-
- split_for_indices = create_op_with_const_inputs(graph, Split, {1: int64_array(1)},
- {'num_splits': 2,
- 'name': output_node_name + '/SplitForIndices'})
- squeeze_for_indices = create_op_with_const_inputs(graph, Squeeze, {1: int64_array([1])})
- split_for_dense_shape = create_op_with_const_inputs(graph, Split, {1: int64_array(0)},
- {'num_splits': 2,
- 'name': output_node_name + '/SplitForDenseShape'})
- squeeze_to_scalar = create_op_with_const_inputs(graph, Squeeze, {1: int64_array([0])})
-
- # TODO: remove Cast nodes once we start to support EmbeddingSegmentSum (new version) with segment_ids,
- # indices, and num_segments of different integer type.
- # Because the real cases show that it is possible to have it in TensorFlow
- cast_indices = Cast(graph, {'name': output_node_name + '/CastIndices', 'dst_type': np.int32}).create_node()
- cast_segment_ids = Cast(graph, {'name': output_node_name + '/CastSegmentIds',
- 'dst_type': np.int32}).create_node()
- cast_default_value = Cast(graph, {'name': output_node_name + '/CastDefaultValue',
- 'dst_type': np.int32}).create_node()
- cast_num_segments = Cast(graph, {'name': output_node_name + '/CastSegmentsNumber',
- 'dst_type': np.int32}).create_node()
-
- if sparse_segment_op.op == 'SparseSegmentSum':
- embedding_segments_op = EmbeddingSegmentsSum(graph, {'name': output_node_name}).create_node()
- else:
- embedding_segments_op = EmbeddingSegmentsMean(graph, {'name': output_node_name}).create_node()
- rename_nodes([(select, output_node_name + '/AbandonedName'), (embedding_segments_op, output_node_name)])
-
- # connect parameters table
- gather.in_port(0).get_connection().set_destination(embedding_segments_op.in_port(0))
- # connect indices values
- greaterequal0.in_port(0).get_connection().set_destination(cast_indices.in_port(0))
- embedding_segments_op.in_port(1).connect(cast_indices.out_port(0))
- # split and connect segment ids
- gather0_1.in_port(0).get_connection().set_destination(split_for_indices.in_port(0))
- squeeze_for_indices.in_port(0).connect(split_for_indices.out_port(0))
- cast_segment_ids.in_port(0).connect(squeeze_for_indices.out_port(0))
- embedding_segments_op.in_port(2).connect(cast_segment_ids.out_port(0))
- # split and connect number of segments
- identity_spw.in_port(0).get_connection().set_destination(split_for_dense_shape.in_port(0))
- squeeze_to_scalar.in_port(0).connect(split_for_dense_shape.out_port(0))
- cast_num_segments.in_port(0).connect(squeeze_to_scalar.out_port(0))
- embedding_segments_op.in_port(3).connect(cast_num_segments.out_port(0))
- # connect default value
- sparse_fill_empty_rows.in_port(3).get_connection().set_destination(cast_default_value.in_port(0))
- embedding_segments_op.in_port(4).connect(cast_default_value.out_port(0))
- # no input port for per_sample_weight
-
- identity_spw.in_port(0).disconnect()
- gather0_1.in_port(0).disconnect()
- gather0_2.in_port(0).disconnect()
- greaterequal0.in_port(0).disconnect()
- sparse_fill_empty_rows.in_port(2).disconnect()
- gather.in_port(0).disconnect()
-
- select.out_port(0).get_connection().set_source(embedding_segments_op.out_port(0))
- graph.remove_nodes_from([gather0_1.id, gather0_2.id, greaterequal0.id, sparse_fill_empty_rows.id,
- select.id, where0.id])
diff --git a/tools/mo/openvino/tools/mo/front/tf/expand_dims_ext.py b/tools/mo/openvino/tools/mo/front/tf/expand_dims_ext.py
deleted file mode 100644
index 8e40ca397774c7..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/expand_dims_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class ExpandDimsExtractor(FrontExtractorOp):
- """
- Due to historical reasons the ExpandDims operation in the Model Optimizer has one input with data and the attribute
- which specifies the dimension to expand. But in the TensorFlow the ExpandDims operation has 2 inputs where the
- second input specifies the dimensions to expand. In the Model Optimizer this operation corresponds to the Unsqueeze.
- """
- op = 'ExpandDims'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Unsqueeze.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/extract_image_patches_ext.py b/tools/mo/openvino/tools/mo/front/tf/extract_image_patches_ext.py
deleted file mode 100644
index 9445d08ea73f44..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extract_image_patches_ext.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ExtractImagePatches import ExtractImagePatches
-from openvino.tools.mo.front.common.partial_infer.utils import convert_tf_padding_to_str
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_int_list
-
-
-class ExtractImagePatchesExtractor(FrontExtractorOp):
- op = 'ExtractImagePatches'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'spatial_dims': int64_array([1, 2]),
- 'sizes': tf_int_list(node.pb.attr['ksizes'].list),
- 'strides': tf_int_list(node.pb.attr['strides'].list),
- 'rates': tf_int_list(node.pb.attr['rates'].list),
- 'auto_pad': convert_tf_padding_to_str(node.pb.attr['padding'].s.decode()),
- }
-
- ExtractImagePatches.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractor.py b/tools/mo/openvino/tools/mo/front/tf/extractor.py
deleted file mode 100644
index eaf4468ee34b44..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractor.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.tf.extractors.concat import tf_concat_ext
-from openvino.tools.mo.front.tf.extractors.fused_bn import tf_fused_bn_extractor
-from openvino.tools.mo.front.tf.extractors.native_tf import native_tf_node_extractor
-from openvino.tools.mo.front.tf.extractors.pack import tf_pack_ext
-from openvino.tools.mo.front.tf.extractors.utils import get_tf_node_port
-from openvino.tools.mo.graph.graph import Node
-
-
-def get_tf_edges(node: Node):
- """
- By TF/NX node find all inputs and return list of all edges.
- Edge direction represents data flow (from source op to this node).
- So the resulting list contains all input edges for a given node.
- Edge attributes: 'in' is index of input port for a given node, 'out' is an index
- of output port of some other node that produces input data for this node.
- """
- edge_list = []
- for in_port, src_node_id in enumerate(node.pb.input):
- edge_list.append(create_tf_edge(src_node_id, node.id, in_port))
- return edge_list
-
-
-def create_tf_edge(src_node_id: str, dst_node_id: str, in_port: int):
- """
- Creates an edge for given nodes and input port.
- """
- src_node, src_port = get_tf_node_port(src_node_id)
- tensor_name = src_node + ":" + str(src_port)
- cf_flag = False
- if src_node[0] == '^':
- src_node = src_node[1:]
- cf_flag = True
- return (src_node, dst_node_id, {
- 'in': in_port,
- 'out': src_port,
- # debug anchor for a framework name, out port and tensor name
- 'fw_tensor_debug_info': [(src_node_id, tensor_name)],
- 'in_attrs': ['in', 'control_flow_edge', 'permutation'],
- 'out_attrs': ['out', 'permutation'],
- 'data_attrs': ['fw_tensor_debug_info'],
- 'control_flow_edge': cf_flag
- })
-
-
-def node_pb_arg(pb_extractor: callable):
- return lambda node: pb_extractor(node.pb)
-
-
-tf_op_extractors = {
- 'TFCustomSubgraphCall': node_pb_arg(lambda pb: None),
- 'FusedBatchNorm': node_pb_arg(tf_fused_bn_extractor),
- 'FusedBatchNormV2': node_pb_arg(tf_fused_bn_extractor),
- 'FusedBatchNormV3': node_pb_arg(tf_fused_bn_extractor),
- 'ConcatV2': node_pb_arg(tf_concat_ext),
- 'Pack': node_pb_arg(tf_pack_ext),
-}
-
-
-def common_tf_fields(node: Node):
- return {
- 'kind': 'op',
- 'name': node.pb.name,
- 'op': node.pb.op,
- }
-
-
-def tf_op_extractor(node: Node, lowered_keys_map: dict):
- # all required attributes for the 'TFCustomSubgraphCall' are set during their initialization
- if (node.has('op') and node.op == 'TFCustomSubgraphCall') or (not node.has_valid('pb')):
- return True, node.graph.node[node.id]
-
- result = common_tf_fields(node)
- node.graph.node[node.id].update(result)
- supported = False
- op = result['op'].lower()
- if op in lowered_keys_map:
- op = lowered_keys_map[op]
- assert op in tf_op_extractors
- attrs = tf_op_extractors[op](node)
- if attrs:
- result.update(attrs)
- supported = True
- new_attrs = native_tf_node_extractor(node.pb)
- new_attrs.update(result)
- result = new_attrs
- return supported, result
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/__init__.py b/tools/mo/openvino/tools/mo/front/tf/extractors/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/concat.py b/tools/mo/openvino/tools/mo/front/tf/extractors/concat.py
deleted file mode 100644
index afef7cb10de481..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/concat.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-
-
-def tf_concat_ext(pb):
- return {
- 'type': 'Concat',
- 'N': pb.attr["N"].i,
- 'infer': concat_infer
- }
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/fused_bn.py b/tools/mo/openvino/tools/mo/front/tf/extractors/fused_bn.py
deleted file mode 100644
index 8ca251a23cef66..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/fused_bn.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, reverse_bypass_infer, shape_array
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-def tf_fused_bn_infer(node):
- output_shape = mo_array(node.in_node(0).shape)
- for port, out_node in node.out_nodes().items():
- out_node.shape = shape_array(output_shape)
-
-
-def tf_fused_bn_extractor(pb):
- is_training = pb.attr['is_training'].b
- if is_training:
- log.warning('FusedBatchNorm doesn\'t support is_training=True')
-
- return {
- 'data_format': pb.attr["data_format"].s.decode(),
- 'data_type': tf_dtype_extractor(pb.attr["T"].type),
- 'eps': pb.attr['epsilon'].f,
- 'infer': tf_fused_bn_infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- 'is_training': is_training
- }
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/identity.py b/tools/mo/openvino/tools/mo/front/tf/extractors/identity.py
deleted file mode 100644
index 1e136bbab38fc4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/identity.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-
-
-def tf_identity_ext(pb):
- return {
- 'infer': copy_shape_infer
- }
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/native_tf.py b/tools/mo/openvino/tools/mo/front/tf/extractors/native_tf.py
deleted file mode 100644
index ce04ea0c0d38c2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/native_tf.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.tf.partial_infer.tf import tf_native_tf_node_infer
-
-
-def native_tf_node_extractor(pb):
- return {
- 'infer': tf_native_tf_node_infer,
- }
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/pack.py b/tools/mo/openvino/tools/mo/front/tf/extractors/pack.py
deleted file mode 100644
index e8fecf3e5a5296..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/pack.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-def tf_pack_ext(pb):
- assert (pb.attr["N"].i == len(pb.input))
- return {
- 'axis': pb.attr["axis"].i,
- 'N': pb.attr["N"].i,
- 'infer': None
- }
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/strided_slice.py b/tools/mo/openvino/tools/mo/front/tf/extractors/strided_slice.py
deleted file mode 100644
index ad1b81eed155b2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/strided_slice.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-def int_to_array_bit_mask(im):
- list_repr = list(np.binary_repr(im))
- list_repr.reverse()
- list_repr = [int(li) for li in list_repr]
- return mo_array(list_repr, dtype=np.int32)
-
-
-class StridedSliceFrontExtractor(FrontExtractorOp):
- op = 'StridedSlice'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.pb
- bm = int_to_array_bit_mask(pb.attr["begin_mask"].i)
- bm = mo_array([1 - b for b in bm], dtype=np.int32)
- em = int_to_array_bit_mask(pb.attr["end_mask"].i)
- em = mo_array([1 - b for b in em], dtype=np.int32)
- attrs = {
- 'begin_mask': bm,
- 'end_mask': em,
- 'ellipsis_mask': int_to_array_bit_mask(pb.attr["ellipsis_mask"].i),
- 'new_axis_mask': int_to_array_bit_mask(pb.attr["new_axis_mask"].i),
- 'shrink_axis_mask': int_to_array_bit_mask(pb.attr["shrink_axis_mask"].i),
- }
-
- StridedSlice.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/subgraph_utils.py b/tools/mo/openvino/tools/mo/front/tf/extractors/subgraph_utils.py
deleted file mode 100644
index 5f3df8af960bd9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/subgraph_utils.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import copy
-
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.front.tf.extractor import tf_op_extractor, tf_op_extractors, create_tf_edge
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-from openvino.tools.mo.graph.graph import Graph, Node, add_opoutput
-from openvino.tools.mo.ops.op import PermuteAttrs
-
-
-def update_body_graph(body_graph: Graph, subgraph_proto: dict,
- body_parameter_names: list, body_results: list):
- """
- Updates the loop body graph with a sub-graph (for body or condition functions)
- :param body_graph: a loop body graph to be updated
- :param subgraph_proto: a sub-graph in a protobuf format to be added into the loop body graph
- :param body_parameter_names: a (unchanged) list of parameters in the loop body graph
- :param body_results: a list of Result nodes that is extended with a list from a sub-graph
- """
- # create a map from a node name in original model to a name in a loop body graph assuming
- # that names in the original model are unique
- # initially, the map contains names for parameters that are common for the body and condition graphs
- map_original_name = {}
- for idx, pb_node in enumerate(subgraph_proto['input_arg']):
- map_original_name[pb_node.name] = body_parameter_names[idx]
-
- # walk through all nodes (non-parameter and non-result nodes) and add into the loop body graph
- for pb_node in subgraph_proto['node_def']:
- # create an NX node
- id = body_graph.unique_id(pb_node.name)
- map_original_name[pb_node.name] = id
- body_graph.add_node(id, pb=pb_node, kind='op')
- if hasattr(body_graph, 'op_names_statistic') and hasattr(pb_node, 'op'):
- body_graph.op_names_statistic[pb_node.op] += 1
-
- # add incoming edges based on data_nodes_map
- for dst_port, inp in enumerate(pb_node.input):
- orig_src_id = inp.split(":")[0]
-
- # TODO: avoid this temporal workaround for TF 2.4 or higher RNN layers:
- # skip control flow dependency
- if orig_src_id[0] == '^':
- continue
-
- src_id = map_original_name[orig_src_id]
- src_port = 0 if len(inp.split(":")) == 1 else int(inp.split(":")[-1])
- assert (body_graph.has_node(src_id))
-
- body_graph.add_edges_from([create_tf_edge(src_id + ":" + str(src_port), id, dst_port)])
-
- # create Result nodes in the loop body graph
- for output in subgraph_proto['output_arg']:
- output_name = subgraph_proto['ret'][output.name]
- orig_src_id = output_name.split(":")[0]
- src_id = map_original_name[orig_src_id]
- src_port = 0 if len(output_name.split(":")) == 1 \
- else int(output_name.split(":")[-1])
- assert body_graph.has_node(src_id), 'The body graph does not contain output with name "{}"'.format(
- src_id)
- body_results.append(Node(body_graph, add_opoutput(body_graph, src_id, src_port, False)))
-
- return True
-
-
-def get_graph_proto(external_graph: Graph, graph_id: str, node_with_graph: Node):
- graph_name = node_with_graph.pb.attr[graph_id].func.name
- node_name = node_with_graph.soft_get('name', node_with_graph.id)
-
- assert 'library' in external_graph.graph, 'The graph does not contain a library that is required ' \
- 'by node with name "{}".'.format(node_name)
-
- library_graph = external_graph.graph['library']
-
- assert graph_name in library_graph, 'The library does not contain a function with name "{}" ' \
- 'that is required by node ' \
- 'with name "{}".'.format(graph_name, node_name)
- return library_graph[graph_name]
-
-
-def create_internal_graph(external_graph: Graph):
- internal_graph = Graph()
- # fill the body graph
- for attr_key in external_graph.graph.keys():
- if attr_key != 'library':
- internal_graph.graph[attr_key] = copy.deepcopy(external_graph.graph[attr_key])
- else:
- # it is sufficient to have a link to the library
- internal_graph.graph['library'] = external_graph.graph['library']
- return internal_graph
-
-
-def convert_graph_inputs_to_parameters(internal_graph, internal_graph_proto):
- # create Parameter nodes for the body graph
- body_parameters = []
- body_parameter_names = []
- for idx, pb_node in enumerate(internal_graph_proto['input_arg']):
- param_id = internal_graph.unique_id(pb_node.name)
- internal_graph.add_node(param_id, name=param_id, kind='op', op='Parameter', pb=None, shape=None)
- parameter_node = Node(internal_graph, pb_node.name)
- Parameter.update_node_stat(parameter_node,
- {'data_type': tf_dtype_extractor(pb_node.type),
- 'permute_attrs': PermuteAttrs().update_attrs(attrs=[('shape', 'output:0')])}
- )
- body_parameters.append(parameter_node)
- body_parameter_names.append(param_id)
- return body_parameters, body_parameter_names
diff --git a/tools/mo/openvino/tools/mo/front/tf/extractors/utils.py b/tools/mo/openvino/tools/mo/front/tf/extractors/utils.py
deleted file mode 100644
index 9f0f835a0a075d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/extractors/utils.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value
-from openvino.tools.mo.front.tf.common import tf_data_type_decode
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-def tf_tensor_shape(pb):
- return shape_array([dim.size if dim.size >= 0 else dynamic_dimension_value for dim in pb.dim])
-
-
-def tf_int_list(pb):
- return int64_array(pb.i)
-
-
-def tf_dtype_extractor(pb_dtype, default=None):
- return tf_data_type_decode[pb_dtype][0] if pb_dtype in tf_data_type_decode else default
-
-
-def tf_data_format_spatial(pb):
- if b"DHW" in pb.s:
- return [pb.s.index(c) for c in b"DHW"]
- return [pb.s.index(c) for c in b"HW"]
-
-
-def tf_data_format_channel(pb):
- return [pb.s.index(b'C')]
-
-
-def tf_data_format_batch(pb):
- return [pb.s.index(b'N')]
-
-
-def get_tf_node_port(tensor):
- delim = ':'
- # tensor should have form 'name:port' or just 'name'
- name_parts = tensor.split(delim)
- if len(name_parts) == 1:
- # just 'name', then port is 0 by default
- return name_parts[0], 0
- else:
- # 'name:port', note name can contain ':' also but port is the last part
- # TODO Is 'name' that contains other ':'s considered valid by TF?
- return delim.join(name_parts[:-1]), int(name_parts[-1])
-
-
-def tf_tensor_content(tf_dtype, shape, pb_tensor):
- type_helper = tf_data_type_decode[tf_dtype] if tf_dtype in tf_data_type_decode else None
- if type_helper is None:
- raise Error("Data type is unsupported: {}. " +
- refer_to_faq_msg(50), tf_dtype)
-
- decode_err_msg = 'Failed to parse a tensor with Unicode characters. Note that OpenVINO does not support ' \
- 'string literals, so the string constant should be eliminated from the graph.'
- if pb_tensor.tensor_content:
- value = mo_array(np.frombuffer(pb_tensor.tensor_content, type_helper[0]))
- else:
- # load typed value
- if type_helper[0] != str:
- value = mo_array(type_helper[1](pb_tensor), dtype=type_helper[0])
- else:
- try:
- value = mo_array(type_helper[1](pb_tensor), dtype=type_helper[0])
- except UnicodeDecodeError:
- log.error(decode_err_msg, extra={'is_warning': True})
- value = mo_array(type_helper[1](pb_tensor))
-
- # Ignore an empty value, if len(shape) > 1
- # For example, value = [] and shape = [1, 1, 0]
- # This is needed to reshape this value later and to return reshaped value = [[[]]]
- # Otherwise there can be failures during partial inference, because we are storing an empty value with incorrect
- # shape
- if len(shape) == 0 or (len(shape) == 1 and shape.prod() == 0):
- try:
- value_length = len(value)
- except TypeError:
- # case, when value is a scalar
- return value
- if value_length == 1:
- # return scalar if shape is [] otherwise broadcast according to shape
- try:
- return mo_array(value[0], dtype=type_helper[0])
- except UnicodeDecodeError:
- log.error(decode_err_msg, extra={'is_warning': True})
- return mo_array(value[0])
- else:
- if len(shape) == 0 and value_length == 0:
- # Since TF 2.10 the model freezing can produce constants with non-empty tensor
- # but with undefined value []
- # in this case, the tensor is filled with the default value
- # that is 0 for numeric types and "" for string
- default_value = 0 if type_helper[0] != str else ""
- value = mo_array(default_value, dtype=type_helper[0])
- # no shape, return value as is
- return value
-
- if len(value) != shape.prod():
- log.warning("Shape and content size of tensor don't match, shape: {} content size: {}".
- format(shape, len(value)))
-
- if len(value) == 0:
- # Since TF 2.10 the model freezing can produce constants with non-empty tensor but with undefined value []
- # In this case, the tensor is filled with the default value that is 0 for numeric types and "" for string
- default_value = 0 if type_helper[0] != str else ""
- value_flatten = mo_array([default_value], dtype=type_helper[0])
- else:
- value_flatten = value.flatten()
-
- # broadcast semantics according to TensorFlow v1.5 documentation:
- # The argument value can be a constant value, or a list of values of type dtype. If value is a list,
- # then the length of the list must be less than or equal to the number of elements implied by the shape
- # argument (if specified). In the case where the list length is less than the number of elements specified
- # by shape, the last element in the list will be used to fill the remaining entries.
- add_value = value_flatten[-1]
- add_length = shape.prod() - len(value_flatten)
- value = np.concatenate([value_flatten, np.full([add_length], add_value)])
-
- return value.reshape(shape)
-
-
-def check_attr_type(a):
- """
- Check type of attribute from TF prototxt message
- param: a - attribute from TF prototxt message
- return: type of attribute
- """
- if a.s:
- return 's'
- if a.i:
- return 'i'
- if a.f:
- return 'f'
- if a.b:
- return 'b'
- if a.type:
- return 'type'
- if a.shape and a.shape.dim:
- return 'shape'
- if a.list:
- return 'list'
-
-
-def collect_tf_attrs(attrs):
- """
- Function generates map for attributes and parsing functions
- param: attrs - TF proto message with attributes
- return: mapping attributes and parsing functions ready for use in update_node_stat function
- """
- ret_attrs = {}
- type_parsers = {
- 's': lambda x: x.s,
- 'i': lambda x: x.i,
- 'f': lambda x: x.f,
- 'b': lambda x: x.b,
- 'type': lambda x: tf_dtype_extractor(x.type),
- 'shape': lambda x: tf_tensor_shape(x.shape),
- 'list': lambda x: x.list
- }
-
- for a in attrs:
- t = check_attr_type(attrs[a])
- a_l = attrs[a]
- while t == 'list':
- a_l = type_parsers[t](attrs[a])
- t = check_attr_type(a_l)
-
- ret_attrs[a] = type_parsers[t](a_l)
-
- return ret_attrs
diff --git a/tools/mo/openvino/tools/mo/front/tf/eye_ext.py b/tools/mo/openvino/tools/mo/front/tf/eye_ext.py
deleted file mode 100644
index 650d7fd18a483f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/eye_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.eye import TFEye
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class EyeExtractor(FrontExtractorOp):
- op = 'Eye'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'output_type': tf_dtype_extractor(node.pb.attr["dtype"].type),
- }
- TFEye.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/eye_tf_to_eye.py b/tools/mo/openvino/tools/mo/front/tf/eye_tf_to_eye.py
deleted file mode 100644
index 5c89279dd84a2e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/eye_tf_to_eye.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph, rename_node
-from openvino.tools.mo.ops.eye import Eye
-from openvino.tools.mo.utils.error import Error
-
-
-class EyeTFToEye(FrontReplacementPattern):
- """
- This transformation converts TFEye operation (TensorFlow semantic) to Eye operation (OpenVINO semantic).
- Refer to the Op implementation for the operations semantics description.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for tfeye in graph.get_op_nodes(op='TFEye'):
- # save the original node name to use it in the new Eye op instance
- original_name = tfeye.soft_get('name', tfeye.id)
- tfeye['name'] = original_name + '/to_be_removed'
-
- if not tfeye.has_valid('output_type'):
- raise Error("TFEye should have valid ''output_type'' attribute.")
- output_type = tfeye.soft_get('output_type')
-
- new_eye = Eye(graph, {'output_type': output_type}).create_node()
- rename_node(new_eye, original_name)
-
- # num_rows
- tfeye.in_port(0).get_connection().set_destination(new_eye.in_port(0))
- # num_columns
- if not tfeye.in_port(1).disconnected:
- tfeye.in_port(1).get_connection().set_destination(new_eye.in_port(1))
- # batch_shape
- if not tfeye.in_port(2).disconnected:
- tfeye.in_port(2).get_connection().set_destination(new_eye.in_port(3))
-
- diagonal_index = Const(graph, {'name': original_name + '/diagonal_index',
- 'value': 0}).create_node()
- diagonal_index.out_port(0).connect(new_eye.in_port(2))
-
- tfeye.out_port(0).get_connection().set_source(new_eye.out_port(0))
- graph.remove_node(tfeye.id)
diff --git a/tools/mo/openvino/tools/mo/front/tf/fake_const_ext.py b/tools/mo/openvino/tools/mo/front/tf/fake_const_ext.py
deleted file mode 100644
index 5b2cbb35fa7c52..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/fake_const_ext.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class FakeConstToConst(FrontReplacementOp):
- op = "FakeConst"
- enabled = True
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- node = match['op']
- if not node.has_valid('value'):
- log.debug("No value in FakeConst node {}".format(node.id))
- return
- node_value = node.value
- extracted_attrs = {
- 'data_type': tf_dtype_extractor(node.pb.attr['dtype'].type),
- 'shape': int64_array(node_value.shape),
- 'value': node_value
- }
- Const.update_node_stat(node, extracted_attrs)
- log.debug('FakeConst op was translated to Const op with shape = {} and value.shape = {}'
- ''.format(extracted_attrs['shape'], extracted_attrs['value'].shape))
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support.json
deleted file mode 100644
index d143ae53000f94..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support.json
+++ /dev/null
@@ -1,112 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "FirstStageBoxPredictor/Reshape",
- "FirstStageBoxPredictor/Reshape_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes,detection_scores,num_detections"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.10.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.10.json
deleted file mode 100644
index 94e0d871e6a648..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.10.json
+++ /dev/null
@@ -1,113 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes,detection_scores,num_detections"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.13.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.13.json
deleted file mode 100644
index 1ce6b0a59a76c9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.13.json
+++ /dev/null
@@ -1,113 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes,detection_scores,num_detections"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.14.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.14.json
deleted file mode 100644
index 8439fa05e9f2ff..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.14.json
+++ /dev/null
@@ -1,113 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_5/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes,detection_scores,num_detections"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.15.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.15.json
deleted file mode 100644
index 3c45df9133e74e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.15.json
+++ /dev/null
@@ -1,113 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_5/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat/concat",
- "concat_1/concat",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes,detection_scores,num_detections"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.7.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.7.json
deleted file mode 100644
index f6ab3ff3195c36..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v1.7.json
+++ /dev/null
@@ -1,113 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes,detection_scores,num_detections"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v2.0.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v2.0.json
deleted file mode 100644
index 3a4c575272cdc8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v2.0.json
+++ /dev/null
@@ -1,82 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/Preprocessor/unstack"],
- "end_nodes": ["StatefulPartitionedCall/Preprocessor/stack",
- "StatefulPartitionedCall/Preprocessor/stack_1"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/stack_3",
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression/stack_10",
- "StatefulPartitionedCall/Shape"
- ],
- "start_points": [
- "StatefulPartitionedCall/concat/concat",
- "StatefulPartitionedCall/concat_1/concat",
- "StatefulPartitionedCall/GridAnchorGenerator/Identity",
- "StatefulPartitionedCall/Cast_1",
- "StatefulPartitionedCall/Cast_2",
- "StatefulPartitionedCall/Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true,
- "background_label_id": 0
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "Cast_3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/SecondStagePostprocessor/Cast_3"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v2.4.json b/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v2.4.json
deleted file mode 100644
index 01d4f2facbbba6..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/faster_rcnn_support_api_v2.4.json
+++ /dev/null
@@ -1,82 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/map/TensorArrayUnstack/TensorListFromTensor"],
- "end_nodes": ["StatefulPartitionedCall/map/TensorArrayV2Stack/TensorListStack",
- "StatefulPartitionedCall/map/TensorArrayV2Stack_1/TensorListStack"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/stack_3",
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression/stack_10",
- "StatefulPartitionedCall/Shape"
- ],
- "start_points": [
- "StatefulPartitionedCall/concat/concat",
- "StatefulPartitionedCall/concat_1/concat",
- "StatefulPartitionedCall/GridAnchorGenerator/Identity",
- "StatefulPartitionedCall/Cast_1",
- "StatefulPartitionedCall/Cast_2",
- "StatefulPartitionedCall/Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true,
- "background_label_id": 0
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "Cast_3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/SecondStagePostprocessor/Cast_3"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/fft_ext.py b/tools/mo/openvino/tools/mo/front/tf/fft_ext.py
deleted file mode 100644
index 3e80fe208c69b2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/fft_ext.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.TFFFT import TFFFT
-
-
-class FFT1DOpFrontExtractor(FrontExtractorOp):
- op = 'FFT'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 1, 'fft_kind': 'DFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class FFT2DOpFrontExtractor(FrontExtractorOp):
- op = 'FFT2D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 2, 'fft_kind': 'DFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class FFT3DOpFrontExtractor(FrontExtractorOp):
- op = 'FFT3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 3, 'fft_kind': 'DFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class IFFT1DOpFrontExtractor(FrontExtractorOp):
- op = 'IFFT'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 1, 'fft_kind': 'IDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class IFFT2DOpFrontExtractor(FrontExtractorOp):
- op = 'IFFT2D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 2, 'fft_kind': 'IDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class IFFT3DOpFrontExtractor(FrontExtractorOp):
- op = 'IFFT3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 3, 'fft_kind': 'IDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class RFFT1DOpFrontExtractor(FrontExtractorOp):
- op = 'RFFT'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 1, 'fft_kind': 'RDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class RFFT2DOpFrontExtractor(FrontExtractorOp):
- op = 'RFFT2D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 2, 'fft_kind': 'RDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class RFFT3DOpFrontExtractor(FrontExtractorOp):
- op = 'RFFT3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 3, 'fft_kind': 'RDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class IRFFT1DOpFrontExtractor(FrontExtractorOp):
- op = 'IRFFT'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 1, 'fft_kind': 'IRDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class IRFFT2DOpFrontExtractor(FrontExtractorOp):
- op = 'IRFFT2D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 2, 'fft_kind': 'IRDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class IRFFT3DOpFrontExtractor(FrontExtractorOp):
- op = 'IRFFT3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'num_of_dimensions': 3, 'fft_kind': 'IRDFT'}
- TFFFT.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/fifo_queue_v2_ext.py b/tools/mo/openvino/tools/mo/front/tf/fifo_queue_v2_ext.py
deleted file mode 100644
index 781ef7067d0e60..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/fifo_queue_v2_ext.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-from openvino.tools.mo.ops.op import Op
-
-
-class FIFOQueueV2Extractor(FrontExtractorOp):
- op = 'FIFOQueueV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- shapes = node.pb.attr['shapes'].list.shape
- tf_types = node.pb.attr['component_types'].list.type
- extracted_types = []
- for t in tf_types:
- extracted_types.append(tf_dtype_extractor(t))
- result_shapes = []
- for shape_pb in shapes:
- shape = shape_pb.dim
- if len(shape) == 3:
- result_shapes.append(int64_array([1, shape[0].size, shape[1].size, shape[2].size]))
- else:
- result_shapes.append(int64_array([dim.size for dim in shape]))
- Op.update_node_stat(node, {'shapes': result_shapes, 'types': extracted_types})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/fifo_replacer.py b/tools/mo/openvino/tools/mo/front/tf/fifo_replacer.py
deleted file mode 100644
index 561e98328070a9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/fifo_replacer.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from collections import defaultdict
-
-import numpy as np
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph, FrontReplacementPattern
-from openvino.tools.mo.front.extractor import add_input_ops
-from openvino.tools.mo.front.output_cut import OutputCut
-from openvino.tools.mo.front.user_data_repack import UserDataRepack
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_precision, SUPPORTED_DATA_TYPES
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.utils.error import Error
-
-
-class FIFOQueue(FrontReplacementSubgraph):
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.override_batch import OverrideBatch
- return [OverrideBatch]
-
- @staticmethod
- def pattern(**kwargs):
- return dict(
- nodes=[
- ('placeholder', dict(op='Parameter', data_type=np.int32)),
- ('fifo_queue', dict(op='FIFOQueueV2')),
- ('batch_join', dict(op='QueueDequeueUpToV2')),
- ('image_batch', dict(op='Identity', data_type=np.float32))
- ],
- edges=[
- ('placeholder', 'batch_join', {'out': 0}),
- ('fifo_queue', 'batch_join', {'out': 0}),
- ('batch_join', 'image_batch', {'out': 0})
- ]
- )
-
- @staticmethod
- def replace_sub_graph(graph: Graph, match: dict, **kwargs):
- r"""
- Usually graph looks like:
-
- main_graph
- ... Result
- | |
- image_batch label_batch
- \ /
- batch_join
- / \
- placeholder fifo_queue
-
- Replacer works for both cases (that's why we have loop - 68 line):
- label_batch was marked as output
- there is no label_batch node
- """
- true_placeholder_shape = match['placeholder'].shape
- placeholder_shape = match['fifo_queue'].shapes[0]
- placeholder_data_type = match['fifo_queue'].types[0]
- # in case OOB conversion batch_size placeholder shape is not required
- # so use a shape specified in FIFOQueueV2 shapes list attribute
- assert true_placeholder_shape is None or true_placeholder_shape.ndim <= 1
- if true_placeholder_shape is not None and true_placeholder_shape.ndim == 1 and len(true_placeholder_shape) > 1:
- log.warning(
- 'Placeholder \'{}\' got non 0-dimensional shape {} in FIFOQueue pattern. Placeholder will have the '
- 'same shape after folding the pattern instead of {} shape which is original for the network.'
- ''.format(match['placeholder'].id, true_placeholder_shape, placeholder_shape))
- placeholder_shape = true_placeholder_shape
- placeholder_name = match['fifo_queue'].name
- graph.erase_node(match['fifo_queue'])
- graph.erase_node(match['placeholder'])
- for _, out in match['batch_join'].out_nodes().items():
- if out.id != match['image_batch'].id:
- if out.out_node().op == 'Result':
- graph.remove_node(out.out_node().id)
- graph.remove_node(out.id)
- graph.remove_node(match['batch_join'].id)
- placeholder = Parameter(graph, {'name': placeholder_name, 'shape': placeholder_shape,
- 'data_type': placeholder_data_type}).create_node()
- graph.create_edge(placeholder, match['image_batch'])
- log.info("FIFOQueueV2 pattern was detected. New shape of placeholder {} is {}. Use -b to set batch size if "
- "needed".format(placeholder.id, placeholder['shape']))
-
-
-class QueueDequeueManyV2(FrontReplacementSubgraph):
- """
- Replaces the combination of the FIFOQueueV2 + QueueDequeueManyV2 operations with a number of Placeholders.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.override_batch import OverrideBatch
- return [OverrideBatch]
-
- @staticmethod
- def pattern(**kwargs):
- return dict(
- nodes=[
- ('fifo_queue', dict(op='FIFOQueueV2')),
- ('queue_deque', dict(op='QueueDequeueManyV2')),
- ],
- edges=[
- ('fifo_queue', 'queue_deque', {'out': 0}),
- ]
- )
-
- @staticmethod
- def replace_sub_graph(graph: Graph, match: dict, **kwargs):
- inputs_dict = {}
- for u, v, edge_attrs in graph.out_edges(match['queue_deque'].id, data=True):
- out_port = edge_attrs['out']
- shape = match['fifo_queue'].shapes[out_port]
- if out_port not in inputs_dict:
- input_op = Parameter(graph, {'shape': shape.copy()})
- inputs_dict[out_port] = input_op.create_node([])
- graph.create_edge(inputs_dict[out_port], Node(graph, v), edge_attrs['out'], edge_attrs['in'], edge_attrs)
-
- graph.remove_node(match['queue_deque'].id)
- graph.remove_node(match['fifo_queue'].id)
-
-
-class FIFOQueueDequeueCut(FrontReplacementPattern):
- """
- Cuts FIFOQueue -> QueueDequeue pattern in order to enable Out Of the Box (OOB) usage.
- Pass runs only if user didn't specify any input names and shapes.
- This transformation relies on output shapes and types extracted from QueueDequeue node.
- In the meantime, the transformations FIFOQueue and QueueDequeueManyV2 expects output shapes and types extracted
- from FIFOQueue node.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['cmd_params'].input is None]
-
- def run_before(self):
- return [OutputCut]
-
- def run_after(self):
- return [UserDataRepack]
-
- def find_and_replace_pattern(self, graph: Graph):
- fifo_qd_shapes = defaultdict(list)
- for node in graph.get_op_nodes():
- if node.op not in ["QueueDequeue", "QueueDequeueV2"]:
- continue
-
- new_inputs = ""
- fifo_qd_name = node.soft_get('name', node.id)
- for port_idx, port in node.out_ports().items():
- if port.disconnected():
- continue
- if not np_data_type_to_precision(node.types[port_idx]) in SUPPORTED_DATA_TYPES:
- raise Error("Data type {} is not supported for the"
- "node {}".format(node.types[port_idx], fifo_qd_name))
-
- fifo_qd_shapes[fifo_qd_name].append(dict(
- shape=node.shapes[port_idx],
- out=port_idx,
- data_type=node.types[port_idx]
- ))
- new_inputs += "{}:{}, ".format(fifo_qd_name, port_idx)
-
- log.error(
- "Found TF {} operation in the model. "
- "PLEASE NOTE, the model will contain new input(s) ".format(node.op)
- + new_inputs +
- "created due to automatically triggered pruning transformation for this operation.",
- extra={'is_warning': True}
- )
-
- add_input_ops(graph, fifo_qd_shapes, True)
diff --git a/tools/mo/openvino/tools/mo/front/tf/fill_ext.py b/tools/mo/openvino/tools/mo/front/tf/fill_ext.py
deleted file mode 100644
index 637883011af8a1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/fill_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.fill import Fill
-
-
-class FillExtractor(FrontExtractorOp):
- op = 'Fill'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Fill.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/floor_div_decomposition.py b/tools/mo/openvino/tools/mo/front/tf/floor_div_decomposition.py
deleted file mode 100644
index d352435f6ba2e4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/floor_div_decomposition.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import Floor
-from openvino.tools.mo.ops.elementwise import Div
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph, Node, rename_node
-
-
-class FloorDivDecomposition(FrontReplacementPattern):
- r"""
- BEFORE: AFTER:
- input_0 input_1 input_0 input_1
- \ / \ /
- FloorDiv Div
- | |
- output Floor
- |
- output
- """
- enabled = True
-
- @staticmethod
- def floor_div_replacement(floor_div: Node):
- graph = floor_div.graph
- name = floor_div.soft_get('name', floor_div.id)
-
- div = Div(graph, {'name': name + '/Div'}).create_node()
- floor = Floor(graph, {'name': name}).create_node()
- div.out_port(0).connect(floor.in_port(0))
-
- div.in_port(0).connect(floor_div.in_port(0).get_source())
- div.in_port(1).connect(floor_div.in_port(1).get_source())
- floor_div.out_port(0).get_connection().set_source(floor.out_port(0))
-
- graph.remove_node(floor_div.id)
- rename_node(floor, name)
-
- def find_and_replace_pattern(self, graph: Graph):
- for floor_div in graph.get_op_nodes(op='FloorDiv'):
- self.floor_div_replacement(floor_div)
diff --git a/tools/mo/openvino/tools/mo/front/tf/floor_ext.py b/tools/mo/openvino/tools/mo/front/tf/floor_ext.py
deleted file mode 100644
index ad64fcea20e39f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/floor_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import Floor
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class FloorExtractor(FrontExtractorOp):
- op = 'Floor'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Floor.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/gather_ext.py b/tools/mo/openvino/tools/mo/front/tf/gather_ext.py
deleted file mode 100644
index 1a11b05ac7d84b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/gather_ext.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.gather import Gather, AttributedGather
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class GatherFrontExtractor(FrontExtractorOp):
- op = 'Gather'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedGather.update_node_stat(node, {'axis': 0})
- return cls.enabled
-
-
-class ResourceGatherFrontExtractor(FrontExtractorOp):
- op = 'ResourceGather'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- AttributedGather.update_node_stat(node, {'axis': 0})
- return cls.enabled
-
-
-class GatherV2FrontExtractor(FrontExtractorOp):
- op = 'GatherV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Gather.update_node_stat(node, {'batch_dims': node.pb.attr['batch_dims'].i})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/gathernd_ext.py b/tools/mo/openvino/tools/mo/front/tf/gathernd_ext.py
deleted file mode 100644
index f0672ec5750651..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/gathernd_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.gathernd import GatherND
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class GatherNDFrontExtractor(FrontExtractorOp):
- op = 'GatherNd'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'batch_dims': 0,
- }
- GatherND.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/graph_utils.py b/tools/mo/openvino/tools/mo/front/tf/graph_utils.py
deleted file mode 100644
index 723eb9619ded6f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/graph_utils.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from typing import Dict
-
-import numpy as np
-
-from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import mark_input_as_in_correct_layout, \
- mark_output_as_in_correct_layout
-from openvino.tools.mo.ops.activation_ops import Sigmoid
-from openvino.tools.mo.ops.elementwise import Add, Less, Mul
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.softmax import Softmax
-from openvino.tools.mo.utils.error import Error
-
-
-def create_op_node_with_second_input(graph: Graph, op: callable, second_input_value: np.array, op_attrs=None,
- input_node=None):
- operation = op(graph, op_attrs)
- node = operation.create_node()
- if input_node is not None:
- input_node.out_port(0).connect(node.in_port(0))
- second_input_node = Const(graph, {'name': node.name + '/value', 'value': second_input_value}).create_node()
- second_input_node.out_port(0).connect(node.in_port(1))
- if graph.stage != 'front':
- second_input_node.infer(second_input_node)
- return node
-
-
-def create_op_with_const_inputs(graph: Graph, op: callable, port_value_dict: Dict[int, np.array],
- op_attrs=None, input_node=None):
- operation = op(graph, op_attrs)
- node = operation.create_node()
- if input_node is not None:
- input_node.out_port(0).connect(node.in_port(0))
-
- for idx, value in port_value_dict.items():
- node.add_input_port(idx, skip_if_exist=True)
- value_input_node = Const(graph, {'name': node.name + '_input_port_' + str(idx) + '/value',
- 'value': value}).create_node()
- value_input_node.out_port(0).connect(node.in_port(idx))
- if graph.stage != 'front':
- value_input_node.infer(value_input_node)
- return node
-
-
-def add_convolution_to_swap_xy_coordinates(graph: Graph, input_node: Node, coordinates_size: int):
- """
- The function add convolution node after the node 'input_node' to swap xy coordinates of the boxes produced
- by the node 'input_node'. It is expected that box coordinates are located in the fastest changing dimension of the
- 'input_node' output, i.e. the input tensor could be reshaped to [num_boxes, 4] or [num_boxes, 5]. If the size is 5,
- then the 0-th element for each of num_boxes blocks is not changed and element 1 is swapped with element 2, element 3
- is swapped with element 4. This is the case when boxes coordinates are produced by the layer "Proposal". The exact
- amount of elements in each block is equal to the 'coordinates_size' parameter.
- :param graph: graph to operate on.
- :param input_node: node producing boxes coordinates.
- :param coordinates_size: integer value equal to 4 or 5.
- :return convolution node that swaps coordinates.
- """
- # swap of input tensor with 4 or 5 numbers describing boxes are supported
- assert (coordinates_size in [4, 5])
-
- input_reshape_4d_node = create_op_node_with_second_input(graph, Reshape, int64_array([-1, 1, 1, coordinates_size]),
- dict(name=input_node.name + '/reshape_4d'), input_node)
- mark_input_as_in_correct_layout(input_reshape_4d_node, 0)
- # do not mark second input because the reshape works in initial model layout and needs to be transformed to NCHW
- mark_output_as_in_correct_layout(input_reshape_4d_node, 0)
-
- if coordinates_size == 5:
- # zero indexed element is not box coordinate ("batch id" in case of Proposal)
- conv_filter_data = mo_array(mo_array([[[[1, 0, 0, 0, 0],
- [0, 0, 1, 0, 0],
- [0, 1, 0, 0, 0],
- [0, 0, 0, 0, 1],
- [0, 0, 0, 1, 0]]]],
- dtype=np.float32))
- else:
- conv_filter_data = mo_array(mo_array([[[[0, 1, 0, 0],
- [1, 0, 0, 0],
- [0, 0, 0, 1],
- [0, 0, 1, 0]]]],
- dtype=np.float32))
-
- conv_filter_data = np.transpose(conv_filter_data, [2, 3, 0, 1])
-
- conv_filter_const_op = Const(graph, dict(value=conv_filter_data))
- conv_filter_const_node = conv_filter_const_op.create_node([], dict(name=input_node.name + '/weights'))
-
- conv_op = Convolution(graph, {
- 'bias_addable': True,
- 'channel_dims': mo_array([3]),
- 'batch_dims': mo_array([0]),
- 'input_feature_channel': 0,
- 'output_feature_channel': 1,
- 'group': 1,
- 'layout': 'NHWC',
- })
- return conv_op.create_node([input_reshape_4d_node, conv_filter_const_node], dict(name=input_node.name + "/conv"))
-
-
-def add_fake_background_loc(graph: Graph, input_node: Node):
- r"""
- DetectionOutput layer expects that box coordinates contains coordinates of boxes for the "background" class also,
- but in the TensorFlow\* Object Detection API the tensor contains information about real object classes only.
- The function copies a slice of the output data of the node 'input_node' and then concats it to the beginning of the
- data. The data in this slice is not used by the Detection Output layer so the actual values are not important. This
- approach allows the model to be reshape-able and does not introduce many layers.
- "background" class box coordinates.
- :param graph: graph to operate on.
- :param input_node: node producing the boxes coordinates.
- :return convolution node that adds slice of data for the "background" class.
- """
- crop_op = Crop(graph, dict(axis=mo_array([1]), offset=mo_array([0]), dim=mo_array([1]), nchw_layout=True))
- crop_node = crop_op.create_node([input_node], dict(name='crop_locs'))
-
- concat_op = Concat(graph, dict(axis=1, in_ports_count=2, nchw_layout=True))
- return concat_op.create_node([crop_node, input_node], dict(name=input_node.id + '/locs_with_fake_background'))
-
-
-def add_activation_function_after_node(graph: Graph, node: Node, activation_function: str):
- """
- The function adds node with activation function defined by string 'activation_function' which gets input from the
- node 'node'.
- :param graph: graph to operate on.
- :param node: node to add activation after.
- :param activation_function: string defining the activation function. These values are read from TensorFlow* object
- detection API pipeline configuration file
- :return: activation function node.
- """
- if activation_function == 'SOFTMAX':
- # softmax to be applied to the confidence
- softmax_conf_op = Softmax(graph, dict(axis=-1, nchw_layout=True))
- activation_node = softmax_conf_op.create_node([node], dict(name=node.name + '/softmax'))
- elif activation_function == 'SIGMOID':
- # sigmoid activation function to be applied to the confidence
- sigmoid_conf_op = Sigmoid(graph, dict(nchw_layout=True))
- activation_node = sigmoid_conf_op.create_node([node], dict(name=node.name + '/sigmoid'))
- elif activation_function == 'IDENTITY':
- # in case of Identity do nothing and just use result from the input node
- activation_node = node
- else:
- raise Error('Unknown post-processing activation function "{}".'.format(activation_function))
- return activation_node
-
-
-def add_constant_to_negative_values(node: Node, port_idx: int, added_value: np.array):
- """
- This function adds the given values to negative elements of value from the given input port.
- :param node: node with corrected values in the input port port_idx
- :param port_idx: input port index for negative values
- :param added_value: the value to add
- :return: None
- """
- negative_values_source = node.in_port(port_idx).get_source()
- negative_values_node = node.in_port(port_idx).get_source().node
- negative_values_node_name = negative_values_node.soft_get('name', negative_values_node.id)
-
- graph = node.graph
-
- less_node = create_op_with_const_inputs(graph, Less,
- {1: mo_array(0, dtype=added_value.dtype)},
- {'name': negative_values_node_name + '/Less'})
- mul_node = create_op_with_const_inputs(graph, Mul, {1: added_value}, {'name': negative_values_node_name + '/Mul'})
-
- node.in_port(port_idx).get_connection().set_destination(less_node.in_port(0))
- less_node.out_port(0).connect(mul_node.in_port(0))
-
- add_node = Add(graph, {}).create_node()
- mul_node.out_port(0).connect(add_node.in_port(1))
- negative_values_source.connect(add_node.in_port(0))
- add_node.out_port(0).connect(node.in_port(port_idx))
diff --git a/tools/mo/openvino/tools/mo/front/tf/identityN_to_identity.py b/tools/mo/openvino/tools/mo/front/tf/identityN_to_identity.py
deleted file mode 100644
index cbef3a36ac9a91..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/identityN_to_identity.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.identity import Identity
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph, Node
-
-
-class IdentityN_to_Identity(FrontReplacementPattern):
- r"""
- Replaces IdentityN op with several Identity ops.
-
- Example:
- input_0 input_1 input_0 input_1
- \ / | |
- IdentityN Identity Identity
- / \ | |
- output_0 output_1 output_0 output_1
-
- ATTENTION: not all in/outputs of the IdentityN may survive during ModelOptimizer pipeline.
- And it breaks the original operation semantics.
- For example, output_1 may be not be used during network output computations.
- To preserve this unused in/output ports we disconnect the corresponding out/input port.
- """
- enabled = True
-
- @staticmethod
- def replace_identityN(node: Node):
- graph = node.graph
- name = node.soft_get('name', node.id)
-
- assert node.has_valid('data_types'), 'IdentityN {} has no `data_types` attribute'.format(name)
- dtypes = node.data_types
-
- for idx, port in node.in_ports().items():
- if not node.is_in_port_connected(idx) or not node.is_out_port_connected(idx):
- # ATTENTION section in the description above
- continue
- assert idx < len(dtypes), 'IdentityN {} has inconsistent `data_types` attribute {}'.format(name, dtypes)
- identity = Identity(graph, {'name': '{}/{}_port'.format(name, idx), 'data_type': dtypes[idx]}).create_node()
- port.get_connection().set_destination(identity.in_port(0))
- node.out_port(idx).get_connection().set_source(identity.out_port(0))
-
- # ATTENTION section in the description above
- for in_port in node.in_ports().values():
- in_port.disconnect()
- for out_port in node.out_ports().values():
- out_port.disconnect()
-
- def find_and_replace_pattern(self, graph: Graph):
- for identityN in graph.get_op_nodes(op='IdentityN'):
- self.replace_identityN(identityN)
diff --git a/tools/mo/openvino/tools/mo/front/tf/identity_ext.py b/tools/mo/openvino/tools/mo/front/tf/identity_ext.py
deleted file mode 100644
index 97e8b50503ac24..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/identity_ext.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.identity import Identity, IdentityN
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-from openvino.tools.mo.graph.graph import Node
-
-
-class IdentityFrontExtractor(FrontExtractorOp):
- op = 'Identity'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Identity.update_node_stat(node, {
- 'data_type': tf_dtype_extractor(node.pb.attr["T"].type),
- })
- return cls.enabled
-
-
-class IdentityNFrontExtractor(FrontExtractorOp):
- op = 'IdentityN'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- dtypes = [tf_dtype_extractor(t) for t in node.pb.attr["T"].list.type]
- IdentityN.update_node_stat(node, {
- 'data_types': dtypes,
- 'in_ports_count': len(dtypes),
- 'out_ports_count': len(dtypes),
- })
- return cls.enabled
-
-
-class ReadVariableOpFrontExtractor(FrontExtractorOp):
- op = 'ReadVariableOp'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Identity.update_node_stat(node, {
- 'data_type': tf_dtype_extractor(node.pb.attr["T"].type),
- })
- return cls.enabled
-
-
-class StopGradientExtractor(FrontExtractorOp):
- op = 'StopGradient'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Identity.update_node_stat(node, {'op': 'StopGradient'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/if_ext.py b/tools/mo/openvino/tools/mo/front/tf/if_ext.py
deleted file mode 100644
index f0aa3994816e35..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/if_ext.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.If import If
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.front.common.register_custom_ops import check_for_duplicates
-from openvino.tools.mo.front.extractor import FrontExtractorOp, extract_node_attrs
-from openvino.tools.mo.front.tf.extractor import tf_op_extractor, tf_op_extractors
-from openvino.tools.mo.front.tf.extractors.subgraph_utils import update_body_graph, convert_graph_inputs_to_parameters, \
- get_graph_proto, create_internal_graph
-from openvino.tools.mo.graph.graph import Node, Graph
-
-
-def extract_if(cls, if_node: Node):
- If.update_node_stat(if_node, {})
-
- # check that required body and condition functions exist in the graph library
- main_graph = if_node.graph
- then_graph_proto = get_graph_proto(main_graph, 'then_branch', if_node)
- else_graph_proto = get_graph_proto(main_graph, 'else_branch', if_node)
-
- then_graph = create_internal_graph(main_graph)
- if_node['then_graph'] = then_graph
-
- else_graph = create_internal_graph(main_graph)
- if_node['else_graph'] = else_graph
-
- # create Parameter nodes for the then/else graphs
- for input_index, (body_graph, body_graph_proto) in enumerate(zip((then_graph, else_graph), (then_graph_proto,
- else_graph_proto))):
-
- body_parameters, body_parameter_names = convert_graph_inputs_to_parameters(body_graph, body_graph_proto)
-
- # update the If body graph with the body function graph
- body_results = []
- update_body_graph(body_graph, body_graph_proto, body_parameter_names, body_results)
-
- body_graph.stage = 'front'
-
- # connect external input ports with body parameter nodes except input with condition
- for idx in range(0, len(body_parameters)):
- If.connect_body_input(if_node, not input_index, idx + 1, body_parameters[idx])
-
- # connect body outputs with If operation output ports
- for idx in range(len(body_results)):
- If.connect_body_output(if_node, not input_index, idx, body_results[idx])
-
- # run function to parse body nodes attributes similar to the main graph
- extract_node_attrs(body_graph, lambda node: tf_op_extractor(node, check_for_duplicates(tf_op_extractors)))
-
- return cls.enabled
-
-
-class IfExtractor(FrontExtractorOp):
- op = 'If'
- enabled = True
-
- @classmethod
- def extract(cls, if_node: Node):
- return extract_if(cls, if_node)
-
-
-class StatelessIfExtractor(FrontExtractorOp):
- op = 'StatelessIf'
- enabled = True
-
- @classmethod
- def extract(cls, if_node: Node):
- return extract_if(cls, if_node)
diff --git a/tools/mo/openvino/tools/mo/front/tf/loader.py b/tools/mo/openvino/tools/mo/front/tf/loader.py
deleted file mode 100644
index 4a7980eb86e00c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/loader.py
+++ /dev/null
@@ -1,383 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import logging as log
-import os
-import re
-from packaging.version import parse, Version
-from pathlib import Path
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error, FrameworkError
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-from openvino.tools.mo.utils.environment_setup_utils import get_environment_setup # pylint: disable=no-name-in-module,import-error
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-try:
- import tensorflow.compat.v1 as tf_v1
- import tensorflow as tf
- from tensorflow.python.framework.convert_to_constants import convert_variables_to_constants_v2
-except ImportError:
- import tensorflow as tf_v1
-
-# in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
-tf_v1.get_logger().setLevel("ERROR")
-
-from google.protobuf import text_format
-from openvino.tools.mo.graph.graph import fill_graph_with_nodes, Graph
-from openvino.tools.mo.utils.summarize_graph import summarize_graph
-
-
-def freeze_checkpoints(graph_def: tf_v1.GraphDef, checkpoint_dir: str, output_node_names: list):
- """
- Loads all the variables in a graph and stores them in a separate dictionary. Freezes output nodes in the graph
- :param graph_def: GraphDef object holding the network.
- :param checkpoint_dir: path to directory with checkpoint files with values of graph variables.
- :param output_node_names: list of output node names.
- :return: GraphDef containing a simplified version of the original.
- """
- log.debug("Loading checkpoint files from directory: {}".format(checkpoint_dir))
- checkpoint_files = []
- for checkpoint_name in sorted(os.listdir(checkpoint_dir)):
- checkpoint_path = os.path.join(checkpoint_dir, checkpoint_name)
- if os.path.isfile(checkpoint_path):
- checkpoint_files.append(checkpoint_path)
- log.debug("File {} will be loaded".format(checkpoint_path))
- else:
- log.debug("Path {} is not a file. Skipping")
-
- if len(checkpoint_files) == 0:
- raise Error("There are no checkpoint files in directory: {}".format(checkpoint_dir))
-
- tf_v1.import_graph_def(graph_def, name='')
-
- with tf_v1.Session() as sess:
- uninitialized_variables = [str(v, 'utf-8') for v in set(sess.run(tf_v1.report_uninitialized_variables()))]
- all_variables = [n.name for n in sess.graph.as_graph_def().node if n.op in ['Variable', 'VariableV2']]
- white_list = [v for v in all_variables if v not in uninitialized_variables]
- black_list = [v for v in all_variables if v in uninitialized_variables]
- output_graph_def = tf_v1.graph_util.convert_variables_to_constants(sess, graph_def, output_node_names,
- variable_names_whitelist=white_list,
- variable_names_blacklist=black_list)
- variable_values = {}
- for checkpoint_file in checkpoint_files:
- log.debug("Loading {}".format(checkpoint_file))
- with tf_v1.Session() as sess:
- var_list = {}
- var_to_shape_map = tf_v1.train.load_checkpoint(checkpoint_file).get_variable_to_shape_map()
- for key in var_to_shape_map:
- try:
- tensor = sess.graph.get_operation_by_name(key).outputs[0]
- except KeyError:
- continue
- var_list[key] = tensor
- tf_v1.train.Saver(var_list=var_list).restore(sess, checkpoint_file)
- for name, tensor in var_list.items():
- variable_values[name] = sess.run(tensor)
- return output_graph_def, variable_values
-
-
-def freeze_checkpoint(graph_def, checkpoint, output_node_names):
- """
- Replaces all the variables in a graph with constants of the same values.
- :param graph_def: GraphDef object holding the network.
- :param checkpoint: path to checkpoint file with values of variables.
- :param output_node_names: list of output node names
- :return: GraphDef containing a simplified version of the original.
- """
- tf_v1.import_graph_def(graph_def, name="")
-
- with tf_v1.Session() as sess:
- var_list = {}
- var_to_shape_map = tf_v1.train.NewCheckpointReader(checkpoint).get_variable_to_shape_map()
- for key in var_to_shape_map:
- try:
- tensor = sess.graph.get_operation_by_name(key).outputs[0]
- except KeyError:
- continue
- var_list[key] = tensor
- tf_v1.train.Saver(var_list=var_list).restore(sess, checkpoint)
- output_graph_def = tf_v1.graph_util.convert_variables_to_constants(sess, graph_def, output_node_names)
- return output_graph_def
-
-
-def read_file_to_graph_def(graph_def: [tf_v1.GraphDef, tf_v1.MetaGraphDef], graph_file_name: str = "",
- is_binary: bool = True):
- """
- Reads file to protobuf
- :param graph_def: GraphDef orr MetaGraphDef object to store the network
- :param graph_file_name: path to file with graph
- :param is_binary: flag to switch between binary and test protobuf format of graph file
- :return: GraphDef or MetaGaphDef containing the network with cleared device info.
- """
- try:
- if is_binary:
- with open(graph_file_name, "rb") as f:
- graph_def.ParseFromString(f.read())
- else:
- with open(graph_file_name, "r") as f:
- text_format.Merge(f.read(), graph_def)
- nodes_to_clear_device = graph_def.node if isinstance(graph_def, tf_v1.GraphDef) else graph_def.graph_def.node
- for node in nodes_to_clear_device:
- node.device = ""
- except Exception as e:
- raise FrameworkError(
- 'TensorFlow cannot read the model file: "{}" is incorrect TensorFlow model file. '
- '\nThe file should contain one of the following TensorFlow graphs:'
- '\n1. frozen graph in text or binary format'
- '\n2. inference graph for freezing with checkpoint (--input_checkpoint) in text or binary format'
- '\n3. meta graph'
- '\n\nMake sure that --input_model_is_text is provided for a model in text format. '
- 'By default, a model is interpreted in binary format. Framework error details: {}. ' +
- refer_to_faq_msg(43),
- graph_file_name,
- str(e)
- ) from e
- return graph_def
-
-
-def get_output_node_names_list(graph_def, user_defined_output_node_names_list: list):
- return summarize_graph(graph_def)['outputs'] \
- if user_defined_output_node_names_list is None or len(user_defined_output_node_names_list) == 0 \
- else user_defined_output_node_names_list
-
-
-def deducing_metagraph_path(meta_graph_file: str):
- match = re.search(r'^(.*)\.(data-\d*-of-\d*|index|meta)$', meta_graph_file)
- if match is not None:
- deduced_meta_graph_file = match.group(1) + '.meta'
- if not os.path.isfile(deduced_meta_graph_file):
- raise Error('\n\nMetaGraph freezing mechanism was enabled. '
- '\n{} file does not represent MetaGraph. '
- '\n{} path to MetaGraph was deduced, but it does not exist'
- '\n\nModel with MetaGraph consists of 3-4 files:'
- '\n1. model_name.meta'
- '\n2. model_name.index'
- '\n3. model_name.data-00000-of-00001 (digit part may vary)'
- '\n4. checkpoint (optional)'.format(meta_graph_file, deduced_meta_graph_file))
- else:
- meta_graph_file = deduced_meta_graph_file
- else:
- raise Error('\n\nMetaGraph freezing mechanism was enabled. '
- '\n{} file does not represent MetaGraph. '
- '\n\nModel with MetaGraph consists of 3-4 files:'
- '\n1. model_name.meta'
- '\n2. model_name.index'
- '\n3. model_name.data-00000-of-00001 (digit part may vary)'
- '\n4. checkpoint (optional)'
- '\n\nTo load this model, simply run:'
- '\npython3 mo_tf.py --input_meta_graph model_name.meta'
- ''.format(meta_graph_file))
- return meta_graph_file
-
-
-def freeze_tf2_concrete_function(model, concrete_func, env_setup):
-
- if "tensorflow" in env_setup and Version(env_setup["tensorflow"]) >= parse("2.2.0"):
- frozen_func = convert_variables_to_constants_v2(concrete_func,
- lower_control_flow=False,
- aggressive_inlining=True) # pylint: disable=E1123
- else:
- frozen_func = convert_variables_to_constants_v2(concrete_func,
- lower_control_flow=False) # pylint: disable=E1123
- graph_def = frozen_func.graph.as_graph_def(add_shapes=True)
-
- input_names = []
- if hasattr(model, 'inputs') and model.inputs is not None:
- # Extract tensor names order from Keras model
- input_names = [tensor.name for tensor in model.inputs]
-
- # After model freezing output tensor names are changing and recieve "Func/PartitionedCall" prefix,
- # so output_names from saved_model cannot be used. Here tensor names from frozen graph are used,
- # as TF adds indexed Identity nodes during freezing to each output, so this indexing is used for
- # order alignment.
- output_names = [tensor.name for tensor in frozen_func.outputs]
-
- inputs_outputs_order = (input_names, output_names)
-
- return graph_def, {}, 'tf2', inputs_outputs_order
-
-
-def prepare_graph_def(model):
- env_setup = get_environment_setup("tf")
- if isinstance(model, tf_v1.GraphDef):
- nodes_to_clear_device = model.node
- for node in nodes_to_clear_device:
- node.device = ""
- return model, {}, "tf", None
- if isinstance(model, tf.keras.Model): # pylint: disable=no-member
-
- assert hasattr(model, "inputs") and model.inputs is not None, "Model inputs specification is required."
-
- model_inputs = []
- for inp in model.inputs:
- if isinstance(inp, tf.Tensor):
- model_inputs.append(inp)
- elif tf.keras.backend.is_keras_tensor(inp): # pylint: disable=no-member
- model_inputs.append(inp.type_spec)
- else:
- raise Error("Unknown input tensor type {}".format(type(input)))
-
- @tf.function
- def tf_function(x):
- return model(x)
-
- conc_func = tf_function.get_concrete_function(model_inputs)
- return freeze_tf2_concrete_function(model, conc_func, env_setup)
- if Version(env_setup["tensorflow"]) >= parse("2.6.0") and isinstance(model, tf.types.experimental.GenericFunction):
-
- assert hasattr(model, "input_signature") and model.input_signature is not None, \
- "'input_signature' needs to be set for model conversion."
-
- conc_func = model.get_concrete_function(*tuple(model.input_signature))
- return freeze_tf2_concrete_function(model, conc_func, env_setup)
- raise Exception("Unknown model type {}.".format(type(model)))
-
-
-def saved_model_load(imported, env_setup):
- # to get a signature by key throws KeyError for TF 1.x SavedModel format in case TF 2.x installed
- concrete_func = imported.signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
- # the aggressive inlining parameter needs to freeze a table of embeddings for Keras Embedding operation
- # and a model with Embedding operation cannot properly converted to IR without this function parameter
-
- return freeze_tf2_concrete_function(imported, concrete_func, env_setup)
-
-
-def load_tf_graph_def(graph_file_name: str = "", is_binary: bool = True, checkpoint: str = "",
- model_dir: str = "", saved_model_tags: list = [], meta_graph_file: str = "",
- user_output_node_names_list: list = []):
- if not isinstance(graph_file_name, str) and graph_file_name is not None:
- return prepare_graph_def(graph_file_name)
- # As a provisional solution, use a native TF methods to load a model protobuf
- graph_def = tf_v1.GraphDef()
- if isinstance(graph_file_name, str) and (re.match(r'.*\.(ckpt|meta)$', graph_file_name)):
- print('[ WARNING ] The value for the --input_model command line parameter ends with ".ckpt" or ".meta" '
- 'extension.\n'
- 'It means that the model is not frozen.\n'
- 'To load non frozen model to Model Optimizer run:'
- '\n\n1. For "*.ckpt" file:'
- '\n- if inference graph is in binary format'
- '\npython3 mo_tf.py --input_model "path/to/inference_graph.pb" --input_checkpoint "path/to/*.ckpt"'
- '\n- if inference graph is in text format'
- '\npython3 mo_tf.py --input_model "path/to/inference_graph.pbtxt" --input_model_is_text '
- '--input_checkpoint "path/to/*.ckpt"'
- '\n\n2. For "*.meta" file:'
- '\npython3 mo_tf.py --input_meta_graph "path/to/*.meta"')
- variables_values = {}
- try:
- if graph_file_name and not meta_graph_file and not checkpoint:
- # frozen graph
- return read_file_to_graph_def(graph_def, graph_file_name, is_binary), variables_values, 'tf', None
- if graph_file_name and not meta_graph_file and checkpoint:
- # inference graph and checkpoint
- graph_def = read_file_to_graph_def(graph_def, graph_file_name, is_binary)
- outputs = get_output_node_names_list(graph_def, user_output_node_names_list)
- if os.path.isfile(checkpoint):
- graph_def = freeze_checkpoint(graph_def=graph_def, checkpoint=checkpoint, output_node_names=outputs)
- elif os.path.isdir(checkpoint):
- graph_def, variables_values = freeze_checkpoints(graph_def=graph_def, checkpoint_dir=checkpoint,
- output_node_names=outputs)
- # we are sure that checkpoint is existing file or directory due to cli_parser configuration
- return graph_def, variables_values, 'tf', None
- if not graph_file_name and meta_graph_file:
- meta_graph_file = deducing_metagraph_path(meta_graph_file)
- input_meta_graph_def = read_file_to_graph_def(tf_v1.MetaGraphDef(), meta_graph_file, is_binary)
- # Since version 2.2 TF can fail with internal error while loading graph from .meta file.
- # It happens because some operation may has an _output_shapes attribute inconsistent with the GraphDef
- # calculated value. To avoid this problem we must delete `_output_shapes` attributes from operations
- for node in input_meta_graph_def.graph_def.node:
- if '_output_shapes' in node.attr:
- del node.attr['_output_shapes']
- tf_v1.reset_default_graph()
- # pylint: disable=no-member
- with tf_v1.Session() as sess:
- restorer = tf_v1.train.import_meta_graph(input_meta_graph_def)
- restorer.restore(sess, re.sub(r'\.meta$', '', meta_graph_file))
- outputs = get_output_node_names_list(input_meta_graph_def.graph_def, user_output_node_names_list)
- graph_def = tf_v1.graph_util.convert_variables_to_constants(sess, input_meta_graph_def.graph_def,
- outputs)
- return graph_def, variables_values, 'tf', None
- if model_dir:
- # saved model directory
- try:
- env_setup = get_environment_setup("tf")
-
- try:
- # Code to extract Keras model.
- # tf.keras.models.load_model function throws TypeError,KeyError or IndexError
- # for TF 1.x SavedModel format in case TF 1.x installed
- imported = tf.keras.models.load_model(model_dir, compile=False) # pylint: disable=no-member
- except:
- imported = tf.saved_model.load(model_dir, saved_model_tags) # pylint: disable=E1120
-
- return saved_model_load(imported, env_setup)
- except:
- # code to extract GraphDef for TF 1.0 SavedModel format
- tags = saved_model_tags if saved_model_tags is not None else [tf_v1.saved_model.tag_constants.SERVING]
- with tf_v1.Session() as sess:
- meta_graph_def = tf_v1.saved_model.loader.load(sess, tags, model_dir)
- outputs = get_output_node_names_list(meta_graph_def.graph_def, user_output_node_names_list)
- graph_def = tf_v1.graph_util.convert_variables_to_constants(sess, meta_graph_def.graph_def, outputs)
- return graph_def, variables_values, 'tf', None
- except Exception as e:
- raise FrameworkError('Cannot load input model: {}', e) from e
- raise Error("Unknown configuration of input model parameters")
-
-
-def protobuf_attrs(pb: tf_v1.NodeDef):
- return {'pb': pb}
-
-
-def protobuf2nx(graph, pb: tf_v1.GraphDef):
- fill_graph_with_nodes(graph, pb.node, get_id=lambda pb: pb.name, get_attrs=protobuf_attrs)
-
- if hasattr(graph, 'op_names_statistic'):
- for node_name in graph.nodes:
- node = Node(graph, node_name)
- node_pb = node.soft_get('pb', None)
- if node_pb is not None:
- if hasattr(node_pb, 'op'):
- graph.op_names_statistic[node_pb.op] += 1
-
- # Create a library with auxiliary functions used in TensorFlow 2 operations
- if hasattr(pb, 'library') and hasattr(pb.library, 'function'):
- graph.graph['library'] = {}
- for library_function in pb.library.function:
- function_name = library_function.signature.name
- graph.graph['library'][function_name] = {}
- graph.graph['library'][function_name]['input_arg'] = library_function.signature.input_arg
- graph.graph['library'][function_name]['output_arg'] = library_function.signature.output_arg
- graph.graph['library'][function_name]['node_def'] = library_function.node_def
- graph.graph['library'][function_name]['ret'] = library_function.ret
- # initial order of nodes in the GraphDef. It is used to specify order in
- # which merged nodes are added to the generated sub-graph GraphDef for the TensorFlow offload feature.
- graph.graph['initial_nodes_order'] = [node.name for node in pb.node]
-
- # Remove data dependency edges. This is needed for the TF offload case
- for _, attrs in list(graph.nodes(data=True)):
- pb = attrs['pb']
- if '_class' in pb.attr:
- index = 0
- while index < len(pb.attr['_class'].list.s):
- if re.match('^loc:@.*', pb.attr['_class'].list.s[index].decode('utf-8')):
- del pb.attr['_class'].list.s[index]
- else:
- index = index + 1
-
-
-def variables_to_constants(graph: Graph, variables_values: dict):
- """
- Converts `Variable` operations to FakeConst operations with `value` from `variables_values` dictionary
- :param graph: graph to operate on
- :param variables_values: dictionary with variable names as keys and np.array data as values
- """
- for node in graph.get_op_nodes(op='FakeConst'):
- node_name = node.name
-
- if node_name not in variables_values:
- log.debug("There is no value for '{}': {} in checkpoint variable values".format(node.op, node_name))
- continue
-
- node['value'] = variables_values[node_name]
diff --git a/tools/mo/openvino/tools/mo/front/tf/log_softmax_ext.py b/tools/mo/openvino/tools/mo/front/tf/log_softmax_ext.py
deleted file mode 100644
index b114a0f038f0a3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/log_softmax_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.log_softmax import LogSoftmax
-
-
-class LogSoftmaxExtractor(FrontExtractorOp):
- op = 'LogSoftmax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # the default value for the TF LogSoftmax is -1
- axis = -1
- if 'axis' in node.pb.attr:
- axis = node.pb.attr['axis'].i
- LogSoftmax.update_node_stat(node, {'axis': axis})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/lrn_ext.py b/tools/mo/openvino/tools/mo/front/tf/lrn_ext.py
deleted file mode 100644
index 342e866c7338fc..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/lrn_ext.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.lrn import AttributedLRN
-
-
-class LRNExtractor(FrontExtractorOp):
- """
- TF and IE(CAFFE) parameters in LRN differs in several places :
- region (IE) : in TF there is no such parameter, they just use last dimension (feature dimension in case of NHWC)
- local-size (IE) : it's the size of 1D vector in Caffe. In TF they have 'depth_radius' that eq
- '(local-size * 2) + 1'
- alpha (IE) : in Caffe 'alpha' divides on local-size, so we should multiply alpha on local-size
-
- Caffe ref : http://caffe.berkeleyvision.org/tutorial/layers/lrn.html
- TF ref : https://www.tensorflow.org/api_docs/python/tf/nn/local_response_normalization
- """
- op = 'LRN'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pb = node.pb
- AttributedLRN.update_node_stat(node, {
- 'alpha': pb.attr['alpha'].f * (2. * pb.attr['depth_radius'].i + 1.),
- 'beta': pb.attr['beta'].f,
- 'bias': pb.attr['bias'].f,
- 'local_size': (2 * pb.attr['depth_radius'].i + 1),
- })
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support.json
deleted file mode 100644
index 33a2aa1981e729..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support.json
+++ /dev/null
@@ -1,120 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "FirstStageBoxPredictor/Reshape",
- "FirstStageBoxPredictor/Reshape_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack_2/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack/TensorArrayGatherV3"
- ],
- "start_points": [
- "SecondStageBoxPredictor/Reshape",
- "SecondStageBoxPredictor/Reshape_1",
- "ExpandDims_7",
- "ToFloat_6"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "CropAndResize_1"
- ],
- "start_points": [
- "CropAndResize_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.11.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.11.json
deleted file mode 100644
index 7abcdf96f821e4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.11.json
+++ /dev/null
@@ -1,121 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack_2/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack/TensorArrayGatherV3"
- ],
- "start_points": [
- "SecondStageBoxPredictor/Reshape",
- "SecondStageBoxPredictor/Reshape_1",
- "ExpandDims_6",
- "ToFloat_6"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "Reshape_10"
- ],
- "start_points": [
- "CropAndResize_1/CropAndResize"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "SecondStageBoxPredictor"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.13.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.13.json
deleted file mode 100644
index bdd113ea81e3f8..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.13.json
+++ /dev/null
@@ -1,122 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack_2/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack/TensorArrayGatherV3"
- ],
- "start_points": [
- "SecondStageBoxPredictor/Reshape",
- "SecondStageBoxPredictor/Reshape_1",
- "ExpandDims_6",
- "ToFloat_3"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "Reshape_15"
- ],
- "start_points": [
- "CropAndResize_1/CropAndResize",
- "CropAndResize_1/Shape_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "SecondStageBoxPredictor"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.14.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.14.json
deleted file mode 100644
index c825b3eed285a3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.14.json
+++ /dev/null
@@ -1,122 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_5/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack_2/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack/TensorArrayGatherV3"
- ],
- "start_points": [
- "SecondStageBoxPredictor/Reshape",
- "SecondStageBoxPredictor/Reshape_1",
- "ExpandDims_6",
- "Cast_5"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "Reshape_10"
- ],
- "start_points": [
- "CropAndResize_1/CropAndResize",
- "CropAndResize_1/Shape_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "SecondStageBoxPredictor"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.15.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.15.json
deleted file mode 100644
index c4db36de05e2cb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.15.json
+++ /dev/null
@@ -1,122 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_5/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat/concat",
- "concat_1/concat",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack_2/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack/TensorArrayGatherV3"
- ],
- "start_points": [
- "SecondStageBoxPredictor/Reshape",
- "SecondStageBoxPredictor/Reshape_1",
- "ExpandDims_6",
- "Cast_5"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "Reshape_10"
- ],
- "start_points": [
- "CropAndResize_1/CropAndResize",
- "CropAndResize_1/Shape_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "SecondStageBoxPredictor"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.7.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.7.json
deleted file mode 100644
index c488580d307c90..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v1.7.json
+++ /dev/null
@@ -1,121 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "concat",
- "concat_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack_2/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression_1/map/TensorArrayStack/TensorArrayGatherV3"
- ],
- "start_points": [
- "SecondStageBoxPredictor/Reshape",
- "SecondStageBoxPredictor/Reshape_1",
- "ExpandDims_7",
- "ToFloat_6"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "CropAndResize_1"
- ],
- "start_points": [
- "CropAndResize_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "SecondStageBoxPredictor"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "SecondStageBoxPredictor_1/Conv_3/BiasAdd|SecondStageBoxPredictor_1/Conv_1/BiasAdd"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes":
- {
- "replacements": [["mul/y", "first_stage_max_proposals"]]
- },
- "id": "ObjectDetectionAPIConstValueOverride",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v2.0.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v2.0.json
deleted file mode 100644
index fc0432c8c29875..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v2.0.json
+++ /dev/null
@@ -1,91 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/Preprocessor/unstack"],
- "end_nodes": ["StatefulPartitionedCall/Preprocessor/stack",
- "StatefulPartitionedCall/Preprocessor/stack_1"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/stack_3",
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression/stack_10",
- "StatefulPartitionedCall/Shape"
- ],
- "start_points": [
- "StatefulPartitionedCall/concat/concat",
- "StatefulPartitionedCall/concat_1/concat",
- "StatefulPartitionedCall/GridAnchorGenerator/Identity",
- "StatefulPartitionedCall/Cast_1",
- "StatefulPartitionedCall/Cast_2",
- "StatefulPartitionedCall/Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true,
- "background_label_id": 0
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression_1/stack_8",
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression_1/stack_6"
- ],
- "start_points": [
- "StatefulPartitionedCall/Reshape_4",
- "StatefulPartitionedCall/Reshape_5",
- "StatefulPartitionedCall/ExpandDims_6",
- "StatefulPartitionedCall/Cast_5"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/Reshape_10"
- ],
- "start_points": [
- "StatefulPartitionedCall/CropAndResize_1/CropAndResize",
- "StatefulPartitionedCall/CropAndResize_1/Reshape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "StatefulPartitionedCall/mask_rcnn_keras_box_predictor/mask_rcnn_mask_head/"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/mask_rcnn_keras_box_predictor/mask_rcnn_mask_head/MaskPredictor_last_conv2d/BiasAdd,StatefulPartitionedCall/Reshape_13"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v2.4.json b/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v2.4.json
deleted file mode 100644
index 3849547e05b38e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mask_rcnn_support_api_v2.4.json
+++ /dev/null
@@ -1,91 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/map/TensorArrayUnstack/TensorListFromTensor"],
- "end_nodes": ["StatefulPartitionedCall/map/TensorArrayV2Stack/TensorListStack",
- "StatefulPartitionedCall/map/TensorArrayV2Stack_1/TensorListStack"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/stack_3",
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression/stack_10",
- "StatefulPartitionedCall/Shape"
- ],
- "start_points": [
- "StatefulPartitionedCall/concat/concat",
- "StatefulPartitionedCall/concat_1/concat",
- "StatefulPartitionedCall/GridAnchorGenerator/Identity",
- "StatefulPartitionedCall/Cast_1",
- "StatefulPartitionedCall/Cast_2",
- "StatefulPartitionedCall/Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true,
- "background_label_id": 0
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression_1/stack_8",
- "StatefulPartitionedCall/BatchMultiClassNonMaxSuppression_1/stack_6"
- ],
- "start_points": [
- "StatefulPartitionedCall/Reshape_4",
- "StatefulPartitionedCall/Reshape_5",
- "StatefulPartitionedCall/ExpandDims_6",
- "StatefulPartitionedCall/Cast_5"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIMaskRCNNROIPoolingSecondReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/Reshape_10"
- ],
- "start_points": [
- "StatefulPartitionedCall/CropAndResize_1/CropAndResize",
- "StatefulPartitionedCall/CropAndResize_1/Reshape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "masks_node_prefix_name": "StatefulPartitionedCall/mask_rcnn_keras_box_predictor/mask_rcnn_mask_head/"
- },
- "id": "ObjectDetectionAPIMaskRCNNSigmoidReplacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/mask_rcnn_keras_box_predictor/mask_rcnn_mask_head/MaskPredictor_last_conv2d/BiasAdd,StatefulPartitionedCall/Reshape_13"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/matmul_ext.py b/tools/mo/openvino/tools/mo/front/tf/matmul_ext.py
deleted file mode 100644
index 11739ce1d6ad7b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/matmul_ext.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.MatMul import MatMul
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-
-
-class MatMulExtractor(FrontExtractorOp):
- op = 'MatMul'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- unsupported_attrs = []
- for attr_name in ['adjoint_a', 'adjoint_b', 'a_is_sparse', 'b_is_sparse']:
- if attr_name in node.pb.attr and node.pb.attr[attr_name].b:
- unsupported_attrs.append(attr_name)
- if len(unsupported_attrs) != 0:
- raise Error('MatMul operation {} use unsupported attrs: {}'.format(node.id, unsupported_attrs))
-
- MatMul.update_node_stat(node,
- {
- 'transpose_a': node.pb.attr['transpose_a'].b,
- 'transpose_b': node.pb.attr['transpose_b'].b,
- })
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/mvn.py b/tools/mo/openvino/tools/mo/front/tf/mvn.py
deleted file mode 100644
index a8415cd7e23069..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mvn.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Node, Graph
-
-
-class MVNReplacer(FrontReplacementSubgraph):
- enabled = True
-
- def pattern(self):
- log.debug('Enabled MVN replacement')
- return dict(
- nodes=[
- ('mean', dict(op='ReduceMean')),
- ('stop_grad', dict(op='StopGradient')),
- ('sqdiff', dict(op='SquaredDifference')),
- ('variance', dict(op='ReduceMean')),
- ('squeeze_mean', dict(op='Squeeze')),
- ('squeeze_variance', dict(op='Squeeze')),
- ('fbn', dict(op=lambda op: op in ['FusedBatchNorm', 'FusedBatchNormV2', 'FusedBatchNormV3'])),
- ],
- edges=[
- ('mean', 'stop_grad', {'in': 0}),
- ('stop_grad', 'sqdiff', {'in': 1}),
- ('sqdiff', 'variance', {'in': 0}),
- ('mean', 'squeeze_mean', {'in': 0}),
- ('variance', 'squeeze_variance', {'in': 0}),
- ('squeeze_mean', 'fbn', {'in': 3}),
- ('squeeze_variance', 'fbn', {'in': 4}),
- ])
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- fbn = match['fbn']
- input = fbn.in_node(0)
- log.debug('Found potential MVN pattern after {} with name {}'.format(input.op, input.name))
- if input.id != match['mean'].in_node(0).id or input.id != match['sqdiff'].in_node(0).id:
- return
-
- log.debug('Confirmed MVN pattern after {} with name {}'.format(input.op, input.name))
-
- mvn = MVN(graph, dict(
- name=fbn.name + '/MVN_',
- eps=fbn.eps,
- eps_mode='outside_sqrt',
- normalize_variance=1
- ))
- mvn.attrs['old_infer'] = mvn.attrs['infer']
- mvn.attrs['infer'] = __class__.infer
-
- mul = Mul(graph, dict(operation='mul', name=fbn.name + '/Mul_'))
- add = Add(graph, dict(operation='sum', name=fbn.name + '/Add_'))
-
- input_gamma = fbn.in_node(1)
- input_beta = fbn.in_node(2)
-
- mean_reduction = match['mean'].in_node(1)
- variance_reduction = match['variance'].in_node(1)
-
- new_subgraph = add.create_node([
- mul.create_node([
- mvn.create_node([input, mean_reduction, variance_reduction]),
- input_gamma
- ]),
- input_beta
- ])
- fbn.replace_node(new_subgraph)
-
- @staticmethod
- def infer(node: Node):
- axes_1_value = node.in_port(1).data.get_value()
- axes_2_value = node.in_port(2).data.get_value()
- if axes_1_value is None or axes_2_value is None:
- log.warning('Reduction indices for mean and variance for MVN node {} are not constants'.format(node.name))
- return
-
- if not (all(axes_1_value == axes_2_value)):
- log.warning('Reduction indices for mean {} and variance {} do not match'.format(
- axes_1_value,
- axes_2_value
- ))
- return
-
- node.in_port(2).disconnect()
- node.old_infer(node)
- node.infer = node.old_infer
- del node['old_infer']
diff --git a/tools/mo/openvino/tools/mo/front/tf/mvn_unrolled.py b/tools/mo/openvino/tools/mo/front/tf/mvn_unrolled.py
deleted file mode 100644
index 985d66a81c03bc..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/mvn_unrolled.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.PowerToEltwises import PowerToEltwises
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Node, Graph
-
-
-class MVNUnrolled(FrontReplacementSubgraph):
- enabled = True
-
- def run_after(self):
- return [PowerToEltwises]
-
- def pattern(self):
- log.debug('Enabled MVN replacement')
- return dict(
- nodes=[
- ('mean', dict(kind='op', op='ReduceMean')),
- ('stop_grad', dict(kind='op', op='StopGradient')),
- ('sqdiff', dict(kind='op', op='SquaredDifference')),
- ('variance', dict(kind='op', op='ReduceMean')),
- ('add', dict(kind='op', op='Add')),
- ('pow', dict(kind='op', op='Pow')),
- ('sub', dict(kind='op', op='Sub')),
- ('truediv', dict(kind='op', op='Div')),
- ],
- edges=[
- ('mean', 'stop_grad', {'in': 0}),
- ('stop_grad', 'sqdiff', {'in': 1}),
- ('sqdiff', 'variance', {'in': 0}),
- ('mean', 'sub', {'in': 1}),
- ('variance', 'add'),
- ('add', 'pow', {'in': 0}),
- ('pow', 'truediv', {'in': 1}),
- ('sub', 'truediv', {'in': 0}),
- ])
-
- @staticmethod
- def replace_sub_graph(graph: Graph, match: dict):
- mvn = MVN(graph, dict(
- name=match['truediv'].name + '/MVN_',
- eps_mode='outside_sqrt',
- normalize_variance=1
- ))
- mvn.attrs['old_infer'] = mvn.attrs['infer']
- mvn.attrs['infer'] = __class__.infer
-
- mean_reduction = match['mean'].in_node(1)
- variance_reduction = match['variance'].in_node(1)
- pow2 = match['pow'].in_node(1)
- eps = match['add'].in_node(0 if match['add'].in_node(0).id != match['variance'].id else 1)
-
- new_subgraph = mvn.create_node([match['mean'].in_node(0), mean_reduction, variance_reduction, pow2, eps])
-
- match['truediv'].replace_node(new_subgraph)
-
- @staticmethod
- def infer(node: Node):
- axes_1_value = node.in_port(1).data.get_value()
- axes_2_value = node.in_port(2).data.get_value()
- if axes_1_value is None or axes_2_value is None:
- log.warning('Reduction indices for mean and variance for MVN node {} are not constants'.format(node.name))
- return
-
- if not (all(axes_1_value == axes_2_value)):
- log.warning('Reduction indices for mean {} and variance {} do not match'.format(
- axes_1_value,
- axes_2_value
- ))
- return
-
- power_value = node.in_port(3).data.get_value()
- eps_value = node.in_port(4).data.get_value()
- if power_value is None or eps_value is None:
- log.warning('Power or/and epsilon values for MVN node {} are not constants'.format(node.name))
- return
-
- if power_value != 0.5:
- log.warning('Power for MVN node {} ({}) is not equal to 0.5'.format(node.name, power_value))
- return
-
- node['eps'] = eps_value
-
- for i in range(2, 5):
- node.in_port(i).disconnect()
- node.old_infer(node)
- node.infer = node.old_infer
- del node['old_infer']
diff --git a/tools/mo/openvino/tools/mo/front/tf/nearest_neighbor_upsampling.py b/tools/mo/openvino/tools/mo/front/tf/nearest_neighbor_upsampling.py
deleted file mode 100644
index f5bba726f7c443..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/nearest_neighbor_upsampling.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.Pack import Pack
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mo_array, float32_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-
-
-class NearestNeighborUpsampling(FrontReplacementSubgraph):
- enabled = True
-
- def run_before(self):
- return [Pack]
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op')),
- ('shape', dict(kind='op', op='ShapeOf')),
- ('strided_slice', dict(kind='op', op='StridedSlice')),
- ('pack_1', dict(kind='op', op='Pack')),
- ('reshape_1', dict(kind='op', op='Reshape')),
- ('mul_const', dict(kind='op', op='Const')),
- ('mul', dict(kind='op', op='Mul')),
- ('pack_2', dict(kind='op', op='Pack')),
- ('reshape_2', dict(kind='op', op='Reshape')),
- ],
- edges=[
- ('op', 'shape'),
- ('op', 'reshape_1'),
- ('shape', 'strided_slice'),
- ('strided_slice', 'pack_1'),
- ('strided_slice', 'pack_2'),
- ('pack_1', 'reshape_1'),
- ('pack_2', 'reshape_2'),
- ('reshape_1', 'mul'),
- ('mul_const', 'mul'),
- ('mul', 'reshape_2'),
- ]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- log.debug('Matched NearestNeighborUpsampling pattern: {}'.format([node.id for node in match.values()]))
- try:
- input_height = match['pack_1'].in_node(1).value.item()
- input_width = match['pack_1'].in_node(3).value.item()
-
- height_scale = match['mul_const'].shape[-4]
- width_scale = match['mul_const'].shape[-2]
- except Exception as ex:
- log.warning('Failed to determine scaling parameters from the topology. Do not apply pattern.')
- return
-
- reshape2_name = match['reshape_2'].name
- resample_op = Interpolate(graph,
- {'mode': 'nearest', 'antialias': 0, 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]), 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor', 'cube_coeff': -0.75, 'version': 'opset4',
- 'name': reshape2_name + '/Resample', 'shape_calculation_mode': 'scales',
- 'in_ports_count': 4})
- resample_node = resample_op.create_node([match['op']])
- axes_node = Const(graph,
- {
- 'name': resample_node.name + '/axes',
- 'value': int64_array([2, 3]) if graph.graph['layout'] == 'NCHW' else int64_array([1, 2])
- }).create_node()
- sizes_node = Const(graph, {'value': mo_array([input_height * height_scale, input_width * width_scale]),
- 'name': resample_node.name + '/target_shape'}).create_node()
- scales_node = Const(graph, {'value': float32_array([height_scale, width_scale]),
- 'name': resample_node.name + '/scales'}).create_node()
-
- match['reshape_2'].replace_node(resample_node)
-
- resample_node.add_input_port(1, skip_if_exist=True)
- assert resample_node.in_port(1).disconnected()
- sizes_node.out_port(0).connect(resample_node.in_port(1))
- scales_node.out_port(0).connect(resample_node.in_port(2))
- axes_node.out_port(0).connect(resample_node.in_port(3))
-
- graph.remove_nodes_from([node.id for node in match.values() if node.id != match['op'].id])
diff --git a/tools/mo/openvino/tools/mo/front/tf/next_iteration_ext.py b/tools/mo/openvino/tools/mo/front/tf/next_iteration_ext.py
deleted file mode 100644
index e70b25db3249f5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/next_iteration_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-
-
-class NextIterationExtractor(FrontExtractorOp):
- op = "NextIteration"
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- node['is_cyclic'] = True
- node['infer'] = copy_shape_infer
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/non_max_suppression_ext.py b/tools/mo/openvino/tools/mo/front/tf/non_max_suppression_ext.py
deleted file mode 100644
index 18b1c5c3f6eed6..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/non_max_suppression_ext.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.non_max_suppression import NonMaxSuppression
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class NonMaxSuppressionV2Extractor(FrontExtractorOp):
- op = 'NonMaxSuppressionV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'sort_result_descending': 1, 'box_encoding': 'corner', 'output_type': np.int32}
- NonMaxSuppression.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class NonMaxSuppressionV3Extractor(FrontExtractorOp):
- op = 'NonMaxSuppressionV3'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {'sort_result_descending': 1, 'box_encoding': 'corner', 'output_type': np.int32}
- NonMaxSuppression.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class NonMaxSuppressionV4Extractor(FrontExtractorOp):
- op = 'NonMaxSuppressionV4'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pad_to_max_output_size = node.pb.attr["pad_to_max_output_size:"].b
- if not pad_to_max_output_size:
- log.warning('The attribute "pad_to_max_output_size" of node {} is equal to False which is not supported. '
- 'Forcing it to be equal to True'.format(node.soft_get('name')))
- attrs = {'sort_result_descending': 1, 'box_encoding': 'corner', 'output_type': np.int32}
- NonMaxSuppression.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class NonMaxSuppressionV5Extractor(FrontExtractorOp):
- op = 'NonMaxSuppressionV5'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- pad_to_max_output_size = node.pb.attr["pad_to_max_output_size:"].b
- if not pad_to_max_output_size:
- log.warning('The attribute "pad_to_max_output_size" of node {} is equal to False which is not supported. '
- 'Forcing it to be equal to True'.format(node.soft_get('name')))
- attrs = {'sort_result_descending': 1, 'box_encoding': 'corner', 'output_type': np.int32}
- NonMaxSuppression.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/non_max_suppression_normalize.py b/tools/mo/openvino/tools/mo/front/tf/non_max_suppression_normalize.py
deleted file mode 100644
index 57164a184f0248..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/non_max_suppression_normalize.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class TFNonMaxSuppressionNormalize(FrontReplacementSubgraph):
- """
- The inputs and outputs format of the TF implementation of the NMS layer is different from the OpenVINO
- implementation and supports just one batch and image class. This transformation converts inputs and outputs to
- match the OpenVINO implementation.
-
- TF inputs: boxes = [num_boxes, 4]
- scores = [num_boxes]
- outputs: box_indices [selected_boxes_count]
- box_scores [selected_boxes_count]
- valid_outputs selected_boxes_count
-
- OV inputs: boxes = [num_batches, num_boxes, 4]
- scores = [num_batches, num_classes, num_boxes]
- outputs: selected_indices [num_selected_indices, 3] where each element is [batch_index, class_index, box_index]
- selected_scores [num_selected_indices, 3] where each element is [batch_index, class_index, box_score]
- valid_outputs num_selected_indices
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.non_max_suppression_normalize import NonMaxSuppressionNormalize
- return [NonMaxSuppressionNormalize]
-
- def find_and_replace_pattern(self, graph: Graph):
- for nms in graph.get_op_nodes(op='NonMaxSuppression'):
- # prepare inputs to the NonMaximumSuppression Node
- unsqueeze_boxes = create_op_node_with_second_input(graph, Unsqueeze, int64_array([0]),
- {'name': nms.soft_get('name') + '/Unsqueeze_0'})
- nms.in_port(0).get_connection().insert_node(unsqueeze_boxes)
-
- unsqueeze_box_scores = create_op_node_with_second_input(graph, Reshape, int64_array([1, 1, -1]),
- {'name': nms.soft_get('name') + '/Unsqueeze_1'})
- nms.in_port(1).get_connection().insert_node(unsqueeze_box_scores)
-
- nms_name = nms.soft_get('name', nms.id)
-
- # prepare output #0
- crop_box_indices_name = nms_name + '/Crop_boxes_'
- crop_box_indices = Crop(graph, {'name': crop_box_indices_name, 'axis': int64_array([1]),
- 'offset': int64_array([2]), 'dim': int64_array([1])}).create_node()
- nms.out_port(0).get_connection().insert_node(crop_box_indices)
- squeeze_output_boxes = create_op_node_with_second_input(graph, Squeeze, int64_array([1]),
- {'name': crop_box_indices_name + '/Squeeze'})
- crop_box_indices.out_port(0).get_connection().insert_node(squeeze_output_boxes)
-
- num_of_outputs = len([port for port in nms.out_ports().values() if not port.disconnected()])
-
- if num_of_outputs == 1:
- continue
-
- # prepare output #1
- crop_score_indices_name = nms_name + '/Crop_scores_'
- crop_score_indices = Crop(graph, {'name': crop_score_indices_name, 'axis': int64_array([1]),
- 'offset': int64_array([2]), 'dim': int64_array([1])}).create_node()
- nms.out_port(1).get_connection().insert_node(crop_score_indices)
- squeeze_output_scores = create_op_node_with_second_input(graph, Squeeze, int64_array([1]),
- {'name': crop_score_indices_name + '/Squeeze'})
- crop_score_indices.out_port(0).get_connection().insert_node(squeeze_output_scores)
diff --git a/tools/mo/openvino/tools/mo/front/tf/noop.py b/tools/mo/openvino/tools/mo/front/tf/noop.py
deleted file mode 100644
index 9a945af23fd79e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/noop.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import networkx as nx
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.error import Error
-
-
-class NoOpElimination(FrontReplacementOp):
- """
- NoOp does nothing and it has no data flow edges.
- It operates only with control flow edges.
- """
- op = "NoOp"
- enabled = True
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- node = match['op']
- in_edges = node.in_edges()
- out_edges = node.out_edges()
- if len(in_edges) == 0 and len(out_edges) == 0:
- graph.remove_node(node.id)
- log.debug('NoOp op was removed {}'.format(node.id))
- else:
- raise Error('NoOp node {} contains data flow edges'.format(node.id))
diff --git a/tools/mo/openvino/tools/mo/front/tf/one_hot_ext.py b/tools/mo/openvino/tools/mo/front/tf/one_hot_ext.py
deleted file mode 100644
index 6b4519b80efe2d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/one_hot_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.one_hot import OneHot
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class OneHotFrontExtractor(FrontExtractorOp):
- op = 'OneHot'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- OneHot.update_node_stat(node, {'axis': node.pb.attr['axis'].i,
- 'data_type': tf_dtype_extractor(node.pb.attr["T"].type, np.float32)})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/pad_ext.py b/tools/mo/openvino/tools/mo/front/tf/pad_ext.py
deleted file mode 100644
index a42affcdbc111c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/pad_ext.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.pad import TFPad
-
-
-class PadFrontExtractor(FrontExtractorOp):
- op = 'Pad'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- TFPad.update_node_stat(node)
- return cls.enabled
-
-
-class PadV2FrontExtractor(FrontExtractorOp):
- op = 'PadV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- TFPad.update_node_stat(node)
- return cls.enabled
-
-
-class MirrorPadFrontExtractor(FrontExtractorOp):
- op = 'MirrorPad'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- TFPad.update_node_stat(node, {'mode': node.pb.attr['mode'].s.decode('utf-8').lower()})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/pad_tf_to_pad.py b/tools/mo/openvino/tools/mo/front/tf/pad_tf_to_pad.py
deleted file mode 100644
index 1eeb69d513dd7a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/pad_tf_to_pad.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ConvertLike import ConvertLike
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_node
-from openvino.tools.mo.ops.pad import Pad
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-class PadTFToPad(FrontReplacementPattern):
- """
- This transformation converts TFPad operation (TensorFlow semantic) to Pad operation (OpenVINO semantic).
- Refer to the Op implementation for the operations semantics description.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for tfpad in graph.get_op_nodes(op='TFPad'):
- # save the original node name to use it in the new Pad op instance
- original_name = tfpad.soft_get('name', tfpad.id)
- tfpad['name'] = original_name + '/to_be_removed'
-
- new_pad = Pad(graph, {'mode': tfpad.soft_get('mode', None), }).create_node()
- rename_node(new_pad, original_name)
-
- tfpad.in_port(0).get_connection().set_destination(new_pad.in_port(0))
-
- if tfpad.soft_get('mode') == 'constant':
- # the input with fill value is an optional third input in TF
- if not tfpad.in_port(2).disconnected():
- tfpad.in_port(2).get_connection().set_destination(new_pad.in_port(3))
-
- # convert TF representation of the pads as [N, 2] to MO representation: [N] and [N]
- transposed_pads = create_op_with_const_inputs(graph, Transpose, {1: int64_array([1, 0])})
- tfpad.in_port(1).get_connection().set_destination(transposed_pads.in_port(0))
- split_pads = create_op_with_const_inputs(graph, Split, {1: int64_array(0)}, {'num_splits': 2})
- transposed_pads.out_port(0).connect(split_pads.in_port(0))
- for port_ind in range(2):
- split_pads.add_output_port(port_ind, skip_if_exist=True)
- new_pad.in_port(port_ind + 1).connect(split_pads.out_port(port_ind))
- new_pad.in_port(port_ind + 1).get_connection().insert_node(
- create_op_with_const_inputs(graph, Squeeze, {1: int64_array([0])}))
-
- tfpad.out_port(0).get_connection().set_source(new_pad.out_port(0))
- graph.remove_node(tfpad.id)
diff --git a/tools/mo/openvino/tools/mo/front/tf/partial_infer/__init__.py b/tools/mo/openvino/tools/mo/front/tf/partial_infer/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/partial_infer/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/front/tf/partial_infer/tf.py b/tools/mo/openvino/tools/mo/front/tf/partial_infer/tf.py
deleted file mode 100644
index 194e8f64d96548..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/partial_infer/tf.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import os
-from re import match
-
-import numpy as np
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-try:
- import tensorflow.compat.v1 as tf_v1
-except ImportError:
- import tensorflow as tf_v1
-
-#in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
-tf_v1.get_logger().setLevel("ERROR")
-
-from google.protobuf import text_format
-from tensorflow.python.eager.context import graph_mode # pylint: disable=no-name-in-module,import-error
-
-from openvino.tools.mo.front.extractor import node_defs_to_str
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape, get_tf_node_port
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.graph import node_incoming_neighbourhood, node_outcoming_neighbourhood
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-
-def tf_native_tf_node_infer(node: Node):
- """
- The infer function should be used to infer shape and data type of the TF operation not supported by IE.
- :param node: node to infer.
- :return: None
- """
- log.info('Called "tf_native_tf_node_infer" for node "{}"'.format(node.id))
-
- # create a sub-graph only to make inference. The sub-graph contains desired node and it's inputs neighbourhood of
- # depth 10. The number 10 is quite big to be sure that determine_data_type function will be able to identify the
- # data type of input tensors, but not too huge to contain the whole graph.
- # Also the sub-graph contains names of the output nodes of the node to perform native infer.
- nodes_to_extract = node_incoming_neighbourhood(node.graph, node.id, 10) + node_outcoming_neighbourhood(node.graph,
- node.id, 1)
- tmp_graph = node.graph.create_sub_graph_copy(nodes_to_extract)
-
- tmp_node_attrs = tmp_graph.node[node.id]
- tmp_node = Node(tmp_graph, node.id)
-
- # node attributes that are required by 'infer_subgraph_output_nodes' function
- lists_to_init = ['input_nodes_names', 'output_tensors_names', 'nodes_order', 'internal_output_node_name',
- 'real_input_dims']
-
- for item in lists_to_init:
- tmp_node_attrs[item] = list()
- tmp_node_attrs['pbs'] = {tmp_node.name: tmp_node.pb}
- tmp_node_attrs['nodes_order'].append(tmp_node.id)
- for ind in range(len(tmp_node.out_edges())):
- tmp_node_attrs['output_tensors_names'].append(tmp_node.id + ":" + str(ind))
-
- with graph_mode():
- tf_subgraph_infer(tmp_node)
-
- # the shape and value has been inferred and saved to the tmp_node's out nodes attribute. Let's copy it back!
- for tmp_out_port, tmp_out_node in tmp_node.out_nodes().items():
- if tmp_out_node.value is not None:
- node.out_node(tmp_out_port).value = mo_array(tmp_out_node.value)
- if tmp_out_node.shape is not None:
- node.out_node(tmp_out_port).shape = mo_array(tmp_out_node.shape)
- if tmp_out_node.data_type is not None:
- node.out_node(tmp_out_port).data_type = tmp_out_node.data_type
- # lets cleanup the temporary graph
- tmp_graph.clear()
-
-
-def generate_feed_dict(graph: tf_v1.Graph, node: Node):
- """
- The first value in the return tuple is True if all inputs for the node has constant values.
- The second returned value is mapping of placeholder tensor to the numpy arrays with the values for these
- placeholders.
- :param graph: the TensorFlow Graph to generate feed dictionary to.
- :param node: the node which represents TensorFlow sub-graph of operations.
- :return: pair where the first element is a flag that specifies that all node inputs are constants and a dictionary
- where key is the input Tensor object and the value is the tensor value.
- """
- all_constants = True
- feed_dict = dict()
- for in_data_node_name, edge_attrs in node.get_inputs():
- if 'control_flow_edge' in edge_attrs and edge_attrs['control_flow_edge']:
- continue
- value = node.in_node(edge_attrs['in']).value
- if value is None:
- all_constants = False
- placeholder_pb = node['pbs'][edge_attrs['placeholder_name']]
- value = np.ones(shape=tf_tensor_shape(placeholder_pb.attr['shape'].shape),
- dtype=tf_dtype_extractor(placeholder_pb.attr['dtype'].type))
- feed_dict[graph.get_tensor_by_name(edge_attrs['placeholder_name'] + ":0")] = value
- return all_constants, feed_dict
-
-
-def get_subgraph_output_tensors(node: Node):
- """
- Infer output shapes of the node. The function uses TF to infer the values of output tensors and then getting tensor
- shape.
- TODO: try to not infer values but just infer the output tensors shapes.
- :param node: sub-graph node to infer.
- :return: pair where the first element is a flag that specifies that all node inputs are constants and a dictionary
- where key is the output port and the value is the tensor value.
- """
- result = dict()
- graph_def = tf_v1.GraphDef()
- text_format.Merge(node_defs_to_str(node), graph_def)
- tf_v1.reset_default_graph()
- graph = tf_v1.Graph()
- sess = tf_v1.Session(graph=graph)
- with graph.as_default(): # pylint: disable=not-context-manager
- with sess.as_default(): # pylint: disable=not-context-manager
- tf_v1.import_graph_def(graph_def, name='')
- all_constants, feed_dict = generate_feed_dict(graph, node)
- for out_port, out_tensor_name in enumerate(node['output_tensors_names']):
- if not match(r'.*:\d+', out_tensor_name):
- out_tensor_name = out_tensor_name + ":" + str(out_port)
- result_tensor = sess.run(graph.get_tensor_by_name(out_tensor_name), feed_dict=feed_dict)
- result[out_port] = result_tensor
- return all_constants, result
-
-
-def tf_subgraph_infer(node: Node):
- """
- Infer output shapes of the node using TF to infer the values of output tensors and then getting tensor shapes.
- If all inputs of the node are constants then the node's attribute 'value' is updated also.
- :param node: sub-graph node to infer. The function updates 'shape' and 'data_type' attributes of the node.
- :return: None
- """
- # TODO: try to not infer values but just infer the output tensors shapes.
- add_placeholders_to_subgraph(node)
-
- all_constants, output_tensors = get_subgraph_output_tensors(node)
- for out_port, tensor_value in output_tensors.items():
- out_node = node.out_node(out_port)
- out_node.shape = mo_array([dim for dim in tensor_value.shape])
- out_node.data_type = tensor_value.dtype
- log.debug("Inferred shape of the output tensor with index '{}' of the node '{}': '{}'".format(str(out_port),
- node.name,
- out_node.shape))
- if all_constants:
- out_node.value = tensor_value
-
-
-def add_node_def_to_subgraph(subgraph_node: Node, node_def: tf_v1.NodeDef, name: str = None, position: int = 0,
- is_input: bool = False):
- """
- Adds NodeDef definition of the node to the internal structures of the sub-graph's_node object that represents a
- sub-graph of operations.
- :param subgraph_node: the node that represents sub-graph where new node should be added.
- :param node_def: the NodeDef (TF operation, variable or constant) to be added to the sub-graph.
- :param name: name how to save added node. Default value is None which means take name from the NodeDef.
- :param position: position in the GraphDef where to put the NodeDef. Default value is 0.
- :param is_input: flag that specifies whether the node is input for the sub-graph. Default value is False.
- :return: None
- """
- name = name or node_def.name
- assert (name not in subgraph_node['pbs'].keys())
- if is_input:
- subgraph_node['input_nodes_names'].append(name)
- subgraph_node['pbs'][node_def.name] = node_def
- subgraph_node['nodes_order'].insert(position, name)
-
-
-def determine_data_type(node: Node):
- """
- Tries to determine data type of the node. The input node could be either data or op node. If we don't know the data
- type of the node then we recursively check the first parent of the node.
- :param node: node to determine data type.
- :return: data type of the node output in the numpy format.
- """
- if node.has_and_set('data_type'):
- return node.data_type
- if node.has_and_set('kind') and node.kind == 'op':
- if node.has_and_set('pb'):
- if 'dtype' in node.pb.attr:
- return tf_dtype_extractor(node.pb.attr['dtype'].type)
- if 'T' in node.pb.attr:
- return tf_dtype_extractor(node.pb.attr['T'].type)
- if node.has_and_set('kind') and node.kind == 'data':
- if 'value' in node and node.value is not None:
- return node.value.dtype
- if len(node.in_nodes()) != 0: # try to guess data type from the first parent
- return determine_data_type(node.in_node(0))
- log.error('Failed to determine data type for node "{}"'.format(node.name))
- return None
-
-
-def add_placeholders_to_subgraph(node: Node):
- """
- Adds placeholders to the node's list of protobufs based on input nodes to the subgraph (the value of
- 'internal_input_node_name' property).
- The function also updates input tensors for nodes which consume output of nodes that were replaced with
- placeholders.
- :param node: the node to add placeholders to.
- :return: None
- """
- inputs_replacements = list()
- for index, (in_data_node, edge_attrs) in enumerate(node.get_sorted_inputs()):
- if 'control_flow_edge' in edge_attrs and edge_attrs['control_flow_edge']:
- continue
-
- if 'internal_input_node_name' in edge_attrs.keys():
- input_tensor_name = edge_attrs['internal_input_node_name']
- else:
- input_tensor_name = node['pb'].input[index]
-
- input_node_name, port = get_tf_node_port(input_tensor_name)
-
- placeholder_name = placeholder_name_for_node(input_node_name, port)
- edge_attrs['placeholder_name'] = placeholder_name
- in_node = node.in_node(index)
-
- assert in_node.shape is not None
-
- if placeholder_name not in node['pbs'].keys():
- placeholder = tf_v1.placeholder(determine_data_type(in_node), in_node.shape, placeholder_name)
- inputs_replacements.append((input_tensor_name, placeholder_name))
- add_node_def_to_subgraph(node, placeholder.op.node_def, is_input=True)
- log.debug("Added placeholder with name '{}'".format(placeholder_name))
-
- # update initial input names to a transposed ones
- for old_input_tensor_name, new_name in inputs_replacements:
- update_input_in_pbs(node, old_input_tensor_name, new_name)
-
-
-def update_input_in_pbs(node: Node, old_input_tensor_name: str, new_input_name: str):
- """
- The function replaces all inputs with name 'old_input_tensor_name' with a
- new input with name 'new_input_name'. This transformation is applied
- for all NodeDef objects in the 'pbs' list.
- """
- log.debug("update_input_in_pbs: replace input '%s' with input '%s'" % (old_input_tensor_name, new_input_name))
- old_input_tensor_name_without_port = old_input_tensor_name.split(":")[0]
- for pb in node['pbs'].values():
- if hasattr(pb, 'input'):
- for ind in range(len(pb.input)):
- if pb.input[ind] == old_input_tensor_name or pb.input[ind] == old_input_tensor_name_without_port:
- pb.input[ind] = new_input_name
- log.debug("Replacing input '{}' of the node '{}' with placeholder '{}'".format(ind, pb.name,
- new_input_name))
-
-
-def placeholder_name_for_node(node_name: str, output_port: int):
- return node_name + "_port_" + str(output_port) + "_ie_placeholder"
diff --git a/tools/mo/openvino/tools/mo/front/tf/placeholder_ext.py b/tools/mo/openvino/tools/mo/front/tf/placeholder_ext.py
deleted file mode 100644
index 01bb83f00baf21..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/placeholder_ext.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape
-from openvino.tools.mo.ops.op import PermuteAttrs
-from openvino.tools.mo.ops.parameter import Parameter
-
-
-class PlaceholderFrontExtractor(FrontExtractorOp):
- op = 'Placeholder'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- shape = shape_array([])
- # Extract output shape from `shape` attribute
- extracted_shape = tf_tensor_shape(node.pb.attr["shape"].shape)
- if len(extracted_shape) != 0:
- shape = extracted_shape
- else:
- # Extract output shape from `_output_shapes` attribute if it is possible
- extracted_output_shapes = node.pb.attr["_output_shapes"].list.shape
- if len(extracted_output_shapes) == 1: # check if attribute not empty
- extracted_output_shapes = tf_tensor_shape(extracted_output_shapes[0])
-
- # Check equality of extracted shapes. We know some cases then Placeholder operation has empty `shape`
- # attribute value and non-empty `_output_shapes` attribute value and need co handle and support it.
- if len(extracted_output_shapes) > len(extracted_shape):
- log.warning('Extracted shapes for Placeholder operation {} have different lengths: `shape` {} and '
- '`_output_shapes` {}. Please, check if model is consistent'.format(
- node.pb.name, extracted_shape, extracted_output_shapes))
- if len(extracted_output_shapes) != 0:
- shape = extracted_output_shapes
-
- attrs = {
- 'data_type': tf_dtype_extractor(node.pb.attr["dtype"].type),
- 'shape': shape,
- 'permute_attrs': PermuteAttrs().update_attrs(attrs=[('shape', 'output:0')])
- }
- if node.pb.attr["shape"].shape.unknown_rank:
- attrs['shape'] = None
- Parameter.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/placeholder_with_default_ext.py b/tools/mo/openvino/tools/mo/front/tf/placeholder_with_default_ext.py
deleted file mode 100644
index 0d718e7936a244..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/placeholder_with_default_ext.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer, copy_value
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor, tf_tensor_shape
-from openvino.tools.mo.ops.op import Op
-
-
-class PlaceholderWithDefaultExtractor(FrontExtractorOp):
- op = 'PlaceholderWithDefault'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'data_type': tf_dtype_extractor(node.pb.attr["dtype"].type),
- 'shape': tf_tensor_shape(node.pb.attr["shape"].shape),
- 'identity': True,
- 'infer': lambda node: copy_shape_infer(node, value_infer=copy_value),
- }
- Op.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/pooling_ext.py b/tools/mo/openvino/tools/mo/front/tf/pooling_ext.py
deleted file mode 100644
index 9f224cd433047c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/pooling_ext.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import convert_tf_padding_to_str
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_data_format_spatial, tf_int_list
-from openvino.tools.mo.ops.pooling import Pooling, PoolingV2
-
-
-class AvgPoolFrontExtractor(FrontExtractorOp):
- op = 'AvgPool'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = create_pooling_attrs(node, 'avg')
- attrs.update({'op': __class__.op})
- # update the attributes of the node
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class MaxPoolFrontExtractor(FrontExtractorOp):
- op = 'MaxPool'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = create_pooling_attrs(node, 'max')
- attrs.update({'op': __class__.op})
- # update the attributes of the node
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class MaxPool3DFrontExtractor(FrontExtractorOp):
- op = 'MaxPool3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = create_pooling_attrs(node, 'max')
- attrs.update({'op': __class__.op})
- # update the attributes of the node
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class AvgPool3DFrontExtractor(FrontExtractorOp):
- op = 'AvgPool3D'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = create_pooling_attrs(node, 'avg')
- attrs.update({'op': __class__.op})
- # update the attributes of the node
- Pooling.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class AvgPoolV2FrontExtractor(FrontExtractorOp):
- op = 'AvgPoolV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = create_pooling_attrs(node, 'avg')
- PoolingV2.update_node_stat(node, attrs)
- return cls.enabled
-
-
-class MaxPoolV2FrontExtractor(FrontExtractorOp):
- op = 'MaxPoolV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = create_pooling_attrs(node, 'max')
- PoolingV2.update_node_stat(node, attrs)
- return cls.enabled
-
-
-def create_pooling_attrs(node, pool_method):
- data_format = node.pb.attr["data_format"]
-
- attrs = {
- 'auto_pad': convert_tf_padding_to_str(node.pb.attr['padding'].s.decode()),
- 'window': tf_int_list(node.pb.attr['ksize'].list),
- 'spatial_dims': tf_data_format_spatial(data_format),
- 'pad': None, # will be inferred when input shape is known
- 'stride': tf_int_list(node.pb.attr['strides'].list),
- 'pad_spatial_shape': None,
- 'output_spatial_shape': None,
- 'pool_method': pool_method,
- 'layout': data_format.s.decode(),
- 'exclude_pad': True,
- }
- return attrs
diff --git a/tools/mo/openvino/tools/mo/front/tf/prelu.py b/tools/mo/openvino/tools/mo/front/tf/prelu.py
deleted file mode 100644
index 2c9d6246effdb2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/prelu.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.PowerToEltwises import PowerToEltwises
-from openvino.tools.mo.ops.prelu import PReLU
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.pattern_match import check_node_usages_out_of_match
-
-
-class PReLUPatternFuse(FrontReplacementSubgraph):
- enabled = True
-
- def run_before(self):
- return [PowerToEltwises]
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op')),
- ('pos_relu', dict(kind='op', op='ReLU')),
- ('neg', dict(kind='op', op='AttributedPower', scale=-1, power=1, shift=0)),
- ('neg_relu', dict(kind='op', op='ReLU')),
- ('neg_1', dict(kind='op', op='AttributedPower', scale=-1, power=1, shift=0)),
- ('mul', dict(kind='op', op='Mul')),
- ('add', dict(kind='op', op='Add')),
- ],
- edges=[
- ('op', 'pos_relu'),
- ('op', 'neg'),
- ('pos_relu', 'add'),
- ('neg', 'neg_relu'),
- ('neg_relu', 'neg_1'),
- ('neg_1', 'mul'),
- ('mul', 'add')
- ]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- consumers = [n for n in match if n not in ['mul', 'op', 'add'] and not check_node_usages_out_of_match(match, n)]
- if consumers:
- log.warning('PReLU pattern was detected. Non pattern consumers of nodes: "{}" were found. Won\'t replace'
- ''.format(', '.join([match[n].id for n in consumers])))
- return
- gamma = match['mul'].in_node(0) if match['mul'].in_node(1).id == match['neg_1'].id else match['mul'].in_node(1)
- prelu_node = PReLU(graph, {'name': '{}/PReLU'.format(match['add'].id)}).create_node([match['op'], gamma])
- match['add'].replace_node(prelu_node)
- log.debug('PReLU pattern starting from "{}" was collapsed to "{}"'.format(match['op'].id, prelu_node.id))
-
-
-class PReLUWithAbsPatternFuse(FrontReplacementSubgraph):
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op')),
- ('relu', dict(kind='op', op='ReLU')),
- ('abs', dict(kind='op', op='Abs')),
- ('sub', dict(kind='op', op='Sub')),
- ('mul', dict(kind='op', op='Mul')),
- ('mul_1', dict(kind='op', op='Mul')),
- ('add', dict(kind='op', op='Add')),
- ],
- edges=[
- ('op', 'relu'),
- ('op', 'abs'),
- ('op', 'sub'),
- ('abs', 'sub'),
- ('sub', 'mul'),
- ('mul', 'mul_1'),
- ('relu', 'add'),
- ('mul_1', 'add'),
- ]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- consumers = [n for n in match if
- n not in ['mul', 'mul_1', 'op', 'add', 'abs', 'sub'] and not check_node_usages_out_of_match(match,
- n)]
- if consumers:
- log.warning('PReLUWithAbs pattern was detected. Non pattern consumers of nodes: "{}" were found. Won\'t '
- 'replace '.format(', '.join([match[n].id for n in consumers])))
- return
- gamma = match['mul'].in_node(0) if match['mul'].in_node(1).id == match['sub'].id else match['mul'].in_node(1)
- prelu_node = PReLU(graph, {'name': '{}/PReLU'.format(match['add'].id)}).create_node([match['op'], gamma])
- match['add'].replace_node(prelu_node)
- log.debug('PReLUWithAbs pattern starting from "{}" was collapsed to "{}"'.format(match['op'].id, prelu_node.id))
diff --git a/tools/mo/openvino/tools/mo/front/tf/random_uniform_ext.py b/tools/mo/openvino/tools/mo/front/tf/random_uniform_ext.py
deleted file mode 100644
index 1c4919e3aba7ac..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/random_uniform_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.random_uniform import AttributedRandomUniform
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class RandomUniformExtractor(FrontExtractorOp):
- op = 'RandomUniform'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'output_type': tf_dtype_extractor(node.pb.attr["dtype"].type),
- 'global_seed': node.pb.attr['seed'].i,
- 'op_seed': node.pb.attr['seed2'].i
- }
- AttributedRandomUniform.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/random_uniform_int_ext.py b/tools/mo/openvino/tools/mo/front/tf/random_uniform_int_ext.py
deleted file mode 100644
index 5a335022472a6d..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/random_uniform_int_ext.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.random_uniform import RandomUniform
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class RandomUniformIntExtractor(FrontExtractorOp):
- op = 'RandomUniformInt'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {
- 'output_type': tf_dtype_extractor(node.pb.attr["Tout"].type),
- 'global_seed': node.pb.attr['seed'].i,
- 'op_seed': node.pb.attr['seed2'].i
- }
- RandomUniform.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/range_ext.py b/tools/mo/openvino/tools/mo/front/tf/range_ext.py
deleted file mode 100644
index df390b442ea6d0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/range_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-from openvino.tools.mo.graph.graph import Node
-
-
-class RangeFrontExtractor(FrontExtractorOp):
- op = 'Range'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Range.update_node_stat(node, {'output_type': tf_dtype_extractor(node.pb.attr['Tidx'].type)})
- return cls.enabled
-
diff --git a/tools/mo/openvino/tools/mo/front/tf/reduce_ext.py b/tools/mo/openvino/tools/mo/front/tf/reduce_ext.py
deleted file mode 100644
index 81f7403ffbed68..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/reduce_ext.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ReduceOps import ReduceProd, ReduceAnd, ReduceMax, ReduceMean, ReduceSum, ReduceL2, \
- ReduceMin, ReduceLogicalOr
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-
-
-class AllFrontExtractor(FrontExtractorOp):
- op = 'All'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- keep_dims = node.pb.attr['keep_dims'].b
- ReduceAnd.update_node_stat(node, {'keep_dims': keep_dims})
- return cls.enabled
-
-
-class AnyExtractor(FrontExtractorOp):
- op = 'Any'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- ReduceLogicalOr.update_node_stat(node, {'keep_dims': node.pb.attr['keep_dims'].b})
- return cls.enabled
-
-
-class MaxFrontExtractor(FrontExtractorOp):
- op = 'Max'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- ReduceMax.update_node_stat(node, {'keep_dims': node.pb.attr['keep_dims'].b})
- return cls.enabled
-
-
-class MinFrontExtractor(FrontExtractorOp):
- op = 'Min'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- ReduceMin.update_node_stat(node, {'keep_dims': node.pb.attr['keep_dims'].b})
- return cls.enabled
-
-
-class MeanExtractor(FrontExtractorOp):
- op = 'Mean'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- ReduceMean.update_node_stat(node, {'keep_dims': node.pb.attr["keep_dims"].b})
- return cls.enabled
-
-
-class ProdFrontExtractor(FrontExtractorOp):
- op = 'Prod'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- ReduceProd.update_node_stat(node, {'keep_dims': node.pb.attr["keep_dims"].b})
- return cls.enabled
-
-
-class SumFrontExtractor(FrontExtractorOp):
- op = 'Sum'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- ReduceSum.update_node_stat(node, {'keep_dims': node.pb.attr["keep_dims"].b})
- return cls.enabled
-
-
-class EuclideanNormFrontExtractor(FrontExtractorOp):
- op = 'EuclideanNorm'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- ReduceL2.update_node_stat(node, {'keep_dims': node.pb.attr["keep_dims"].b})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/register_custom_ops.py b/tools/mo/openvino/tools/mo/front/tf/register_custom_ops.py
deleted file mode 100644
index 1e2be280b06390..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/register_custom_ops.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp, FrontReplacementPattern, FrontReplacementSubgraph
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileSubGraph, FrontReplacementFromConfigFileOp, \
- FrontReplacementFromConfigFileGeneral
-
-
-def get_front_classes():
- front_classes = [FrontExtractorOp, FrontReplacementOp, FrontReplacementPattern, FrontReplacementSubgraph,
- FrontReplacementFromConfigFileSubGraph, FrontReplacementFromConfigFileOp,
- FrontReplacementFromConfigFileGeneral]
- return front_classes
diff --git a/tools/mo/openvino/tools/mo/front/tf/replacement.py b/tools/mo/openvino/tools/mo/front/tf/replacement.py
deleted file mode 100644
index 62069a1ea80006..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/replacement.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.front.common.custom_replacement_registry import CustomReplacementRegistry
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph, FrontReplacementPattern
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatcher, SubgraphMatch
-from openvino.tools.mo.front.tf.custom_subgraph_call import merge_nodes
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils import class_registration
-from openvino.tools.mo.utils.graph import is_connected_component
-from openvino.tools.mo.utils.replacement_pattern import ReplacementPattern
-
-
-class FrontReplacementFromConfigFileGeneral(FrontReplacementPattern):
- """
- Translates graph to transform with the configuration files with custom attributes
- """
- replacement_id = ""
-
- def __init__(self):
- super().__init__()
-
- def transform_graph(self, graph, replacement_descriptions):
- raise Exception('Function "transform_graph" must be overridden in the sub-class')
-
- def find_and_replace_pattern(self, graph: Graph):
- replacement_descriptions = CustomReplacementRegistry().get_custom_replacement_description(self.replacement_id)
- if replacement_descriptions is None or len(replacement_descriptions) < 1:
- log.info("Failed to find custom replacement description with id '{}'".format(self.replacement_id))
- return
- for desc in replacement_descriptions:
- if 'custom_attributes' in desc._replacement_desc:
- self.transform_graph(graph, desc._replacement_desc['custom_attributes'])
- else:
- log.info("Failed to find \'custom_attributes\' in replacement description with id '{}'".format(
- self.replacement_id))
-
- registered_ops = {}
- registered_cls = []
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.FRONT_REPLACER
-
-
-ReplacementPattern.excluded_replacers.append(FrontReplacementFromConfigFileGeneral)
-
-
-class FrontReplacementFromConfigFileSubGraph(FrontReplacementSubgraph):
- """
- Replace sub-graph defined in the configuration files with a sub-graph of operations.
- """
- replacement_id = ""
-
- def __init__(self):
- super().__init__()
-
- def nodes_to_remove(self, graph: Graph, match: SubgraphMatch):
- return match.matched_nodes_names()
-
- def find_and_replace_pattern(self, graph: Graph):
- replacement_descriptions = CustomReplacementRegistry().get_custom_replacement_description(self.replacement_id)
- if replacement_descriptions is None:
- log.info("Failed to find custom replacement description with id '{}'".format(self.replacement_id))
- return
- # there are a list of custom replacements descriptions that have the same replacement id
- for replacement_description in replacement_descriptions:
- sub_graph_matcher = SubgraphMatcher(replacement_description)
- matched_instances = list(sub_graph_matcher.matched_sub_graph_instances(graph))
- if not len(matched_instances):
- log.error("Failed to match nodes from custom replacement description with id '{}':\nIt means model and "
- "custom replacement description are incompatible.\nTry to correct custom replacement "
- "description according to documentation with respect to model node names"
- "".format(self.replacement_id))
- for match in matched_instances:
- if not is_connected_component(graph, match.matched_nodes_names()):
- log.warning("The following nodes don't form connected sub-graph: {}".format(
- match.matched_nodes_names()))
- # graph.dump_graph_for_graphviz(match.matched_nodes_names())
- self.replace_sub_graph(graph, match)
-
- registered_ops = {}
- registered_cls = []
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.FRONT_REPLACER
-
-
-ReplacementPattern.excluded_replacers.append(FrontReplacementFromConfigFileSubGraph)
-
-
-class FrontReplacementFromConfigFileOp(FrontReplacementFromConfigFileSubGraph):
- """
- Replace sub-graph defined in the configuration file with as single operation.
- """
- replacement_id = ""
-
- def __init__(self):
- super().__init__()
-
- def input_edges_match(self, # pylint: disable=method-hidden
- graph: Graph,
- match: SubgraphMatch,
- new_sub_graph: dict):
- """
- Function that generates matching of sub-graph input edges to a new sub-graph input edges. It works in case when
- the sub-graph is replaced with a single custom-layer node.
- :param graph: networkX graph to operate on.
- :param match: object describing matched sub-graph.
- :param new_sub_graph: dictionary of Nodes objects that forms new sub-graph.
- :return: object describing edges matching.
- """
- input_edges_match = dict()
- inputs_count = match.inputs_count()
- for sub_graph_input_port in range(inputs_count):
- # just create single edge for each input port of the sub-graph
- input_node, input_port = match.input_nodes(sub_graph_input_port)[0]
- input_edges_match[(input_node.id, input_port)] = (new_sub_graph['new_node'].id, sub_graph_input_port)
- return input_edges_match
-
- def output_edges_match(self, # pylint: disable=method-hidden
- graph: Graph,
- match: SubgraphMatch,
- new_sub_graph: dict):
- """
- Function that generates matching of sub-graph output edges to a new sub-graph output edges. It works in case
- when the sub-graph is replaced with a single custom-layer node.
- :param graph: networkX graph to operate on.
- :param match: object describing matched sub-graph.
- :param new_sub_graph: dictionary of Nodes objects that forms new sub-graph.
- :return: object describing edges matching.
- """
- output_edges_match = dict()
- outputs_count = match.outputs_count()
- # prepare output_edges_match based on custom replacement configuration file
- for sub_graph_output_port in range(outputs_count):
- output_node, output_port = match.output_node(sub_graph_output_port)
- output_edges_match[(output_node.id, output_port)] = (new_sub_graph['new_node'].id, sub_graph_output_port)
- return output_edges_match
-
- def generate_sub_graph(self, graph: Graph, match: SubgraphMatch):
- replacement_desc = match.custom_replacement_desc
- op = Op.get_op_class_by_name(replacement_desc.op)(graph, match.custom_replacement_desc.custom_attributes)
- op.default_backend_attrs = list(match.custom_replacement_desc.custom_attributes.keys())
- if 'infer' not in op.attrs:
- # update OV attrs
- op.substitute_ie_attrs(op.attrs)
- node = merge_nodes(graph, match.matched_nodes_names(), replacement_desc.get_inputs_description(),
- replacement_desc.get_outputs_description())
- node.name = graph.unique_id(op.attrs['type'])
- node_attrs = graph.node[node.id]
- # copy attributes which are defined in the custom operation
- for key in op.attrs.keys():
- if key not in ['name', 'op']:
- node_attrs[key] = op.attrs[key]
- # functions below should return nothing because 'merge_nodes' already created input/output edges
- self.input_edges_match = lambda gr, ma, new_sub_graph: dict() # pylint: disable=method-hidden
- self.output_edges_match = lambda gr, ma, new_sub_graph: dict() # pylint: disable=method-hidden
- else:
- node = op.add_node(name=op.attrs['type'] + '_')
- node.type = op.attrs['type']
- return {'new_node': node}
-
- registered_ops = {}
- registered_cls = []
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.FRONT_REPLACER
-
-
-ReplacementPattern.excluded_replacers.append(FrontReplacementFromConfigFileOp)
diff --git a/tools/mo/openvino/tools/mo/front/tf/reshape_related_ext.py b/tools/mo/openvino/tools/mo/front/tf/reshape_related_ext.py
deleted file mode 100644
index 985070cd7dddc9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/reshape_related_ext.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.rank import Rank
-from openvino.tools.mo.ops.size import Size
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_int_list, tf_dtype_extractor
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-class RankFrontExtractor(FrontExtractorOp):
- op = 'Rank'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Rank.update_node_stat(node, {'output_type': np.int32})
- return cls.enabled
-
-
-class ReshapeExtractor(FrontExtractorOp):
- op = 'Reshape'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Reshape.update_node_stat(node, {'special_zero': False})
- return cls.enabled
-
-
-class ShapeExtractor(FrontExtractorOp):
- op = 'Shape'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Shape.update_node_stat(node, {'output_type': tf_dtype_extractor(node.pb.attr['out_type'].type, np.int32)})
- return cls.enabled
-
-
-class SizeFrontExtractor(FrontExtractorOp):
- op = 'Size'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Size.update_node_stat(node, {'output_type': tf_dtype_extractor(node.pb.attr['out_type'].type, np.int32)})
- return cls.enabled
-
-
-class SqueezeExtractor(FrontExtractorOp):
- op = 'Squeeze'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Squeeze.update_node_stat(node, {'squeeze_dims': tf_int_list(node.pb.attr['squeeze_dims'].list)})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/resize_bilinear.py b/tools/mo/openvino/tools/mo/front/tf/resize_bilinear.py
deleted file mode 100644
index 8112489d6e7428..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/resize_bilinear.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.TFResize import TFResize
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.front.tf.extractors.utils import tf_dtype_extractor
-
-
-class ResizeBilinearFrontExtractor(FrontExtractorOp):
- op = 'ResizeBilinear'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- align_corners = False
- if 'align_corners' in node.pb.attr:
- align_corners = node.pb.attr['align_corners'].b
-
- half_pixel_centers = False
- if 'half_pixel_centers' in node.pb.attr:
- half_pixel_centers = node.pb.attr['half_pixel_centers'].b
-
- attrs = {
- 'align_corners': align_corners,
- 'half_pixel_centers': half_pixel_centers,
- 'mode': 'linear',
- 'data_type': tf_dtype_extractor(node.pb.attr["T"].type),
- }
- TFResize.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/resize_nearest_neighbor.py b/tools/mo/openvino/tools/mo/front/tf/resize_nearest_neighbor.py
deleted file mode 100644
index a9be8e7aa50cc1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/resize_nearest_neighbor.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.TFResize import TFResize
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class ResizeNearestNeighborFrontExtractor(FrontExtractorOp):
- op = 'ResizeNearestNeighbor'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- align_corners = False
- if 'align_corners' in node.pb.attr:
- align_corners = node.pb.attr['align_corners'].b
-
- half_pixel_centers = False
- if 'half_pixel_centers' in node.pb.attr:
- half_pixel_centers = node.pb.attr['half_pixel_centers'].b
-
- attrs = {
- 'align_corners': align_corners,
- 'half_pixel_centers': half_pixel_centers,
- 'mode': 'nearest'
- }
- TFResize.update_node_stat(node, attrs)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/retinanet.json b/tools/mo/openvino/tools/mo/front/tf/retinanet.json
deleted file mode 100644
index 0254fe9d61964a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/retinanet.json
+++ /dev/null
@@ -1,30 +0,0 @@
-[
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CORNER",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "confidence_threshold": 0.05,
- "top_k": 6000,
- "keep_top_k": 300,
- "variance": [0.2, 0.2, 0.2, 0.2]
- },
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "id": "RetinaNetFilteredDetectionsReplacement",
- "instances": {
- "end_points": [
- "filtered_detections/map/TensorArrayStack/TensorArrayGatherV3",
- "filtered_detections/map/TensorArrayStack_1/TensorArrayGatherV3",
- "filtered_detections/map/TensorArrayStack_2/TensorArrayGatherV3"
- ],
- "start_points": [
- "regression/concat",
- "classification/concat",
- "anchors/concat",
- "clipped_boxes/Shape"
- ]
- },
- "match_kind": "points"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/reverse_sequence.py b/tools/mo/openvino/tools/mo/front/tf/reverse_sequence.py
deleted file mode 100644
index 94b40bb6bc5777..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/reverse_sequence.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.reverse_sequence import ReverseSequence
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class ReverseSequenceFrontExtractor(FrontExtractorOp):
- op = 'ReverseSequence'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- if node.has_valid('seq_dim'):
- return
-
- ReverseSequence.update_node_stat(node, {
- 'seq_axis': node.pb.attr['seq_dim'].i,
- 'batch_axis': node.pb.attr['batch_dim'].i,
- })
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/reverse_v2.py b/tools/mo/openvino/tools/mo/front/tf/reverse_v2.py
deleted file mode 100644
index 9ae3c412331008..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/reverse_v2.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.Reverse import Reverse
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class ReverseV2FrontExtractor(FrontExtractorOp):
- op = 'ReverseV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Reverse.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/rfcn_support.json b/tools/mo/openvino/tools/mo/front/tf/rfcn_support.json
deleted file mode 100644
index e69be6ee1c56b1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/rfcn_support.json
+++ /dev/null
@@ -1,106 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false,
- "do_not_swap_proposals": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "FirstStageBoxPredictor/Reshape",
- "FirstStageBoxPredictor/Reshape_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": true,
- "clip_after_nms": false,
- "swap_proposals": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.10.json b/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.10.json
deleted file mode 100644
index b630bc9c9b26db..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.10.json
+++ /dev/null
@@ -1,145 +0,0 @@
-[
- {
- "custom_attributes": {},
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_1/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "FirstStageBoxPredictor/Reshape",
- "FirstStageBoxPredictor/Reshape_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {},
- "id": "ObjectDetectionAPIPSROIPoolingReplacement",
- "inputs": [
- [
- {
- "node": "Shape$",
- "port": 0
- },
- {
- "node": "TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ],
- [
- {
- "node": "TensorArrayUnstack_1/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- },
- {
- "node": "TensorArrayUnstack_1/Shape$",
- "port": 0
- }
- ]
- ],
- "instances": [
- "SecondStageBoxPredictor/map/",
- "SecondStageBoxPredictor/map_1/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.13.json b/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.13.json
deleted file mode 100644
index 5c014ae51357ab..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.13.json
+++ /dev/null
@@ -1,145 +0,0 @@
-[
- {
- "custom_attributes": {},
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_4/TensorArrayGatherV3"
- ],
- "start_points": [
- "FirstStageBoxPredictor/Reshape",
- "FirstStageBoxPredictor/Reshape_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {},
- "id": "ObjectDetectionAPIPSROIPoolingReplacement",
- "inputs": [
- [
- {
- "node": "Shape$",
- "port": 0
- },
- {
- "node": "TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ],
- [
- {
- "node": "TensorArrayUnstack_1/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- },
- {
- "node": "TensorArrayUnstack_1/Shape$",
- "port": 0
- }
- ]
- ],
- "instances": [
- "SecondStageBoxPredictor/map/",
- "SecondStageBoxPredictor/map_1/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.14.json b/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.14.json
deleted file mode 100644
index 1b147c79cee82a..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/rfcn_support_api_v1.14.json
+++ /dev/null
@@ -1,145 +0,0 @@
-[
- {
- "custom_attributes": {},
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "operation_to_add": "Proposal",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIProposalReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "map/TensorArrayStack/TensorArrayGatherV3",
- "map_2/TensorArrayStack/TensorArrayGatherV3",
- "BatchMultiClassNonMaxSuppression/map/TensorArrayStack_5/TensorArrayGatherV3"
- ],
- "start_points": [
- "FirstStageBoxPredictor/Reshape",
- "FirstStageBoxPredictor/Reshape_1",
- "GridAnchorGenerator/Identity",
- "Shape"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPIDetectionOutputReplacement",
- "inputs": [
- [
- {
- "node": "Reshape$",
- "port": 0
- }
- ],
- [
- {
- "node": "Reshape_1$",
- "port": 0
- }
- ],
- [
- {
- "node": "ExpandDims$",
- "port": 0
- }
- ]
- ],
- "instances": [
- ".*SecondStagePostprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "BatchMultiClassNonMaxSuppression/map/TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {},
- "id": "ObjectDetectionAPIPSROIPoolingReplacement",
- "inputs": [
- [
- {
- "node": "Shape$",
- "port": 0
- },
- {
- "node": "TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ],
- [
- {
- "node": "TensorArrayUnstack_1/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- },
- {
- "node": "TensorArrayUnstack_1/Shape$",
- "port": 0
- }
- ]
- ],
- "instances": [
- "SecondStageBoxPredictor/map/",
- "SecondStageBoxPredictor/map_1/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "TensorArrayStack/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "outputs": "detection_boxes"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/roll_ext.py b/tools/mo/openvino/tools/mo/front/tf/roll_ext.py
deleted file mode 100644
index de52db2272cc78..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/roll_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.roll import Roll
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class RollExtractor(FrontExtractorOp):
- op = 'Roll'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Roll.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/scatter_nd_ext.py b/tools/mo/openvino/tools/mo/front/tf/scatter_nd_ext.py
deleted file mode 100644
index a9539afbf4f0ef..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/scatter_nd_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.scatternd import TFScatterND
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class ScatterNDExtractor(FrontExtractorOp):
- op = 'ScatterNd'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- TFScatterND.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/select_ext.py b/tools/mo/openvino/tools/mo/front/tf/select_ext.py
deleted file mode 100644
index 711e2524db835b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/select_ext.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-
-
-class SelectExtractor(FrontExtractorOp):
- op = 'Select'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Select.update_node_stat(node, {'format': 'tf',})
- return cls.enabled
-
-
-class SelectV2Extractor(FrontExtractorOp):
- op = 'SelectV2'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Select.update_node_stat(node, {'format': 'tf'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/sign_ext.py b/tools/mo/openvino/tools/mo/front/tf/sign_ext.py
deleted file mode 100644
index f162bc17f46c1f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/sign_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import Sign
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SignExtractor(FrontExtractorOp):
- op = 'Sign'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Sign.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/slice_ext.py b/tools/mo/openvino/tools/mo/front/tf/slice_ext.py
deleted file mode 100644
index 6ae0bbd3701626..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/slice_ext.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.slice import TFSlice
-
-
-class SliceExtractor(FrontExtractorOp):
- op = 'Slice'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- TFSlice.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/softmax_ext.py b/tools/mo/openvino/tools/mo/front/tf/softmax_ext.py
deleted file mode 100644
index 5679cdfe1fac01..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/softmax_ext.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.softmax import Softmax
-
-
-class SoftmaxExtractor(FrontExtractorOp):
- op = 'Softmax'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # the default value for the TF Softmax is -1
- axis = -1
- if 'axis' in node.pb.attr:
- axis = node.pb.attr['axis'].i
- Softmax.update_node_stat(node, {'axis': axis})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/softplus_ext.py b/tools/mo/openvino/tools/mo/front/tf/softplus_ext.py
deleted file mode 100644
index 83e969404f4a2b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/softplus_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.activation_ops import SoftPlus
-
-
-class SoftPlusExtractor(FrontExtractorOp):
- op = 'Softplus'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- SoftPlus.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/space_to_batch.py b/tools/mo/openvino/tools/mo/front/tf/space_to_batch.py
deleted file mode 100644
index d5c7b6f79f9721..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/space_to_batch.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Sub
-from openvino.tools.mo.ops.rank import Rank
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs, create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.pad import Pad
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class BatchToSpaceNormalizer(FrontReplacementPattern):
- """
- This transformation converts BatchToSpace, SpaceToBatch operations (TensorFlow semantic)
- to BatchToSpace, SpaceToBatch operations (OpenVINO semantic).
- Refer to the Op implementation for the operations semantics description.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.rank_decomposer import RankDecomposer
- return [RankDecomposer]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='SpaceToBatch') + graph.get_op_nodes(op='BatchToSpace'):
- node.add_input_port(3, skip_if_exist=True)
-
- # convert TF representation of the pads/crops as [N, 2] to OV representation: [N] and [N]
- transposed_pads = create_op_with_const_inputs(graph, Transpose, {1: int64_array([1, 0])})
- node.in_port(2).get_connection().set_destination(transposed_pads.in_port(0))
- split_pads = create_op_with_const_inputs(graph, Split, {1: int64_array(0)}, {'num_splits': 2})
- transposed_pads.out_port(0).connect(split_pads.in_port(0))
- for port_ind in range(2):
- node.in_port(port_ind + 2).connect(split_pads.out_port(port_ind))
- node.in_port(port_ind + 2).get_connection().insert_node(
- create_op_with_const_inputs(graph, Squeeze, {1: int64_array([0])}))
-
- # add zeros/ones to related inputs to align it with data input
- in0_rank = Rank(graph, {'name': node.name + '/rank_0'}).create_node()
- in1_shape = Shape(graph, {'name': node.name + '/rank_1'}).create_node()
-
- diff_size = Sub(graph, {'name': node.name + '/sub_0'}).create_node()
- diff = Sub(graph, {'name': node.name + '/sub_1'}).create_node()
- const_begin = Const(graph, {'value': int64_array([1])}).create_node()
- const_pad_val = Const(graph, {'value': int64_array(1)}).create_node()
-
- block_shape = Pad(graph, {'name': node.name + '/aligned_block_shape', 'mode': 'constant'}).create_node()
-
- # in case of SpaceToBatch begin = pads_begin, end = pads_end
- # in case of BatchToSpace begin = crops_begin, end = crops_end
- new_begin_name = '/aligned_pads_begin'
- new_end_name = '/aligned_pads_end'
- if node.type == 'BatchToSpace':
- new_begin_name = '/aligned_crops_begin'
- new_end_name = '/aligned_crops_end'
-
- begin = Pad(graph, {'name': node.name + new_begin_name, 'mode': 'constant'}).create_node()
- end = Pad(graph, {'name': node.name + new_end_name, 'mode': 'constant'}).create_node()
-
- in0_rank_1d = create_op_node_with_second_input(graph, Unsqueeze, int64_array([0]),
- {'name': node.name + '/1d_rank_of_0'}, in0_rank)
-
- node.in_port(0).get_source().connect(in0_rank.in_port(0))
- node.in_port(1).get_source().connect(in1_shape.in_port(0))
- in0_rank_1d.out_port(0).connect(diff_size.in_port(0))
- in1_shape.out_port(0).connect(diff_size.in_port(1))
- diff_size.out_port(0).connect(diff.in_port(0))
- const_begin.out_port(0).connect(diff.in_port(1))
- const_pad_val.out_port(0).connect(block_shape.in_port(3))
-
- inputs_array = [block_shape, begin, end]
- for idx, input_to_node in enumerate(inputs_array):
- name_of_input_to_node = input_to_node.name
- node.in_port(idx + 1).get_connection().set_destination(input_to_node.in_port(0))
- const_begin.out_port(0).connect(input_to_node.in_port(1))
- diff.out_port(0).connect(input_to_node.in_port(2))
- input_to_node.out_port(0).connect(node.in_port(idx + 1))
- convert = Cast(graph, {'name': name_of_input_to_node + '/i64', 'dst_type': np.int64}).create_node()
- input_to_node.in_port(0).get_connection().insert_node(convert)
diff --git a/tools/mo/openvino/tools/mo/front/tf/space_to_batch_ext.py b/tools/mo/openvino/tools/mo/front/tf/space_to_batch_ext.py
deleted file mode 100644
index 5cfa28b6afb19e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/space_to_batch_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.space_to_batch import SpaceToBatch
-
-
-class SpaceToBatchFrontExtractor(FrontExtractorOp):
- op = 'SpaceToBatchND'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- SpaceToBatch.update_node_stat(node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/space_to_depth_ext.py b/tools/mo/openvino/tools/mo/front/tf/space_to_depth_ext.py
deleted file mode 100644
index 6e99271c404d11..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/space_to_depth_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.space_to_depth import SpaceToDepth
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SpaceToDepthFrontExtractor(FrontExtractorOp):
- op = 'SpaceToDepth'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # update the attributes of the node
- block_size = node.pb.attr['block_size'].i
- data_format = node.pb.attr['data_format'].s.decode('utf-8')
- SpaceToDepth.update_node_stat(node, {'block_size': block_size, 'data_format': data_format})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/sparse_fill_empty_rows_ext.py b/tools/mo/openvino/tools/mo/front/tf/sparse_fill_empty_rows_ext.py
deleted file mode 100644
index 9ff68256f2d888..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/sparse_fill_empty_rows_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.sparse_fill_empty_rows import SparseFillEmptyRows
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SparseFillEmptyRowsFrontExtractor(FrontExtractorOp):
- op = 'SparseFillEmptyRows'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {}
-
- SparseFillEmptyRows.update_node_stat(node, attrs)
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/sparse_segment_mean_ext.py b/tools/mo/openvino/tools/mo/front/tf/sparse_segment_mean_ext.py
deleted file mode 100644
index 232f85791bfc32..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/sparse_segment_mean_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.sparse_segment_mean import SparseSegmentMean
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SparseSegmentMeanFrontExtractor(FrontExtractorOp):
- op = 'SparseSegmentMean'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {}
-
- SparseSegmentMean.update_node_stat(node, attrs)
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/sparse_segment_sqrtn_ext.py b/tools/mo/openvino/tools/mo/front/tf/sparse_segment_sqrtn_ext.py
deleted file mode 100644
index 8e53bf8637df6f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/sparse_segment_sqrtn_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.sparse_segment_sqrtn import SparseSegmentSqrtN
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SparseSegmentSqrtNFrontExtractor(FrontExtractorOp):
- op = 'SparseSegmentSqrtN'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {}
-
- SparseSegmentSqrtN.update_node_stat(node, attrs)
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/sparse_segment_sum_ext.py b/tools/mo/openvino/tools/mo/front/tf/sparse_segment_sum_ext.py
deleted file mode 100644
index 593d426fed53cb..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/sparse_segment_sum_ext.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.sparse_segment_sum import SparseSegmentSum
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class SparseSegmentSumFrontExtractor(FrontExtractorOp):
- op = 'SparseSegmentSum'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- attrs = {}
-
- SparseSegmentSum.update_node_stat(node, attrs)
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/sparse_to_dense_replacer.py b/tools/mo/openvino/tools/mo/front/tf/sparse_to_dense_replacer.py
deleted file mode 100644
index 6a4857ab547da4..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/sparse_to_dense_replacer.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementOp
-from openvino.tools.mo.graph.graph import Node, Graph, rename_nodes
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.scatternd import ScatterNDUpdate
-
-
-class SparseToDenseReplacer(FrontReplacementOp):
- """
- This replacer substitutes TensorFlow SparseToDense operation with Broadcast -> ScatterND chain.
- The Broadcast operation creates a tensor filled with default value and of required shape.
- The ScatterND operation updates the created tensor with required values at required locations.
- """
- op = "SparseToDense"
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.front.tf.CTCGreedyDecoderReplacement import CTCGreedyDecoderReplacement
- from openvino.tools.mo.front.tf.CTCLossReplacement import CTCLossReplacement
- return [CTCGreedyDecoderReplacement, CTCLossReplacement]
-
- def replace_op(self, graph: Graph, node: Node):
- node_name = node.soft_get('name', node.id)
-
- # broadcast default value to required shape
- broadcast_node = Broadcast(graph, {'name': node_name + '/Broadcast_'}).create_node()
- node.in_port(1).get_connection().set_destination(broadcast_node.in_port(1))
- if not node.in_port(3).disconnected():
- node.in_port(3).get_connection().set_destination(broadcast_node.in_port(0))
- else:
- broadcast_node.in_port(0).connect(Const(graph, {'name': broadcast_node.name + '/FillValue_',
- 'value': np.float32(0)}
- ).create_node().out_port(0))
-
- # update broadcasted tensor with required values at required locations
- scatternd_node = ScatterNDUpdate(graph, {'name': node_name + '/ScatterNDUpdate_'}).create_node()
- scatternd_node.in_port(0).connect(broadcast_node.out_port(0))
- node.in_port(0).get_connection().set_destination(scatternd_node.in_port(1))
- node.in_port(2).get_connection().set_destination(scatternd_node.in_port(2))
-
- rename_nodes([(node, node_name + "/AbandonedName"), (scatternd_node, node_name)])
-
- return [scatternd_node.id]
diff --git a/tools/mo/openvino/tools/mo/front/tf/split_ext.py b/tools/mo/openvino/tools/mo/front/tf/split_ext.py
deleted file mode 100644
index 6f5ded238c7376..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/split_ext.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.split import VariadicSplit, Split, AttributedSplit
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-
-
-class SplitVExtractor(FrontExtractorOp):
- op = 'SplitV'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- VariadicSplit.update_node_stat(node, {'out_ports_count': node.pb.attr['num_split'].i,
- 'swap_axis_and_split_size_inputs': True})
- return cls.enabled
-
-
-class UnpackExtractor(FrontExtractorOp):
- op = 'Unpack'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- pb = node.pb
- AttributedSplit.update_node_stat(node,
- {
- 'axis': pb.attr['axis'].i,
- 'num_splits': pb.attr['num'].i,
- 'squeeze_axis': True,
- })
- return cls.enabled
-
-
-class SplitExtractor(FrontExtractorOp):
- op = 'Split'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- pb = node.pb
- Split.update_node_stat(node, {
- 'num_splits': pb.attr['num_split'].i,
- 'input_port': 1,
- })
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_support.json b/tools/mo/openvino/tools/mo/front/tf/ssd_support.json
deleted file mode 100644
index 3c728ec956119c..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_support.json
+++ /dev/null
@@ -1,64 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": true,
- "clip_after_nms": false
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "detection_boxes",
- "detection_scores",
- "num_detections"
- ],
- "start_points": [
- "Postprocessor/Shape",
- "Postprocessor/Slice",
- "Postprocessor/ExpandDims",
- "Postprocessor/Reshape_1",
- "Postprocessor/ToFloat"
- ]
- },
- "match_kind": "points"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v1.14.json b/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v1.14.json
deleted file mode 100644
index 5fee821300e0c0..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v1.14.json
+++ /dev/null
@@ -1,64 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "detection_boxes",
- "detection_scores",
- "num_detections"
- ],
- "start_points": [
- "Postprocessor/Shape",
- "Postprocessor/scale_logits",
- "Postprocessor/Tile",
- "Postprocessor/Reshape_1",
- "Postprocessor/Cast"
- ]
- },
- "match_kind": "points"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v1.15.json b/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v1.15.json
deleted file mode 100644
index b3e76e94099e34..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v1.15.json
+++ /dev/null
@@ -1,64 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "detection_boxes",
- "detection_scores",
- "num_detections"
- ],
- "start_points": [
- "Postprocessor/Shape",
- "Postprocessor/scale_logits",
- "Postprocessor/Tile",
- "Postprocessor/Reshape_1",
- "Postprocessor/Cast_1"
- ]
- },
- "match_kind": "points"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v2.0.json b/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v2.0.json
deleted file mode 100644
index 8c62fdd3340e77..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v2.0.json
+++ /dev/null
@@ -1,49 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/Preprocessor/unstack"],
- "end_nodes": ["StatefulPartitionedCall/Preprocessor/stack"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true,
- "disable_prior_boxes_layers_generator": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/Identity",
- "StatefulPartitionedCall/Identity_1",
- "StatefulPartitionedCall/Identity_2",
- "StatefulPartitionedCall/Identity_3",
- "StatefulPartitionedCall/Identity_4",
- "StatefulPartitionedCall/Identity_5",
- "StatefulPartitionedCall/Identity_6",
- "StatefulPartitionedCall/Identity_7"
- ],
- "start_points": [
- "StatefulPartitionedCall/Postprocessor/Reshape_1",
- "StatefulPartitionedCall/Postprocessor/scale_logits",
- "StatefulPartitionedCall/Postprocessor/Tile",
- "StatefulPartitionedCall/Postprocessor/Cast_1"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/Identity,StatefulPartitionedCall/Identity_1,StatefulPartitionedCall/Identity_2,StatefulPartitionedCall/Identity_3,StatefulPartitionedCall/Identity_4,StatefulPartitionedCall/Identity_5,StatefulPartitionedCall/Identity_6,StatefulPartitionedCall/Identity_7"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v2.4.json b/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v2.4.json
deleted file mode 100644
index 8ccb3d0de7c5bf..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_support_api_v2.4.json
+++ /dev/null
@@ -1,52 +0,0 @@
-[
- {
- "custom_attributes": {
- "start_nodes": ["StatefulPartitionedCall/map/TensorArrayUnstack/TensorListFromTensor",
- "StatefulPartitionedCall/map/Shape"],
- "end_nodes": ["StatefulPartitionedCall/map/TensorArrayV2Stack/TensorListStack",
- "StatefulPartitionedCall/map/TensorArrayV2Stack_1/TensorListStack"]
- },
- "id": "ObjectDetectionAPIPreprocessor2Replacement",
- "match_kind": "general"
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true,
- "disable_prior_boxes_layers_generator": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "StatefulPartitionedCall/Identity",
- "StatefulPartitionedCall/Identity_1",
- "StatefulPartitionedCall/Identity_2",
- "StatefulPartitionedCall/Identity_3",
- "StatefulPartitionedCall/Identity_4",
- "StatefulPartitionedCall/Identity_5",
- "StatefulPartitionedCall/Identity_6",
- "StatefulPartitionedCall/Identity_7"
- ],
- "start_points": [
- "StatefulPartitionedCall/Postprocessor/raw_box_encodings",
- "StatefulPartitionedCall/Postprocessor/scale_logits",
- "StatefulPartitionedCall/Postprocessor/Tile",
- "StatefulPartitionedCall/Postprocessor/Cast_1",
- "StatefulPartitionedCall/Postprocessor/Cast"
- ]
- },
- "match_kind": "points"
- },
- {
- "custom_attributes": {
- "outputs": "StatefulPartitionedCall/Identity,StatefulPartitionedCall/Identity_1,StatefulPartitionedCall/Identity_2,StatefulPartitionedCall/Identity_3,StatefulPartitionedCall/Identity_4,StatefulPartitionedCall/Identity_5,StatefulPartitionedCall/Identity_6,StatefulPartitionedCall/Identity_7"
- },
- "id": "ObjectDetectionAPIOutputReplacement",
- "match_kind": "general"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_toolbox_detection_output.json b/tools/mo/openvino/tools/mo/front/tf/ssd_toolbox_detection_output.json
deleted file mode 100644
index 2407e02d96bef1..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_toolbox_detection_output.json
+++ /dev/null
@@ -1,28 +0,0 @@
-[
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "confidence_threshold": 0.01,
- "keep_top_k": 200,
- "nms_threshold": 0.45,
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP"
- },
- "id": "SSDToolboxDetectionOutput",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "SSD/concat_reshape_softmax/mbox_loc_final",
- "SSD/concat_reshape_softmax/mbox_conf_final",
- "SSD/fc7_priorbox"
- ],
- "start_points": [
- "SSD/concat_reshape_softmax/mbox_loc_final",
- "SSD/concat_reshape_softmax/mbox_conf_final",
- "SSD/fc7_priorbox"
- ]
- },
- "match_kind": "points"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_toolbox_multihead_detection_output.json b/tools/mo/openvino/tools/mo/front/tf/ssd_toolbox_multihead_detection_output.json
deleted file mode 100644
index bc5674dd521526..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_toolbox_multihead_detection_output.json
+++ /dev/null
@@ -1,28 +0,0 @@
-[
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "confidence_threshold": 0.01,
- "keep_top_k": 200,
- "nms_threshold": 0.45,
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP"
- },
- "id": "SSDToolboxDetectionOutput",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "SSD/concat_reshape_softmax/mbox_loc_final",
- "SSD/concat_reshape_softmax/mbox_conf_final",
- "SSD/concat_reshape_softmax/mbox_priorbox"
- ],
- "start_points": [
- "SSD/concat_reshape_softmax/mbox_loc_final",
- "SSD/concat_reshape_softmax/mbox_conf_final",
- "SSD/concat_reshape_softmax/mbox_priorbox"
- ]
- },
- "match_kind": "points"
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/ssd_v2_support.json b/tools/mo/openvino/tools/mo/front/tf/ssd_v2_support.json
deleted file mode 100644
index 70c40f0f709b98..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/ssd_v2_support.json
+++ /dev/null
@@ -1,64 +0,0 @@
-[
- {
- "custom_attributes": {
- },
- "id": "ObjectDetectionAPIPreprocessorReplacement",
- "inputs": [
- [
- {
- "node": "map/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/Shape$",
- "port": 0
- },
- {
- "node": "map/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3$",
- "port": 2
- }
- ]
- ],
- "instances": [
- ".*Preprocessor/"
- ],
- "match_kind": "scope",
- "outputs": [
- {
- "node": "sub$",
- "port": 0
- },
- {
- "node": "map/TensorArrayStack_1/TensorArrayGatherV3$",
- "port": 0
- }
- ]
- },
- {
- "custom_attributes": {
- "code_type": "caffe.PriorBoxParameter.CENTER_SIZE",
- "pad_mode": "caffe.ResizeParameter.CONSTANT",
- "resize_mode": "caffe.ResizeParameter.WARP",
- "clip_before_nms": false,
- "clip_after_nms": true
- },
- "id": "ObjectDetectionAPISSDPostprocessorReplacement",
- "include_inputs_to_sub_graph": true,
- "include_outputs_to_sub_graph": true,
- "instances": {
- "end_points": [
- "detection_boxes",
- "detection_scores",
- "num_detections"
- ],
- "start_points": [
- "Postprocessor/Shape",
- "Postprocessor/scale_logits",
- "Postprocessor/Tile",
- "Postprocessor/Reshape_1",
- "Postprocessor/ToFloat"
- ]
- },
- "match_kind": "points"
- }
-]
diff --git a/tools/mo/openvino/tools/mo/front/tf/swap_deconv_inputs.py b/tools/mo/openvino/tools/mo/front/tf/swap_deconv_inputs.py
deleted file mode 100644
index 2dca7e883a4775..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/swap_deconv_inputs.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.graph.graph import Graph
-
-
-class SwapDeconvInputs(FrontReplacementSubgraph):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(swap_0_and_2_inputs=True):
- shape_src = node.in_port(0).get_source()
- node.in_port(0).disconnect()
-
- node.in_port(2).get_connection().set_destination(node.in_port(0))
- shape_src.connect(node.in_port(2))
- node['swap_0_and_2_inputs'] = False
diff --git a/tools/mo/openvino/tools/mo/front/tf/swish_ext.py b/tools/mo/openvino/tools/mo/front/tf/swish_ext.py
deleted file mode 100644
index bd1b5cb7dd0a8f..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/swish_ext.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.activation_ops import Swish
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-
-
-class SwishExtractor(FrontExtractorOp):
- op = 'swish_f32'
- enabled = True
-
- @classmethod
- def extract(cls, node: Node):
- Swish.update_node_stat(node, {})
- return cls.enabled
-
diff --git a/tools/mo/openvino/tools/mo/front/tf/tensorflow_custom_operations_config_update.py b/tools/mo/openvino/tools/mo/front/tf/tensorflow_custom_operations_config_update.py
deleted file mode 100644
index 9f2539a0767690..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/tensorflow_custom_operations_config_update.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import json
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.custom_replacement_config import parse_custom_replacement_config_file
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class TensorflowCustomOperationsConfigUpdate(FrontReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['cmd_params'].tensorflow_custom_operations_config_update is not None]
-
- def run_before(self):
- return []
-
- def run_after(self):
- from openvino.tools.mo.front.freeze_placeholder_value import FreezePlaceholderValue
- return [FreezePlaceholderValue]
-
- @staticmethod
- def save_custom_replacement_config_file(descriptions: list, file_name: str):
- """
- Save custom layer(s) description(s) to the file.
- :param file_name: file to save description information to.
- :param descriptions: list with instances of the CustomLayerDescriptor classes.
- :return: True if operation is successful.
- """
- try:
- json.dump([replacement_desc.get_config_file_representation() for replacement_desc in descriptions],
- open(file_name, "w"), indent=4, sort_keys=True)
- except Exception as ex:
- raise Error("failed to update configuration file {}: {}".format(file_name, str(ex)))
-
- def find_and_replace_pattern(self, graph: Graph):
- argv = graph.graph['cmd_params']
- file_name = argv.tensorflow_custom_operations_config_update
-
- data = parse_custom_replacement_config_file(file_name)
- if data is None:
- raise Error("Cannot update the file '{}' because it is broken. ".format(file_name) + refer_to_faq_msg(73))
-
- for replacement_desc in data:
- replacement_desc.update_custom_replacement_attributes(graph)
-
- self.save_custom_replacement_config_file(data, file_name)
diff --git a/tools/mo/openvino/tools/mo/front/tf/tile_ext.py b/tools/mo/openvino/tools/mo/front/tf/tile_ext.py
deleted file mode 100644
index 9eac84939f9f26..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/tile_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.tile import Tile
-
-
-class TileExtractor(FrontExtractorOp):
- op = 'Tile'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Tile.update_node_stat(node, {})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/topk_ext.py b/tools/mo/openvino/tools/mo/front/tf/topk_ext.py
deleted file mode 100644
index 5b06a097228f26..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/topk_ext.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.topk import TopK
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class TopKExtractor(FrontExtractorOp):
- op = 'TopK'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- sort = 'value' if node.pb.attr['sorted'] else 'none'
- TopK.update_node_stat(node, {'mode': 'max', 'axis': -1, 'sort': sort, 'k': node.pb.attr['k'].i,
- 'index_element_type': np.int32})
-
- return cls.enabled
-
-
-class TopKV2Extractor(FrontExtractorOp):
- op = 'TopKV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- sort = 'value' if node.pb.attr['sorted'] else 'none'
- TopK.update_node_stat(node, {'mode': 'max', 'axis': -1, 'sort': sort, 'index_element_type': np.int32})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/transpose_ext.py b/tools/mo/openvino/tools/mo/front/tf/transpose_ext.py
deleted file mode 100644
index b2baf696c5ce18..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/transpose_ext.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class TransposeFrontExtractorTF(FrontExtractorOp):
- op = 'Transpose'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Transpose.update_node_stat(node, {'order': None})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/transposed_mvn_unrolled.py b/tools/mo/openvino/tools/mo/front/tf/transposed_mvn_unrolled.py
deleted file mode 100644
index beab52745940ee..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/transposed_mvn_unrolled.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.PowerToEltwises import PowerToEltwises
-from openvino.tools.mo.front.tf.mvn_unrolled import MVNUnrolled
-from openvino.tools.mo.ops.elementwise import Add, Mul
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.replacement import FrontReplacementSubgraph
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input, create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-
-
-def check_applicability(match: dict) -> bool:
- mean = match['mean']
- mean_reduction = mean.in_port(1).get_connection().get_source().node
- variance_reduction = match['variance'].in_port(1).get_connection().get_source().node
- pow2 = match['pow']['power']
- add = match['add']
- variance = match['variance']
- eps_port_num = 0 if add.in_port(0).get_connection().get_source().node.id != variance.id else 1
- eps = add.in_port(eps_port_num).get_connection().get_source().node
-
- new_name = match['division'].name + '/MVN/MVN_T_'
-
- if not (mean_reduction.has_valid('value') and variance_reduction.has_valid('value')):
- log.debug('Reduction indices for mean and variance for MVN node {} are not constants'.format(new_name))
- return False
-
- if not (all(mean_reduction.value == variance_reduction.value)):
- log.debug('Reduction indices for mean {} and variance {} do not match.'.format(
- mean_reduction.value,
- variance_reduction.value
- ))
- return False
-
- if not eps.has_valid('value'):
- log.debug('epsilon value for MVN node {} is not constant'.format(new_name))
- return False
-
- if pow2 != 0.5:
- log.debug('Power for MVN node {} ({}) is not equal to 0.5'.format(new_name, pow2))
- return False
-
- return True
-
-
-class TransposedMVNUnrolled(FrontReplacementSubgraph):
- """
- This transformation looks for mean value normalization (across selected channels) implemented using simple
- operations and replaces found pattern with a sequence Reshape, Transpose, MVN, Transpose, Reshape, Mul, Add.
-
- Here we assume that
- 1) the input of 'transpose' is in NHWC layout and is a 4D-tensor
- 2) the constant for 'transpose' is equal to [0, 3, 1, 2]
- 3) the shape for 'reshape' is [N, C1, C2, H, W]
- 4) reduction indices for 'mean' and 'variance' are [2, 3, 4]
- 5) the shape of 'reshape2' is equal to [N, C, H, W]
- 6) the constant for 'transpose2' is [0, 2, 3, 1]
-
- Found pattern will be replaced with
- nodes=[
- ('new_reshape', dict(kind='op', op='Reshape')),
- ('first_permute', dict(kind='op', op='Transpose')),
- ('mvn_node', dict(kind='op', op='MVN')),
- ('second_permute', dict(kind='op', op='Transpose')),
- ('new_reshape2', dict(kind='op', op='Reshape')),
- ('new_mul', dict(kind='op', op='Mul')),
- ('new_add_2', dict(kind='op', op='Add'))
- ],
- edges=[
- ('new_reshape', 'first_permute', {'in': 0}),
- ('first_permute', 'mvn_node', {'in': 0}),
- ('mvn_node', 'second_permute', {'in': 0}),
- ('second_permute', 'new_reshape2', {'in': 0}),
- ('new_reshape2', 'new_mul', {'in': 0}),
- ('new_mul', 'new_add_2', {'in': 0}),
- ]
-
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.front.tf.mvn import MVNReplacer
- return [MVNReplacer, MVNUnrolled, PowerToEltwises]
-
- def pattern(self):
- log.debug('Enabled Transposed MVN replacement')
- return dict(
- nodes=[
- ('transpose', dict(kind='op', op='Transpose')),
- ('reshape', dict(kind='op', op='Reshape')),
- ('mean', dict(kind='op', op='ReduceMean')),
- ('stop_grad', dict(kind='op', op='StopGradient')),
- ('sqdiff', dict(kind='op', op='SquaredDifference')),
- ('variance', dict(kind='op', op='ReduceMean')),
- ('add', dict(kind='op', op='Add')),
- ('pow', dict(kind='op', op='AttributedPower')),
- ('sub', dict(kind='op', op='Sub')),
- ('division', dict(kind='op', op='Div')),
- ('reshape2', dict(kind='op', op='Reshape')),
- ('reshape3', dict(kind='op', op='Reshape')),
- ('reshape4', dict(kind='op', op='Reshape')),
- ('gamma_identity', dict(kind='op', op='Identity')),
- ('mul', dict(kind='op', op='Mul')),
- ('beta_identity', dict(kind='op', op='Identity')),
- ('add2', dict(kind='op', op='Add')),
- ('transpose2', dict(kind='op', op='Transpose')),
- ],
- edges=[
- ('transpose', 'reshape'),
- ('reshape', 'mean'),
- ('reshape', 'sub', {'in': 0}),
- ('reshape', 'sqdiff', {'in': 0}),
- ('mean', 'stop_grad', {'in': 0}),
- ('stop_grad', 'sqdiff', {'in': 1}),
- ('sqdiff', 'variance', {'in': 0}),
- ('mean', 'sub', {'in': 1}),
- ('variance', 'add'),
- ('add', 'pow', {'in': 0}),
- ('pow', 'division', {'in': 1}),
- ('sub', 'division', {'in': 0}),
- ('division', 'reshape2'),
- ('reshape2', 'mul', {'in': 0}),
- ('reshape3', 'mul', {'in': 1}),
- ('gamma_identity', 'reshape3'),
- ('mul', 'add2', {'in': 0}),
- ('reshape4', 'add2', {'in': 1}),
- ('beta_identity', 'reshape4'),
- ('add2', 'transpose2'),
- ]
- )
-
- def replace_sub_graph(self, graph: Graph, match: dict):
- if not check_applicability(match):
- return
-
- reshape = match['reshape']
- div_name = match['division'].name
-
- input_shape = Shape(graph, dict(name=div_name + '/shape/MVN_T_')).create_node()
- shape_of_reshape = reshape.in_port(1).get_connection().get_source().node.value
- c1, c2 = shape_of_reshape[1], shape_of_reshape[2]
- c = c1 * c2
-
- new_reshape = create_op_node_with_second_input(graph, Reshape, int64_array([0, 0, 0, c1, c2]),
- dict(name=div_name + '/first_reshape/MVN_T_'))
- permute_order = int64_array([0, 1, 2, 4, 3])
- first_permute = create_op_node_with_second_input(graph, Transpose, permute_order,
- dict(name=div_name + '/first_permute/MVN_T_'), new_reshape)
-
- add = match['add']
- variance = match['variance']
- eps_port_num = 0 if add.in_port(0).get_connection().get_source().node.id != variance.id else 1
- eps = add.in_port(eps_port_num).get_connection().get_source().node
- mvn_node = create_op_with_const_inputs(graph, MVN, {1: int64_array([1, 2, 3])},
- dict(name=div_name + '/MVN/MVN_T_',
- eps=eps.value, normalize_variance=1,
- eps_mode='inside_sqrt'))
- first_permute.out_port(0).connect(mvn_node.in_port(0))
-
- second_permute = create_op_node_with_second_input(graph, Transpose, permute_order,
- dict(name=div_name + '/second_permute/MVN_T_'), mvn_node)
- new_reshape2 = Reshape(graph, dict(name=div_name + '/second_reshape/MVN_T_')).create_node()
- second_permute.out_port(0).connect(new_reshape2.in_port(0))
- gamma_val = np.reshape(match['gamma_identity'].in_port(0).get_connection().get_source().node.value,
- int64_array([1, 1, 1, c]))
- new_mul = create_op_node_with_second_input(graph, Mul, gamma_val,
- dict(name=match['mul'].name + '/MVN_T_'), new_reshape2)
- beta_val = np.reshape(match['beta_identity'].in_port(0).get_connection().get_source().node.value,
- int64_array([1, 1, 1, c]))
- new_add2 = create_op_node_with_second_input(graph, Add, beta_val,
- dict(name=match['add2'].name + '/MVN_T_'), new_mul)
-
- transpose_connection = match['transpose'].in_port(0).get_connection()
- before_transpose = transpose_connection.get_source().node
- transpose_connection.set_destination(new_reshape.in_port(0))
- input_shape.out_port(0).connect(new_reshape2.in_port(1))
- before_transpose.out_port(0).connect(input_shape.in_port(0))
- match['transpose2'].out_port(0).get_connection().set_source(new_add2.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/front/tf/unique_ext.py b/tools/mo/openvino/tools/mo/front/tf/unique_ext.py
deleted file mode 100644
index c74fbcb70f23d2..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/unique_ext.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.unique import Unique
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-
-
-class UniqueFrontExtractor(FrontExtractorOp):
- op = 'Unique'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- # TensorFlow Unique operation always returns two outputs: unique elements and indices
- # The unique elements in the output are not sorted
- attrs = {
- 'sorted': 'false',
- 'return_inverse': 'true',
- 'return_counts': 'false'
- }
-
- Unique.update_node_stat(node, attrs)
-
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/variable_ext.py b/tools/mo/openvino/tools/mo/front/tf/variable_ext.py
deleted file mode 100644
index cf27d737a74114..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/variable_ext.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import FrontExtractorOp
-from openvino.tools.mo.ops.op import Op
-
-
-class VariableExtractor(FrontExtractorOp):
- op = 'Variable'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Op.update_node_stat(node, {'op': 'FakeConst'})
- return cls.enabled
-
-
-class VariableV2Extractor(FrontExtractorOp):
- op = 'VariableV2'
- enabled = True
-
- @classmethod
- def extract(cls, node):
- Op.update_node_stat(node, {'op': 'FakeConst'})
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/variables_values_freezing.py b/tools/mo/openvino/tools/mo/front/tf/variables_values_freezing.py
deleted file mode 100644
index 9deeb6456810b9..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/variables_values_freezing.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.loader import variables_to_constants
-from openvino.tools.mo.graph.graph import Graph
-
-
-class VariablesToConstants(FrontReplacementPattern):
- enabled = True
- force_clean_up = True
- graph_condition = [lambda graph: graph.graph['variables_values']]
-
- def run_after(self):
- from openvino.tools.mo.front.input_cut import InputCut
- return [InputCut]
-
- def run_before(self):
- from openvino.tools.mo.front.freeze_placeholder_value import FreezePlaceholderValue
- return [FreezePlaceholderValue]
-
- def find_and_replace_pattern(self, graph: Graph):
- variables_to_constants(graph, graph.graph['variables_values'])
- del graph.graph['variables_values']
diff --git a/tools/mo/openvino/tools/mo/front/tf/while_ext.py b/tools/mo/openvino/tools/mo/front/tf/while_ext.py
deleted file mode 100644
index 81deccfc117041..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/while_ext.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.front.common.register_custom_ops import check_for_duplicates
-from openvino.tools.mo.front.extractor import extract_node_attrs, FrontExtractorOp
-from openvino.tools.mo.front.tf.extractor import tf_op_extractor, tf_op_extractors, create_tf_edge
-from openvino.tools.mo.front.tf.extractors.subgraph_utils import update_body_graph, convert_graph_inputs_to_parameters, \
- get_graph_proto, create_internal_graph
-from openvino.tools.mo.graph.graph import add_opoutput, Graph, Node
-
-
-class WhileExtractor(FrontExtractorOp):
- """
- The While operation is a variation of the while_loop primitive from TensorFlow 2 Python API.
- While can have stateful operations in the body and condition graphs that does not influence on inference so
- the logic for handling While and StatelessWhile (see below) is the same.
- """
- op = 'While'
- enabled = True
-
- @classmethod
- def extract(cls, loop_node):
- Loop.update_node_stat(loop_node, {})
-
- # check that required body and condition functions exist in the graph library
- main_graph = loop_node.graph
- body_graph_proto = get_graph_proto(main_graph, 'body', loop_node)
- cond_graph_proto = get_graph_proto(main_graph, 'cond', loop_node)
-
- body_graph = create_internal_graph(main_graph)
- loop_node['body'] = body_graph
- # create Parameter nodes for the body graph
- body_parameters, body_parameter_names = convert_graph_inputs_to_parameters(body_graph, body_graph_proto)
-
- # update the loop body graph with the body function graph
- body_results = []
- update_body_graph(body_graph, body_graph_proto, body_parameter_names, body_results)
-
- # update the loop body graph with the condition function graph
- update_body_graph(body_graph, cond_graph_proto, body_parameter_names, body_results)
-
- # add 'internal_layer_id' attribute which is a must have attribute for the loop body node
- for idx, body_node in enumerate(body_graph.get_op_nodes()):
- body_node['internal_layer_id'] = idx
-
- body_graph.stage = 'front'
-
- # Currently,
- # Loop Inputs Order:
- # 0 - current iteration
- # 1 - trip count
- # 2.. - "loop carried" dependencies variables
- #
- # Body Inputs Order:
- # 0 - current iteration
- # 1 - trip count
- # 2.. - "loop carried" dependencies variables
- #
- # Body Outputs Order:
- # 0 - current iteration
- # 1 - trip count
- # 2.. - "loop carried" dependencies variables
- #
- # Loop Outputs Order:
- # 0 - current iteration
- # 1 - trip count
- # 2.. - "loop carried" dependencies variables
- #
- # so inputs must be reordered and execution condition must be created in the front transformation
- # to be aligned with the specification
-
- # connect external input ports with body parameter nodes except current iteration
- # since it must be disconnected from external port
- for idx in range(1, len(body_parameters)):
- Loop.connect_body_input(loop_node, idx, body_parameters[idx])
-
- # mark current iteration input Parameter node and execution condition Result node
- Loop.mark_current_iteration_parameter_node(loop_node, body_parameters[0])
- Loop.mark_execution_condition_result_node(loop_node, body_results[-1])
-
- # connect back edges in the body except current iteration
- for idx in range(1, len(body_parameters)):
- Loop.add_back_edge(loop_node, body_parameters[idx], body_results[idx])
-
- # connect body outputs with Loop operation output ports except the execution condition result
- for idx in range(len(body_results) - 1):
- Loop.connect_body_output(loop_node, idx, body_results[idx])
-
- # run function to parse body nodes attributes similar to the main graph
- extract_node_attrs(body_graph, lambda node: tf_op_extractor(node, check_for_duplicates(tf_op_extractors)))
- return cls.enabled
-
-
-class StatelessWhileExtractor(FrontExtractorOp):
- """
- The StatelessWhile operation is a variation of the while_loop primitive from TensorFlow 2 Python API.
- StatelessWhile does not have stateful operations in the body and condition graphs.
- """
- op = 'StatelessWhile'
- enabled = True
-
- @classmethod
- def extract(cls, loop_node):
- WhileExtractor.extract(loop_node)
- return cls.enabled
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v1.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v1.json
deleted file mode 100644
index 78f2e97c8a3acd..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v1.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- {
- "id": "TFYOLO",
- "match_kind": "general",
- "custom_attributes": {
- "classes": 20,
- "coords": 4,
- "num": 3,
- "do_softmax": 0
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v1_tiny.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v1_tiny.json
deleted file mode 100644
index a14d5166e2f7ea..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v1_tiny.json
+++ /dev/null
@@ -1,12 +0,0 @@
-[
- {
- "id": "TFYOLO",
- "match_kind": "general",
- "custom_attributes": {
- "classes": 20,
- "coords": 4,
- "num": 2,
- "do_softmax": 0
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v2.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v2.json
deleted file mode 100644
index b77df24f2b1a21..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v2.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- "id": "TFYOLO",
- "match_kind": "general",
- "custom_attributes": {
- "anchors": [0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828],
- "classes": 80,
- "coords": 4,
- "num": 5,
- "do_softmax": 1
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v2_tiny.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v2_tiny.json
deleted file mode 100644
index b77df24f2b1a21..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v2_tiny.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- "id": "TFYOLO",
- "match_kind": "general",
- "custom_attributes": {
- "anchors": [0.57273, 0.677385, 1.87446, 2.06253, 3.33843, 5.47434, 7.88282, 3.52778, 9.77052, 9.16828],
- "classes": 80,
- "coords": 4,
- "num": 5,
- "do_softmax": 1
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v2_tiny_voc.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v2_tiny_voc.json
deleted file mode 100644
index e2c3cd6a435ad5..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v2_tiny_voc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- "id": "TFYOLO",
- "match_kind": "general",
- "custom_attributes": {
- "anchors": [1.08, 1.19, 3.42, 4.41, 6.63, 11.38, 9.42, 5.11, 16.62, 10.52],
- "classes": 20,
- "coords": 4,
- "num": 5,
- "do_softmax": 1
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v2_voc.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v2_voc.json
deleted file mode 100644
index 6be299dd1120cd..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v2_voc.json
+++ /dev/null
@@ -1,13 +0,0 @@
-[
- {
- "id": "TFYOLO",
- "match_kind": "general",
- "custom_attributes": {
- "anchors": [1.3221, 1.73145, 3.19275, 4.00944, 5.05587, 8.09892, 9.47112, 4.84053, 11.2364, 10.0071],
- "classes": 20,
- "coords": 4,
- "num": 5,
- "do_softmax": 1
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v3.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v3.json
deleted file mode 100644
index 3d94074221649b..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v3.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "id": "TFYOLOV3",
- "match_kind": "general",
- "custom_attributes": {
- "classes": 80,
- "anchors": [10, 13, 16, 30, 33, 23, 30, 61, 62, 45, 59, 119, 116, 90, 156, 198, 373, 326],
- "coords": 4,
- "num": 9,
- "masks":[[6, 7, 8], [3, 4, 5], [0, 1, 2]],
- "entry_points": ["detector/yolo-v3/Reshape", "detector/yolo-v3/Reshape_4", "detector/yolo-v3/Reshape_8"]
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v3_tiny.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v3_tiny.json
deleted file mode 100644
index 0c0d8718235ede..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v3_tiny.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "id": "TFYOLOV3",
- "match_kind": "general",
- "custom_attributes": {
- "classes": 80,
- "anchors": [10, 14, 23, 27, 37, 58, 81, 82, 135, 169, 344, 319],
- "coords": 4,
- "num": 6,
- "masks": [[3, 4, 5], [0, 1, 2]],
- "entry_points": ["detector/yolo-v3-tiny/Reshape", "detector/yolo-v3-tiny/Reshape_4"]
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/tf/yolo_v3_voc.json b/tools/mo/openvino/tools/mo/front/tf/yolo_v3_voc.json
deleted file mode 100644
index b8abcc0c6a67c6..00000000000000
--- a/tools/mo/openvino/tools/mo/front/tf/yolo_v3_voc.json
+++ /dev/null
@@ -1,14 +0,0 @@
-[
- {
- "id": "TFYOLOV3",
- "match_kind": "general",
- "custom_attributes": {
- "classes": 20,
- "anchors": [10, 13, 16, 30, 33, 23, 30, 61, 62, 45, 59, 119, 116, 90, 156, 198, 373, 326],
- "coords": 4,
- "num": 9,
- "masks":[[6, 7, 8], [3, 4, 5], [0, 1, 2]],
- "entry_points": ["detector/yolo-v3/Reshape", "detector/yolo-v3/Reshape_4", "detector/yolo-v3/Reshape_8"]
- }
- }
-]
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/front/transformations_config.py b/tools/mo/openvino/tools/mo/front/transformations_config.py
deleted file mode 100644
index ea75b66820a33e..00000000000000
--- a/tools/mo/openvino/tools/mo/front/transformations_config.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.custom_replacement_registry import CustomReplacementRegistry
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.tf.replacement import FrontReplacementFromConfigFileOp
-from openvino.tools.mo.graph.graph import Graph
-
-
-class TransformationsConfig(FrontReplacementPattern):
- enabled = True
- # do not run this transformation recursively otherwise transformations which are enabled with a configuration file
- # will be registered multiple times
- run_not_recursively = True
- graph_condition = [lambda graph: graph.graph['cmd_params'].transformations_config is not None]
-
- def run_before(self):
- from openvino.tools.mo.front.pass_separator import FrontStart
- return [FrontStart]
-
- def run_after(self):
- from openvino.tools.mo.load.loader import LoadFinish
- return [LoadFinish]
-
- def find_and_replace_pattern(self, graph: Graph):
- argv = graph.graph['cmd_params']
- transformations_config = argv.transformations_config
- registry = CustomReplacementRegistry()
- registry.add_custom_replacement_description_from_config(transformations_config)
-
- # automatically generate sub-classes for custom replacements that replace sub-graph with a single node
- for replacement_desc in registry.get_all_replacements_descriptions():
- if replacement_desc.has('op'):
- transform = type('FrontReplacementFromConfigFileOp' + replacement_desc.op,
- (FrontReplacementFromConfigFileOp,),
- {'replacement_id': replacement_desc.id})
- transform().find_and_replace_pattern(graph)
diff --git a/tools/mo/openvino/tools/mo/front/user_data_repack.py b/tools/mo/openvino/tools/mo/front/user_data_repack.py
deleted file mode 100644
index 6819084418a1c3..00000000000000
--- a/tools/mo/openvino/tools/mo/front/user_data_repack.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.replacement import FrontReplacementPattern
-from openvino.tools.mo.front.extractor import user_data_repack
-from openvino.tools.mo.graph.graph import Graph
-
-
-class UserDataRepack(FrontReplacementPattern):
- enabled = True
- run_not_recursively = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- argv = graph.graph['cmd_params']
-
- packed_user_shapes, packed_outputs, freeze_placeholder = user_data_repack(
- graph, argv.placeholder_shapes, argv.placeholder_data_types,
- argv.output, argv.freeze_placeholder_with_value)
-
- # save packed user shapes in arguments since nodes names and their ports
- # will be required to compose placeholder names with custom types
- # for MOCLegacyTransformations
- argv.packed_user_shapes = packed_user_shapes
-
- graph.graph['user_shapes'] = packed_user_shapes
- graph.graph['packed_outputs'] = packed_outputs
- graph.graph['freeze_placeholder'] = freeze_placeholder
-
- if argv.inputs_list is not None and isinstance(argv.inputs_list, list) and len(argv.inputs_list) > 0:
- graph.inputs_order = argv.inputs_list
- if argv.output is not None and isinstance(argv.output, list) and len(argv.output) > 0:
- graph.outputs_order = argv.output
-
- inputs = list(packed_user_shapes.keys()) \
- if packed_user_shapes is not None and isinstance(packed_user_shapes, dict) else None
- graph.graph['inputs'] = inputs # save user defined inputs for other extensions
diff --git a/tools/mo/openvino/tools/mo/graph/__init__.py b/tools/mo/openvino/tools/mo/graph/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/graph/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/graph/connection.py b/tools/mo/openvino/tools/mo/graph/connection.py
deleted file mode 100644
index 348948baabee5c..00000000000000
--- a/tools/mo/openvino/tools/mo/graph/connection.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from collections import namedtuple
-from copy import deepcopy
-
-from openvino.tools.mo.utils.error import Error
-
-
-class Connection:
- def __init__(self, graph, source, destinations: list, control_flow=False):
- self.graph = graph
- self.source = source
- self.destinations = destinations
- self.control_flow = control_flow
- self.data = namedtuple('Data', ['get_value', 'get_shape'])
- self.data.get_value = self._get_value
- self.data.get_shape = self._get_shape
-
- def _get_value(self):
- if self.graph.stage == 'front':
- return None
- return self.source.node.out_node(self.source.idx, control_flow=self.control_flow).value
-
- def _get_shape(self):
- if self.graph.stage == 'front':
- return None
- return self.source.node.out_node(self.source.idx, control_flow=self.control_flow).shape
-
- @staticmethod
- def _get_new_tensor_debug_info(attributes_save_mode: str, source_attrs: dict, dest_attrs: dict):
- source_debug_info = []
- attr_name = 'fw_tensor_debug_info'
- if attr_name in source_attrs:
- source_debug_info = source_attrs[attr_name]
- dest_debug_info = []
- if attr_name in dest_attrs:
- dest_debug_info = dest_attrs[attr_name]
- if attributes_save_mode == "merge":
- return source_debug_info + dest_debug_info
- elif attributes_save_mode == "source":
- return source_debug_info
- else:
- return dest_debug_info
-
- @staticmethod
- def _update_tensor_debug_info(attrs: dict, new_value: list):
- if new_value is not None and len(new_value) > 0:
- attrs['fw_tensor_debug_info'] = new_value
- else:
- if 'fw_tensor_debug_info' in attrs:
- del attrs['fw_tensor_debug_info']
-
- def get_source(self):
- return self.source
-
- def get_destination(self):
- if self.destinations and len(self.destinations) > 1:
- raise Error("Connection has more than one destination: {}".format(len(self.destinations)))
- return self.destinations[0] if self.destinations else None
-
- def get_destinations(self):
- return self.destinations
-
- def set_source(self, port, attributes_save_mode=None):
- # In this method we are changing source for a connection with given port.
- # See detailed example below.
- #
- # SOURCE - Op1(out_port:0)
- #
- # | Op4(in_port:0)
- # DESTINATIONS - | Op3(in_port:0)
- # | Op2(in_port:0)
- #
- # NEW PORT - Op5(out_port:0)
- #
- # ,--->Op4(in_port:0)
- # CONNECTION ,--->Op3(in_port:0)
- # Op1(out_port:0)--->Op2(in_port:0)
- #
- # When we set source for connection we disconnect existing source and reconnect all consumers to
- # the new given port with type='out'.
- #
- # UPDATED CONNECTION ,--->Op4(in_port:0)
- # ,--->Op3(in_port:0)
- # Op5(out_port:0)--->Op2(in_port:0)
- #
- # attributes_save_mode defines which attributes with tensor debug information should be
- # transferred to resulting connection.
- # 'source' - attributes are transferred from the outgoing edge (front phase) or
- # outgoing data node (middle/back phase) of the source of resulting connection.
- # 'dest' - attributes are transferred from the incoming edge (front phase) or
- # incoming data node (middle/back phase) of the destination of resulting connection.
- # 'merge' - attributes from source and destination are merged.
-
- if port.type == 'in':
- raise Error("Wrong port type in set_source method. Should be 'out' but given 'in'")
-
- if self.control_flow is True:
- raise Error("Cannot operate with connection with control_flow=True")
-
- if attributes_save_mode is None:
- attributes_save_mode = "merge"
- if self.source is not None:
- scr_node = self.source.node
-
- # Force "source" mode for "Parameter" source node, which preserves tensor names for
- # source node in connection.
- if scr_node.soft_get("type") == "Parameter":
- attributes_save_mode = "source"
-
- if self.graph.stage == 'front':
- scr_node = port.node
-
- source_fw_names = []
- for dst_port in port.get_connection().destinations:
- edge_attrs, u, v, key = dst_port.get_in_edge_attrs(data=True)
- for attr in edge_attrs:
- if attr == "fw_tensor_debug_info":
- source_fw_names += edge_attrs[attr]
- # remove duplicates
- source_fw_names = list(set(source_fw_names))
- if not source_fw_names:
- attrs = {}
- else:
- attrs = {'fw_tensor_debug_info': source_fw_names}
-
- # Reconnecting all destinations as consumers to the source port preserving edge attrs
- for dst_port in self.destinations:
- edge_attrs, u, v, key = dst_port.get_in_edge_attrs(data=True)
- if u is not None:
- edge_attrs['out'] = port.idx
-
- new_tensor_info = self._get_new_tensor_debug_info(attributes_save_mode, attrs, edge_attrs)
- self._update_tensor_debug_info(edge_attrs, new_tensor_info)
-
- self.graph.remove_edge(u, v, key=key)
- self.graph.add_edge(scr_node.id, v, **edge_attrs)
- else:
- if attributes_save_mode == "dest":
- attrs = {}
- self.graph.create_edge(scr_node, dst_port.node, port.idx, dst_port.idx, edge_attrs=attrs)
- else:
- # Create out data node if not exists and mark node with need_shape_inference = True
- # In case if data node exists just use it.
- port._create_data_if_necessary()
- port_out_data = port.node.out_node(port.idx)
-
- attrs = {}
- if self.source is not None and self.source.idx in self.source.node.out_nodes():
- source_out_data = self.source.node.out_node(self.source.idx)
- # Copy attrs from source_out_data to port_out_data
- attrs = deepcopy(source_out_data.attrs())
- if attributes_save_mode != "source":
- # Remove debug info
- if 'fw_tensor_debug_info' in source_out_data.attrs():
- del self.graph.node[source_out_data.id]['fw_tensor_debug_info']
- # Copy attrs to new data node
- for attr in attrs:
- if attr != 'fw_tensor_debug_info':
- port_out_data[attr] = attrs[attr]
-
- new_tensor_info = self._get_new_tensor_debug_info(attributes_save_mode, port_out_data.attrs(), attrs)
- self._update_tensor_debug_info(port_out_data.attrs(), new_tensor_info)
-
- for dst_port in self.destinations:
- edge_attrs, u, v, key = dst_port.get_in_edge_attrs(data=True)
- if u is not None:
- self.graph.remove_edge(u, v, key=key)
- self.graph.add_edge(port_out_data.id, v, **edge_attrs)
- else:
- self.graph.add_edge(port_out_data.id, dst_port.node.id, **{'in': dst_port.idx})
-
- def set_destination(self, port, attributes_save_mode=None):
- # In this method we are changing destination for a connection with given port with type 'in'.
- # This method requires exactly one destination or empty destinations list.
- # See detailed example below.
- #
- # SOURCE - Op1(out_port:0)
- #
- # DESTINATIONS - Op2(in_port:0)
- #
- # NEW PORT - Op3(in_port:0)
- #
- # CONNECTION
- # Op1(out_port:0)--->Op2(in_port:0)
- #
- # When we set destination for connection we disconnect destination port if exists and connect source to
- # the new given port with type='in'.
- #
- # UPDATED CONNECTION
- #
- # Op1(out_port:0)--->Op3(in_port:0)
- #
- # attributes_save_mode defines which attributes with tensor debug information should be
- # transferred to resulting connection.
- # 'source' - attributes are transferred from the outgoing edge (front phase) or
- # outgoing data node (middle/back phase) of the source of resulting connection.
- # 'dest' - attributes are transferred from the incoming edge (front phase) or
- # incoming data node (middle/back phase) of the destination of resulting connection.
- # 'merge' - attributes from source and destination are merged.
-
- def check_and_remove_edge():
- if self.destinations:
- for destination in self.destinations:
- edge_attrs, u, v, key = destination.get_in_edge_attrs(data=True)
- if u is None:
- raise Error(
- "Broken Connection object! Destination (node:{}) is not connected to source.".format(
- destination.node.name))
- destination.disconnect()
- return edge_attrs, key
- return {}, None
-
- if self.destinations and len(self.destinations) > 1:
- raise Error("set_destination applicable only for connections that has exactly one destination or "
- "when there is no destinations")
-
- if port.type == 'out':
- raise Error("Wrong port type in set_destination method. Should be 'in' but given 'out'")
-
- if self.control_flow is True:
- raise Error("Cannot operate with connection with control_flow=True")
-
- if attributes_save_mode is None:
- attributes_save_mode = "merge"
- if self.source is not None:
- scr_node = self.source.node
-
- # Force "source" mode for "Parameter" source node, which preserves tensor names for
- # source node in connection.
- if scr_node.soft_get("type") == "Parameter":
- attributes_save_mode = "source"
-
- if self.graph.stage == 'front':
- if self.source is not None:
- node = self.source.node
- source_attrs, _ = check_and_remove_edge()
- dest_attrs = port.get_in_edge_attrs() or {}
-
- edge_attrs = {}
- new_tensor_info = self._get_new_tensor_debug_info(attributes_save_mode, source_attrs, dest_attrs)
- self._update_tensor_debug_info(edge_attrs, new_tensor_info)
-
- self.graph.create_edge(node, port.node, out_port=self.source.idx, in_port=port.idx,
- edge_attrs=edge_attrs)
- self.destinations = [port]
- else:
- # create out node if not exists and mark node with need_shape_inference = True
- # in case if data node exists just use it as is
- if self.source is not None:
- data_node = self.source._create_data_if_necessary()
- edge_attrs, key = check_and_remove_edge()
- edge_attrs.update({'in': port.idx})
-
- dest_attrs = {}
- if port.idx in port.node.in_nodes():
- dest_attrs = port.node.in_node(port.idx).attrs()
-
- new_tensor_info = self._get_new_tensor_debug_info(attributes_save_mode, data_node.attrs(), dest_attrs)
- self._update_tensor_debug_info(data_node.attrs(), new_tensor_info)
-
- self.graph.add_edge(data_node.id, port.node.id, key=key, **edge_attrs)
- self.destinations = [port]
-
- def add_destination(self, port):
- # In this method we are adding destination port with type 'in' for a connection.
- # See detailed example below.
- #
- # SOURCE - Op1(out_port:0)
- #
- # DESTINATIONS - Op2(in_port:0)
- #
- # NEW PORT - Op3(in_port:0)
- #
- # CONNECTION
- # Op1(out_port:0)--->Op2(in_port:0)
- #
- # When we set destination for connection we disconnect destination port if exists and connect source to
- # the new given port with type='in'.
- #
- # UPDATED CONNECTION
- # ,-->Op3(in_port:0)
- # Op1(out_port:0)--->Op2(in_port:0)
- #
-
- if self.control_flow is True:
- raise Error("Cannot operate with connection with control_flow=True")
-
- if self.source is None:
- raise Error("Can not add destination for connection without source port!")
-
- if self.graph.stage == 'front':
- node = self.source.node
- self.graph.create_edge(node, port.node, out_port=self.source.idx, in_port=port.idx)
- else:
- data_node = self.source._create_data_if_necessary()
- self.graph.add_edge(data_node.id, port.node.id, **{'in': port.idx})
-
- self.destinations.append(port)
-
- def remove(self):
- # This method deletes all edges in connection. After that connection is not more accessible.
- # See detailed example below.
- #
- # SOURCE - Op1(out_port:0)
- #
- # | Op4(in_port:0)
- # DESTINATIONS - | Op3(in_port:0)
- # | Op2(in_port:0)
- #
- # ,--->Op4(in_port:0)
- # CONNECTION ,--->Op3(in_port:0)
- # Op1(out_port:0)--->Op2(in_port:0)
- #
- # After removing edges connection will be empty
- #
- # REMOVED CONNECTION
- # Op5(out_port:0) Op4(in_port:0) Op2(in_port:0) Op3(in_port:0)
- #
-
- if self.destinations:
- for dst_port in self.destinations:
- dst_port.disconnect()
- self.source = None
- self.destinations = []
-
- def insert_node(self, new_node, attributes_save_mode: str = "merge"):
- assert len(new_node.out_ports()) == 1, 'The node {} has several output ports'.format(new_node.soft_get('name'))
- source_port = self.get_source()
- self.set_source(new_node.out_port(0), attributes_save_mode)
- source_port.connect(new_node.in_port(0))
diff --git a/tools/mo/openvino/tools/mo/graph/graph.py b/tools/mo/openvino/tools/mo/graph/graph.py
deleted file mode 100644
index db0f97efebed23..00000000000000
--- a/tools/mo/openvino/tools/mo/graph/graph.py
+++ /dev/null
@@ -1,1348 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import collections
-import logging as log
-from copy import deepcopy
-from typing import List
-
-import networkx as nx
-import numpy as np
-
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.middle.passes.eliminate import mark_output_reachable_nodes, shape_inference, mark_undead_nodes, \
- mark_const_producer_nodes, eliminate_dead_nodes, add_constant_operations
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg, deprecated_api, shrink_str_value
-
-
-def dict_to_ordered_dict(d: dict, func=lambda t: t):
- return collections.OrderedDict(sorted(d.items(), key=lambda t: func(t[0])))
-
-
-class Node:
- def __init__(self, graph, node: str):
- assert node in graph, "Attempt to access node {} that not in graph".format(node)
-
- super(Node, self).__setattr__('graph', graph)
- super(Node, self).__setattr__('node', node) # obsolete
- super(Node, self).__setattr__('id', node)
-
- def __str__(self, max_length: int = 100):
- node_dict = self.graph.node[self.id]
- print_dict = {k: v if k != 'value' else shrink_str_value(v, max_symbols=max_length) for k, v in
- node_dict.items()}
- return str(print_dict)
-
- def __setattr__(self, k, v):
- # you can assign only existing attributes
- attrs = self.graph.node[self.node]
- if not k in attrs:
- raise AttributeError("Attribute {} missing in {} node".format(k, self.name))
- if k == 'version' and attrs.get(k, v) != v:
- raise AttributeError("Attribute 'version' cannot be updated in {} node".format(self.name))
-
- attrs[k] = v
-
- def __getattr__(self, k):
- return self.graph.node[self.node][k]
-
- def __getitem__(self, k):
- return self.graph.node[self.node][k]
-
- def __setitem__(self, k, v):
- if k == 'version' and self.graph.node[self.node].get(k, v) != v:
- raise AttributeError("Attribute 'version' cannot be updated in {} node".format(self.name))
- self.graph.node[self.node][k] = v
-
- def __contains__(self, k):
- return self.has(k)
-
- def __eq__(self, other):
- return (
- self.__class__ == other.__class__ and
- self.graph == other.graph and
- self.id == other.id
- )
-
- def __hash__(self):
- return hash((self.graph, self.id))
-
- def __delitem__(self, k):
- del self.graph.node[self.node][k]
-
- def add_input_port(self, idx, skip_if_exist=False, **kwargs):
- if not self.has_valid('_in_ports'):
- Node(self.graph, self.id)['_in_ports'] = {}
- control_flow = kwargs['control_flow'] if kwargs.get('control_flow') is not None else False
- if skip_if_exist is False and idx in self.in_ports(control_flow=control_flow):
- raise Error("Input port with {} index already exists for {} node.".format(idx, self.name))
- self._in_ports.update({idx: kwargs})
-
- def delete_input_ports(self, idx_set, skip_if_absent=False):
- if len(idx_set) == 0:
- return # there is nothing to delete
- for idx in idx_set:
- self.delete_input_port(idx, skip_if_absent)
-
- def delete_input_port(self, idx, skip_if_absent=False):
- if not self.has_valid('_in_ports'):
- raise Error(
- 'Cannot removed ports with indices {} from node {} because node doesn\'t '
- 'have _in_ports attribute'.format(idx, self.soft_get('name')))
- # no handling of control flow edges -- TODO
- control_flow = False
- if not skip_if_absent and idx not in self.in_ports(control_flow=control_flow):
- raise Error("Input port with index {} doesn't exist in node {}.".format(idx, self.soft_get('name')))
- if not self.in_port(idx).disconnected():
- self.in_port(idx).disconnect()
- del self._in_ports[idx]
- # update in_ports_count for consistency but it is unlikely have any effect somewhere in the code
- self['in_ports_count'] = len(self._in_ports)
-
- def delete_output_port(self, idx, skip_if_absent=False):
- if not self.has_valid('_out_ports'):
- raise Error(
- 'Cannot removed ports with indices {} from node {} because node doesn\'t '
- 'have _out_ports attribute'.format(idx, self.soft_get('name')))
- # no handling of control flow edges -- TODO
- control_flow = False
- if not skip_if_absent and idx not in self.out_ports(control_flow=control_flow):
- raise Error("Output port with index {} doesn't exist in node {}.".format(idx, self.soft_get('name')))
- if not self.out_port(idx).disconnected():
- self.out_port(idx).disconnect()
- del self._out_ports[idx]
- # update in_ports_count for consistency but it is unlikely have any effect somewhere in the code
- self['out_ports_count'] = len(self._out_ports)
-
- def add_output_port(self, idx, skip_if_exist=False, **kwargs):
- if not self.has_valid('_out_ports'):
- Node(self.graph, self.id)['_out_ports'] = {}
- control_flow = kwargs['control_flow'] if kwargs.get('control_flow') is not None else False
- if skip_if_exist is False and idx in self.out_ports(control_flow=control_flow):
- raise Error("Output port with {} index already exists for {} node.".format(idx, self.name))
- self._out_ports.update({idx: kwargs})
-
- def add_sequence_of_ports(self, type: str, rng):
- assert type in ['in', 'out']
- for idx in rng:
- if type == 'in':
- self.add_input_port(idx, skip_if_exist=True)
- if type == 'out':
- self.add_output_port(idx, skip_if_exist=True)
-
- def in_port(self, idx=None, control_flow=False) -> Port:
- if not self.has_valid('_in_ports'):
- raise Error("Operation {} {} has no _in_ports attribute", self.op, self.name)
- if idx not in self._in_ports:
- raise Error("Input port with index {} is not in node {}".format(idx, self.name))
- if not control_flow and 'control_flow' in self._in_ports[idx] and self._in_ports[idx]['control_flow']:
- raise Error("Attempt to access control flow port when it's prohibited for node {}".format(self.name))
- return Port(node=self, idx=idx, type='in', **self._in_ports[idx])
-
- def in_ports(self, control_flow=False):
- if not self.has_valid('_in_ports'):
- raise Error("Operation {} {} has no _in_ports attribute", self.op, self.name)
- ports = {}
- for idx in self._in_ports:
- if control_flow or 'control_flow' not in self._in_ports[idx] or not self._in_ports[idx]['control_flow']:
- ports.update({idx: self.in_port(idx, control_flow=control_flow)})
- return dict_to_ordered_dict(ports, func=lambda t: int(str(t).replace('control_flow_', '')))
-
- def out_port(self, idx=None, control_flow=False) -> Port:
- if not self.has_valid('_out_ports'):
- raise Error("Operation {} {} has no _out_ports attribute", self.op, self.name)
- if idx not in self._out_ports:
- raise Error("Output port with index {} is not in node {}".format(idx, self.name))
- if not control_flow and 'control_flow' in self._out_ports[idx] and self._out_ports[idx]['control_flow']:
- raise Error("Attempt to access control flow port when it's prohibited for node {}".format(self.name))
- return Port(node=self, idx=idx, type='out', **self._out_ports[idx])
-
- def out_ports(self, control_flow=False):
- if not self.has_valid('_out_ports'):
- raise Error("Operation {} {} has no _out_ports attribute", self.op, self.name)
- ports = {}
- for idx in self._out_ports:
- if control_flow or 'control_flow' not in self._out_ports[idx] or not self._out_ports[idx]['control_flow']:
- ports.update({idx: self.out_port(idx, control_flow=control_flow)})
- return dict_to_ordered_dict(ports, func=lambda t: int(str(t).replace('control_flow_', '')))
-
- def has_port(self, port_type, idx, control_flow=False):
- assert port_type in ['in', 'out'], "Invalid usage of has_port method"
-
- if port_type == 'in':
- return self.has_valid('_in_ports') and idx in self.in_ports(control_flow=control_flow)
- else:
- return self.has_valid('_out_ports') and idx in self.out_ports(control_flow=control_flow)
-
- def is_in_port_connected(self, idx, control_flow=False):
- return self.has_port('in', idx, control_flow) and not self.in_port(idx, control_flow).disconnected()
-
- def is_out_port_connected(self, idx, control_flow=False):
- return self.has_port('out', idx, control_flow) and not self.out_port(idx, control_flow).disconnected()
-
- def attrs(self):
- return self.graph.node[self.node]
-
- def has(self, k):
- return k in self.graph.node[self.node]
-
- def has_valid(self, k):
- return self.has(k) and not self.graph.node[self.node][k] is None
-
- def has_and_set(self, k):
- return self.has_valid(k) and self[k]
-
- def in_nodes_edges(self, control_flow: bool = False):
- return dict_to_ordered_dict({x[1]['in']: (Node(self.graph, x[0]), x[1]) for x in
- self.get_inputs(control_flow=control_flow)},
- func=lambda t: int(str(t).replace('control_flow_', '')))
-
- def in_nodes(self, control_flow: bool = False):
- if self.kind == 'op':
- return dict_to_ordered_dict({x[1]['in']: Node(self.graph, x[0]) for x in
- self.get_inputs(control_flow=control_flow)},
- func=lambda t: int(str(t).replace('control_flow_', '')))
- elif self.kind == 'data':
- return [Node(self.graph, n) for n, d in self.get_inputs(control_flow=control_flow)]
-
- def in_node(self, key=0, control_flow: bool = False):
- return self.in_nodes(control_flow=control_flow)[key]
-
- def in_edges(self, control_flow: bool = False):
- assert self.has('kind')
- assert self.kind in ['op', 'data']
- if self.kind == 'op':
- return dict_to_ordered_dict({x[1]['in']: x[1] for x in self.get_inputs(control_flow=control_flow)},
- func=lambda t: int(str(t).replace('control_flow_', '')))
- elif self.kind == 'data':
- return [d for n, d in self.get_inputs(control_flow=control_flow)]
-
- def out_nodes_edges(self, control_flow: bool = False):
- return dict_to_ordered_dict({x[1]['out']: (Node(self.graph, x[0]), x[1]) for x in
- self.get_outputs(control_flow=control_flow)},
- func=lambda t: int(str(t).replace('control_flow_', '')))
-
- def out_nodes(self, control_flow: bool = False):
- assert self.has('kind')
- assert self.kind in ['op', 'data']
- if self.kind == 'op':
- return dict_to_ordered_dict({x[1]['out']: Node(self.graph, x[0]) for x in
- self.get_outputs(control_flow=control_flow)},
- func=lambda t: int(str(t).replace('control_flow_', '')))
- elif self.kind == 'data':
- return [Node(self.graph, n) for n, d in self.get_outputs(control_flow=control_flow)]
-
- def out_edges(self, control_flow: bool = False):
- assert self.has('kind')
- assert self.kind in ['op', 'data']
- if self.kind == 'op':
- return dict_to_ordered_dict({x[1]['out']: x[1] for x in self.get_outputs(control_flow=control_flow)},
- func=lambda t: int(str(t).replace('control_flow_', '')))
- elif self.kind == 'data':
- return [d for n, d in self.get_outputs(control_flow=control_flow)]
-
- def out_node(self, key=0, control_flow: bool = False):
- return self.out_nodes(control_flow=control_flow)[key]
-
- def in_edge(self, key=0, control_flow: bool = False):
- return self.in_edges(control_flow=control_flow)[key]
-
- def out_edge(self, key=0, control_flow: bool = False):
- return self.out_edges(control_flow=control_flow)[key]
-
- def get_attrs(self):
- return self.graph.node[self.node]
-
- def get_inputs(self, edge_attr: dict = None, control_flow: bool = False):
- if edge_attr is None:
- edge_attr = {}
- in_edges = self.graph.in_edges(self.id, data=True)
- if not control_flow:
- in_edges = [(u, v, d) for u, v, d in in_edges if 'control_flow_edge' not in d or not d['control_flow_edge']]
- return [(u, d) for u, v, d in in_edges if all([attr in d and d[attr] == edge_attr[attr] for attr in edge_attr])]
-
- def get_outputs(self, edge_attr: dict = None, control_flow: bool = False):
- if edge_attr is None:
- edge_attr = {}
- out_edges = self.graph.out_edges(self.id, data=True)
- if not control_flow:
- out_edges = [(u, v, d) for u, v, d in out_edges if
- 'control_flow_edge' not in d or not d['control_flow_edge']]
- return [(v, d) for u, v, d in out_edges if
- all([attr in d and d[attr] == edge_attr[attr] for attr in edge_attr])]
-
- def get_sorted_inputs(self, control_flow: bool = False):
- return sorted([x for x in self.get_inputs(control_flow=control_flow) if 'in' in x[1]],
- key=lambda x: x[1]['in'])
-
- def get_sorted_outputs(self, control_flow: bool = False):
- return sorted([x for x in self.get_outputs(control_flow=control_flow) if 'out' in x[1]],
- key=lambda x: x[1]['out'])
-
- def soft_get(self, k, default=''):
- return self[k] if self.has_valid(k) else default
-
- def edges(self, attrs: dict = None):
- """ Get a single edge with specified set of attributes.
-
- If none or multiple edges satisfies this criteria, exception is raised
- Edge is represented as tuple (u, v, d), where u is source node,
- v is destination node and d is edge attributes.
- """
- edges = list(self.graph.in_edges([self.id], data=True)) + list(self.graph.out_edges([self.id], data=True))
- return [(u, v, d) for u, v, d in edges if dict_includes(d, attrs)]
-
- def edge(self, attrs: dict = None):
- """ Get a single edge with specified set of attributes.
-
- If none or multiple edges satisfies this criteria, exception is raised
- Edge is represented as tuple (u, v, d), where u is source node,
- v is destination node and d is edge attributes.
- """
- edges = self.edges(attrs)
- assert len(edges) == 1, 'edges: {}, required attributes: {}'.format(edges, attrs)
- return edges[0]
-
- def copy_node(self, new_attrs: dict = None, dst_graph=None):
- ''' Copies node with all attributes (optionally updated) within the same graph or to different graph.'''
- if new_attrs is None:
- new_attrs = {}
- if dst_graph is None:
- dst_graph = self.graph
-
- attrs = deepcopy(self.attrs())
- new_id = dst_graph.unique_id(attrs['name']) if 'name' in attrs else dst_graph.unique_id()
- attrs['name'] = new_id
- attrs.update(new_attrs)
- dst_graph.add_node(new_id, **attrs)
- return Node(dst_graph, new_id)
-
- def insert_node_with_data_before(self, inp, new_op_class: callable, op_before_params: dict = None,
- infer_current: bool = False, additional_inputs: list = None):
- """
- Inserts operation node with op_before_params and data node before current operation
-
- :param inp: input data node of current node
- :param new_op_class: class of operation that will be inserted before current operation node
- :param op_before_params: parameters to be added to operation that will be inserted before current operation
-
- Before calling:
- [...] -> inp -> Cur_Op -> Cur_Data -> [...]
-
- After calling:
- [...] -> inp -> New_Op_bef -> New_Data_bef -> Cur_Op -> Cur_Data -> [...]
- [op_before_params]
- """
- graph = self.graph
- node = Node(graph, self.node)
- cls_name = new_op_class.op
- op_before_params = {} if op_before_params is None else op_before_params
-
- # operating with input
- new_op_before = new_op_class(graph, op_before_params)
- edge_attrs = deepcopy(graph.get_edge_data(inp.id, node.id)[0])
- graph.remove_edge(inp.id, node.id)
- # form a list of input nodes for a new op node combining new_out and additional_inputs
- inputs = [inp] + (additional_inputs if additional_inputs else [])
- new_inp = new_op_before.create_node_with_data(inputs, {'name': node.name + cls_name + '/Before'})
- graph.add_edge(new_inp.id, node.id, **edge_attrs)
- if infer_current:
- node.infer(node)
-
- def insert_node_with_data_after(self, out, new_op_class: callable, op_after_params: dict = None,
- additional_inputs: list = None):
- """
- Inserts operation node with op_after_params and data node after current operation
-
- :param out: output data node of current node
- :param new_op_class: class of operation that will be inserted after current operation node
- :param op_after_params: parameters to be added to operation that will be inserted after current operation
- :param additional_inputs: other parameters for a new operation node in addition to one that is created
- at the 'out' placed; new nodes are added after 0-th input
-
- TODO Allow indexing for input parameters as well as for 'out' data node to explicitly
- specify ports that are connected to.
-
- Before calling:
- [...] -> Cur_Op -> Cur_Data -> [...]
-
- After calling:
- [...] -> Cur_Op -> Cur_Data -> New_Op_aft -> New_Data_aft(==out) -> [...]
- [op_after_params]
- """
- # we import it here because Op imports Node and unique_id from this file
- from openvino.tools.mo.ops.op import Op
-
- graph = self.graph
- node = Node(graph, self.node)
- cls_name = new_op_class.op
- op_after_params = {} if op_after_params is None else op_after_params
-
- new_op_after = new_op_class(graph, op_after_params)
- graph.remove_edge(node.id, out.id)
- new_out = Op.create_data_node(graph, node)
- node.infer(node)
- # form a list of input nodes for a new op node combining new_out and additional_inputs
- inputs = [new_out] + (additional_inputs if additional_inputs else [])
- new_op_after.create_node_with_data(inputs, {'name': node.name + cls_name + '/After'}, data_nodes=out)
-
- def bracket_with_different_nodes_with_data(self, inp, out, new_op_class_before: callable,
- new_op_class_after: callable,
- op_before_params: dict = None, op_after_params: dict = None):
- """
- Inserts one operation node with op_before_params and data node before current operation node and
- inserts one operation node with op_after_params and data node after current operation node
- :param inp: input data node of self.node node
- :param out: output data node of self.node node
- :param new_op_class_before: class of operation that will be inserted before current operation node
- :param new_op_class_after: class of operation that will be inserted after current operation node
- :param op_before_params: parameters to be added to operation that will be inserted before current operation
- :param op_after_params: parameters to be added to operation that will be inserted after current operation
-
- Before calling:
- [...] -> inp -> Cur_Op -> out -> [...]
-
- After calling:
- [...] -> inp -> New_Op_bef -> New_Data_bef -> Cur_Op -> Cur_Data -> New_Op_aft -> New_Data_aft(==out) -> [...]
- [op_before_params] [op_after_params]
- """
- op_before_params = {} if op_before_params is None else op_before_params
- op_after_params = {} if op_after_params is None else op_after_params
- self.insert_node_with_data_before(inp, new_op_class_before, op_before_params)
- self.insert_node_with_data_after(out, new_op_class_after, op_after_params)
-
- def bracket_op_with_another_op(self, inp, out, new_op_class: callable,
- op_before_params: dict = None, op_after_params: dict = None):
- """
- Covers current operation with two similar another ones of class new_op_class:
- :param inp: input data node of self.node node
- :param out: output data node of self.node node
- :param new_op_class: class of operation with which current operation will be covered
- :param op_before_params: parameters to be added to operation that will be inserted before current operation
- :param op_after_params: parameters to be added to operation that will be inserted after current operation
-
- Before calling:
- [...] -> inp -> Cur_Op -> out -> [...]
-
- After calling:
- [...] -> inp -> New_Op_bef -> New_Data_bef -> Cur_Op -> Cur_Data -> New_Op_aft -> New_Data_aft(==out) -> [...]
- [op_before_params] [op_after_params]
- """
- self.bracket_with_different_nodes_with_data(inp=inp, out=out,
- new_op_class_before=new_op_class, new_op_class_after=new_op_class,
- op_before_params=op_before_params, op_after_params=op_after_params)
-
- def insert_node_after(self, new_node, node_out_port: int = 0):
- """
- Insert node 'new_node' after output with index 'node_out_port' of the node 'node'. All consumers of node 'node'
- output with index 'node_out_port' will be changed to consume node 'new_node'.
- The function should be used when graph doesn't contain data nodes yet.
- :param node: node after which new node should be inserted.
- :param new_node: node to be inserted.
- :param node_out_port: the output index for the node 'node' to insert
- :return: None
- """
- assert self.graph is new_node.graph
- assert (len([name for name in self.graph.nodes() if Node(self.graph, name).soft_get('kind') == 'data']) == 0)
-
- graph = self.graph
- old_edges = list(graph.out_edges(self.id, data=True, keys=True))
- # create new edges first and then remove all old edges. This is needed for case when 'node' has several consumers
- # getting input from 'node_out_port'.
- # save tuple ("name of the destination edge", "edge key") to be removed
- node_name_and_edge_key = []
- for _, dst_name, edge_key, edge_attrs in old_edges:
- if edge_attrs['out'] == node_out_port:
- log.debug('Create edge from "{}" to "{}"'.format(new_node.name, dst_name))
- graph.create_edge(new_node, Node(graph, dst_name), 0, edge_attrs['in'])
- node_name_and_edge_key.append((dst_name, edge_key))
- for dst_name, edge_key in node_name_and_edge_key:
- log.debug('Remove edge from "{}" to "{}"'.format(self.id, dst_name))
- graph.remove_edge(self.id, dst_name, edge_key)
- graph.create_edge(self, new_node, node_out_port, 0, {})
-
- def insert_op_on_input_port(self, in_port_idx: int, new_op_class: callable, new_op_attrs: dict,
- value: np.ndarray = None):
- """
- Inserts new operation of new_op_class on in_port_index input port with new_op_attrs
- Connects Const operation with value to 1 input port of new node if value was passed
-
- Returns new operation node
- """
- graph = self.graph
- name = self.soft_get('name', self.id)
-
- op_node = new_op_class(graph, new_op_attrs).create_node()
-
- assert self.has_port('in', in_port_idx), \
- 'Node `{}` should have input port with idx `{}` but it does not'.format(name, in_port_idx)
-
- in_port_source = self.in_port(in_port_idx).get_source()
- self.in_port(in_port_idx).get_connection().set_source(op_node.out_port(0))
- op_node.in_port(0).connect(in_port_source)
-
- if value is not None:
- from openvino.tools.mo.ops.const import Const
- constant = Const(graph, {'value': value, 'name': op_node.name + '/value'}).create_node()
- op_node.in_port(1).connect(constant.out_port(0))
-
- return op_node
-
- def replace_node(self, new_node, new_node_out_port: int = None):
- """
- Replaces node 'old_node' with a node 'new_node' preserving edge attributes.
- :param old_node: node to be replaced.
- :param new_node: node to replace with.
- :return: None
- """
- assert self.graph is new_node.graph
- assert self.id != new_node.id, "New node and replaceable node are the same"
- graph = self.graph
- # save output edges and reconnect them to new node
- for _, dst_node_name, edge_attrs in graph.out_edges(self.id, data=True):
- new_edge_attrs = deepcopy(edge_attrs)
- if new_node_out_port is not None:
- assert 'out' not in edge_attrs or edge_attrs['out'] == 0, \
- 'replace_node function can replace old node with a single output port only if new_node_out_port is ' \
- 'specified'
- new_edge_attrs.update({'out': new_node_out_port})
- graph.add_edge(new_node.id, dst_node_name, **new_edge_attrs)
-
- # if the node for replace is output node then we propagate this attribute to a new node
- if len(self.out_nodes()) == 1 and self.out_node().has('op') and self.out_node().op == 'Result':
- graph.remove_node(self.out_node().id)
- add_opoutput(graph, new_node.id, 0, False)
- graph.remove_node(self.id)
-
- def input_ports_with(self, node):
- """
- Returns a list of integers that specify input ports that connected to a given node.
- :param node: node in the graph that is expected to appear at input port for self node
- :return: a list of integers with port indices that are connected to self node
- """
- return [i for i in range(len(self.in_nodes())) if self.in_node(i).id == node.id]
-
- def update_node(self):
- """
- Update internal node attributes. Currently it just add input/output ports.
- :return: None
- """
- in_ports_count = self.in_ports_count if self.has_valid('in_ports_count') else None
- out_ports_count = self.out_ports_count if self.has_valid('out_ports_count') else None
-
- if not self.has_valid('_in_ports'):
- Node(self.graph, self.id)['_in_ports'] = dict()
- if not self.has_valid('_out_ports'):
- Node(self.graph, self.id)['_out_ports'] = dict()
-
- if in_ports_count is not None:
- for idx in range(in_ports_count):
- if idx not in self._in_ports:
- self.add_input_port(idx=idx)
-
- if out_ports_count is not None:
- for idx in range(out_ports_count):
- if idx not in self._out_ports:
- self.add_output_port(idx=idx)
-
- def get_opset(self):
- """
- Gets the operation set version where the operation was introduced.
- If the version is not defined then consider it an extension
- :return: the string with the opset name
- """
- return self.soft_get('version', 'extension')
-
-
-class Graph(nx.MultiDiGraph):
- def __init__(self, data=None, **attr):
- self.stage = None
- self.strict_mode = True
- super().__init__(data, **attr)
-
- if not hasattr(self, 'node'):
- self.node = self.nodes
-
- unique_id_count = 0
- op_names_statistic = collections.Counter()
- inputs_order = []
- outputs_order = []
-
- # SAFE API DESCRIPTION
- # all provided methods below are designed to be more safe and convenient
- # be careful while using other methods from nx.MultiDiGraph
-
- def add_node(self, node_for_adding, **attrs):
- # TODO: check required attrs for node
- super().add_node(node_for_adding, **attrs)
- node = Node(self, node_for_adding)
- node.update_node()
-
- def add_edge(self, u_for_edge, v_for_edge, key=None, **attr):
-
- # TODO: turn on strict mode
- if self.strict_mode:
- unode = Node(self, u_for_edge)
- vnode = Node(self, v_for_edge)
-
- # Check that we connect Op->Op in front phase, and data->Op or Op->data in middle(back) phase
- # Also check that all necessary ports are exists
- message = "Attempt to connect {} to {}.".format(u_for_edge, v_for_edge)
- if self.stage == 'front':
- assert unode.kind == 'op' and vnode.kind == 'op', "{} Wrong add_adge usage! You can connect only two " \
- "operations in front phase".format(message)
- assert 'in' in attr and 'out' in attr, "Missing necessary attribute in or out when adding edge " \
- "between {} and {}".format(u_for_edge, v_for_edge)
- is_control_flow = 'control_flow_edge' in attr and attr['control_flow_edge'] is True
- in_port = 'control_flow_{}'.format(attr['in']) if is_control_flow else attr['in']
- out_port = 'control_flow_{}'.format(attr['out']) if is_control_flow else attr['out']
- assert unode.has_port('out', out_port, control_flow=is_control_flow), \
- "{} Missing out port ({}) in {} node".format(message, out_port, unode.soft_get('name', unode.id))
- assert vnode.has_port('in', in_port, control_flow=is_control_flow), \
- "{} Missing in port ({}) in {} node".format(message, in_port, vnode.soft_get('name', vnode.id))
- elif self.stage in ['middle', 'back']:
- assert (unode.kind == 'data' and vnode.kind == 'op') or (unode.kind == 'op' and vnode.kind == 'data')
- if unode.kind == 'data' and vnode.kind == 'op':
- assert 'in' in attr, "Attribute in is missing when adding edge to {}".format(v_for_edge)
- assert vnode.has_port('in', attr['in']), "{} Node {} has no in port ({})" \
- "".format(message, vnode.name, attr['in'])
- if unode.kind == 'op' and vnode.kind == 'data':
- assert 'out' in attr, "Attribute out is missing when adding edge from {}".format(u_for_edge)
- assert unode.has_port('out', attr['out']), "{} Node {} has no out port ({})" \
- "".format(message, unode.name, attr['out'])
-
- return super().add_edge(u_for_edge, v_for_edge, key=key, **attr)
-
- def add_edges_from(self, ebunch_to_add, **attr):
- for e in ebunch_to_add:
- ne = len(e)
- if ne == 4:
- u, v, key, dd = e
- elif ne == 3:
- u, v, dd = e
- key = None
- elif ne == 2:
- u, v = e
- dd = {}
- key = None
- else:
- raise Error("Edge tuple %s must be a 2-tuple, 3-tuple or 4-tuple." % (e,))
- ddd = attr.copy()
- ddd.update(dd)
- self.add_edge(u, v, key=key, **ddd)
-
- def remove_edge(self, u, v, key=None):
- return super().remove_edge(u, v, key=key)
-
- def erase_node(self, node: Node):
- """
- Erases node from the graph and reconnect edges from input node(s) to output node(s)
- Produces assertion error if the node being removed has multiple inputs or outputs.
- The function can be used in the front phase only (when there are no data nodes in the graph).
- :param node: Node to erase
- """
- node_id = node.id
-
- inputs = list(self.in_edges(node_id, data=True))
- outputs = list(self.out_edges(node_id, data=True))
-
- assert node.kind == 'op' and (len(node.out_nodes()) == 0 or list(node.out_nodes().values())[0].kind != 'data'), \
- "The function must be used before the partial infer when graph doesn't contain data nodes."
- assert len(node.out_nodes()) <= 1, "The node {} must produce just one output tensor".format(
- node.soft_get('name'))
- assert len(inputs) <= 1, "The node {} must have just one input".format(node.soft_get('name'))
-
- if len(outputs) == 0 and len(inputs) != 0:
- from openvino.tools.mo.front.extractor import add_output_ops
- input_ids = {input_node_id: {'port': {'out': [attrs['out']]}} for input_node_id, _, attrs in inputs}
- if node.has('op') and node.op == 'Result':
- add_output_ops(self, input_ids)
-
- if len(outputs) == 0 or len(inputs) == 0:
- self.remove_node(node_id)
- return
-
- input_node_id = inputs[0][0]
- for src, dst, attrs in outputs:
- self.remove_edge(src, dst)
- # update the 'out' attribute of the edge from the node being removed
- attrs['out'] = inputs[0][2]['out']
- self.add_edge(input_node_id, dst, **attrs)
- self.remove_node(node_id)
-
- def get_edge_data(self, u, v, key=None, default=None):
- return super().get_edge_data(u, v, key=key, default=default)
-
- def get_inputs_with_ports(self, match, pattern_edges, input_names_in_pattern):
- """
- Front replacements of multi-input nodes should specify output port to add_node-like functions
- This function is a helper to get such information out of matched nodes
- :param graph: graph to operate on
- :param match: dictionary returned by matching function
- :param pattern_edges: edges that are specified in pattern
- :param input_names_in_pattern: names of matched nodes as they were specified in pattern that should be in
- resulting list
- :return: list of tuples of node and output port
- """
- inputs = []
- for name in input_names_in_pattern:
- assert name in match, "node named {} not in match {}".format(name, match)
- src = match[name]
- dst = []
- for edge in pattern_edges:
- if edge[0] == name:
- assert edge[1] in match, "name from pattern_edges {} not in match {}".format(edge[1], match)
- dst.append(match[edge[1]])
- if len(dst) != 1:
- raise Error('Multiple output ports detected for node {} as {} in pattern'.format(match[name].id, name))
- dst = dst[0]
- out_port = self.get_edge_data(src.id, dst.id)[0]['out']
- inputs.append((src, out_port))
- return inputs
-
- def get_node_id_by_name(self, name: str):
- nodes = self.get_nodes_with_attributes(name=name)
- if len(nodes) == 0:
- raise Error('No node with name {}. ' + refer_to_faq_msg(51), name)
- elif len(nodes) > 1:
- raise Error('Multiple nodes with name {}'.format(name))
- else:
- return nodes[0]
-
- def get_op_nodes(self, **attrs):
- nodes = self.get_nodes_with_attributes(**dict(kind='op', **attrs))
- return [Node(self, node) for node in nodes]
-
- def get_data_nodes(self, has_value=None):
- """
- Returns list of data nodes.
- If has_value = True, returns data nodes with value
- If has_value = False, returns data nodes without value
- """
- data_nodes = [Node(self, node) for node in self.nodes() if Node(self, node).soft_get('kind') == 'data']
- return [node for node in data_nodes if has_value is None or node.has_valid('value') == has_value]
-
- def get_nodes_with_attributes(self, **attrs: dict):
- node_attrs = self.nodes(data=True)
- return [n for n, d in node_attrs if all(a in d.items() for a in attrs.items())]
-
- def unique_id(self, prefix: str = ""):
- """
- Generates a unique node id for a new node in a given graph.
- The optional string prefix can be specified.
- """
- # TODO thread safety?
- self.unique_id_count = max(self.unique_id_count, self.number_of_nodes()) + 1
- if prefix and not self.has_node(prefix):
- return str(prefix)
- while self.has_node(prefix + str(self.unique_id_count)):
- self.unique_id_count += 1
- return prefix + str(self.unique_id_count)
-
- def check_empty_graph(self, description: str):
- if len(self.nodes()) <= 1:
- raise Error(
- "Graph contains {} node after executing {}. It considered as error because resulting IR will be "
- "empty which is not usual".format(len(self.nodes()), description))
-
- def check_shapes_consistency(self):
- data_nodes = self.get_data_nodes()
- data_nodes_with_wrong_shapes = []
- for data_node in data_nodes:
- if not data_node.has('shape'):
- data_nodes_with_wrong_shapes.append((data_node.name, "no shape attribute"))
- continue
- if data_node.shape is not None and not isinstance(data_node.shape, np.ndarray):
- data_nodes_with_wrong_shapes.append((data_node.name, type(data_node.shape)))
- if len(data_nodes_with_wrong_shapes) > 0:
- raise Error("Graph contains data nodes ({}) with inconsistent shapes: {}".format(
- len(data_nodes_with_wrong_shapes),
- data_nodes_with_wrong_shapes
- ))
-
- def check_nodes_ports_are_consecutive(self):
- # Check that all operation nodes has consecutive ports indexes
- op_nodes = self.get_op_nodes()
- for node in op_nodes:
- for idx in range(len(node.in_ports())):
- if idx not in node.in_ports():
- raise Error("Node {} has not consecutive in ports indexes: {}".format(node.name,
- list(node.in_ports().keys())))
- for idx in range(len(node.out_ports())):
- if idx not in node.out_ports():
- raise Error("Node {} has not consecutive out ports indexes: {}".format(node.name,
- list(
- node.out_ports().keys())))
-
- def dump_graph_for_graphviz(self, node_attrs: list = ['kind', 'op', 'shape', 'correct_data_layout', 'nchw_layout',
- 'internal_layer_id'],
- edge_attrs: list = ['in', 'out'], nodes_to_dump: list = None,
- save_to_svg=False, highlight_nodes: list = None):
-
- from openvino.tools.mo.ops.tensor_iterator import _get_internal_output_node_id, _get_internal_input_node_id
-
- fill_color = {'op': 'lightblue', 'data': 'whitesmoke', 'highlight': 'firebrick'}
- fill_color_by_type = {'Const': 'lightpink', 'Parameter': 'yellowgreen', 'TensorIterator': 'lemonchiffon'}
- style = {'op': 'filled,bold', 'data': 'filled,rounded'}
-
- subgraphs = {}
- if highlight_nodes is None:
- highlight_nodes = []
-
- def _subgraph_label(node_id, node_attrs: dict, attrs_to_print: list):
- subgraphs[node_id] = "cluster_{}".format(node_id)
- label = 'subgraph "cluster_{}" '.format(node_id) + '{\n'
- label += 'label = "{}"; \n'.format(node_id)
- label += 'color={}; \nstyle="filled,rounded";\n'.format(fill_color_by_type[node_attrs['op']])
-
- subgraph_name = node_attrs['sub_graphs']
- assert len(subgraph_name) == 1
- body = node_attrs[subgraph_name[0]].dump_graph_for_graphviz()
- body = body.split('\n')[2:-1]
- label += '\n'.join(body)
- label += '\n}\n'
- return label
-
- def _node_label(node_id, node_attrs: dict, attrs_to_print: list):
- label = str(node_id) + '\\n' + '\\n'.join([str(key) + '=' + str(node_attrs.get(key, 'None'))
- for key in attrs_to_print if key in node_attrs])
- if node_attrs.get('type', '') == 'Const':
- if 'value' not in attrs_to_print and 'value' in node_attrs:
- if node_attrs['value'] is not None:
- label += '\\nvalue=\\"' + \
- ','.join([str(val) for val in node_attrs['value'].flatten()])[:40] + '\\"'
- else:
- label += '\\nvalue=None'
- return label
-
- def _dump_nodes_attrs():
- string = ''
- for node_id in nodes_to_dump:
- attrs = self.node[node_id]
- color = fill_color_by_type.get(attrs.get('type', ''), fill_color[attrs['kind']])
-
- if node_id in highlight_nodes or 'highlight' in node_attrs and node_attrs['highlight']:
- color = fill_color['highlight']
-
- if attrs.get('op') == 'TensorIterator':
- string += _subgraph_label(node_id, attrs, node_attrs)
- else:
- string += '"{}" [fillcolor={} style="{}" shape=box label="{}"];\n'.format(
- node_id, color, style[attrs['kind']], _node_label(node_id, attrs, node_attrs))
- return string
-
- def _dump_edges_attrs():
- string = ''
- for src_node_id, dst_node_id, attrs in self.edges(data=True):
- if src_node_id not in nodes_to_dump or dst_node_id not in nodes_to_dump:
- continue
-
- if src_node_id in subgraphs:
- edge_label = subgraphs[src_node_id]
- edge_label_name = 'ltail'
- src_node_id = _get_internal_output_node_id(self, src_node_id, attrs['external_port_id'])
- elif dst_node_id in subgraphs:
- edge_label = subgraphs[dst_node_id]
- edge_label_name = 'lhead'
- dst_node_id = _get_internal_input_node_id(self, dst_node_id, attrs['external_port_id'])
- else:
- edge_label = ' '.join(
- [str(key) + '=' + str(attrs.get(key, 'None')) for key in edge_attrs if key in attrs])
- edge_label_name = 'label'
-
- string += '"{}" -> "{}" [{} = "{}"];\n'.format(src_node_id, dst_node_id, edge_label_name, edge_label)
- return string
-
- log.debug("---- GRAPHVIZ OUTPUT STARTS ----")
-
- if nodes_to_dump is None:
- nodes_to_dump = self.nodes()
-
- string = '\ndigraph {\n'
-
- string += _dump_nodes_attrs()
- string += _dump_edges_attrs()
-
- string += '}'
- log.debug("---- GRAPHVIZ OUTPUT ENDS ----")
-
- if save_to_svg:
- try:
- import graphviz
- import os
- file_name = "{}_{}.txt".format(self.name.replace('/', '_'), 0)
- id = 1
- while os.path.exists(file_name):
- file_name = "{}_{}.txt".format(self.name.replace('/', '_'), id)
- id += 1
- with open(file_name, "w") as f:
- f.write(string)
- graphviz.render('dot', 'svg', file_name)
- print('Graph was saved to {}.{}'.format(file_name, 'svg'))
- except ImportError:
- raise ImportError('Can\'t import graphviz')
- except Exception as e:
- raise Error('Can\'t save graph to svg') from e
-
- return string
-
- def print_graph_stat(self):
- log.debug('Number of nodes in graph: {}'.format(self.number_of_nodes()))
- log.debug('Number of edges in graph: {}'.format(len(list(self.edges()))))
- ops = collections.defaultdict(int)
- for _node in self.nodes():
- node = Node(self, _node)
- kind = node.kind if node.has('kind') else ''
- if node.has('op'):
- ops['op/' + node.op] += 1
- else:
- ops[kind] += 1
- if node.has('shape') and np.any(node.shape == 0):
- log.error("Found bad shape: '{}' for node '{}'".format(node.shape, node.node))
- for k, v in ops.items():
- log.debug(' {} : {}'.format(k, v))
-
- def create_sub_graph_copy(self, nodes_to_extract: list):
- """
- Create new graph which is a sub-graph of the 'graph' that contains just nodes from 'nodes_to_extract' list. The
- returned sub-graph is a deep copy of the provided graph nodes.
- :param graph: graph to create a sub-graph from.
- :param nodes_to_extract: list of node names to extract.
- :return: new graph.
- """
- return self.subgraph(nodes_to_extract).copy()
-
- def create_edge(self, src_node: Node, dst_node: Node, out_port: int = 0, in_port: int = 0, edge_attrs: dict = None):
- """
- Creates edge from node 'src_node' from output with index 'out_port' to node 'dst_node' with input index 'in_port'.
- :param src_node: node to create edge from.
- :param dst_node: node to create edge to.
- :param out_port: the index of output tensor of the 'src_node'.
- :param in_port: the input index of the node 'dst_node'.
- :param edge_attrs: dictionary with edge attrs.
- :return: None
- """
- # edges must belong to the same graph
- assert src_node.graph is dst_node.graph
- graph = src_node.graph
-
- if edge_attrs is None:
- edge_attrs = dict()
- else:
- edge_attrs = edge_attrs.copy()
- edge_attrs.update(
- {'in': in_port, 'out': out_port, 'in_attrs': ['in', 'permutation'], 'out_attrs': ['out', 'permutation'],
- 'data_attrs': ['fw_tensor_debug_info']})
-
- # TODO: in case if in_port do not exists, we should raise an Exception here
- graph.add_edges_from([(src_node.id, dst_node.id, edge_attrs)])
-
- def dfs(self, node_name: str, visited: set):
- """
- Implementation of the depth-first search algorithm starting from the specific node.
- :param graph: networkx graph to operate on.
- :param node_name: node name to start search from.
- :param visited: set of already visited nodes.
- :return: list of nodes in the DFS-visit order.
- """
- order = []
- stack = [node_name]
- while len(stack) != 0:
- node_name = stack[0]
- stack.pop(0)
- visited.add(node_name)
- has_child = False
- for _, out_node_name in self.out_edges(node_name):
- if out_node_name not in visited:
- stack.insert(0, node_name)
- stack.insert(0, out_node_name)
- has_child = True
- break
- if not has_child:
- order.append(node_name)
- return order
-
- def pseudo_topological_sort(self, reverse: bool = False):
- """
- The function performs topological sort but doesn't check for cycle existence. So it may produce wrong nodes order
- for some applications.
- :param graph: graph to pseudo-topologically sort.
- :param reverse: flag indicating whether need to reverse nodes order.
- :return: nodes in the topological sort if cycle doesn't exist and in pseudo-topological sort if not.
- """
- nodes_without_inputs = list()
- for node_name in self.nodes():
- if len(self.in_edges(node_name)) == 0:
- nodes_without_inputs.append(node_name)
- order = list()
- visited = set()
- for node_name in nodes_without_inputs:
- if node_name not in visited:
- order.extend(self.dfs(node_name, visited))
-
- order = [Node(self, node) for node in order]
-
- if reverse:
- return order
- else:
- return list(reversed(order))
-
- def pseudo_topological_sort_with_start_node(self, start_node: Node, reverse: bool = False):
- nodes_without_inputs = [start_node.soft_get('name')]
- visited = set()
- order = self.dfs(nodes_without_inputs[0], visited)
-
- order = [Node(self, node) for node in order]
-
- if reverse:
- return order
- else:
- return list(reversed(order))
-
- def clean_up(self, undead_node_types: list = None):
- if undead_node_types is None:
- undead_node_types = []
-
- if not getattr(self.graph['cmd_params'], 'static_shape', False):
- undead_node_types.extend(['ShapeOf', 'Shape', 'slice_like'])
-
- mark_output_reachable_nodes(self)
- shape_inference(self)
- mark_undead_nodes(self, undead_node_types)
- mark_const_producer_nodes(self)
- eliminate_dead_nodes(self)
- # Add Const op for constant data nodes
- add_constant_operations(self)
-
- def get_tensor_names_set(self):
- """
- Get set of tensor names of the graph.
- """
- tensor_names_set = set()
- for node in self.get_op_nodes():
- if self.stage is None:
- for out_edge_idx in node.out_edges():
- out_edge = node.out_edge(out_edge_idx)
- if "fw_tensor_debug_info" in out_edge:
- for _, tensor_name in out_edge["fw_tensor_debug_info"]:
- tensor_names_set.add(tensor_name)
- else:
- for _, port in node.out_ports().items():
- tensor_names = port.get_tensor_names()
- tensor_names_set = tensor_names_set.union(set(tensor_names))
- return tensor_names_set
-
- def has_tensor_name(self, tensor_name: str):
- """
- Checks if graph has tensor name.
- """
- # TODO: This can be optimized. Tensor names can be stored as set, which is initialized after model loading.
- names = self.get_tensor_names_set()
- return tensor_name in names
-
-
- def topological_sort(self, reverse: bool = False):
- sorted_node_ids = nx.topological_sort(self)
-
- sorted_nodes = [Node(self, node_id) for node_id in sorted_node_ids]
-
- if not reverse:
- return sorted_nodes
- else:
- return list(reversed(sorted_nodes))
-
- def set_node_attributes(self, name: str, values):
- return nx.set_node_attributes(self, values=values, name=name)
-
-
-def fill_graph_with_nodes(graph, src_nodes, get_id: callable, get_attrs: callable):
- """
- Go over all nodes in src_nodes that should be enumerable and create new NX nodes
- using get_id and get_attrs functions to create node id and node attributes correspondingly.
- """
- for node in src_nodes:
- graph.add_node(get_id(node), **get_attrs(node))
-
-
-def dict_includes_compare_attrs(attr, attr_probe):
- if callable(attr_probe) and not isinstance(attr_probe, type):
- return attr_probe(attr)
- else:
- res = (attr == attr_probe)
- # check if the result of comparison is a numpy scalar value which occur when attr is python scalar and
- # attr_probe is a numpy scalar
- if hasattr(res, 'ndim') and res.ndim == 0:
- return res.item()
- return res if isinstance(res, bool) else all(res)
-
-
-def dict_includes(big: dict, sub_dict: dict, skip_attr_names=[]):
- """ Searches attributes from sub_dict in big and ensures that all values match.
-
- Entries in sub_dict can be of two types: callable or not callable. If callable is specified
- it is treated as probing function for attribute value from big dictionary by callable(attr) expression.
- If it is not callable, the values are compared with == operator.
- """
- return all(
- dict_includes_compare_attrs(big.get(attr, None), sub_dict[attr])
- for attr in sub_dict.keys() if attr not in skip_attr_names
- )
-
-
-def add_opoutput(graph: Graph, node_name: str, port: int, cut: bool = True, keep_output_port: bool = False,
- user_defined_name=None):
- """
- Creates and connects Result node to node_name port. Cuts existing port if requested.
- :param graph: graph to operate with
- :param node_name: name of existing node in the graph that we want to add Result to
- :param port: output port of node to connect Result to
- :param cut: determines way of operating with edge specified by node_name and port
- :param keep_output_port: special attribute determines if this operation is saved in IR or not
- :param user_defined_name: User defined operation name, which should be added to tensor names list
- """
- # we import it here because Op imports add_attrs_props and update_ie_fields from this file
- from openvino.tools.mo.ops.result import Result
- node = Node(graph, node_name)
- if cut and len(node.out_edges()) != 0:
- opoutput_node = Result(graph).create_node_on_port(node, port, {'name': node_name + '/sink_port_' + str(port),
- 'keep_output_port': keep_output_port})
- else:
- opoutput_node = Result(graph).create_node([(node, port)], {'name': node_name + '/sink_port_' + str(port),
- 'keep_output_port': keep_output_port})
- opoutput_node.in_edge()['data_attrs'] = ['fw_tensor_debug_info']
-
- if user_defined_name is not None and (graph.stage == 'front' or graph.stage is None):
- # Following code adds user_defined_name to tensor names list
- # Not applicable for middle stage
- prev_op_tensor_names = set()
- in_edge_attrs = opoutput_node.in_edge()
- if 'fw_tensor_debug_info' in in_edge_attrs:
- for _, tensor_name in opoutput_node.in_edge()['fw_tensor_debug_info']:
- prev_op_tensor_names.add(tensor_name)
- if user_defined_name not in prev_op_tensor_names:
- if graph.has_tensor_name(user_defined_name):
- log.warning('Could not add user defined output name {} to tensor names list of {} node as '
- 'graph contains tensor name with same name.'.format(user_defined_name,
- opoutput_node.soft_get('name')))
- else:
- if 'fw_tensor_debug_info' not in in_edge_attrs:
- in_edge_attrs['fw_tensor_debug_info'] = []
- in_edge_attrs['fw_tensor_debug_info'].append([user_defined_name, user_defined_name])
-
- log.debug('Sink: {} for node {}'.format(opoutput_node.id, node_name))
- log.debug(str(graph.node[opoutput_node.id]))
- log.debug("Add edge from {} to {}".format(node_name, opoutput_node.id))
- return opoutput_node.id
-
-
-# TODO implement merging for keys with dictionary values?
-def merge_edge_props(attrs: dict, additional_attrs: dict):
- """
- Update edge attributes without changing 'in' and 'out' keys.
- It is necessary to copy edge attributes during merging of nodes when
- result of one subgraph call is passed as input to another subgraph call
- """
- result = attrs
- for (key, value) in additional_attrs.items():
- if key not in ['in', 'out']:
- if type(additional_attrs[key]) is list:
- if key not in result:
- result[key] = []
- result[key].extend(additional_attrs[key])
- result[key] = list(set(result[key])) # silly solution to find unique elements
- else:
- result[key] = value
- return result
-
-
-def rename_node(node: Node, name):
- if not node.graph.get_nodes_with_attributes(name=name):
- node.name = name
- else:
- assert 'Node with name {} already exists'.format(name)
-
-
-def rename_nodes(nodes: List[tuple]):
- for node, name in nodes:
- rename_node(node, name)
-
-
-def get_edge_attribute_between_nodes(node1: Node, node2: Node, attr_name: str):
- """
- Gets edge attribute value between two nodes.
- This method is introduced for implementation of manual replacing of nodes attributes
- with tensor debug information. It is needed after removing of fake outputs.
- Also there are cases when graph transformations lead to mismatch of tensor name
- and input node, so manual attribute change is needed.
- This method should only be used during the front phase.
- And it is applicable only for cases when there is just one edge between two given nodes.
- """
- for edge_idx in node1.out_edges():
- edge = node1.out_edge(edge_idx)
- out_port = edge['out']
- out_node = node1.out_node(out_port)
- if out_node.id == node2.id:
- if attr_name in edge:
- return edge[attr_name]
- return None
-
-
-def set_edge_attribute_between_nodes(node1: Node, node2: Node, attr_name: str, new_value):
- """
- Sets edge attribute value between two nodes.
- This method is introduced for implementation of manual replacing of nodes attributes
- with tensor debug information. It is needed after removing of fake outputs.
- Also there are cases when graph transformations lead to mismatch of tensor name
- and input node, so manual attribute change is needed.
- This method should only be used during the front phase.
- And it is applicable only for cases when there is just one edge between two given nodes.
- """
- for edge_idx in node1.out_edges():
- edge = node1.out_edge(edge_idx)
- out_port = edge['out']
- out_node = node1.out_node(out_port)
- if out_node.id == node2.id:
- edge[attr_name] = new_value
-
-# All functions below are deprecated and will be removed in next release
-# Please, use methods from Graph/Node classes instead
-
-
-@deprecated_api(Graph)
-def get_node_id_by_name(graph: Graph, name: str):
- return graph.get_node_id_by_name(name=name)
-
-
-@deprecated_api(Graph)
-def print_graph_stat(graph: Graph):
- return graph.print_graph_stat()
-
-
-@deprecated_api(Graph)
-def get_inputs_with_ports(graph: Graph, match, pattern_edges, input_names_in_pattern):
- """
- Front replacements of multi-input nodes should specify output port to add_node-like functions
- This function is a helper to get such information out of matched nodes
- :param graph: graph to operate on
- :param match: dictionary returned by matching function
- :param pattern_edges: edges that are specified in pattern
- :param input_names_in_pattern: names of matched nodes as they were specified in pattern that should be in
- resulting list
- :return: list of tuples of node and output port
- """
- return graph.get_inputs_with_ports(match=match,
- pattern_edges=pattern_edges,
- input_names_in_pattern=input_names_in_pattern)
-
-
-@deprecated_api(Graph)
-def dump_graph_for_graphviz(graph: Graph, node_attrs: list = ['kind', 'op', 'shape'],
- edge_attrs: list = ['in', 'out'],
- nodes_to_dump: list = None, save_to_svg=False):
- return graph.dump_graph_for_graphviz(node_attrs=node_attrs,
- edge_attrs=edge_attrs,
- nodes_to_dump=nodes_to_dump,
- save_to_svg=save_to_svg)
-
-
-@deprecated_api(Graph)
-def create_sub_graph_copy(graph: Graph, nodes_to_extract: list):
- """
- Create new graph which is a sub-graph of the 'graph' that contains just nodes from 'nodes_to_extract' list. The
- returned sub-graph is a deep copy of the provided graph nodes.
- :param graph: graph to create a sub-graph from.
- :param nodes_to_extract: list of node names to extract.
- :return: new graph.
- """
- return graph.create_sub_graph_copy(nodes_to_extract=nodes_to_extract)
-
-
-@deprecated_api(Graph)
-def get_graph_ops(graph: Graph):
- return graph.get_op_nodes()
-
-
-@deprecated_api(Graph)
-def check_empty_graph(graph: Graph, description: str):
- return graph.check_empty_graph(description=description)
-
-
-@deprecated_api(Graph)
-def create_edge(src_node: Node, dst_node: Node, out_port: int = 0, in_port: int = 0, edge_attrs: dict = None):
- """
- Creates edge from node 'src_node' from output with index 'out_port' to node 'dst_node' with input index 'in_port'.
- :param src_node: node to create edge from.
- :param dst_node: node to create edge to.
- :param out_port: the index of output tensor of the 'src_node'.
- :param in_port: the input index of the node 'dst_node'.
- :param edge_attrs: dictionary with edge attrs.
- :return: None
- """
- assert src_node.graph is dst_node.graph
- graph = src_node.graph
- return graph.create_edge(src_node=src_node, dst_node=dst_node, out_port=out_port, in_port=in_port,
- edge_attrs=edge_attrs)
-
-
-@deprecated_api(Graph)
-def erase_node(node: Node):
- """
- Erases node from the graph and reconnect edges from input node(s) to output node(s)
- Produces assertion error if the node being removed has multiple inputs or outputs.
- The function can be used in the front phase only (when there are no data nodes in the graph).
- :param node: Node to erase
- """
- graph = node.graph
- return graph.erase_node(node)
-
-
-@deprecated_api(Node)
-def get_sorted_inputs(node: Node, control_flow: bool = False):
- return node.get_sorted_inputs(control_flow=control_flow)
-
-
-@deprecated_api(Node)
-def get_sorted_outputs(node: Node, control_flow: bool = False):
- return node.get_sorted_outputs(control_flow=control_flow)
-
-
-@deprecated_api(Node)
-def insert_node_after(node: Node, new_node: Node, node_out_port: int = 0):
- """
- Insert node 'new_node' after output with index 'node_out_port' of the node 'node'. All consumers of node 'node'
- output with index 'node_out_port' will be changed to consume node 'new_node'.
- The function should be used when graph doesn't contain data nodes yet.
- :param node: node after which new node should be inserted.
- :param new_node: node to be inserted.
- :param node_out_port: the output index for the node 'node' to insert
- :return: None
- """
- return node.insert_node_after(new_node=new_node, node_out_port=node_out_port)
-
-
-@deprecated_api(Node)
-def replace_node(old_node: Node, new_node: Node, new_node_out_port: int = None):
- """
- Replaces node 'old_node' with a node 'new_node' preserving edge attributes.
- :param old_node: node to be replaced.
- :param new_node: node to replace with.
- :return: None
- """
- return old_node.replace_node(new_node=new_node, new_node_out_port=new_node_out_port)
-
-
-@deprecated_api(Node)
-def copy_node(src_node: Node, new_attrs: dict = None, dst_graph: nx.MultiDiGraph = None):
- """ Copies node with all attributes (optionally updated) within the same graph or to different graph."""
- return src_node.copy_node(new_attrs=new_attrs, dst_graph=dst_graph)
-
-
-@deprecated_api(Node)
-def get_inputs(graph: Graph, node: str, edge_attr: dict = None, control_flow: bool = False):
- return Node(graph, node).get_inputs(edge_attr=edge_attr, control_flow=control_flow)
-
-
-@deprecated_api(Node)
-def get_outputs(graph: Graph, node: str, edge_attr: dict = None, control_flow: bool = False):
- return Node(graph, node).get_outputs(edge_attr=edge_attr, control_flow=control_flow)
diff --git a/tools/mo/openvino/tools/mo/graph/perm_inputs.py b/tools/mo/openvino/tools/mo/graph/perm_inputs.py
deleted file mode 100644
index ddae286ccf150f..00000000000000
--- a/tools/mo/openvino/tools/mo/graph/perm_inputs.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.const import Const
-
-
-def get_node_with_permutation(node: Node, port_info: str):
- node_type, port = port_info.split(':')
- port = int(port)
- return node.in_node(port) if node_type == 'input' else node.out_node(port)
-
-
-def axis(op_node: Node, port_info: str, input_port: int):
- """
- Performs layout change related transformation of the data on the in_port_idx port of op_node.
- Translates shape indexes from one layout to another according to inverse permutation
-
- Transformation inserts Gather operation with
- permutation as 0-port input data and
- actual data to translate as 1-port input indexes of Gather
-
- For example:
- NHWC Reduce operation has 0-port input with data of shape [1, 2, 3, 4] and
- 1-port input with axis indices [0, 1].
-
- After translating such operation to NCHW layout:
- 0-port input shape = [1, 4, 2, 3]
- 1-port input axis indices = [0, 2]
- """
- graph = op_node.graph
-
- permutation_data_node = get_node_with_permutation(op_node, port_info)
- assert permutation_data_node.has_and_set('permutation'), 'Data node "{}" does not have permutation for node {}, ' \
- 'port_info "{}".'.format(permutation_data_node.id,
- op_node.id, port_info)
- permutation = permutation_data_node.permutation
- if len(permutation.perm) == 0:
- return
-
- data_node = op_node.in_node(input_port)
-
- gather_name = op_node.soft_get('name', op_node.id) + '/AxisGather'
- const = Const(graph, {'value': permutation.inv, 'name': gather_name + '/const',
- 'need_shape_inference': True}).create_node_with_data()
- axis_const = Const(graph, {'value': int64_array(0), 'name': gather_name + '/axis'}).create_node_with_data()
- gather = Gather(graph, {'name': gather_name, 'need_shape_inference': True}).create_node_with_data(
- [const, data_node, axis_const])
- attrs = graph.get_edge_data(data_node.id, op_node.id, key=0).copy()
- graph.add_edge(gather.id, op_node.id, **attrs)
- graph.remove_edge(data_node.id, op_node.id)
- op_node['need_shape_inference'] = True
-
-
-def order(op_node: Node, port_info: str, input_port: int):
- """
- Performs layout change related transformation of the data on the in_port_idx port of op_node.
- Translates ordered shape indexes from one layout to another according to permutation
-
- Transformation inserts two Gather operations
-
- 1 Gather reorders data to new layout according to direct permutation:
- actual data to translate as 1-port input indexes of Gather and
- permutation as 0-port input data
- 2 Gather translates shape indexes from one layout to another according to inverse permutation
- permutation as 0-port input data and
- actual data to translate as 1-port input indexes of Gather
-
- For example:
- NHWC Transpose operation has 0-port input with data of shape [1, 2, 3, 4] and
- 1-port input with new order indices [0, 1, 3, 2].
-
- After translating such operation to NCHW layout:
- 0-port input shape = [1, 4, 2, 3]
-
- 1 phase (after first Gather insertion):
- 1-port input order indices = [0, 2, 1, 3]
- 2 phase (after second Gather insertion):
- 1-port input order indices = [0, 3, 2, 1]
- """
- graph = op_node.graph
- permutation_data_node = get_node_with_permutation(op_node, port_info)
- assert permutation_data_node.has_and_set('permutation'), 'Data node "{}" does not have permutation for node {}, ' \
- 'port_info "{}".'.format(permutation_data_node.id,
- op_node.id, port_info)
- permutation = permutation_data_node.permutation
- if len(permutation.perm) == 0:
- return
-
- data_node = op_node.in_node(input_port)
-
- gather_name = op_node.soft_get('name', op_node.id) + '/OrderGather_1'
- const = Const(graph, {'value': permutation.perm, 'name': gather_name + '/const',
- 'need_shape_inference': True}).create_node_with_data()
- axis_const = Const(graph, {'value': int64_array(0), 'name': gather_name + '/axis'}).create_node_with_data()
- gather = Gather(graph, {'name': gather_name,
- 'need_shape_inference': True}).create_node_with_data([data_node, const, axis_const])
-
- gather_1_name = op_node.soft_get('name', op_node.id) + '/OrderGather_2'
- const_1 = Const(graph, {'value': permutation.inv, 'name': gather_1_name + '/const',
- 'need_shape_inference': True}).create_node_with_data()
- axis_const_1 = Const(graph, {'value': int64_array(0), 'name': gather_1_name + '/axis'}).create_node_with_data()
- gather_1 = Gather(graph, {'name': gather_1_name,
- 'need_shape_inference': True}).create_node_with_data([const_1, gather, axis_const_1])
-
- attrs = graph.get_edge_data(data_node.id, op_node.id, key=0).copy()
- graph.add_edge(gather_1.id, op_node.id, **attrs)
- graph.remove_edge(data_node.id, op_node.id)
- op_node['need_shape_inference'] = True
-
-
-def strided_slice(op_node: Node, port_info: str, input_port: int):
- """
- StridedSLice must be permuted even if input or output tensors have rank lesser than 4
- e.g. input_shape = (1, 10, 10), out = input[:, 0:10, :, new_axis], input_rank < 4
- input_shape = (1, 10, 10, 3), out = input[:, 0:5, 0:4, 0], output_rank < 4
- in both examples slice_rank is >= 4
- slice_rank is defined by length of begin, end, strides (they all are of the same length)
- """
- permutation_data_node = get_node_with_permutation(op_node, port_info)
- assert permutation_data_node.has_and_set('permutation'), 'Data node "{}" does not have permutation for node {}, ' \
- 'port_info "{}".'.format(permutation_data_node.id,
- op_node.id, port_info)
- permute_indices_for_gather = permutation_data_node.permutation.perm
- if len(permute_indices_for_gather) == 0:
- return
- from openvino.tools.mo.ops.op import PermuteAttrs
-
- slice_rank = op_node.in_port(input_port).data.get_shape()[0] # length of begin, end or strides
- permute_indices_for_gather = PermuteAttrs.get_nhwc_to_nchw_permutation(slice_rank).perm
- reorder_inputs_for_shape_or_slice(op_node, input_port, permute_indices_for_gather)
-
-
-def shape(op_node: Node, port_info: str, input_port: int):
- permutation_data_node = get_node_with_permutation(op_node, port_info)
- assert permutation_data_node.has_and_set('permutation'), 'Data node "{}" does not have permutation for node {}, ' \
- 'port_info "{}".'.format(permutation_data_node.id,
- op_node.id, port_info)
- permute_indices_for_gather = permutation_data_node.permutation.perm
- if len(permute_indices_for_gather) == 0:
- return
- reorder_inputs_for_shape_or_slice(op_node, input_port, permute_indices_for_gather)
-
-
-def reorder_inputs_for_shape_or_slice(op_node: Node, input_port: int, permute_indices_for_gather: list):
- """
- axis and slice permutations are almost the same the only difference is that for slice in general
- case permutation depends from slice_rank not from input_rank or output_rank
- """
- graph = op_node.graph
- data_node = op_node.in_node(input_port)
-
- gather_name = op_node.soft_get('name', op_node.id) + '/ShapeGather'
- const = Const(graph, {'value': permute_indices_for_gather, 'name': gather_name + '/const',
- 'need_shape_inference': True}).create_node_with_data()
- axis_const = Const(graph, {'value': int64_array(0), 'name': gather_name + '/axis'}).create_node_with_data()
- gather = Gather(graph, {'name': gather_name,
- 'need_shape_inference': True}).create_node_with_data([data_node, const, axis_const])
- attrs = graph.get_edge_data(data_node.id, op_node.id, key=0).copy()
-
- graph.add_edge(gather.id, op_node.id, **attrs)
- graph.remove_edge(data_node.id, op_node.id)
-
- # need to run manually to override output shape value to resolve shape collision for nodes with
- # 'correct_data_layout' output port attrs
- op_node['need_shape_inference'] = True
-
-
-def transpose(op_node: Node, port_info: str, input_port: int):
- graph = op_node.graph
- permutation_data_node = get_node_with_permutation(op_node, port_info)
- assert permutation_data_node.has_and_set('permutation'), \
- 'Data node "{}" does not have permutation for node {}, port_info "{}".'.format(
- permutation_data_node.id, op_node.id, port_info)
- permutation = permutation_data_node.permutation
- if len(permutation.perm) == 0:
- return
-
- transpose_name = op_node.soft_get('name', op_node.id) + '/Transpose'
- from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs # avoiding recursive imports
- transpose = create_op_with_const_inputs(
- graph, Transpose, {1: permutation.perm}, {'name': transpose_name, 'override_output_shape': True})
- op_node.in_port(input_port).get_connection().insert_node(transpose)
- transpose.infer(transpose)
-
-
-def transpose_nchw_to_nhwc(op_node: Node, port_info: str, input_port: int):
- graph = op_node.graph
- permutation_data_node = get_node_with_permutation(op_node, port_info)
- rank = len(permutation_data_node.shape)
- assert rank >= 4, 'Rank must be 4D or higher for HCHW to HHWC permutation on node {}.'.format(op_node.id)
-
- perm = list(range(rank))
- perm.insert(1, perm.pop())
- perm = int64_array(perm)
-
- transpose_name = op_node.soft_get('name', op_node.id) + '/Transpose'
- from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs # avoiding recursive imports
- transpose = create_op_with_const_inputs(
- graph, Transpose, {1: perm}, {'name': transpose_name, 'override_output_shape': True})
- op_node.in_port(input_port).get_connection().insert_node(transpose)
- transpose.infer(transpose)
-
-
-class PermuteInputs:
- input_permutes = {
- 'axis': lambda node, port_info, input_port: axis(node, port_info, input_port),
- 'slice': lambda node, port_info, input_port: strided_slice(node, port_info, input_port),
- 'order': lambda node, port_info, input_port: order(node, port_info, input_port),
- 'shape': lambda node, port_info, input_port: shape(node, port_info, input_port),
- 'transpose': lambda node, port_info, input_port: transpose(node, port_info, input_port),
- 'transpose_nchw_to_nhwc': lambda node, port_info, input_port: transpose_nchw_to_nhwc(node, port_info,
- input_port),
- }
-
- shape_check_rules = {
- 'rank': lambda port: bool(len(port.data.get_shape()) >= 4),
- 'dim_size': lambda port: bool(port.data.get_shape()[0] >= 4), # if input 'dim_size' >= 4 need to permute
- }
-
- def set_input_permutation(self, node1: Node, node2: Node, port_info: str, permutation_rule: str,
- shape_check_rule: str = 'rank'):
- """
- Sets input permutation attribute on the edge between node1 and node2.
- Input permutation consists of function that perform input permutation and
- input port info 'input' or 'output' + that points on the input with PermuteAttr.Permutation which
- current input depends on.
-
- shape_check_rule defines the check rule if the op node inputs need to be permuted.
- By default 'rank' rule is applied, 'dim_size' is used only for StridedSlice so far.
- """
- assert permutation_rule in self.input_permutes, 'No `{}` permutation rule in {}'.format(permutation_rule,
- __class__.__name__)
- assert shape_check_rule in self.shape_check_rules, 'No `{}` permutation shape check rule ' \
- 'in {}'.format(shape_check_rule, __class__.__name__)
- nx.set_edge_attributes(G=node1.graph,
- values={(node1.id, node2.id, 0): (self.input_permutes[permutation_rule], port_info,
- self.shape_check_rules[shape_check_rule])},
- name='input_permutation')
diff --git a/tools/mo/openvino/tools/mo/graph/port.py b/tools/mo/openvino/tools/mo/graph/port.py
deleted file mode 100644
index 86ddd81cfe4ead..00000000000000
--- a/tools/mo/openvino/tools/mo/graph/port.py
+++ /dev/null
@@ -1,506 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from copy import deepcopy
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, strict_compare_tensors
-from openvino.tools.mo.graph.connection import Connection
-from openvino.tools.mo.utils.error import Error
-
-
-class Port:
- class DataAccessor:
- def __init__(self):
- pass
-
- def __init__(self, node, idx: int, type: str, **kwargs):
- if type not in ['in', 'out']:
- raise Error("Inappropriate port type: {}".format(type))
-
- # We use self.__dict__ only to not to call __setattr__ method from __init__ function
- self.__dict__['node'] = node
- self.__dict__['idx'] = idx
- self.__dict__['type'] = type
- self.__dict__['data'] = self.DataAccessor()
- self.__dict__['control_flow'] = False
- self.__dict__.update(kwargs)
-
- self.data.get_shape = self._get_shape
- self.data.set_shape = self._set_shape
-
- self.data.get_value = self._get_value
- self.data.set_value = self._set_value
-
- self.data.get_attr = self._get_attr
- self.data.set_attr = self._set_attr
-
- self.data.has_valid = self._has_valid
-
- def __eq__(self, other):
- return (
- self.__class__ == other.__class__ and
- self.node.graph == other.node.graph and
- self.node.id == other.node.id and
- self.type == other.type and
- self.idx == other.idx
- )
-
- def __hash__(self):
- return hash((self.node.id, self.type, self.idx))
-
- def __deepcopy__(self, memo):
- cls = self.__class__
- result = cls.__new__(cls)
- memo[id(self)] = result
- for k, v in self.__dict__.items():
- result.__dict__[k] = v if k in ['graph', 'node'] else deepcopy(v)
- return result
-
- def __setattr__(self, key, value):
- edge = self.node.in_edge(self.idx, control_flow=self.control_flow) if self.type == 'in' else \
- self.node.out_edge(self.idx, control_flow=self.control_flow)
- edge[key] = value
-
- def __getattr__(self, item):
- edge = self.node.in_edge(self.idx, control_flow=self.control_flow) if self.type == 'in' else \
- self.node.out_edge(self.idx, control_flow=self.control_flow)
- if edge.get(item) is None:
- raise Error(
- "Edge from {}_port {} at node {} has no attribute {}".format(self.type, self.idx, self.node.name, item))
- return edge[item]
-
- def _create_data_if_necessary(self):
- if self.node.graph.stage == 'front':
- raise Error("_create_data_if_necessary method is not applicable for front Graph phase!")
- if self.type == 'in':
- raise Error("_create_data_if_necessary method is not applicable for 'in' Port type!")
-
- if self.idx not in self.node.out_nodes(control_flow=self.control_flow):
- from openvino.tools.mo.ops.op import Op
- Op.create_data_node(self.node.graph, self.node, out_port=self.idx)
- self.node['need_shape_inference'] = True
- return self.node.out_node(self.idx, control_flow=self.control_flow)
-
- def _get_shape(self):
- if self.node.graph.stage == 'front':
- return None
- else:
- node_caller = self.node.in_node if self.type == 'in' else self.node.out_node
- return node_caller(self.idx, control_flow=self.control_flow).shape
-
- def _set_shape(self, shape):
- if self.node.graph.stage == 'front':
- raise NotImplementedError("set_shape not implemented for front phase")
- else:
- if self.type == 'in':
- assert self.node.in_node(self.idx, control_flow=self.control_flow).value is None
- self.node.in_node(self.idx, control_flow=self.control_flow).shape = shape_array(shape)
- else:
- data_node = self.node.out_node(self.idx, control_flow=self.control_flow)
- assert data_node.value is None or self.node.has_and_set('override_output_shape') or \
- strict_compare_tensors(data_node.soft_get('force_shape', data_node.shape), shape_array(shape))
- self.node.out_node(self.idx, control_flow=self.control_flow).shape = shape_array(shape)
-
- def _get_value(self):
- if self.node.graph.stage == 'front':
- return None
- else:
- if self.type == 'in':
- if self.idx in self.node.in_nodes(control_flow=self.control_flow) and \
- self.node.in_node(self.idx, control_flow=self.control_flow).has_valid('value'):
- return self.node.in_node(self.idx, control_flow=self.control_flow).value
- else:
- if self.idx in self.node.out_nodes(control_flow=self.control_flow) and \
- self.node.out_node(self.idx, control_flow=self.control_flow).has_valid('value'):
- return self.node.out_node(self.idx, control_flow=self.control_flow).value
- return None
-
- def _set_value(self, value):
- if self.node.graph.stage == 'front':
- raise Error("set_value is not applicable for graph front phase")
- else:
- data_node_caller = self.node.in_node if self.type == 'in' else self.node.out_node
- data_node = data_node_caller(self.idx, control_flow=self.control_flow)
- const_node = data_node.in_node(control_flow=self.control_flow) if self.type == 'in' else self.node
-
- force_shape = data_node.soft_get('force_shape', const_node.soft_get('force_shape', None))
- shape = int64_array(value.shape if force_shape is None else force_shape)
-
- # Set value to data node
- data_node.value = value
- data_node.shape = shape
-
- # Set value to constant producer
- if const_node.soft_get('type') == 'Const':
- const_node.value = value
- const_node.shape = shape
-
- def _get_attr(self, item: str):
- if self.node.graph.stage == 'front':
- return None
- else:
- if self.type == 'in':
- if self.idx in self.node.in_nodes(control_flow=self.control_flow) and \
- self.node.in_node(self.idx, control_flow=self.control_flow).has_valid(item):
- return self.node.in_node(self.idx, control_flow=self.control_flow)[item]
- else:
- if self.idx in self.node.out_nodes(control_flow=self.control_flow) and \
- self.node.out_node(self.idx, control_flow=self.control_flow).has_valid(item):
- return self.node.out_node(self.idx, control_flow=self.control_flow)[item]
- return None
-
- def _set_attr(self, item, value):
- raise NotImplementedError()
-
- def get_in_edge_attrs(self, data=False):
- assert self.type == 'in'
- for u, v, d in list(self.node.graph.in_edges(self.node.id, data=True)):
- if d['in'] == self.idx:
- edge_attrs = self.node.graph.get_edge_data(u, v)
- for key in edge_attrs:
- if edge_attrs[key]['in'] == self.idx:
- if data:
- return edge_attrs[key], u, v, key
- else:
- return edge_attrs[key]
- if data:
- return None, None, None, None
- else:
- return None
-
- def _has_valid(self, item):
- if self.node.graph.stage == 'front':
- raise NotImplementedError
- else:
- if self.type == 'in':
- if self.idx in self.node.in_nodes(control_flow=self.control_flow) and \
- self.node.in_node(self.idx, control_flow=self.control_flow).has_valid(item):
- return True
- else:
- if self.idx in self.node.out_nodes(control_flow=self.control_flow) and \
- self.node.out_node(self.idx, control_flow=self.control_flow).has_valid(item):
- return True
- return False
-
- def disconnected(self):
- # This method returns False if port connected with some other port
- # otherwise it returns True
-
- if self.type == 'in':
- return self.get_source() is None
- else:
- return len(self.get_destinations()) == 0
-
- def get_source(self):
- # This method returns Port object that is producer (source) port for out port.
- # In case if out port has no source port return None
-
- assert self.type != 'out', "Can't get source for output port at {} node".format(self.node.name)
-
- from openvino.tools.mo.graph.graph import Node
- producer_ports = []
-
- has_producer = False
- if self.node.graph.stage == 'front':
- for n, d in self.node.get_inputs(control_flow=self.control_flow):
- if d['in'] == self.idx:
- node = Node(self.node.graph, n)
- producer_ports.append(node.out_port(d['out'], control_flow=self.control_flow))
- has_producer = True
- if not has_producer:
- return None
- else:
- if self.idx not in self.node.in_nodes(control_flow=self.control_flow):
- return None
-
- in_data = self.node.in_node(self.idx, control_flow=self.control_flow)
- for n, d in in_data.get_inputs(control_flow=self.control_flow):
- node = Node(self.node.graph, n)
- producer_ports.append(node.out_port(d['out'], control_flow=self.control_flow))
-
- if len(producer_ports) != 1:
- if self.node.graph.strict_mode:
- raise Error('Something bad has happened with graph! Data node "{}" has {} producers'.format(
- self.node.id, len(producer_ports)))
- else:
- return None
- return producer_ports[0]
-
- def get_destination(self):
- # This method returns Port that is consumer (destination) port for in port.
- # In case if in port has no consumer return None
-
- consumer_ports = self.get_destinations()
- if not consumer_ports:
- return None
-
- if len(consumer_ports) > 1:
- raise Error("The number of destinations for {} node at {} port is {}".format(self.node.name,
- self.idx,
- len(consumer_ports)))
- return consumer_ports[0]
-
- def get_destinations(self):
- assert self.type != 'in', "Can't get destinations for input port at {} node".format(self.node.name)
-
- from openvino.tools.mo.graph.graph import Node
- consumer_ports = []
- if self.node.graph.stage == 'front':
- producer_node = self.node
- else:
- # In case if node has no output data node in given port, we return None
- if self.idx not in self.node.out_nodes(control_flow=self.control_flow):
- return []
- producer_node = self.node.out_node(self.idx, control_flow=self.control_flow)
-
- for n, d in producer_node.get_outputs(edge_attr={'out': self.idx} if self.node.graph.stage == 'front' else None,
- control_flow=self.control_flow):
- node = Node(self.node.graph, n)
- consumer_ports.append(node.in_port(d['in'], control_flow=self.control_flow))
- return consumer_ports
-
- def get_tensor_names(self, port_renumber: bool = False):
- """
- Gets sorted tensor names list.
- :param port_renumber: defines whether data node index should be calculated considering port renumbering.
- """
- tensor_debug_info = self.get_tensor_debug_info(port_renumber)
- tensor_names_list = []
- for attr in tensor_debug_info:
- if attr is not None and len(attr) >= 2:
- tensor_name = attr[1]
- if tensor_name is not None and len(tensor_name) > 0:
- tensor_names_list.append(tensor_name.replace(',', '\\,'))
- return sorted(tensor_names_list)
-
- def add_tensor_names(self, tensor_names: list, port_renumber: bool = False):
- """
- Sets tensor names list.
- :param tensor_names: list of tensor names.
- :param port_renumber: defines whether data node index should be calculated considering port renumbering.
- """
-
- if len(tensor_names) == 0:
- return
-
- new_debug_items = []
- op_name = self.node.soft_get('name', self.node.id)
- for tensor_name in tensor_names:
- assert isinstance(tensor_name, str), "Tensor names elements should be strings."
- new_debug_items.append((op_name, tensor_name))
-
- tensor_debug_info = self.get_tensor_debug_info(port_renumber)
- tensor_debug_info += new_debug_items
- self.set_tensor_debug_info(tensor_debug_info, port_renumber)
-
- def remove_tensor_names(self, port_renumber: bool = False):
- """
- Removes tensor names.
- :param port_renumber: defines whether data node index should be calculated considering port renumbering.
- """
- self.remove_debug_info(port_renumber=port_renumber)
-
- def get_tensor_debug_info(self, port_renumber: bool = False):
- """
- Gets tensor debug info attribute.
- :param port_renumber: defines whether data node index should be calculated considering port renumbering.
- """
- def get_tensor_debug_info_from_attrs(attrs):
- if 'fw_tensor_debug_info' in attrs:
- if attrs['fw_tensor_debug_info'] is not None:
- return attrs['fw_tensor_debug_info']
- return []
-
- assert self.type != 'in', "Can't get tensor debug info for input port at {} node".format(self.node.name)
-
- fw_debug_info = []
- if self.node.graph.stage == 'front':
- if self.idx in self.node.out_edges():
- out_edge = self.node.out_edge(self.idx)
- fw_debug_info += get_tensor_debug_info_from_attrs(out_edge)
- else:
- # before port renumbering we use sequential numbering
- node_idx = self.idx
- if port_renumber:
- if self.node.type != 'Const':
- # after port renumbering port indices start from zero,
- # but data node indices remain the same
- node_idx = self.idx + len(self.node.in_nodes())
-
- if node_idx in self.node.out_nodes():
- out_node = self.node.out_node(node_idx)
- fw_debug_info += get_tensor_debug_info_from_attrs(out_node.attrs())
- return fw_debug_info
-
- def set_tensor_debug_info(self, tensor_info: list, port_renumber: bool = False):
- """
- Gets tensor debug info attribute.
- :param tensor_info: new tensor debug info value.
- :param port_renumber: defines whether data node index should be calculated considering port renumbering.
- """
-
- assert self.type != 'in', "Can't get tensor debug info for input port at {} node".format(self.node.name)
-
- if self.node.graph.stage == 'front':
- if self.idx in self.node.out_edges():
- out_edge = self.node.out_edge(self.idx)
- out_edge['fw_tensor_debug_info'] = tensor_info
- else:
- # before port renumbering we use sequential numbering
- node_idx = self.idx
- if port_renumber:
- if self.node.type != 'Const':
- # after port renumbering port indices start from zero,
- # but data node indices remain the same
- node_idx = self.idx + len(self.node.in_nodes())
-
- if node_idx in self.node.out_nodes():
- out_node = self.node.out_node(node_idx)
- out_node['fw_tensor_debug_info'] = tensor_info
-
- def remove_debug_info(self, port_renumber: bool = False):
- """
- Removes tensor debug info attribute.
- :param port_renumber: defines whether data node index should be calculated considering port renumbering.
- """
-
- assert self.type != 'in', "Tensor debug info is not defined for input port at {} node".format(self.node.name)
-
- if self.node.graph.stage == 'front':
- if self.idx in self.node.out_edges():
- out_edge = self.node.out_edge(self.idx)
- if 'fw_tensor_debug_info' in out_edge:
- del out_edge['fw_tensor_debug_info']
- else:
- # before port renumbering we use sequential numbering
- node_idx = self.idx
- if port_renumber:
- if self.node.type != 'Const':
- # after port renumbering port indices start from zero,
- # but data node indices remain the same
- node_idx = self.idx + len(self.node.in_nodes())
-
- if node_idx in self.node.out_nodes():
- out_node = self.node.out_node(node_idx)
- if 'fw_tensor_debug_info' in out_node:
- del out_node['fw_tensor_debug_info']
-
- def disconnect(self):
- if self.type == 'out':
- consumer_ports = self.get_destinations()
- if self.node.graph.stage == 'front':
- for port in consumer_ports:
- self.node.graph.remove_edge(self.node.id, port.node.id)
- else:
- for port in consumer_ports:
- src_node = port.node.in_node(port.idx).id
- dst_node = port.node.id
- for key, val in self.node.graph.get_edge_data(src_node, dst_node).items():
- if val['in'] == port.idx:
- self.node.graph.remove_edge(src_node, dst_node, key=key)
- break
- else:
- source_port = self.get_source()
- if source_port is None:
- return
- for u, v, d in list(self.node.graph.in_edges(self.node.id, data=True)):
- if d['in'] == self.idx:
- for key in self.node.graph.get_edge_data(u, v):
- if self.node.graph.get_edge_data(u, v)[key]['in'] == self.idx:
- self.node.graph.remove_edge(u, v, key=key)
- return
-
- def get_connection(self):
- if self.type == 'in':
- return Connection(self.node.graph, self.get_source(), [self], control_flow=self.control_flow)
- else:
- return Connection(self.node.graph, self, self.get_destinations(), control_flow=self.control_flow)
-
- def connect(self, port):
- if self.type == 'in':
- self.get_connection().set_source(port)
- else:
- self.get_connection().add_destination(port)
-
- def _get_data_type(self):
- """
- Internal method which does not raise with error if the data type is not known.
- Check value of the data node to determine input port data type as well as the respective value in the
- '_out_port_data_type' dictionary.
- :return: The data type or None if it is not defined
- """
- node = self.node
- if self.type == 'out':
- if node.has_valid('_out_port_data_type') and self.idx in node._out_port_data_type:
- return node._out_port_data_type[self.idx]
-
- # check the data type of the output data node
- value = self.data.get_value()
- value_data_type = value.dtype if value is not None else None
- if value_data_type is not None:
- value_data_type = value.dtype if value is not None else None
- log.debug('The precision of the output port {} of node {} is determined from the data node as {}'
- ''.format(self.idx, self.node.name, value_data_type))
- return value_data_type
- return None
- else:
- # check the data type of the input data node
- value = self.data.get_value()
- value_data_type = value.dtype if value is not None else None
- if value_data_type is not None:
- log.debug('The precision of the input port {} of node {} is determined from the data node as {}'
- ''.format(self.idx, self.node.name, value_data_type))
-
- # The 'get_source' method raises an error if there is no producer op node for the input port. But here we
- # don't want to do this, so we temporary disable graph strict mode
- old_strict_mode_value = node.graph.strict_mode
- node.graph.strict_mode = False
- source_port = self.get_source()
- source_port_data_type = None
- if source_port is not None:
- source_port_data_type = source_port._get_data_type()
- node.graph.strict_mode = old_strict_mode_value
-
- # check for the data node and port data type inconsistency. TODO should we raise an error here?
- if value_data_type is not None and source_port_data_type is not None and \
- value_data_type != source_port_data_type:
- log.warning('Inconsistent data type of the data node and port attribute for port {} of node {}: {} vs '
- '{}. Return data type of the data node.'.format(self.idx, self.node.name,
- value_data_type, source_port_data_type))
- # the source port data type has higher priority over the value data type because the MO calculates values in
- # I64 precision for shapes but not all OV plugins support I64, so we should trust data type infer functions
- return source_port_data_type if source_port_data_type is not None else value_data_type
-
- def get_data_type(self):
- data_type = self._get_data_type()
- if data_type is None:
- raise Error('The data type for {} port {} of node {} is not defined'.format(self.type, self.idx,
- self.node.name))
- return data_type
-
- def is_data_type_defined(self):
- """
- Check if the data-type is already defined for the port.
- :return: the result of the check
- """
- return self._get_data_type() is not None
-
- def set_data_type(self, data_type, override=False):
- assert self.type == 'out', 'The method can be called for output ports only'
- node = self.node
- if not node.has_valid('_out_port_data_type'):
- node['_out_port_data_type'] = {}
- if self.idx in node._out_port_data_type and data_type != node._out_port_data_type[self.idx] and not override:
- raise Error('Trying to override data type for output port {} of operation {}: from {} to {}'.format(
- self.idx, node.name, node._out_port_data_type[self.idx], data_type))
- node._out_port_data_type[self.idx] = data_type
-
- def get_default_tensor_name(self):
- """
- Gets default_tensor_name
- :return: tensor name
- """
- if self.type == 'in':
- return None
- return self.node.soft_get('name', self.node.id) + ":" + str(self.idx)
diff --git a/tools/mo/openvino/tools/mo/load/__init__.py b/tools/mo/openvino/tools/mo/load/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/load/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/load/caffe/__init__.py b/tools/mo/openvino/tools/mo/load/caffe/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/load/caffe/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/load/caffe/loader.py b/tools/mo/openvino/tools/mo/load/caffe/loader.py
deleted file mode 100644
index aaf5538998de66..00000000000000
--- a/tools/mo/openvino/tools/mo/load/caffe/loader.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-from openvino.tools.mo.load.loader import Loader
-from openvino.tools.mo.front.caffe import custom_layers_mapping, loader
-from openvino.tools.mo.front.caffe.extractor import caffe_type_extractors, caffe_extractor
-from openvino.tools.mo.front.common.register_custom_ops import update_extractors_with_extensions, check_for_duplicates
-from openvino.tools.mo.front.extractor import extract_node_attrs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.telemetry_utils import send_op_names_info, send_shapes_info
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class CaffeLoader(Loader):
- enabled = True
-
- def load(self, graph: Graph):
- argv = graph.graph['cmd_params']
- if argv.caffe_parser_path is None:
- argv.caffe_parser_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'front', 'caffe', 'proto')
- caffe_pb2 = loader.import_caffe_pb2(argv.caffe_parser_path)
-
- proto, model = loader.load_caffe_proto_model(caffe_pb2, argv.input_proto, argv.input_model)
-
- update_extractors_with_extensions(
- caffe_type_extractors,
- argv.disable_omitting_optional if hasattr(argv, 'disable_omitting_optional') else False,
- argv.disable_flattening_optional_params if hasattr(argv, 'disable_flattening_optional_params') else False
- )
-
- try:
- original_shapes = loader.caffe_pb_to_nx(graph, proto, model)
- except ValueError as e:
- raise Error('Invalid prototxt file: value error {}. ' +
- refer_to_faq_msg(11), str(e)) from e
- graph.check_empty_graph('load_caffe_proto_model')
-
- graph.__setattr__('proto_path', argv.input_proto)
- graph.__setattr__('caffemodel_path', argv.input_model)
- graph.__setattr__('name', getattr(proto, 'name', None) or argv.model_name)
- graph.graph['layout'] = 'NCHW'
- graph.graph['fw'] = 'caffe'
- graph.graph['original_shapes'] = original_shapes
- graph.graph['caffe_pb2'] = caffe_pb2
-
- if argv.k is None:
- argv.k = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'front', 'caffe', 'CustomLayersMapping.xml')
- custom_layers_map = custom_layers_mapping.load_layers_xml(argv.k)
- custom_layers_mapping.update_extractors(
- caffe_type_extractors,
- custom_layers_map,
- argv.disable_omitting_optional if hasattr(argv, 'disable_omitting_optional') else False,
- argv.enable_flattening_nested_params if hasattr(argv, 'enable_flattening_nested_params') else False
- )
- extract_node_attrs(graph, lambda node: caffe_extractor(node, check_for_duplicates(caffe_type_extractors)))
- send_op_names_info('caffe', graph)
- send_shapes_info('caffe', graph)
diff --git a/tools/mo/openvino/tools/mo/load/kaldi/__init__.py b/tools/mo/openvino/tools/mo/load/kaldi/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/load/kaldi/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/load/kaldi/loader.py b/tools/mo/openvino/tools/mo/load/kaldi/loader.py
deleted file mode 100644
index 376d848138a2a3..00000000000000
--- a/tools/mo/openvino/tools/mo/load/kaldi/loader.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.load.loader import Loader
-from openvino.tools.mo.front.common.register_custom_ops import update_extractors_with_extensions
-from openvino.tools.mo.front.extractor import extract_node_attrs
-from openvino.tools.mo.front.kaldi.extractor import kaldi_extractor, kaldi_type_extractors
-from openvino.tools.mo.front.kaldi.loader.loader import load_kaldi_model
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.telemetry_utils import send_shapes_info, send_op_names_info
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class KaldiLoader(Loader):
- enabled = True
-
- def load(self, graph: Graph):
- argv = graph.graph['cmd_params']
- try:
- load_kaldi_model(graph, argv.input_model)
- except Exception as e:
- raise Error('Model Optimizer is not able to parse Kaldi model {}. '.format(argv.input_model) +
- refer_to_faq_msg(91)) from e
- graph.check_empty_graph('load_kaldi_nnet_model')
- graph.graph['layout'] = 'NCHW'
- graph.graph['fw'] = 'kaldi'
-
- update_extractors_with_extensions(kaldi_type_extractors)
- extract_node_attrs(graph, lambda node: kaldi_extractor(node))
-
- send_op_names_info('kaldi', graph)
- send_shapes_info('kaldi', graph)
diff --git a/tools/mo/openvino/tools/mo/load/loader.py b/tools/mo/openvino/tools/mo/load/loader.py
deleted file mode 100644
index 355bbe69d8ede3..00000000000000
--- a/tools/mo/openvino/tools/mo/load/loader.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils import class_registration
-
-
-class Loader(object):
- registered_cls = []
- registered_ops = {}
- excluded_replacers = []
-
- def find_and_replace_pattern(self, graph: Graph):
- self.load(graph)
-
- def load(self, graph: Graph):
- raise Exception("Define load logic of {} class in its load method".format(
- self.__class__.__name__
- ))
-
- def run_before(self):
- """
- Returns list of loader classes which this loader must be run before.
- :return: list of classes
- """
- return [LoadFinish]
-
- def run_after(self):
- """
- Returns list of loader classes which this loader must be run after.
- :return: list of classes
- """
- return []
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.LOADER
-
-
-class LoadFinish(Loader):
- enabled = True
-
- def run_before(self):
- return []
-
- def run_after(self):
- return []
-
- def load(self, graph: Graph):
- graph.check_empty_graph('loading from framework')
diff --git a/tools/mo/openvino/tools/mo/load/onnx/__init__.py b/tools/mo/openvino/tools/mo/load/onnx/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/load/onnx/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/load/onnx/loader.py b/tools/mo/openvino/tools/mo/load/onnx/loader.py
deleted file mode 100644
index 72b819b35b66f1..00000000000000
--- a/tools/mo/openvino/tools/mo/load/onnx/loader.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from __future__ import absolute_import
-from __future__ import division
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import logging as log
-
-from openvino.tools.mo.load.loader import Loader
-from openvino.tools.mo.front.common.register_custom_ops import update_extractors_with_extensions, check_for_duplicates
-from openvino.tools.mo.front.extractor import extract_node_attrs
-from openvino.tools.mo.front.onnx.extractor import onnx_op_extractor, onnx_op_extractors
-from openvino.tools.mo.front.onnx.loader import load_onnx_model, protobuf2nx
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.telemetry_utils import send_shapes_info, send_op_names_info
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class ONNXLoader(Loader):
- enabled = True
- run_not_recursively = True
-
- def load(self, graph: Graph):
- import onnx
- import io
- argv = graph.graph['cmd_params']
- if isinstance(argv.input_model, str):
- model_proto = load_onnx_model(argv.input_model)
- elif isinstance(argv.input_model, io.BytesIO):
- model_proto = onnx.load_model_from_string(argv.input_model.getvalue())
- else:
- raise Error('Unknown ONNX model type: {}'.format(type(argv.input_model)))
-
- model_graph = model_proto.graph # pylint: disable=no-member
- # print(model_graph)
- # assert len(model_graph) == 1, "An ONNX model contains more than 1 graph: unsupported"
- log.debug("Number of nodes in graph_def: {}".format(len(model_graph.node)))
- log.debug("Number of all input ports (not true inputs) in graph_def: {}".format(len(model_graph.input)))
- log.debug("Number of initializers in graph_def: {}".format(len(model_graph.initializer)))
- log.debug(
- "Number of real inputs in graph_def: {}".format(len(model_graph.input) - len(model_graph.initializer)))
- update_extractors_with_extensions(onnx_op_extractors)
-
- try:
- protobuf2nx(graph, model_proto)
- except Exception as e:
- raise Error(
- 'Cannot pre-process ONNX graph after reading from model file "{}". ' \
- 'File is corrupt or has unsupported format. Details: {}. ' +
- refer_to_faq_msg(44),
- argv.input_model,
- str(e)
- ) from e
- log.debug("Number of nodes in NX graph: {}".format(graph.number_of_nodes()))
-
- graph.__setattr__('name',
- argv.model_name if argv.model_name else model_proto.graph.name) # pylint: disable=no-member
- graph.graph['layout'] = 'NCHW'
- graph.graph['fw'] = 'onnx'
- graph.graph['feature_dim'] = 1
- if hasattr(model_proto, 'opset_import'):
- graph.graph['fw_opset_version'] = model_proto.opset_import[0].version # pylint: disable=no-member
- else:
- graph.graph['fw_opset_version'] = None
-
- graph.check_empty_graph('protobuf2nx. It may happen due to problems with loaded model')
- extract_node_attrs(graph, lambda node: onnx_op_extractor(node, check_for_duplicates(onnx_op_extractors)))
- send_op_names_info('onnx', graph)
- send_shapes_info('onnx', graph)
diff --git a/tools/mo/openvino/tools/mo/load/tf/__init__.py b/tools/mo/openvino/tools/mo/load/tf/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/load/tf/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/load/tf/loader.py b/tools/mo/openvino/tools/mo/load/tf/loader.py
deleted file mode 100644
index efc517b156b51e..00000000000000
--- a/tools/mo/openvino/tools/mo/load/tf/loader.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-try:
- import tensorflow.compat.v1 as tf_v1
-except ImportError:
- import tensorflow as tf_v1
-
-#in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
-tf_v1.get_logger().setLevel("ERROR")
-
-try:
- import tensorflow.contrib # pylint: disable=no-name-in-module,import-error
-except:
- pass # we try to import contrib for loading models that use contrib operations
-
-import logging as log
-
-from openvino.tools.mo.load.loader import Loader
-from openvino.tools.mo.front.common.register_custom_ops import check_for_duplicates
-from openvino.tools.mo.front.common.register_custom_ops import update_extractors_with_extensions
-from openvino.tools.mo.front.extractor import restore_edges, extract_node_attrs, remove_control_dependency_inputs, add_outputs_identity
-from openvino.tools.mo.front.tf.extractor import get_tf_edges, create_tf_edge, tf_op_extractor, tf_op_extractors
-from openvino.tools.mo.front.tf.loader import load_tf_graph_def, protobuf2nx
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.utils import tensorboard_util
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.telemetry_utils import send_op_names_info, send_shapes_info, send_framework_info
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class TFLoader(Loader):
- enabled = True
- run_not_recursively = True
-
- def load(self, graph: Graph):
- argv = graph.graph['cmd_params']
- if argv.tensorflow_custom_layer_libraries:
- libraries = argv.tensorflow_custom_layer_libraries.split(',')
- for library in libraries:
- log.info('Loading library "{}" with custom operations'.format(library))
- tf_v1.load_op_library(library)
-
- graph_def, variables_values, framework, inputs_outputs_order = load_tf_graph_def(
- graph_file_name=argv.input_model,
- is_binary=not argv.input_model_is_text,
- checkpoint=argv.input_checkpoint,
- user_output_node_names_list=argv.output,
- model_dir=argv.saved_model_dir,
- meta_graph_file=argv.input_meta_graph,
- saved_model_tags=argv.saved_model_tags)
-
- if inputs_outputs_order is not None and isinstance(inputs_outputs_order, tuple):
- graph.inputs_order = inputs_outputs_order[0]
- graph.outputs_order = inputs_outputs_order[1]
-
- send_framework_info(framework)
-
- try:
- tf_v1.import_graph_def(graph_def, name='')
- except:
- log.warning("TensorFlow post-processing of loaded model was unsuccessful. "
- "This is an optional step that Model Optimizer performs for any input model but it is not usually "
- "required for all models. "
- "It likely means that the original model is ill-formed. "
- "Model Optimizer will continue converting this model.")
-
- log.debug("Number of nodes in graph_def: {}".format(len(graph_def.node))) # pylint: disable=no-member
-
- if argv.tensorboard_logdir:
- tensorboard_util.dump_for_tensorboard(graph_def, argv.tensorboard_logdir)
-
- update_extractors_with_extensions(tf_op_extractors)
-
- try:
- protobuf2nx(graph, graph_def)
- except Exception as e:
- raise Error(
- 'Cannot pre-process TensorFlow graph after reading from model file "{}". ' \
- 'File is corrupt or has unsupported format. Details: {}. ' +
- refer_to_faq_msg(44),
- argv.model_name,
- str(e)
- ) from e
-
- graph.__setattr__('name', argv.model_name)
- # 'layout' parameter change may cause an issue in EltwiseInputReshape replacer
- # and convert_nhwc_to_nchw(graph)
- graph.graph['layout'] = 'NHWC'
- graph.graph['fw'] = 'tf'
-
- graph.graph['variables_values'] = variables_values
- del variables_values
-
- used_tensors = restore_edges(graph, get_tf_edges)
-
- # Tensor names information corresponding to a node is stored on outgoing edges.
- # As output nodes do not have outgoing edges, fake outputs are required. In the following code
- # for each output Identity node is added, and tensor name for the output is kept
- # on (output, fake output) edge. After Result nodes adding transformation fake outputs
- # are deleted from graph.
- add_outputs_identity(graph, graph.nodes - used_tensors, lambda g, output, fake_node_name: g.add_edges_from([
- create_tf_edge(output, fake_node_name, 0)]))
-
- remove_control_dependency_inputs(graph)
-
- graph.check_empty_graph('protobuf2nx. It may happen due to problems with loaded model')
- extract_node_attrs(graph, lambda node: tf_op_extractor(node, check_for_duplicates(tf_op_extractors)))
-
- # try to detect layout from the nodes of the graph. If there are no convolution nodes in N(D)HWC layout then we
- # consider that the graph is in NCHW layout and no layout conversion should be performed
- if not graph_or_sub_graph_has_nhwc_ops(graph):
- if not argv.silent:
- log.debug('disable_nhwc_to_nchw" was automatically enabled.')
- for_graph_and_each_sub_graph_recursively(graph, update_cmd_params_and_layout)
-
- send_op_names_info(framework, graph)
- send_shapes_info(framework, graph)
-
-
-def is_node_layout_nhwc(node: Node):
- """
- Check the layout attribute of specific operations and return True if any of them has layout NHWC.
- :param node: Node to check
- :return: Boolean result of the check
- """
- if node.soft_get('op') in ["Conv2D", "DepthwiseConv2dNative", "Conv3D", "Conv2DBackpropInput",
- "Conv3DBackpropInputV2"]:
- if node.soft_get('layout') in ["NHWC", "NDHWC"]:
- log.debug('Detected convolution node with NHWC layout: "{}"'.format(node.soft_get('name', node.id)))
- return True
- return False
-
-
-def graph_or_sub_graph_has_nhwc_ops(graph: Graph):
- """
- Checks that a graph or any sub-graph (inside Loop) operation contains nodes with NHWC layout.
- :param graph: main graph to check
- :return: Boolean result of the check
- """
- NHWC_conv_detected = False
- for node in graph.get_op_nodes():
- if is_node_layout_nhwc(node):
- NHWC_conv_detected = True
- break
-
- if node.has('sub_graphs'):
- for sub_graph_name in node['sub_graphs']:
- NHWC_conv_detected |= graph_or_sub_graph_has_nhwc_ops(node.soft_get(sub_graph_name))
-
- return NHWC_conv_detected
-
-
-def update_cmd_params_and_layout(graph: Graph):
- """
- Updates "cmd_params" and "layout" attribute as the model has only NCHW layout operations.
- :param graph: graph to update attributes
- :return: Nones
- """
- if 'cmd_params' in graph.graph:
- graph.graph['cmd_params'].auto_disable_nhwc_to_nchw = True
- if 'layout' in graph.graph:
- graph.graph['layout'] = 'NCHW'
diff --git a/tools/mo/openvino/tools/mo/main.py b/tools/mo/openvino/tools/mo/main.py
deleted file mode 100644
index a1e9ef58efe250..00000000000000
--- a/tools/mo/openvino/tools/mo/main.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import sys
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-from openvino.tools.mo.convert_impl import _convert
-from openvino.tools.mo.pipeline.common import get_ir_version
-
-# pylint: disable=no-name-in-module,import-error
-from openvino.runtime import serialize
-
-
-def main(cli_parser: argparse.ArgumentParser, framework=None):
- ngraph_function, argv = _convert(cli_parser, framework, {}, False)
- if ngraph_function is None:
- return 1
-
- output_dir = argv.output_dir if argv.output_dir != '.' else os.getcwd()
- model_path_no_ext = os.path.normpath(os.path.join(output_dir, argv.model_name))
- model_path = model_path_no_ext + '.xml'
-
- serialize(ngraph_function, model_path.encode('utf-8'), model_path.replace('.xml', '.bin').encode('utf-8'))
-
- print('[ SUCCESS ] Generated IR version {} model.'.format(get_ir_version(argv)))
- print('[ SUCCESS ] XML file: {}'.format(model_path))
- print('[ SUCCESS ] BIN file: {}'.format(model_path.replace('.xml', '.bin')))
- return 0
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.utils.cli_parser import get_all_cli_parser # pylint: disable=no-name-in-module,import-error
- sys.exit(main(get_all_cli_parser(), None))
diff --git a/tools/mo/openvino/tools/mo/main_caffe.py b/tools/mo/openvino/tools/mo/main_caffe.py
deleted file mode 100644
index 6554b8e70ae6c5..00000000000000
--- a/tools/mo/openvino/tools/mo/main_caffe.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import sys
-
-from openvino.tools.mo.utils.cli_parser import get_caffe_cli_parser # pylint: disable=no-name-in-module,import-error
-
-if __name__ == "__main__":
- from openvino.tools.mo.main import main
- sys.exit(main(get_caffe_cli_parser(), 'caffe'))
diff --git a/tools/mo/openvino/tools/mo/main_kaldi.py b/tools/mo/openvino/tools/mo/main_kaldi.py
deleted file mode 100644
index b1ea7fbd9064d9..00000000000000
--- a/tools/mo/openvino/tools/mo/main_kaldi.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import sys
-
-from openvino.tools.mo.utils.cli_parser import get_kaldi_cli_parser # pylint: disable=no-name-in-module,import-error
-
-if __name__ == "__main__":
- from openvino.tools.mo.main import main
- sys.exit(main(get_kaldi_cli_parser(), 'kaldi'))
diff --git a/tools/mo/openvino/tools/mo/main_onnx.py b/tools/mo/openvino/tools/mo/main_onnx.py
deleted file mode 100644
index 802ce4700e2b4f..00000000000000
--- a/tools/mo/openvino/tools/mo/main_onnx.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import sys
-
-from openvino.tools.mo.utils.cli_parser import get_onnx_cli_parser # pylint: disable=no-name-in-module,import-error
-
-if __name__ == "__main__":
- from openvino.tools.mo.main import main
-
- sys.exit(main(get_onnx_cli_parser(), 'onnx'))
diff --git a/tools/mo/openvino/tools/mo/main_paddle.py b/tools/mo/openvino/tools/mo/main_paddle.py
deleted file mode 100644
index 4a556d54c57eec..00000000000000
--- a/tools/mo/openvino/tools/mo/main_paddle.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import sys
-
-from openvino.tools.mo.utils.cli_parser import get_all_cli_parser # pylint: disable=no-name-in-module,import-error
-
-from openvino.frontend import FrontEndManager # pylint: disable=no-name-in-module,import-error
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.main import main
- sys.exit(main(get_all_cli_parser(), 'paddle'))
diff --git a/tools/mo/openvino/tools/mo/main_tf.py b/tools/mo/openvino/tools/mo/main_tf.py
deleted file mode 100644
index e48309b2630d06..00000000000000
--- a/tools/mo/openvino/tools/mo/main_tf.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import sys
-
-from openvino.tools.mo.utils.cli_parser import get_tf_cli_parser # pylint: disable=no-name-in-module,import-error
-
-if __name__ == "__main__":
- from openvino.tools.mo.main import main
- sys.exit(main(get_tf_cli_parser(), 'tf'))
diff --git a/tools/mo/openvino/tools/mo/middle/AddFakeQuantizeFuse.py b/tools/mo/openvino/tools/mo/middle/AddFakeQuantizeFuse.py
deleted file mode 100644
index a48aa1d465f111..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/AddFakeQuantizeFuse.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from typing import Dict
-
-from openvino.tools.mo.middle.MulFakeQuantizeFuse import resolve_shared_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.fusing.helpers import get_tensor_in_port, get_value_in_port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class AddFakeQuantizeFuse(MiddleReplacementPattern):
- """ Fuses Add --> FakeQuantize sequence if possible
- """
- enabled = False
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def pattern(self):
- return dict(
- nodes=[
- ('preop', dict(op='Add', can_be_fused=True)),
- ('preoped', dict()),
- ('quantize', dict(op='FakeQuantize')),
- ],
- edges=[
- ('preop', 'preoped'),
- ('preoped', 'quantize', {'in': 0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- quantize = match['quantize']
- preop = match['preop']
-
- for i in [0, 1]:
- if preop.in_port(i).get_source().node.soft_get('type') in ['Convolution', 'Deconvolution', 'MatMul']:
- return
-
- tensor_port, value_port = get_tensor_in_port(preop), get_value_in_port(preop)
-
- if value_port is None or value_port.data.get_value() is None:
- log.debug('AddQuantizeFuse: cannot fuse because Add op has dynamic inputs')
- return
-
- # Direct modifications to quantize 1-st and 2-nd port inputs are performed.
- # So the data nodes at those inputs shouldn't have more than 1 consumer maximum 2 consumers to the same
- # quantize op (consumed by 1st and 2nd ports). So we duplicate FakeQuantize in_port 1, 2, 3, 4 data
- resolve_shared_inputs(node=quantize, port_ids_to_duplicate=[1, 2])
-
- quantize.in_port(1).data.set_value(quantize.in_port(1).data.get_value() - value_port.data.get_value())
- if quantize.in_node(1).id != quantize.in_node(2).id:
- quantize.in_port(2).data.set_value(quantize.in_port(2).data.get_value() - value_port.data.get_value())
-
- in_add_connection = quantize.in_port(0).get_source().node.in_port(0).get_connection()
- quantize.in_port(0).disconnect()
- in_add_connection.add_destination(quantize.in_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/AddIsCyclicAttribute.py b/tools/mo/openvino/tools/mo/middle/AddIsCyclicAttribute.py
deleted file mode 100644
index 77d591f21422ec..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/AddIsCyclicAttribute.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class AddIsCyclicAttribute(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.DeleteControlFlowEdges import DeleteControlFlowEdges
- return [DeleteControlFlowEdges]
-
- def run_before(self):
- return []
-
- @staticmethod
- def find_and_replace_pattern(graph: Graph):
- is_acyclic = nx.is_directed_acyclic_graph(graph)
- graph.graph['is_cyclic'] = not is_acyclic
diff --git a/tools/mo/openvino/tools/mo/middle/ApplyNHWCtoNCHWpermutation.py b/tools/mo/openvino/tools/mo/middle/ApplyNHWCtoNCHWpermutation.py
deleted file mode 100644
index 7e9568d9eb96e7..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ApplyNHWCtoNCHWpermutation.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.LayoutChangeForConstantShapePaths import LayoutChangeForConstantShapePaths
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.op import PermuteAttrs
-
-
-class ApplyNHWCtoNCHWpermutation(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['layout'] == 'NHWC']
-
- def run_after(self):
- return [LayoutChangeForConstantShapePaths]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_data_nodes():
- if node.has_and_set('nchw_layout'):
- continue
-
- # Get NHWC to NCHW permutation for N dims, where N = len(node.shape)
- permutation = PermuteAttrs().get_nhwc_to_nchw_permutation(len(node.shape))
-
- # Check that data node already has permutation
- skip_permutation = False
- for in_node in node.in_nodes():
- edge_attrs = node.graph.get_edge_data(in_node.id, node.id)[0]
- if 'permutation' in edge_attrs:
- skip_permutation = True
- for out_node in node.out_nodes():
- edge_attrs = node.graph.get_edge_data(node.id, out_node.id)[0]
- if 'permutation' in edge_attrs:
- skip_permutation = True
-
- if skip_permutation:
- continue
-
- # Set permutation to all in/out edges
- for in_node in node.in_nodes():
- PermuteAttrs.set_permutation(in_node, node, permutation)
-
- for out_node in node.out_nodes():
- PermuteAttrs.set_permutation(node, out_node, permutation)
diff --git a/tools/mo/openvino/tools/mo/middle/ApplyPermutations.py b/tools/mo/openvino/tools/mo/middle/ApplyPermutations.py
deleted file mode 100644
index 46c3a70852abb9..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ApplyPermutations.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import is_input_data_in_correct_layout, \
- is_output_data_in_correct_layout
-from openvino.tools.mo.middle.LayoutChangeForConstantShapePaths import LayoutChangeForConstantShapePaths
-from openvino.tools.mo.middle.PreserveRuntimeInfo import PreserveRuntimeInfo
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.graph.perm_inputs import get_node_with_permutation
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-
-
-class ApplyPermutation(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
- # can't be turned on for Kaldi until permutation logic will be aligned
- graph_condition = [lambda graph: graph.graph['fw'] != 'kaldi']
-
- def run_after(self):
- return [PreserveRuntimeInfo]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- self.permute_data_nodes_attrs(graph)
- self.permute_op_nodes_attrs(graph)
- self.shape_of_sub_graph_reinference(graph)
- self.permute_input_data(graph)
- graph.graph['layout'] = 'NCHW'
-
- @staticmethod
- def permute_data_nodes_attrs(graph: Graph):
- # Iterate over all data nodes and apply permutation if exists
- for node in graph.get_data_nodes():
- if not node.has_valid('permutation') or \
- all([attrs.get('input_permutation', False) for u, v, attrs in graph.out_edges(node.id, data=True)]):
- continue
-
- if len(node.in_nodes()) != 0: # there are data nodes without input operation node inside the TensorIterator
- edge_attrs = graph.get_edge_data(node.in_node(0).id, node.id)[0]
- if is_output_data_in_correct_layout(node.in_node(0), edge_attrs['out']):
- log.debug('Do not permute data node attrs for node "{}" output port "{}"'.format(node.in_node(0).id,
- edge_attrs['out']))
- continue
-
- # Apply permutation for shape and value if exists
- if len(node.permutation.perm) == 0:
- continue
- node.shape = shape_array(node.shape)[node.permutation.perm]
- if node.has_valid('value'):
- assert len(node.value.shape) == len(node.permutation.perm), \
- 'Node {} has shape {} and permutation {} that does not match. Their lengths should be equal' \
- ''.format(node.name, node.value.shape, node.permutation.perm)
- node.value = mo_array(node.value.transpose(node.permutation.perm))
-
- @staticmethod
- def permute_op_nodes_attrs(graph: Graph):
- for node in graph.get_op_nodes():
- if node.has_valid('permute_attrs') and not node.has_and_set('nchw_layout'):
- try:
- node.permute_attrs.permute_attrs(node)
- except Exception as e:
- raise Error('Can\'t permute attrs for node {}. Error message: {}'.format(node.id, e))
-
- @staticmethod
- def permute_input_data(graph: Graph):
- for node in graph.get_op_nodes():
- input_permutations = [(in_port, edge_attrs['input_permutation']) for in_port, edge_attrs in
- node.in_edges().items() if edge_attrs.get('input_permutation') is not None]
- for in_port, input_perm in input_permutations:
- permutation, port_info, check_shape = input_perm
- direction, port = port_info.split(':')
- port = int(port)
- port_to_check = node.in_port(port) if direction == 'input' else node.out_port(port)
- permutation_data_node = get_node_with_permutation(node, port_info)
-
- if permutation_data_node.has_and_set('permutation') and \
- not is_input_data_in_correct_layout(node, in_port) and check_shape(port_to_check):
- permutation(node, port_info, in_port)
- if node.has_and_set('need_shape_inference'):
- node.infer(node)
- node.need_shape_inference = False
-
- @staticmethod
- def shape_of_sub_graph_reinference(graph: Graph):
- """
- After layout permutation (shape change in data nodes) shape sub-graphs contain values in the old layout
- To change that we execute full partial inference on the shape-of sub-graphs
- """
- shape_ops = graph.get_op_nodes(op='ShapeOf')
- for shape in shape_ops:
- shape.infer(shape)
-
- def reinfer_once(in_port: Port):
- node = in_port.node
- if not node.soft_get('reinferred', False):
- node.infer(node)
- node['reinferred'] = True
-
- LayoutChangeForConstantShapePaths().find_shape_subgraph_endpoints(
- out_ports=[shape.out_port(0) for shape in shape_ops], action=reinfer_once)
diff --git a/tools/mo/openvino/tools/mo/middle/ArgOpsToTopK.py b/tools/mo/openvino/tools/mo/middle/ArgOpsToTopK.py
deleted file mode 100644
index 15b19eb469460c..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ArgOpsToTopK.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.topk import TopK
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-
-
-class ArgOpsToTopK(MiddleReplacementPattern):
- """
- The transformation replaces ArgMax/ArgMin with the TopK layer.
- """
-
- enabled = True
- force_clean_up = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('node', dict(op=lambda x: x in ['ArgMax', 'ArgMin'])),
- ],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- node = match['node']
- node_name = node.soft_get('name', node.id)
-
- connected_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- if len(connected_ports) == 2:
- axis = node.in_port(1).data.get_value()
- else:
- axis = node.axis
-
- assert axis is not None, 'The "axis" should be defined for node "{}"'.format(node_name)
- assert node.has_and_set('output_type'), 'The data type is not set for node "{}"'.format(node_name)
-
- topk_mode = 'max' if node.op == 'ArgMax' else 'min'
- topk_node = TopK(graph, {'axis': axis, 'mode': topk_mode, 'sort': 'index',
- 'remove_values_output': node.has_and_set('remove_values_output'),
- 'index_element_type': node.output_type}).create_node()
- node.in_port(0).get_connection().set_destination(topk_node.in_port(0))
- if node.has_and_set('out_max_val'): # in this mode the ArgMax produces tuples (max_ind, max_value)
- concat_node = Concat(graph, {'axis': 1, 'name': node.name + '/Concat'}).create_node()
- concat_node.add_input_port(0, skip_if_exist=True)
- concat_node.add_input_port(1, skip_if_exist=True)
- topk_node.out_port(0).connect(concat_node.in_port(1)) # indices
- topk_node.out_port(1).connect(concat_node.in_port(0)) # values
- if not node.out_port(0).disconnected():
- node.out_port(0).get_connection().set_source(concat_node.out_port(0))
- else:
- if not node.out_port(0).disconnected():
- node.out_port(0).get_connection().set_source(topk_node.out_port(1))
-
- topk_node.in_port(1).connect(Const(graph, {'name': node.soft_get('name') + '/TopK',
- 'value': node.top_k}).create_node().out_port(0))
-
- graph.remove_nodes_from([node.id, node.out_node(0).id])
diff --git a/tools/mo/openvino/tools/mo/middle/AttributedTileNormalizer.py b/tools/mo/openvino/tools/mo/middle/AttributedTileNormalizer.py
deleted file mode 100644
index b73a6409999612..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/AttributedTileNormalizer.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.tile import Tile
-
-
-class AttributedTileNormalizer(MiddleReplacementPattern):
- enabled = True
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('tile', dict(op='AttributedTile', axis=lambda x: x is not None, tiles=lambda x: x is not None))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- node = match['tile']
- name = node.soft_get('name', node.id)
-
- axis = node.axis
- tiles = node.tiles
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None
- tiles_input_value = int64_array(np.ones(input_shape.size))
- tiles_input_value[axis] = tiles
-
- const = Const(graph, {'value': tiles_input_value, 'name': name + '/tiles'}).create_node()
- tile = Tile(graph, {'name': name}).create_node()
-
- node.out_port(0).get_connection().set_source(tile.out_port(0))
- node.in_port(0).get_connection().set_destination(tile.in_port(0))
- const.out_port(0).connect(tile.in_port(1))
diff --git a/tools/mo/openvino/tools/mo/middle/BiasAddBroadcasting.py b/tools/mo/openvino/tools/mo/middle/BiasAddBroadcasting.py
deleted file mode 100644
index 63bfcfc2420fbc..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/BiasAddBroadcasting.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.EltwiseChecker import EltwiseChecker
-from openvino.tools.mo.ops.elementwise import Add
-from openvino.tools.mo.front.common.layout import get_features_dim
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class BiasAddInputBroadcasting(MiddleReplacementPattern):
- """
- In TF BiasAdd op have 2 inputs: data tensor and bias tensor. Bias always has 1D shape and should be broadcasted
- to data tensor by features dimension.
-
- Also replacing BiasAdd by usual Add op after broadcasting.
- """
- enabled = True
- force_shape_inference = True
-
- def run_before(self):
- return [EltwiseChecker]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('BiasAdd', dict(kind='op', op='Add', type='BiasAdd'))
- ],
- edges=[])
-
- def replace_pattern(self, graph: Graph, match: dict):
- bias_add = match['BiasAdd']
-
- # Replace BiasAdd by Add operation
- new_add = Add(graph, {'name': bias_add.id + '/Add'}).create_node()
-
- bias_add.in_port(0).get_connection().set_destination(new_add.in_port(0))
- bias_add.in_port(1).get_connection().set_destination(new_add.in_port(1))
- bias_add.out_port(0).get_connection().set_source(new_add.out_port(0))
-
- if bias_add.data_format != 'NCHW':
- return
-
- input_shape = new_add.in_port(0).data.get_shape()
- bias_shape = new_add.in_port(1).data.get_shape()
- assert len(bias_shape) == 1
-
- unsqueeze_dims = np.arange(len(input_shape))
- channel_dim = get_features_dim('NCHW', len(input_shape))
- unsqueeze_dims = np.delete(unsqueeze_dims, channel_dim, 0)
-
- unsqueeze_node = Unsqueeze(graph, {'name': new_add.id + '/BiasUnsqueeze'}).create_node()
- unsqueeze_dims_node = Const(graph, {'name': new_add.id + '/Dims',
- 'value': unsqueeze_dims}).create_node()
- # Reconnecting nodes
- unsqueeze_node.in_port(1).connect(unsqueeze_dims_node.out_port(0))
- unsqueeze_node['override_output_shape'] = True
-
- new_add.in_port(1).get_connection().insert_node(unsqueeze_node)
diff --git a/tools/mo/openvino/tools/mo/middle/BinarizeWeightsM1P1.py b/tools/mo/openvino/tools/mo/middle/BinarizeWeightsM1P1.py
deleted file mode 100644
index d128745b452e2f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/BinarizeWeightsM1P1.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.middle.CheckForCycle import CheckForCycle
-from openvino.tools.mo.middle.DeleteNotExecutable import DeleteNotExecutable
-from openvino.tools.mo.ops.elementwise import Mul, Pow
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class BinarizeWeightsM1P1(MiddleReplacementPattern):
- """ Convert weights to -1/+1 form
-
- Applicable for convolutions and other operations that have 'weights' that combined with the input data
- by mean of multiplication operation. So any linear operator suits. Detect such operations by
- multiplication_transparent attribute -- if it is presents and set to True, then multiplication term
- can be passed through the operation. If multiplication_transparent attribute is set to True for an operation,
- such operation should also has multiplication_transparent_ports that contain a list of pairs with
- port indices (in_port, out_port) that defines which port pairs can pass multiplication through.
-
- For example for some convolutional operation which has 2 ports (input tensor and weights) and 1 output port
- this list includes [(0,0)(1,0)]. If convolutional operation also has biases at port 2, it is not included into
- this list because this port is not transparent for multiplication operation.
-
- multiplication_transparent_ports can be None if all possible input/output pairs are multiplication
- transparent.
-
- #TODO Describe how to apply multiplication at output ports -- this is not specified. In the current definition
- we can pass through only scalar multiplication, but we already require passing it channel-wise.
- """
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- # CheckForCycle and DeleteNotExecutable run graph clean up which should not be run before weights binarization
- return [CheckForCycle, DeleteNotExecutable]
-
- def pattern(self):
- return dict(
- nodes=[
- ('quantize', dict(kind='op', op='FakeQuantize')),
- ('quantized', dict()),
- ('operator', dict(kind='op', multiplication_transparent=True)),
- ],
- edges=[
- ('quantize', 'quantized'),
- ('quantized', 'operator'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- assert match['operator'].has('multiplication_transparent_ports')
-
- port = match['operator'].input_ports_with(match['quantized'])
- assert len(port) >= 1
- if len(port) > 1:
- log.debug('BinarizeWeightsM1P1 cannot apply transformation for data {} because it consumed more'
- ' than once'.format(match['quantized'].name))
- return
-
- assert len(port) == 1
- port = port[0]
- applicable = [pair for pair in match['operator'].multiplication_transparent_ports if pair[0] == port]
- if len(applicable) == 0:
- return
-
- # Look at 3-rd and 4-th inputs of FakeQuantize -- they have constants that should be passed through.
- # Assume that the constant that should be passed through is a scalar.
- quantize = match['quantize']
- output_low = quantize.in_node(3)
- output_high = quantize.in_node(4)
-
- quantize_name = quantize.soft_get('name', quantize.id)
-
- if not output_low.has_valid('value') and not output_high.has_valid('value'):
- return
-
- output_low = output_low.value
- output_high = output_high.value
-
- # This pass is applicable for binarization only. Other intX variants are not relevant.
- if quantize.levels != 2:
- return
-
- # Recognize two cases: 0/+1 and -1/+1.
- zp1 = np.all(output_low == 0) or np.all(output_high == 0)
- m1p1 = np.all(-output_low == output_high)
- if (not zp1 and not m1p1) or (zp1 and m1p1):
- log.debug('BinarizeWeightsM1P1 cannot apply transformation for data {} because it does\'t has one of'
- ' 0/+1 or -1/+1 forms.'.format(match['quantized'].name))
- return
-
- # TODO: Extract real scalar from 3rd and 4th inputs; reusing original tensors is dangerous because
- # it may have incompatible shape.
-
- mult_term = quantize.in_node(3) if np.all(output_high == 0) else quantize.in_node(4)
-
- new_shape = Const(graph, {'name': quantize_name + '/Reshape/Shape',
- 'value': int64_array([-1, 1, 1])}).create_node_with_data()
- reshape = Reshape(graph, {'name': quantize_name + '/Reshape'}).create_node_with_data([mult_term, new_shape])
-
- # Patch inflow path (by diving by mult_term)
- # Put a new Pow/Mul combination here:
- # ---->---- (here)---> data ---> [3rd/4th ports]quantize ---> quantized ---> operator
-
- if len(match['quantized'].out_nodes()) > 1:
- log.debug('BinarizeWeightsM1P1: len(match[\'quantized\'].out_nodes()) > 1')
- return
- power_of_exponent = Const(graph, {'name': quantize_name + '/DivNormalize/Power',
- 'value': mo_array(-1.0)}).create_node_with_data()
- div_op = Pow(graph, {'name': quantize_name + '/DivNormalize'})
- div_output = div_op.create_node_with_data([mult_term, power_of_exponent])
-
- for i in [3, 4]:
- match['quantize'].insert_node_with_data_before(
- match['quantize'].in_node(i),
- Mul,
- dict(name=quantize_name + '/MulNormalize'),
- additional_inputs=[div_output],
- )
-
- match['quantized'].value = None # reset value because it will be recomputed
- match['quantize'].infer(match['quantize'])
-
- # Put a complimentary new Mul node here: operator -->---(here)-----> operator.out_node()
-
- match['operator'].insert_node_with_data_after(
- match['operator'].out_node(),
- Mul,
- dict(name=match['operator'].name + '/MulNormalize'),
- [reshape],
- )
-
- # Disable 'operator' fusion with linear ops, otherwise it will annihilate changes that we just made
- match['operator']['can_be_fused'] = False
diff --git a/tools/mo/openvino/tools/mo/middle/BlockLSTMtoLSTMSequence.py b/tools/mo/openvino/tools/mo/middle/BlockLSTMtoLSTMSequence.py
deleted file mode 100644
index 5dc21ed7674ede..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/BlockLSTMtoLSTMSequence.py
+++ /dev/null
@@ -1,378 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.LSTM import LSTM
-from openvino.tools.mo.utils.error import Error
-
-
-class BlockLSTMtoLSTMSequenceSingleFirstOutput(MiddleReplacementPattern):
- """
- This transformation handles BlockLSTM with just one output, concatenation of all the intermediate
- output values of the hidden.
- TODO: implement for non-constant weights and bias.
- For this, it requires to unbound from LSTMRNNSequenceToTensorIterator transformation
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.LSTMRNNSequenceToTensorIterator import LSTMToTensorIterator
- return [LSTMToTensorIterator]
-
- def run_after(self):
- from openvino.tools.mo.middle.RNNSequenceNormalizeToIE import RNNSequenceNormalize
- return [RNNSequenceNormalize, BlockLSTMtoLSTMSequence]
-
- def pattern(self):
- return dict(
- nodes=[
- ('BlockLSTM', dict(op='BlockLSTM')),
- ('weights', dict(op='Const')),
- ('weights_data', dict(kind='data')),
- ('bias', dict(op='Const')),
- ('bias_data', dict(kind='data')),
- ],
- edges=[
- ('weights', 'weights_data'),
- ('weights_data', 'BlockLSTM', {'in': 1}),
- ('bias', 'bias_data'),
- ('bias_data', 'BlockLSTM', {'in': 2}),
- ]
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- block_lstm = match['BlockLSTM']
- connected_out_ports = [port_idx for port_idx, port in block_lstm.out_ports().items() if
- not port.disconnected()]
- # support only BlockLSTM with one output of concatenated hidden states from all steps
- if len(connected_out_ports) != 1 or connected_out_ports[0] != 0:
- return
- shift_const = block_lstm.forget_bias
-
- # determine hidden_size based on weights shapes
- w_shape = block_lstm.in_port(1).data.get_shape()
- b_shape = block_lstm.in_port(2).data.get_shape()
- hidden_size = dynamic_dimension
- if len(b_shape) > 0 and b_shape[0] is not dynamic_dimension:
- hidden_size = b_shape[0] // 4
- elif len(w_shape) > 1 and w_shape[1] is not dynamic_dimension:
- hidden_size = w_shape[1] // 4
-
- assert hidden_size is not dynamic_dimension, "OpenVINO does not support BlockLSTM with dynamic hidden_size."
-
- # normalize weights to the format required by OpenVINO LSTMSequence
- weights = block_lstm.in_port(1).data.get_value()
- biases = block_lstm.in_port(2).data.get_value()
- assert weights is not None and biases is not None, \
- "Internal Model Optimizer error: weights and bias values should be defined."
- # 1. reshape weights and bias to highlight channel dimension
- weights = weights.reshape([weights.shape[0], 4, hidden_size])
- biases = biases.reshape([4, hidden_size])
- # 2. reorder gates icfo --> fico for both weights and biases
- gate_reorder = [2, 0, 1, 3]
- weights = np.take(weights, gate_reorder, axis=1)
- biases = np.take(biases, gate_reorder, axis=0)
- # 3. shift_const.value should be added to the first 1/4th part of the biases (f-gate: 0)
- # Note: in case of moving this code up before gate reordering, the addition
- # should be applied at different place
- biases[0] += shift_const
- # 4. return to the original shapes
- weights = weights.reshape([weights.shape[0], -1])
- biases = biases.flatten()
- # 5. TF stores weights in IO, but OV requires it in OI: transpose
- weights = weights.transpose()
- # 6. set up normalized values for Constant weights and bias
- block_lstm.in_port(1).data.set_value(weights)
- block_lstm.in_port(2).data.set_value(biases)
-
- # re-number h_init_state, c_init_state input ports to match RNNSequence ports order
- # at this point there is no clear match to RNNSequence operations
- # next re-ordering is expected in LSTMRNNSequenceToTensorIterator transformation
- # to match LSTMCell inputs order
- init_hidden_state_source = block_lstm.in_port(3).get_source()
- init_cell_state_source = block_lstm.in_port(4).get_source()
- block_lstm.in_port(4).get_connection().set_source(init_hidden_state_source)
- block_lstm.add_input_port(5, skip_if_exist=True)
- block_lstm.in_port(5).get_connection().set_source(init_cell_state_source)
- block_lstm.delete_input_port(3, skip_if_absent=True)
-
- new_attrs = {'sequence_dim': 0,
- 'batch_dim': 1,
- 'direction': 'forward',
- 'hidden_size': hidden_size,
- 'format': 'tf',
- }
-
- # update attributes of existing operation
- # input edges have "bin" attribute for LSTMRNNSequenceToTensorIterator
- LSTM.update_node_stat(block_lstm, new_attrs)
-
-
-class BlockLSTMtoLSTMSequence(MiddleReplacementPattern):
- """
- MO virtual operation RNNSequence that converts to OV TensorIterator with LSTMCell inside supports 3 outputs:
- 0: concatenated hidden states over the whole time sequence,
- 1: last hidden state,
- 2: last cell state.
-
- Replacer do several tasks:
- 1. Checks if current BlockLSTM can be translated to IR (OV does not support concatenated cell state output
- which can be produced by BlockLSTM)
- 2. Searches for sub-graph, that takes last cell state out of unsupported concatenated cell state output.
- We cut this sub-graph off in case if there are no other consumers of concatenated cell state output and we connect
- BlockLSTM to consumers of this sub-graph by port producing last cell state output
- 3. Renumber input ports of BlockLSTM to match RNNSequence specification.
- 4. (Optional. Resolves by multiple checks) We cut the same sug-graph (as in 2) for concatenated cell states check
- for better performance
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.LSTMRNNSequenceToTensorIterator import LSTMToTensorIterator
- return [LSTMToTensorIterator]
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- from openvino.tools.mo.middle.RNNSequenceNormalizeToIE import RNNSequenceNormalize
- return [MiddleStart, RNNSequenceNormalize]
-
- def pattern(self):
- return dict(
- nodes=[
- ('BlockLSTM', dict(op='BlockLSTM')),
-
- # 0 port: output h vector over the whole time sequence
- ('concatenated_hidden_states', (dict(kind='data'))),
-
- ('mul', dict(op='Mul')),
- ('mul_data', dict(kind='data')),
- ('after_mul_op_to_the_rest_of_model', dict(kind='op')),
- ('concat_0', dict(op='ConcatV2')),
- ('concat_0_data', dict(kind='data')),
- ('reshape_0', dict(op='Reshape')),
- ('reshape_0_data', dict(kind='data')),
- ('gather_0', dict(op='Gather')),
- ('gather_0_data', dict(kind='data')),
-
- # 1 port: cell state before the tanh over the whole time sequence
- ('concatenated_cell_states_data', (dict(kind='data'))),
-
- ('concat_1', dict(op='ConcatV2')),
- ('concat_1_data', dict(kind='data')),
- ('reshape_1', dict(op='Reshape')),
- ('reshape_1_data', dict(kind='data')),
- ('gather_1', dict(op='Gather')),
- ('gather_1_data', dict(kind='data')),
- ],
- edges=[
- ('BlockLSTM', 'concatenated_hidden_states', {'out': 0}),
- ('concatenated_hidden_states', 'mul'),
- ('mul', 'mul_data'),
- ('mul_data', 'after_mul_op_to_the_rest_of_model'),
- ('mul_data', 'concat_0'),
- ('concat_0', 'concat_0_data'),
- ('concat_0_data', 'reshape_0'),
- ('reshape_0', 'reshape_0_data'),
- ('reshape_0_data', 'gather_0'),
- ('gather_0', 'gather_0_data'),
-
- ('BlockLSTM', 'concatenated_cell_states_data', {'out': 1}),
- ('concatenated_cell_states_data', 'concat_1', {'in': 1}),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'reshape_1'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_1_data', 'gather_1'),
- ('gather_1', 'gather_1_data')
- ]
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- time_len = match['concatenated_hidden_states'].shape[0]
- r"""
- Working with concatenated_cell_states_data part first, because OV TensorIterator primitive doesn't have
- concatenated cell states output and if we can not collapse it, then we does not support this type of BlockLSTM
-
- We simplify the sub-graph below by taking another output of BlockLSTM:
- concatenated cell states over the whole time sequence -> last cell state
-
- BlockLSTM
- || out 1 (concatenated cell states coming out of BlockLSTM)
- \/ in 1
- ConcatV2
- || (concatenation with initial state or another unused data)
- \/
- Reshape
- ||
- \/
- Gather (taking the last cell state from previous BlockLSTM, if Gather indexes == time_len)
- """
- # check that there are no other consumers of concatenated_cell_states_data data flow
- valid_output_names = ['concat_1', 'concat_1_data', 'reshape_1', 'reshape_1_data', 'gather_1', 'gather_1_data']
- valid_output_node_ids = [match[name].id for name in valid_output_names]
- node_names_to_check_outputs = ['concatenated_cell_states_data', 'concat_1_data', 'reshape_1_data']
- for name in node_names_to_check_outputs:
- for node in match[name].out_nodes():
- if node.id not in valid_output_node_ids:
- raise Error("BlockLSTM node {} has output which contains concatenated cell states over the whole "
- "time sequence. It is not replaceable by another output and is not supported "
- "originally".format(match['BlockLSTM'].id))
-
- # check that we really take the last cell state data by Gather
- gather_indexes = match['gather_1'].in_node(1).value
- if len(gather_indexes) == 1:
- gather_index = gather_indexes[0]
- else:
- raise Error("BlockLSTM node {} has output which contains concatenated cell states over the whole "
- "time sequence. It is not replaceable by another output and is not supported "
- "originally".format(match['BlockLSTM'].id))
- if gather_index != time_len:
- raise Error("BlockLSTM node {} has output which contains concatenated cell states over the whole "
- "time sequence. It is not replaceable by another output and is not supported "
- "originally".format(match['BlockLSTM'].id))
-
- """
- We passed #1 and #2 stages from class description. It means that we can translate the rest of the pattern
- to LSTMSequence even without following optimizations
- """
-
- node = match['BlockLSTM']
- weights_node = node.in_node(1)
- biases_node = node.in_node(2)
- shift_const = node.forget_bias
-
- # Assign temporary shape for them for easier manipulation
- # TF stores weights in IO order
- input_size = node.in_node(0).shape[-1]
- hidden_size = node.in_node(3).shape[-1]
- weights = weights_node.value
- biases = biases_node.value
- assert weights.shape[0] == input_size + hidden_size, \
- "weights.shape={} input_size={} hidden_size={}".format(weights.shape, input_size, hidden_size)
- assert weights.shape[1] == biases.shape[0] == 4 * hidden_size, \
- "weights.shape={} biases.shape={} hidden_size={}".format(weights.shape, biases.shape, hidden_size)
-
- weights = weights.reshape([
- weights.shape[0],
- 4, # gates
- hidden_size
- ])
-
- biases = biases.reshape([
- 4, # gates
- hidden_size
- ])
-
- # Reorder gates icfo --> fico for both weights and biases
- gate_reorder = [2, 0, 1, 3]
- weights = np.take(weights, gate_reorder, axis=1)
- biases = np.take(biases, gate_reorder, axis=0)
-
- # shift_const.value should be added to the first 1/4th part of the biases (f-gate: 0)
- # Note: in case of moving this code up before gate reordering, the addition
- # should be applied at different place
- biases[0] += shift_const
-
- # Return to the original shapes
- weights = weights.reshape([weights.shape[0], -1])
- biases = biases.flatten()
-
- # TF stores weights in IO, but OV requires it in OI: transpose
- weights = weights.transpose()
-
- weights_node.value = weights
- weights_node.shape = int64_array(weights.shape)
- biases_node.value = biases
- biases_node.shape = int64_array(biases.shape)
-
- attrs = dict(graph.get_edge_data(match['gather_1'].id, match['gather_1_data'].id)[0])
- attrs.update({'out': 2})
- graph.remove_edge(match['BlockLSTM'].id, match['concatenated_cell_states_data'].id)
- graph.remove_edge(match['gather_1'].id, match['gather_1_data'].id)
-
- match['BlockLSTM'].add_output_port(attrs['out'])
- graph.add_edge(match['BlockLSTM'].id, match['gather_1_data'].id, **attrs)
-
- """
- #3 Renumbering h_init_state, c_init_state input ports to match RNNSequence ports order.
- """
- h_init_port = 4
- c_init_port = 5
- # c_init_state
- if 4 in node.in_nodes():
- assert c_init_port not in node.in_nodes()
- cell_state_edge = graph.get_edge_data(node.in_node(4).id, node.id)
- cell_state_edge[0]['in'] = c_init_port
-
- # h_init_state
- if 3 in node.in_nodes():
- assert h_init_port not in node.in_nodes()
- hidden_state_edge = graph.get_edge_data(node.in_node(3).id, node.id)
- hidden_state_edge[0]['in'] = h_init_port
-
- new_attrs = {'sequence_dim': 0,
- 'batch_dim': 1,
- 'direction': 'forward',
- 'hidden_size': match['concatenated_hidden_states'].shape[-1],
- 'format': 'tf',
- }
-
- LSTM.update_node_stat(match['BlockLSTM'], new_attrs)
-
- """
- Optional #4 optimization from class description following
- """
- data_to_mul = [n for n in match['mul'].in_nodes().values() if n.id != match['concatenated_hidden_states'].id]
- if len(data_to_mul) != 1:
- return # unexpected type of mul
- data_to_mul = data_to_mul[0]
- if not data_to_mul.has_valid('value'):
- return # unexpected type of mul
- data_to_mul_value = data_to_mul.value
- if not np.all(data_to_mul_value == 1):
- return # unexpected type of mul
-
- # remove useless mul
- attrs = dict(graph.get_edge_data(match['BlockLSTM'].id, match['concatenated_hidden_states'].id)[0])
- graph.remove_edge(match['BlockLSTM'].id, match['concatenated_hidden_states'].id)
- graph.remove_edge(match['mul'].id, match['mul_data'].id)
- graph.add_edge(match['BlockLSTM'].id, match['mul_data'].id, **attrs)
-
- # find true usages of concatenated hidden states data (not last hidden state)
- valid_output_names = ['mul_data', 'concat_0', 'concat_0_data', 'reshape_0', 'reshape_0_data', 'gather_0',
- 'gather_0_data']
- valid_output_node_ids = [match[name].id for name in valid_output_names]
- node_names_to_check_outputs = ['mul_data', 'concat_0_data', 'reshape_0_data']
-
- list_of_concatenated_hidden_states_children_node_ids = []
- for name in node_names_to_check_outputs:
- for node in match[name].out_nodes():
- if node.id not in valid_output_node_ids:
- list_of_concatenated_hidden_states_children_node_ids.append(node.id)
-
- if len(list_of_concatenated_hidden_states_children_node_ids) != 1:
- return # not supported placement of pattern
- conacenated_child_node_id = list_of_concatenated_hidden_states_children_node_ids[0]
- if conacenated_child_node_id != match['after_mul_op_to_the_rest_of_model'].id:
- return # not supported placement of pattern
-
- gather_indexes = match['gather_0'].in_node(1).value
- if len(gather_indexes) == 1:
- gather_index = gather_indexes[0]
- else:
- return # we have to translate this type of BlockLSTM to LSTMSequence to TensorIterator as is
- if gather_index != time_len:
- return # we have to translate this type of BlockLSTM to LSTMSequence to TensorIterator as is
-
- attrs = dict(graph.get_edge_data(match['gather_0'].id, match['gather_0_data'].id)[0])
- attrs.update({'out': 1})
- graph.remove_edge(match['mul_data'].id, match['concat_0'].id)
- graph.remove_edge(match['gather_0'].id, match['gather_0_data'].id)
-
- graph.add_edge(match['BlockLSTM'].id, match['gather_0_data'].id, **attrs)
diff --git a/tools/mo/openvino/tools/mo/middle/CheckForCycle.py b/tools/mo/openvino/tools/mo/middle/CheckForCycle.py
deleted file mode 100644
index df2f7ffe9ebac5..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/CheckForCycle.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class CheckForCycle(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- is_acyclic = nx.is_directed_acyclic_graph(graph)
- if not is_acyclic:
- raise Error('Graph contains a cycle. Can not proceed. ' + refer_to_faq_msg(97))
diff --git a/tools/mo/openvino/tools/mo/middle/ConcatOptimization.py b/tools/mo/openvino/tools/mo/middle/ConcatOptimization.py
deleted file mode 100644
index 123f5e5562f9a0..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ConcatOptimization.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ConcatOdInputEraserAndPortsReconnect(MiddleReplacementPattern):
- """
- The transformation performs two actions with Concat operations:
- 1. Disconnects empty inputs (input tensor has at least one input dimension equal to 0)
- 2. Renumber Concat inputs to be 0, 1, 2,...
- """
- enabled = True
- force_clean_up = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for concat in graph.get_op_nodes(type='Concat'):
- for in_port in concat.in_ports().values():
- if not in_port.disconnected():
- shape = in_port.data.get_shape()
- assert shape is not None
- if 0 in shape:
- concat.delete_input_port(in_port.idx)
-
- connected_ports = [port for port_idx, port in sorted(concat.in_ports().items()) if not port.disconnected()]
- assert len(connected_ports), 'Concat "{}" have no inputs after removing inputs with 0 dimensions' \
- ''.format(concat.soft_get('name', concat.id))
-
- max_port_index = max([port_idx for port_idx in concat.in_ports().keys()])
- # re-connect input ports sequentially and remove all not used
- port_idx_to_connect = 0
- for port_idx in range(max_port_index + 1):
- if concat.is_in_port_connected(port_idx):
- if port_idx != port_idx_to_connect:
- concat.add_input_port(port_idx_to_connect, skip_if_exist=True)
- concat.in_port(port_idx).get_connection().set_destination(concat.in_port(port_idx_to_connect))
- port_idx_to_connect += 1
- elif port_idx in concat.in_ports():
- concat.delete_input_port(port_idx)
diff --git a/tools/mo/openvino/tools/mo/middle/ConstSwitchResolver.py b/tools/mo/openvino/tools/mo/middle/ConstSwitchResolver.py
deleted file mode 100644
index f6bda280efdc93..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ConstSwitchResolver.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ConstSwitchEraser(MiddleReplacementPattern):
- """
- Erases switch operation and its constant input after data and control flow infer
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.pseudo_topological_sort():
- if node.kind == 'data' or node.op != 'Switch':
- continue
- switch_op_node = node
- pred_id_data_node = switch_op_node.in_node(1)
- graph.remove_edge(pred_id_data_node.id, switch_op_node.id)
- remove_op_node_with_data_node(graph, switch_op_node)
diff --git a/tools/mo/openvino/tools/mo/middle/ConvToBinaryConv.py b/tools/mo/openvino/tools/mo/middle/ConvToBinaryConv.py
deleted file mode 100644
index d9875258983d4d..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ConvToBinaryConv.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ConvToBinaryConv(MiddleReplacementPattern):
- """ Transform usual convolution with [0,+1] input and [-1,+1] to BinaryConvolution
-
- Modifies output terms after the Convolution to be able to apply BinaryConvolution
- operation instead that accepts [-1,1] input and [-1,1] weights. It requires modification
- channel-wise addition with weights reduced along all axis except output channel dimension.
- """
- enabled = True
- force_clean_up = True
-
- def pattern(self):
- return dict(
- nodes=[
- # This pass is applicable for binarization only. Other intX variants are not relevant.
- ('quantize', dict(kind='op', op='FakeQuantize', levels=2)),
- ('quantized', dict()), # input tensor, not weights
- ('operator', dict(kind='op', type='Convolution')),
- ],
- edges=[
- ('quantize', 'quantized'),
- ('quantized', 'operator', {'in':0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- assert match['operator'].has('multiplication_transparent_ports')
-
- quantize = match['quantize']
-
- port = match['operator'].input_ports_with(match['quantized'])
- assert len(port) >= 1
- if len(port) > 1:
- log.debug('BinarizeWeightsM1P1 cannot apply transformation for data {} because it consumed more'
- ' than once'.format(match['quantized'].name))
- return
-
- assert len(port) == 1
- port = port[0]
- applicable = [pair for pair in match['operator'].multiplication_transparent_ports if pair[0] == port]
- if len(applicable) == 0:
- return
-
- # Look at 3-rd and 4-th inputs of FakeQuantize -- they have constants that should be passed through.
- # Assume that the constant that should be passed through is a scalar.
- output_low = quantize.in_node(3)
- output_high = quantize.in_node(4)
- assert len(output_low.out_nodes()) == 1
- assert len(output_high.out_nodes()) == 1
-
- if not output_low.has_valid('value') and not output_high.has_valid('value'):
- return
-
- output_low = output_low.value
- output_high = output_high.value
-
- operator = match['operator']
-
- weights = operator.in_node(1).value
- weights_rounded = np.round(weights)
- weights_consistent = np.all(np.isclose(weights, weights_rounded)) and \
- set(np.unique(weights_rounded)).issubset({-1, 1})
-
- if weights_consistent and np.all(np.isclose(output_low, 0)) and np.all(np.isclose(output_high, 1)):
- reduction_indices = set(range(len(weights.shape))) - set([operator.output_feature_channel])
- weights_reduced = np.add.reduce(weights, axis=tuple(reduction_indices))
- weights_reduced = weights_reduced.reshape([len(weights_reduced), 1, 1]) # FIXME: works for NCHW only
-
- operator_name = operator.soft_get('name', operator.id)
- add = create_op_node_with_second_input(graph, Add, weights_reduced, {'name': operator_name + '/Add_'})
- mul = create_op_node_with_second_input(graph, Mul, mo_array(0.5), {'name': operator_name + '/Mul_'})
-
- add.out_port(0).connect(mul.in_port(0))
-
- operator.out_port(0).get_connection().set_source(mul.out_port(0))
- add.in_port(0).connect(operator.out_port(0))
-
- operator['pad_value'] = float(-1.0)
- elif weights_consistent and np.all(np.isclose(output_low, -1)) and np.all(np.isclose(output_high, +1)):
- pass
- else:
- log.debug('ConvToBinaryConv: cannot apply transformation because input range is neither in [0, +1] nor '
- 'in [-1, +1].')
- return
-
- operator['type'] = 'BinaryConvolution'
- operator['mode'] = 'xnor-popcount'
- operator['pad_value'] = operator.soft_get('pad_value', float(0))
- operator['input'] = operator.in_node(0).shape[1]
- # Weights are not bit-packed yet; there should be a separate transformation to do that
-
- assert output_low.size == 1
- assert output_high.size == 1
-
- output_low = quantize.in_node(3)
- output_high = quantize.in_node(4)
-
- # Make sure that low/high values are exactly 0/1
- output_low.value = np.zeros(output_low.shape, dtype=np.float32)
- output_high.value = np.ones(output_high.shape, dtype=np.float32)
diff --git a/tools/mo/openvino/tools/mo/middle/ConvertGroupedStridedSlice.py b/tools/mo/openvino/tools/mo/middle/ConvertGroupedStridedSlice.py
deleted file mode 100644
index 01a823f98a8439..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ConvertGroupedStridedSlice.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from copy import deepcopy
-
-import numpy as np
-
-from openvino.tools.mo.middle.SliceConverter import ConvertSlice
-from openvino.tools.mo.ops.split import VariadicSplit
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph, Node, add_opoutput
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from openvino.tools.mo.utils.utils import unique_by
-
-
-def strided_slices_equality(lhs: Node, rhs: Node) -> bool:
- """
- Equality criterion for StridedSlice layers.
- :param lhs: the first StridedSlice layer
- :param rhs: the second StridedSlice layer
- :return: True, if lhs and rhs have identical attributes 'slices', 'begin_mask', 'end_mask', 'ellipsis_mask',
- 'new_axis_mask', 'shrink_axis_mask', and False otherwise.
- """
- for attr in ['slices', 'new_axis_mask', 'shrink_axis_mask', 'begin_mask', 'end_mask', 'ellipsis_mask']:
- if not np.array_equal(lhs[attr], rhs[attr]):
- return False
- return True
-
-
-class ConvertGroupedStridedSlice(MiddleReplacementPattern):
- """
- This pass converts subgraphs where StridedSlices used for splitting single channel to single Split layers
- In case if StrdedSlices consume not entire tensor will be created fake outputs for Split layer
- For example:
- Let's suppose we have next graph:
- Data(1,H,W,54)
- |`---->Sslice1_out (1,H,W,(10,18))
- `---->Sslice2_out (1,H,W,(18,36))
-
- In this case StridedSlices takes only [10, 36] from input tensor in 3rd dim
- So this pass will convert this graph to the next one:
- Split(1,H,W,54)
- |`---->Fake_data (1,H,W,10)
- |`---->Sslice1_out (1,H,W,8)
- |`---->Sslice2_out (1,H,W,18)
- `----->Fake_data (1,H,W,18)
- Where Fake_data - data nodes that have not any consumers.
- """
-
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.StridedSliceNormalizer import StridedSliceNormalizer
- return [ConvertSlice, StridedSliceNormalizer]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def find_and_replace_pattern(self, graph: Graph):
- # Iterate over all data nodes and find all with >= 1 consumers
- for input_data in list(graph.get_data_nodes()):
- # We don't use constant data nodes
- if input_data.value is not None:
- continue
-
- if input_data.shape is None:
- continue
- input_shape = shape_array(input_data.shape)
-
- # Get all unique StridedSlice consumers
- out_nodes = [node for node in input_data.out_nodes() if node.op == 'StridedSlice' and
- node.in_node(0).id == input_data.id]
-
- if len(out_nodes) <= 1:
- continue
-
- valid_for_replacement = True
- for n in out_nodes:
- if any(not isinstance(s, slice) for s in n.slices):
- # this is a slice with dynamic dimension. Such operation is not valid for replacement
- valid_for_replacement = False
- if not valid_for_replacement:
- continue
-
- sorted_out_nodes = sorted(out_nodes, key=lambda n: list(n.slices))
- out_nodes = unique_by(sorted_out_nodes, strided_slices_equality)
- # if there is only one StridedSlice out_node with unique 'slices',
- # there is nothing to optimize, continue to the next data node
- if len(out_nodes) <= 1:
- continue
-
- for node in out_nodes:
- if len(node.slices) != len(out_nodes[0].slices):
- valid_for_replacement = False
-
- # Detect dimension for splitting
- split_channel_dim = None
- for dim_id, s in enumerate(out_nodes[0].slices):
- l, r, stride = s.start, s.stop, s.step
- # if both l and r are None then the dimension is not sliced
- if (l != 0 or r != input_shape[dim_id]) and (l is not None or r is not None):
- if split_channel_dim is None:
- split_channel_dim = dim_id
- else:
- valid_for_replacement = False
-
- if split_channel_dim is None:
- valid_for_replacement = False
-
- # split_dims contains tuples with split range and output data node
- split_dims = []
- for out_id, node in enumerate(out_nodes):
- # Check that StridedSlice op has stride eq 1 and splits only feature channel
- for id, s in enumerate(node.slices):
- l, r, stride = s.start, s.stop, s.step
- # We don't support StridedSlice with stride != 1
- if stride != 1:
- valid_for_replacement = False
- if id == split_channel_dim:
- split_dims.append((s.start, s.stop, node.out_node()))
-
- if not valid_for_replacement:
- continue
-
- # Check feature split intersection
- final_data_nodes_list = []
- sorted_split_dims = sorted(split_dims, key=lambda item: (item[0], item[1]))
-
- # check if we have similar StridedSlice operations with different outputs
- prev_sd = sorted_split_dims[0]
- to_remove = []
- for i in range(1, len(sorted_split_dims)):
- if sorted_split_dims[i][0] == prev_sd[0] and sorted_split_dims[i][1] == prev_sd[1] and sorted_split_dims[i][2].name != prev_sd[2].name:
- cur_node = sorted_split_dims[i][2]
- for out in cur_node.out_nodes():
- attrs = deepcopy(graph.get_edge_data(cur_node.id, out.id)[0])
- graph.remove_edge(cur_node.id, out.id)
- graph.add_edge(prev_sd[2].id, out.id, **attrs)
- to_remove.append(i)
-
- for ind in reversed(to_remove):
- sorted_split_dims.pop(ind)
-
- size_splits = []
- prev_r = 0
- for l, r, out in sorted_split_dims:
- # Split dims shouldn't intersect
- if l < prev_r:
- valid_for_replacement = False
- prev_r = r
-
- if prev_r > input_shape[split_channel_dim]:
- valid_for_replacement = False
-
- if not valid_for_replacement:
- continue
-
- prev_r = 0
- for l, r, out in sorted_split_dims:
- # Save missing tensor part
- if l > prev_r:
- shape = mo_array(input_shape)
- size_splits.append(l - prev_r)
- shape[split_channel_dim] = l - prev_r
- data_node = Op._create_data_node(graph, 'fake_data_'+out_nodes[0].name, {'shape': shape})
- add_opoutput(graph, data_node.id, 0, False, keep_output_port=True)
- final_data_nodes_list.append(data_node)
-
- prev_r = r
- size_splits.append(r - l)
- final_data_nodes_list.append(out)
-
- if prev_r < input_shape[split_channel_dim]:
- # Add last part of tensor
- shape = input_shape.copy()
- shape[split_channel_dim] = input_shape[split_channel_dim] - prev_r
- size_splits.append(input_shape[split_channel_dim] - prev_r)
- data_node = Op._create_data_node(graph, 'fake_data_'+out_nodes[0].name, {'shape': shape})
- add_opoutput(graph, data_node.id, 0, False, keep_output_port=True)
- final_data_nodes_list.append(data_node)
-
- for node in out_nodes:
- if not np.all([x == 0 for x in node.shrink_axis_mask]):
- out_node = node.out_node()
- if np.any(node['shrink_axis_mask']):
- self.add_squeeze_for_shrink(graph, node)
- if np.any(node['new_axis_mask']):
- self.add_unsqueeze_for_new(graph, node)
-
- for i in range(len(final_data_nodes_list)):
- if final_data_nodes_list[i].name == out_node.name:
- final_data_nodes_list[i] = node.out_node()
- break
-
- # Insert Split layer and remove old StridedSlice layers
- # 1. Remove connections from input_data to StridedSlice ops
- out_data_nodes = []
- name_for_future_split = out_nodes[0].name
- for node in out_nodes:
- out_data_nodes.append(node.out_node())
- graph.remove_edge(input_data.id, node.id)
- graph.remove_edge(node.id, node.out_node().id)
- graph.remove_node(node.id)
- log.debug("Removed: {}".format(node.id))
-
- # 2. Create Split layer and reorder outputs
- name = name_for_future_split + "/Split"
- axis_const = Const(graph, {'value': int64_array(split_channel_dim),
- 'name': name + '/Axis'}).create_node_with_data()
- size_splits_const = Const(graph, {'value': int64_array(size_splits),
- 'name': name + '/Sizes'}).create_node_with_data()
- split = VariadicSplit(graph, dict(name=name, out_ports_count=len(size_splits)))
-
- split.create_node_with_data(inputs=[input_data, axis_const, size_splits_const],
- data_nodes=final_data_nodes_list)
-
- @staticmethod
- def add_squeeze_for_shrink(graph: Graph, ss_node: Node):
- # add Squeeze for shrink_axis_mask
- log.info("StridedSlice op with shrink mask '{}' has been detected".format(ss_node.id))
-
- if len(ss_node.in_nodes()) != 4 or len(ss_node.out_nodes()) != 1:
- return
-
- shape_out = ss_node.out_node().shape
- dim = mo_array(range(len(ss_node['shrink_axis_mask'])))[mo_array(ss_node['shrink_axis_mask'], dtype=bool)]
- ss_shape = []
- i = 0
- k = 0
-
- # Don't permute reshape if channels were squeezed
- dont_permute = graph.graph['layout'] == 'NCHW'
- if graph.graph['layout'] == 'NHWC' and ss_node['shrink_axis_mask'][-1] == 1:
- dont_permute = True
-
- while k < len(shape_out):
- if i >= len(ss_node['shrink_axis_mask']) or not ss_node['shrink_axis_mask'][i]:
- ss_shape.append(shape_out[k])
- k = k + 1
- else:
- ss_node['shrink_axis_mask'][i] = 0
- ss_shape.append(1)
- i = i + 1
-
- while i < len(ss_node['shrink_axis_mask']):
- ss_node['shrink_axis_mask'][i] = 0
- ss_shape.append(1)
- i = i + 1
-
- ss_node.out_port(0).data.set_shape(ss_shape)
-
- # insert Squeeze
- squeeze_node = Squeeze(graph, dict(name=ss_node.name + '/Squeeze_shrink',
- nchw_layout=dont_permute,
- correct_data_layout=dont_permute)).create_node()
- ss_node.out_port(0).get_connection().insert_node(squeeze_node)
- squeeze_node.out_port(0).data.set_shape(shape_out)
-
- dims_node = Const(graph, {'name': squeeze_node.id + '/Indices', 'value': int64_array(dim)}).create_node()
- dims_node.out_port(0).connect(squeeze_node.in_port(1))
-
- @staticmethod
- def add_unsqueeze_for_new(graph: Graph, ss_node: Node):
- log.info("StridedSlice op with new axis mask '{}' has been detected".format(ss_node.id))
- if len(ss_node.in_nodes()) != 4 or len(ss_node.out_nodes()) != 1:
- return
-
- shape_out = ss_node.out_node().shape
- dim = mo_array(range(len(ss_node['new_axis_mask'])))[mo_array(ss_node['new_axis_mask'], dtype=bool)]
- ss_shape = []
- for i in range(0, len(ss_node['new_axis_mask'])):
- if not ss_node['new_axis_mask'][i]:
- ss_shape.append(shape_out[i])
- else:
- ss_node['new_axis_mask'][i] = 0
-
- ss_node.out_port(0).data.set_shape(ss_shape)
-
- # insert Unsqueeze
- unsqueeze_node = Unsqueeze(graph, dict(name=ss_node.name + '/Unsqueeze_new')).create_node()
- ss_node.out_port(0).get_connection().insert_node(unsqueeze_node)
- unsqueeze_node.out_port(0).data.set_shape(shape_out)
-
- dims_node = Const(graph, {'name': unsqueeze_node.id + '/Indices', 'value': int64_array(dim)}).create_node()
- dims_node.out_port(0).connect(unsqueeze_node.in_port(1))
diff --git a/tools/mo/openvino/tools/mo/middle/ConvertLayoutDependentOperations.py b/tools/mo/openvino/tools/mo/middle/ConvertLayoutDependentOperations.py
deleted file mode 100644
index cf4d70dde64922..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ConvertLayoutDependentOperations.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.layout import indices_mapping
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-class ConvertLayoutDependentOperations(MiddleReplacementPattern):
- """
- This pass finds all convolutions and in case if layout of convolution differs from graph layout
- we insert permutes before and after convolution and convert convolution attributes
- """
-
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in list(graph.nodes()):
- node = Node(graph, node)
- node_name = node.soft_get('name', node.id)
- # Check that node layout mismatch with graph layout
- # For example: NHWC and NCHW or NCDHW and NDHWC
- if node.kind == 'op' and node.has_valid('layout') and node.layout != indices_mapping[len(node.layout)][
- graph.graph['layout']]:
- input = node.in_node()
- output = node.out_node()
-
- # Calculate permutation for further Transpose operations
- if graph.graph['layout'] == 'NCHW':
- # if Node has NCHW and graph has NHWC layout
- permutation = PermuteAttrs.get_nhwc_to_nchw_permutation(len(node.layout))
- else:
- # if Node has NHWC and graph has NCHW layout
- permutation = PermuteAttrs.get_nchw_to_nhwc_permutation(len(node.layout))
-
- # Schematic representation of transformation below
- #
- # \ NCHW NCHW
- # NHWC -- \ | permutation permutation |
- # data-->Convolution(example)-->data -- / | | NCHW | |
- # / data->Transpose->data->Convolution->data->Transpose->data
-
- # 1. Insert input Transpose
- # This Transpose will permute input from original input layout to operation layout
- edge_attrs = graph.get_edge_data(input.id, node.id)[0]
- graph.remove_edge(input.id, node.id)
-
- input_permute_name = node_name + '/input_transpose'
- input_order_const = Const(graph, {'name': input_permute_name + '/order',
- 'value': permutation.perm}).create_node_with_data()
- input_permute_op = Transpose(graph, {'name': input_permute_name})
- input_permute_data_node = input_permute_op.create_node_with_data([input, input_order_const])
-
- graph.add_edge(input_permute_data_node.id, node.id, **edge_attrs)
-
- # 2. Insert output Transpose
- # This Transpose will permute output from operation layout to original input layout
- edge_attrs = graph.get_edge_data(node.id, output.id)[0]
- graph.remove_edge(node.id, output.id)
-
- input_data_node = Op.create_data_node(graph, node, {'shape': output.shape[permutation.perm]},
- edge_attrs)
-
- output_permute_name = node_name + '/output_transpose'
- output_order_const = Const(graph, {'name': output_permute_name + '/order',
- 'value': permutation.inv}).create_node_with_data()
- output_permute_op = Transpose(graph, {'name': output_permute_name}
- ).create_node_with_data([input_data_node, output_order_const],
- data_nodes=output)
-
- # 3. Add permutations for Node
- # Here we use permutation mechanism where data nodes takes permutation attribute.
- # And then we call permute_attrs method that permutes node attributes according to permutations on
- # data nodes.
- node.in_node()['permutation'] = permutation
- node.out_node()['permutation'] = permutation
- node.permute_attrs.permute_attrs(node)
-
- node.in_node()['permutation'] = None
- node.out_node()['permutation'] = None
diff --git a/tools/mo/openvino/tools/mo/middle/ConvertMultiInputConv.py b/tools/mo/openvino/tools/mo/middle/ConvertMultiInputConv.py
deleted file mode 100644
index a0a3856f20eb2a..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ConvertMultiInputConv.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import copy
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ConvertMultiInputConv(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op', op='ConvND'))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- node = match['op']
- node.op = 'Conv2D'
-
- if node.bias_term:
- num_inputs = len(node.in_nodes()) - 2
- w_node = node.in_node(len(node.in_nodes()) - 2)
- b_node = node.in_node(len(node.in_nodes()) - 1)
- else:
- num_inputs = len(node.in_nodes()) - 1
- w_node = node.in_node(len(node.in_nodes()) - 1)
-
- for i in range(1, num_inputs):
- in_i = node.in_node(i)
- out_i = node.out_node(i)
- conv_id = graph.unique_id(node.id + '__')
- graph.add_node(conv_id, **copy.deepcopy(node.get_attrs()))
- new_conv = Node(graph, conv_id)
- new_conv.name = conv_id
-
- graph.remove_edge(in_i.id, node.id)
- graph.remove_edge(node.id, out_i.id)
- graph.add_edges_from([
- (w_node.id, conv_id, {'in': 1, 'bin': 'weights'}),
- ])
-
- if node.bias_term:
- graph.add_edges_from([
- (b_node.id, conv_id, {'in': 2, 'bin': 'biases'}),
- ])
-
- graph.add_edges_from([
- (in_i.id, conv_id, {'in': 0}),
- ])
- graph.add_edge(conv_id, out_i.id, **{'out': 0})
diff --git a/tools/mo/openvino/tools/mo/middle/CustomSubgraphCall.py b/tools/mo/openvino/tools/mo/middle/CustomSubgraphCall.py
deleted file mode 100644
index 092acf10d18e64..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/CustomSubgraphCall.py
+++ /dev/null
@@ -1,318 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import copy
-import logging as log
-
-import numpy as np
-import os
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-
-from openvino.tools.mo.front.common.layout import nhwc_to_nchw_permute
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, shape_insert
-from openvino.tools.mo.front.extractor import update_ie_fields
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.graph.graph import Node, add_opoutput
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-nchw_to_nhwc_constant_name = 'IE_NCHW_TO_NHWC'
-nhwc_to_nchw_constant_name = 'IE_NHWC_TO_NCHW'
-
-
-class CustomSubgraphCall(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'tf']
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- @staticmethod
- def update_placeholders(graph: Graph):
- """
- Iterates over all nodes of the graph, find all TF sub-graph call operations and updates placeholders shapes and adds
- transpose operation if necessary.
- :param graph: graph to operate on
- :return: None
- """
- for node in graph.get_op_nodes(op='TFCustomSubgraphCall'):
- CustomSubgraphCall.update_placeholder_shape_and_add_transpose(node)
-
- @staticmethod
- def update_placeholder_shape_and_add_transpose(node: Node):
- """
- The function changes placeholders shapes from NHWC to NCHW format and add transpose operations if needed.
- :param node: node to operate on.
- :return: None
- """
- try:
- import tensorflow.compat.v1 as tf_v1
- except ImportError:
- import tensorflow as tf_v1
- # in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
- tf_v1.get_logger().setLevel("ERROR")
-
- from openvino.tools.mo.front.common.layout import convert_shape, nhwc_to_nchw_permute, nchw_to_nhwc_permute
- from openvino.tools.mo.front.tf.extractors.utils import tf_tensor_shape
- from openvino.tools.mo.front.tf.partial_infer.tf import add_node_def_to_subgraph, update_input_in_pbs
-
- tf_v1.reset_default_graph()
-
- inputs_replacements = list()
-
- # transpose permutation constant
- nchw_to_nhwc_constant = tf_v1.constant(nchw_to_nhwc_permute, dtype=tf_v1.int32, name=nchw_to_nhwc_constant_name)
- nhwc_to_nchw_constant = tf_v1.constant(nhwc_to_nchw_permute, dtype=tf_v1.int32, name=nhwc_to_nchw_constant_name)
-
- for placeholder_name in node['input_nodes_names']:
- # dummy node which we can refer to as input in the transpose for the output node
- # dummy node should be unique for each placeholder
- dummy_node = tf_v1.constant(value=[[[[1]]]], dtype=tf_v1.float32,
- name='random_dummy_name_' + placeholder_name)
-
- placeholder = node['pbs'][placeholder_name]
- cur_shape = tf_tensor_shape(placeholder.attr['shape'].shape)
- if len(cur_shape) == 4: # TODO think about better check that transpose is required
- nchw_shape = convert_shape(cur_shape, nhwc_to_nchw_permute)
- for ind in range(len(cur_shape)):
- placeholder.attr['shape'].shape.dim[ind].size = nchw_shape[ind]
- transpose_name = placeholder.name + '_transpose'
- transpose = tf_v1.transpose(dummy_node, nchw_to_nhwc_constant, transpose_name) # NCHW -> NHWC
-
- # add transpose operations to GraphDef after placeholders
- add_node_def_to_subgraph(node, transpose.op.node_def, transpose_name, len(node['input_nodes_names']))
- inputs_replacements.append((placeholder.name, transpose_name))
- inputs_replacements.append((dummy_node.name, placeholder.name))
- node['real_input_dims'].append(nchw_shape)
- else:
- node['real_input_dims'].append(cur_shape)
- add_node_def_to_subgraph(node, nchw_to_nhwc_constant.op.node_def)
- add_node_def_to_subgraph(node, nhwc_to_nchw_constant.op.node_def)
-
- # update initial input names to a transposed ones
- for old_input_tensor_name, new_name in inputs_replacements:
- update_input_in_pbs(node, old_input_tensor_name, new_name)
-
- @staticmethod
- def add_output_nodes_transposes(graph: Graph):
- """
- Iterates over all nodes of the graph, find all TF sub-graph call operations and adds Transpose operations to the
- output nodes if they are 4D to covert output from NHWC to NCHW.
- :param graph: graph to operate on
- :return: None
- """
- for node in graph.get_op_nodes(op='TFCustomSubgraphCall'):
- CustomSubgraphCall.add_sub_graph_call_output_tensors_transposes(node)
-
- @staticmethod
- def make_shape_4d(shape: np.array):
- """
- Create 4D tensor from 1D, 2D or 3D by adding new dimensions of size 1.
- :param shape: shape to extend.
- :return: 4D tensor.
- """
- new_shape = shape_array(shape)
- old_shape_len = len(shape)
-
- # TODO think about proper way to add additional dimensions considering layout
- for x in range(4 - old_shape_len):
- # if the shape is 0D or 1D then we should add additional dimensions to batch dimension
- if len(new_shape) <= 1:
- new_shape = shape_insert(new_shape, 0, 1)
- else:
- new_shape = shape_insert(new_shape, 1, 1)
- return new_shape
-
- @staticmethod
- def add_reshape_before_op_node(graph: Graph, data_node_name: str, op_node_name: str, edge_attrs: dict):
- """
- Adds reshape operation which expands dimension of the specified data tensor to 4D.
- :param graph: graph to operate on.
- :param data_node_name: the name of the data node to be reshaped to 4D tensor.
- :param op_node_name: name of the TFCustomSubgraphCall node which produces the tensor.
- :param edge_attrs: edge attributes which should be preserved.
- :return: None
- """
- data_node = Node(graph, data_node_name)
-
- graph.remove_edge(data_node_name, op_node_name)
-
- assert data_node['shape'] is not None
-
- new_shape = CustomSubgraphCall.make_shape_4d(data_node['shape'])
-
- # reshape shape data node
- reshape_shape_data_node_name = graph.unique_id("Reshape_shape_")
- graph.add_node(reshape_shape_data_node_name, kind='data', name=reshape_shape_data_node_name, value=new_shape,
- shape=[1])
-
- # reshape operation node
- reshape_node_name = graph.unique_id("Reshape_")
- graph.add_node(reshape_node_name, kind='op', type='Reshape', name=reshape_node_name, op='Reshape',
- data_type=data_node['data_type'])
- update_ie_fields(graph.node[reshape_node_name])
-
- # reshaped data node
- reshaped_value = None
- if data_node['value'] is not None:
- reshaped_value = np.reshape(data_node['value'], new_shape)
- reshaped_data_node_name = graph.unique_id("reshaped_data_")
- graph.add_node(reshaped_data_node_name, kind='data', name=reshaped_data_node_name, shape=new_shape,
- value=reshaped_value, nchw_layout=True)
-
- graph.add_edges_from([
- (data_node_name, reshape_node_name, {'in': 0}),
- (reshape_shape_data_node_name, reshape_node_name, {'in': 1}),
- (reshape_node_name, reshaped_data_node_name, {'out': 0}),
- (reshaped_data_node_name, op_node_name, edge_attrs)
- ])
-
- @staticmethod
- def add_reshape_after_data_node(graph: Graph, data_node_name: str):
- """
- Adds reshape operation which changes shape of the tensor produced by TFSubgraphCall from 4D to real dimension
- of the tensor. The data_node_name node contains real dimensions of the tensor but they will be changed in the
- add_reshapes_for_tf_subgraph_calls function to a 4D because OV TF call layer supports output in 4D only.
- :param graph: graph to operate on.
- :param data_node_name: name of the data node to be reshaped to correct dimensions.
- :return: None
- """
- data_node = Node(graph, data_node_name)
-
- # if the data node was previously marked as output then we need to mark as output new reshaped data node
- is_out_node = False
- if len(data_node.out_nodes()) == 1 and data_node.out_node().has('op') and data_node.out_node().op == 'Result':
- is_out_node = True
- graph.remove_node(data_node.out_node().id)
-
- # save old consumers nodes with edge attributes
- old_consumer_nodes_with_attrs = list()
- for index, out_op in enumerate(data_node.out_nodes()):
- edge_attrs = graph.get_edge_data(data_node_name, out_op.name)[0]
- old_consumer_nodes_with_attrs.append((out_op.name, edge_attrs))
-
- # remove old consumers from the data node
- for out_op in list(data_node.out_nodes()):
- graph.remove_edge(data_node_name, out_op.name)
-
- # reshape operation node
- reshape_node_name = graph.unique_id("Reshape_")
- graph.add_node(reshape_node_name, kind='op', type='Reshape', name=reshape_node_name, op='Reshape',
- data_type=data_node['data_type'])
- update_ie_fields(graph.node[reshape_node_name])
-
- # reshape shape data node
- reshape_shape_data_node_name = graph.unique_id("Reshape_shape_")
- graph.add_node(reshape_shape_data_node_name, kind='data', name=reshape_shape_data_node_name,
- value=mo_array(data_node['shape']), shape=[1])
-
- # reshaped data node
- reshaped_value = None
- if data_node['value'] is not None:
- reshaped_value = mo_array(data_node['value'])
- reshaped_data_node_name = graph.unique_id("reshaped_data_")
- graph.add_node(reshaped_data_node_name, kind='data', name=reshaped_data_node_name,
- shape=mo_array(data_node['shape']), value=reshaped_value, nchw_layout=True)
-
- if is_out_node:
- add_opoutput(graph, reshaped_data_node_name, 0, False)
-
- graph.add_edges_from([
- (data_node_name, reshape_node_name, {'in': 0}),
- (reshape_shape_data_node_name, reshape_node_name, {'in': 1}),
- (reshape_node_name, reshaped_data_node_name, {'out': 0}),
- ])
-
- for out_node_name, edge_attrs in old_consumer_nodes_with_attrs:
- graph.add_edges_from([
- (reshaped_data_node_name, out_node_name, edge_attrs)
- ])
-
- @staticmethod
- def add_reshapes_for_tf_subgraph_calls(graph: Graph):
- """
- Input and output tensors of the TFCustomSubgraphCall must be 4D because OV layer accepts and produces only 4D
- tensors. This function adds reshape operations where it is necessary.
- :param graph: graph to operate on.
- :return: None.
- """
- for src_node_name, dst_node_name, edge_attrs in list(graph.edges(data=True)):
- src_node = Node(graph, src_node_name)
- dst_node = Node(graph, dst_node_name)
- if dst_node.kind == 'op' and dst_node.has_valid('type') and dst_node.type == 'TFCustomSubgraphCall' and \
- src_node.has_valid('shape') and len(src_node.shape) != 4:
- log.info("There is an data tensor of shape '{}' which goes into '{}' node".format(
- src_node.shape, dst_node.type))
- CustomSubgraphCall.add_reshape_before_op_node(graph, src_node_name, dst_node_name, edge_attrs)
-
- for node in graph.get_op_nodes(op='TFCustomSubgraphCall'):
- for index, data_node in node.out_nodes().items():
- real_dims_count = len(data_node.shape)
- if real_dims_count != 4:
- log.info(
- "There is an data tensor of shape '{}' with real dims count '{}' which goes out of '{}' "
- "node".format(data_node.shape, real_dims_count, node.name))
- CustomSubgraphCall.add_reshape_after_data_node(graph, data_node.id)
-
- # need to update shape of the op so OV generates XML with 4D tensors
- out_shape = CustomSubgraphCall.make_shape_4d(data_node['shape'])
-
- data_node['shape'] = out_shape
-
- @staticmethod
- def add_sub_graph_call_output_tensors_transposes(node: Node):
- """
- Adds transpose operations to the output nodes if they are 4D to change layout from NCHW to NHWC.
- :param node: the node to add transposes to the output nodes to.
- :return: None
- """
- try:
- import tensorflow.compat.v1 as tf_v1
- except ImportError:
- import tensorflow as tf_v1
- # in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
- tf_v1.get_logger().setLevel("ERROR")
-
- from openvino.tools.mo.front.tf.partial_infer.tf import get_subgraph_output_tensors, add_node_def_to_subgraph
- _, output_tensors = get_subgraph_output_tensors(node)
-
- # transpose permutation constant
- nhwc_to_nchw_constant = tf_v1.constant(nhwc_to_nchw_permute, dtype=tf_v1.int32, name=nhwc_to_nchw_constant_name)
-
- # dummy node which we can refer to as input in the transpose for the output node
- dummy_node = tf_v1.constant(value=[[[[1]]]], dtype=tf_v1.float32, name='random_dummy_name')
-
- new_out_tensor_names = list()
- for out_tensor_name in node['output_tensors_names']:
- out_name, out_port = out_tensor_name.split(':')
- if len(output_tensors[
- int(out_port)].shape) == 4: # TODO think about better check whether transpose is required
- out_transpose_name = out_name + '_port_' + out_port + '_transpose'
- transpose = tf_v1.transpose(dummy_node, nhwc_to_nchw_constant, name=out_transpose_name)
-
- # starting from TF 1.8 it is not possible to modify the "node_def" of the "tf.op", so we create a copy,
- # update it and use further
- new_input_names = transpose.op.node_def.input[:]
- new_input_names[0] = out_tensor_name
- new_node_def = copy.deepcopy(transpose.op.node_def)
- new_node_def.input[:] = new_input_names
- add_node_def_to_subgraph(node, new_node_def, position=len(node['nodes_order']))
- new_out_tensor_names.append(out_transpose_name)
- else:
- new_out_tensor_names.append(out_tensor_name)
-
- # update output tensor names with transposes operations
- node['output_tensors_names'] = new_out_tensor_names
-
- def find_and_replace_pattern(self, graph: Graph):
- CustomSubgraphCall.update_placeholders(graph)
- CustomSubgraphCall.add_output_nodes_transposes(graph)
- CustomSubgraphCall.add_reshapes_for_tf_subgraph_calls(graph)
diff --git a/tools/mo/openvino/tools/mo/middle/CutInputHavingZeroDimFromConcat.py b/tools/mo/openvino/tools/mo/middle/CutInputHavingZeroDimFromConcat.py
deleted file mode 100644
index 647aa5b9d7c151..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/CutInputHavingZeroDimFromConcat.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.concat import Concat
-
-
-class CutInputHavingZeroDimFromConcat(MiddleReplacementPattern):
- """
- This transformation deletes inputs of Concat having zeros in their shapes, if not all inputs have such shapes.
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('concat', dict(type='Concat'))
- ],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- concat_node = match['concat']
- sources_of_ports = [concat_node.in_port(i).get_connection().get_source() for i in concat_node.in_ports()]
- # If 'concat' is ConcatV2 layer from TF, then this layer initially had input 'axis' as the last input.
- # But then this input was deleted and the attribute 'axis' was added. Hence, the last port source can
- # be None in such case.
- sources_of_ports = [s for s in sources_of_ports if s is not None]
-
- input_nodes = [s.node for s in sources_of_ports]
- if not all(n.has_valid('type') for n in input_nodes):
- return
-
- saved_ports = []
- disconnected_ports = []
-
- for port_num, node in enumerate(input_nodes):
- if node.soft_get('type') == 'Const' and len(node.shape) > 1 and any(i == 0 for i in node.shape):
- disconnected_ports.append(port_num)
- else:
- saved_ports.append(port_num)
-
- if not saved_ports or not disconnected_ports:
- return
-
- if len(saved_ports) == 1:
- before_concat = concat_node.in_port(saved_ports[0]).get_connection().get_source()
- concat_node.out_port(0).get_connection().set_source(before_concat)
- return
-
- new_concat_attrs = concat_node.attrs().copy()
- new_concat_attrs['name'] = concat_node.name + '/Concat_'
- new_concat_attrs['in_ports_count'] = len(saved_ports)
- new_concat_node = Concat(graph, attrs=new_concat_attrs).create_node()
-
- for new_port_num, old_port_num in enumerate(saved_ports):
- concat_node.in_port(old_port_num).get_connection().set_destination(new_concat_node.in_port(new_port_num))
-
- for p in disconnected_ports:
- concat_node.in_port(p).disconnect()
-
- concat_node.out_port(0).get_connection().set_source(new_concat_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/DecomposeBias.py b/tools/mo/openvino/tools/mo/middle/DecomposeBias.py
deleted file mode 100644
index 87c73b50f973b7..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/DecomposeBias.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.elementwise import Add
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class DecomposeBias(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('op', dict(kind='op', op=lambda op: op in ['Conv', 'ConvTranspose', 'Conv2D',
- 'Conv3D', 'Conv2DBackpropInput', 'MatMul',
- 'Conv3DBackpropInputV2', 'Convolution',
- 'Deconvolution', 'ConvND', 'Conv2D', 'Deconv2D']))],
- edges=[]
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- if node.has_port('in', 2) and not node.in_port(2).disconnected() and not node.has_and_set('shape_input'):
- bias_name = node.name
- new_node_name = node.name + '/WithoutBiases'
- add = Add(graph, dict(name=bias_name)).create_node()
- rename_nodes([(node, new_node_name), (add, bias_name)])
- node.out_port(0).get_connection().set_source(add.out_port(0))
- node.out_port(0).connect(add.in_port(0))
- node.in_port(2).get_connection().set_destination(add.in_port(1))
-
- bias = add.in_port(1).get_source().node
- if bias.has_valid("type") and bias.type == "Const":
- input_shape = add.in_port(0).data.get_shape()
- if len(input_shape) > 2:
- dims_to_add = len(input_shape) - 2 if graph.graph['layout'] == 'NCHW' else 0
- if dims_to_add > 0:
- reshape = create_op_node_with_second_input(
- graph, Reshape, int64_array([input_shape[1]] + [1] * dims_to_add),
- {'name': node.id + '/Dims'})
- add.in_port(1).get_connection().set_destination(reshape.in_port(0))
- reshape.out_port(0).connect(add.in_port(1))
diff --git a/tools/mo/openvino/tools/mo/middle/DecomposeBidirectionalRNNSequence.py b/tools/mo/openvino/tools/mo/middle/DecomposeBidirectionalRNNSequence.py
deleted file mode 100644
index a199ef8f92ba95..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/DecomposeBidirectionalRNNSequence.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.split import Split
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-
-
-class DecomposeBidirectionalRNNSequence(MiddleReplacementPattern):
- """
- Decomposes bidirectional RNNSequence to forward and reverse RNNSequence ops.
-
- Both initial state are split to two part, two parts of the results are concatenated.
-
- Axis of split/concat is completely defined by ONNX recurrent layers specification.
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.MXNetRNNSequenceNormalize import MXNetRNNSequenceNormalize
- from openvino.tools.mo.middle.ONNXRNNSequenceNormalize import ONNXRNNSequenceNormalize
- return [ONNXRNNSequenceNormalize, MXNetRNNSequenceNormalize]
-
- def pattern(self):
- return dict(
- nodes=[
- ('lstm', dict(kind='op', type='RNNSequence', direction='bidirectional')),
- ('input', dict(kind='data')),
- ('W', dict(kind='data')),
- ('R', dict(kind='data')),
- ('B', dict(kind='data')),
- ],
- edges=[
- ('input', 'lstm', {'in': 0}),
- ('W', 'lstm', {'in': 1}),
- ('R', 'lstm', {'in': 2}),
- ('B', 'lstm', {'in': 3}),
- ]
- )
-
- @staticmethod
- def split_helper(node: Node, index: int, direction: str, axis: int = 0):
- return Op._create_data_node(
- node.graph,
- name=node.name + '/SplittedBiLSTM/{}/'.format(direction),
- attrs={'value': np.take(node.value, [index], axis),
- 'shape': shape_array(np.take(node.value, [index], axis).shape)}
- )
-
- def split_data(self, data: Node):
- """ Helper. Split data node into two part along 0 axis """
- assert len(data.shape) == 3
- assert data.shape[0] == 2
-
- output_data = [Op._create_data_node(data.graph,
- name=data.name + '/SplittedBiLSTM/{}'.format(['forward', 'reverse'][i])) for
- i in [0, 1]]
- split_op = Split(data.graph, dict(name=data.name + '/DecomposedBiLSTM_0', num_splits=2))
- axis_const = Const(data.graph, {'name': data.name + '/DecomposedBiLSTM_0' + '/Split_axis',
- 'value': np.int64(0)}).create_node_with_data()
- return split_op.create_node_with_data([data, axis_const], data_nodes=output_data)
-
- def replace_pattern(self, graph: Graph, match: dict):
- bidirectional_cell = match['lstm']
- new_init_hiddens = self.split_data(bidirectional_cell.in_node(5))
- new_init_cells = self.split_data(bidirectional_cell.in_node(6)) if 6 in bidirectional_cell.in_nodes() \
- else (None, None)
-
- blob_bidirectional_split = lambda node: (
- self.split_helper(node, 0, 'forward'),
- self.split_helper(node, 1, 'reverse')
- )
-
- splitted_W = blob_bidirectional_split(bidirectional_cell.in_node(1))
- splitted_R = blob_bidirectional_split(bidirectional_cell.in_node(2))
- splitted_B = blob_bidirectional_split(bidirectional_cell.in_node(3))
-
- outputs = self.split_bidirectional(
- bidirectional_cell,
- new_init_hiddens,
- new_init_cells,
- splitted_W,
- splitted_R,
- splitted_B,
- )
-
- self.concat_outputs(bidirectional_cell, outputs[0], outputs[1], bidirectional_cell.out_nodes())
-
- @staticmethod
- def get_new_cell(bidirectional_cell: Node, direction: str):
- assert direction in ['forward', 'reverse']
-
- cell_class = Op.get_op_class_by_name(bidirectional_cell.op)
- new_cell = lambda graph, attrs: cell_class(graph, attrs)
- attrs = bidirectional_cell.attrs().copy()
- new_attrs = {
- 'direction': direction,
- 'name': bidirectional_cell.name + '/Split/' + direction,
- }
- attrs.update(new_attrs)
- # split bidirectional activations
- assert 'activations' in attrs
- if attrs['activations'] is not None and len(attrs['activations']) > 1:
- assert len(attrs['activations']) == 2, 'Bidirectional RNN should have 2 activations'
- activations = attrs['activations']
- attrs['activations'] = [activations[0 if direction == 'forward' else 1]]
- return new_cell(bidirectional_cell.graph, attrs)
-
- def split_bidirectional(self,
- bidirectional_cell: Node,
- new_init_hiddens: list,
- new_init_cells: list,
- splitted_W: tuple,
- splitted_R: tuple,
- splitted_B: tuple):
- """
- Split one bidirectional RNNSequence node into 2 one-directional RNNSequence nodes.
-
- All input data nodes should be already prepared; they are
- have 2 in the num_dir dimension.
- """
- all_outputs = []
- for i in [0, 1]:
- direction = ['forward', 'reverse'][i]
- op = self.get_new_cell(bidirectional_cell, direction)
-
- output_data = Op._create_data_node(
- bidirectional_cell.graph,
- name=bidirectional_cell.out_node(0).name + '/Split/' + str(i),
- attrs={'shape': bidirectional_cell.out_node(0).shape.copy()}
- )
-
- assert output_data.shape[1] == 2
- output_data.shape[1] = 1
-
- output_hidden = Op._create_data_node(
- bidirectional_cell.graph,
- name=bidirectional_cell.out_node(1).name + '/Split/' + str(i),
- attrs={'shape': bidirectional_cell.out_node(1).shape.copy()}
- )
-
- assert output_hidden.shape[0] == 2
- output_hidden.shape[0] = 1
-
- data_nodes = [
- output_data,
- output_hidden,
- ]
-
- if bidirectional_cell.op == 'LSTM':
- output_cell = Op._create_data_node(
- bidirectional_cell.graph,
- name=bidirectional_cell.out_node(2).name + '/Split/' + str(i),
- attrs={'shape': bidirectional_cell.out_node(2).shape.copy()}
- )
-
- assert output_cell.shape[0] == 2
- output_cell.shape[0] = 1
-
- data_nodes.append(output_cell)
-
- all_outputs.append(
- op.create_node_with_data(
- inputs=[
- bidirectional_cell.in_node(0),
- splitted_W[i],
- splitted_R[i],
- splitted_B[i],
- None,
- new_init_hiddens[i],
- new_init_cells[i] if bidirectional_cell.op == 'LSTM' else None,
- ],
- data_nodes=data_nodes
- )
- )
- return all_outputs
-
- @staticmethod
- def concat_outputs(bi_rnn, forward_outputs, reverse_outputs, final_outputs):
- """ Concatenates two set of outputs from bidirectiondl RNNSequence nodes """
- concat_ops = [
- Concat(bi_rnn.graph, {
- 'name': bi_rnn.name + '/FinalConcat/Data',
- 'axis': 1,
- 'in_ports_count': 2,
- }),
- Concat(bi_rnn.graph, {
- 'name': bi_rnn.name + '/FinalConcat/HiddenState',
- 'axis': 0,
- 'in_ports_count': 2,
- }),
- Concat(bi_rnn.graph, {
- 'name': bi_rnn.name + '/FinalConcat/CellState',
- 'axis': 0,
- 'in_ports_count': 2,
- })
- ]
-
- bi_rnn.graph.remove_node(bi_rnn.id)
-
- for i in final_outputs:
- concat_ops[i].create_node_with_data(
- [forward_outputs[i], reverse_outputs[i]],
- data_nodes=[final_outputs[i]]
- )
diff --git a/tools/mo/openvino/tools/mo/middle/Deconvolution3rdInputNormalization.py b/tools/mo/openvino/tools/mo/middle/Deconvolution3rdInputNormalization.py
deleted file mode 100644
index 307948afccc07e..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/Deconvolution3rdInputNormalization.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import PermuteAttrs
-
-
-class Deconvolution3rdInputNormalization(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('op', dict(kind='op', type='Deconvolution'))],
- edges=[]
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- if not node.has_port('in', 2) or node.in_port(2).disconnected() or not node.has_and_set('shape_input'):
- return
-
- if node.has_valid('layout') and not node.layout.startswith('NC') and graph.graph['layout'] == 'NCHW':
- input_shape_rank = len(node.in_port(0).data.get_shape())
- permutation = PermuteAttrs.get_nhwc_to_nchw_permutation(input_shape_rank)
-
- data_node = node.in_node(2)
-
- name = node.soft_get('name', node.id) + '/ShapeGather'
- const = Const(graph, {'value': permutation.perm, 'name': name + '/Const',
- 'need_shape_inference': True}).create_node_with_data()
- axis_const = Const(graph, {'value': int64_array(0), 'name': name + '/Axis'}).create_node_with_data()
- gather = Gather(graph, {'name': name,
- 'need_shape_inference': True}).create_node_with_data([data_node, const, axis_const])
- attrs = graph.get_edge_data(data_node.id, node.id, key=0).copy()
-
- graph.add_edge(gather.id, node.id, **attrs)
- graph.remove_edge(data_node.id, node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/DeleteControlFlowEdges.py b/tools/mo/openvino/tools/mo/middle/DeleteControlFlowEdges.py
deleted file mode 100644
index 296d3dbd9f502c..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/DeleteControlFlowEdges.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class DeleteControlFlowEdges(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.PartialInfer import PartialInfer
- return [PartialInfer]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- for u, v, k, attrs in list(graph.edges(keys=True, data=True)):
- if 'control_flow_edge' in attrs and attrs['control_flow_edge']:
- graph.remove_edge(u, v, k)
- log.debug('Removing control flow edge from {} to {}'.format(u, v))
diff --git a/tools/mo/openvino/tools/mo/middle/DeleteNotExecutable.py b/tools/mo/openvino/tools/mo/middle/DeleteNotExecutable.py
deleted file mode 100644
index 2a2166838e2cd0..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/DeleteNotExecutable.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class DeleteNotExecutable(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.TensorIteratorConditionChecker import ConditionChecks
- return [ConditionChecks]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- nodes_to_remove = set()
- for node_name, node_attrs in list(graph.nodes(data=True)):
- if node_attrs['kind'] == 'data' and 'executable' in node_attrs and not node_attrs['executable']:
- [nodes_to_remove.add(op) for op, _ in graph.in_edges(node_name)]
- nodes_to_remove.add(node_name)
- log.debug('Removing the following not executable nodes: {}'
- ''.format('\n'.join(sorted(map(str, nodes_to_remove)))))
- graph.remove_nodes_from(nodes_to_remove)
diff --git a/tools/mo/openvino/tools/mo/middle/DilatedConvolution.py b/tools/mo/openvino/tools/mo/middle/DilatedConvolution.py
deleted file mode 100644
index 0e248fe6c466c6..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/DilatedConvolution.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_insert
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-
-
-class DilatedConvolutionConverter(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[
- ('conv', dict(kind='op', op=lambda value: value in ['Conv2D', 'DepthwiseConv2dNative', 'Conv3D'])),
- ('space_to_batch', dict(kind='op', op='SpaceToBatch')),
- ('batch_to_space', dict(kind='op', op='BatchToSpace')),
- ('stb_pad_begin', dict(kind='op', op='Const')),
- ('stb_pad_end', dict(kind='op', op='Const')),
- ('bts_crop_begin', dict(kind='op', op='Const')),
- ('bts_crop_end', dict(kind='op', op='Const')),
- ('input', dict(kind='data')),
- ('output', dict(kind='data')),
- ('conv_output', dict(kind='data')),
- ('stb_output', dict(kind='data')),
- ('stb_bs', dict(kind='data')),
- ('stb_pad_begin_d', dict(kind='data')),
- ('stb_pad_end_d', dict(kind='data')),
- ('bts_bs', dict(kind='data')),
- ('bts_crop_begin_d', dict(kind='data')),
- ('bts_crop_end_d', dict(kind='data'))
- ],
- edges=[
- ('input', 'space_to_batch', {'in': 0}),
- ('stb_bs', 'space_to_batch', {'in': 1}),
- ('stb_pad_begin', 'stb_pad_begin_d', {'in': 0}),
- ('stb_pad_begin_d', 'space_to_batch', {'in': 2}),
- ('stb_pad_end', 'stb_pad_end_d', {'in': 0}),
- ('stb_pad_end_d', 'space_to_batch', {'in': 3}),
- ('space_to_batch', 'stb_output', {'out': 0}),
- ('stb_output', 'conv', {'in': 0}),
- ('conv', 'conv_output', {'out': 0}),
- ('conv_output', 'batch_to_space', {'in': 0}),
- ('bts_bs', 'batch_to_space', {'in': 1}),
- ('bts_crop_begin', 'bts_crop_begin_d', {'in': 0}),
- ('bts_crop_begin_d', 'batch_to_space', {'in': 2}),
- ('bts_crop_end', 'bts_crop_end_d', {'in': 0}),
- ('bts_crop_end_d', 'batch_to_space', {'in': 3}),
- ('batch_to_space', 'output', {'out': 0}),
- ])
-
- def replace_pattern(self, graph: Graph, match: dict):
- conv = match['conv']
- stb = match['space_to_batch']
- bts = match['batch_to_space']
-
- block_size = match['stb_bs']
-
- conv.in_port(0).disconnect()
- stb.in_port(0).get_connection().set_destination(conv.in_port(0))
- bts.out_port(0).get_connection().set_source(conv.out_port(0))
-
- conv.dilation[conv.spatial_dims] = block_size.value[conv.spatial_dims]
-
- pad_begin = match['stb_pad_begin_d'].value - match['bts_crop_begin_d'].value
- pad_end = match['stb_pad_end_d'].value - match['bts_crop_end_d'].value
- conv.pad[conv.spatial_dims] = [[pad_begin[x], pad_end[x]] for x in conv.spatial_dims]
- conv['auto_pad'] = None
-
-
-class DilatedConvolution1DConverter(MiddleReplacementPattern):
- """
- Transformation looks for a pattern that TF generates for a 1D dilated convolution with help of SpaceToBatch (STB)
- and BatchToSpace (BTS). The transformation removes STB and BTS operations and updates the Convolution node
- attributes with a dilation values.
- """
- enabled = True
- force_clean_up = True
- force_shape_inference = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[
- ('conv', dict(kind='op', op=lambda value: value in ['Conv2D', 'DepthwiseConv2dNative'])),
- ('space_to_batch', dict(kind='op', op='SpaceToBatch')),
- ('unsqueeze', dict(kind='op', op='Unsqueeze')),
- ('squeeze', dict(kind='op', op='Squeeze')),
- ('batch_to_space', dict(kind='op', op='BatchToSpace')),
- ('input_data', dict(kind='data')),
- ('output', dict(kind='data')),
- ('unsqueeze_output', dict(kind='data')),
- ('squeeze_output', dict(kind='data')),
- ('conv_output', dict(kind='data')),
- ('stb_output', dict(kind='data')),
- ('stb_bs', dict(kind='data')),
- ('unsqueeze_dim', dict(kind='data')),
- ('stb_pad', dict(kind='data')),
- ('bts_bs', dict(kind='data')),
- ('bts_crop', dict(kind='data'))
- ],
- edges=[
- ('input_data', 'space_to_batch', {'in': 0}),
- ('stb_bs', 'space_to_batch', {'in': 1}),
- ('stb_pad', 'space_to_batch', {'in': 2}),
- ('space_to_batch', 'stb_output', {'out': 0}),
- ('stb_output', 'unsqueeze', {'in': 0}),
- ('unsqueeze_dim', 'unsqueeze', {'in': 1}),
- ('unsqueeze', 'unsqueeze_output', {'out': 0}),
- ('unsqueeze_output', 'conv', {'in': 0}),
- ('conv', 'conv_output', {'out': 0}),
- ('conv_output', 'squeeze', {'in': 0}),
- ('squeeze', 'squeeze_output', {'out': 0}),
- ('squeeze_output', 'batch_to_space', {'in': 0}),
- ('bts_bs', 'batch_to_space', {'in': 1}),
- ('bts_crop', 'batch_to_space', {'in': 2}),
- ('batch_to_space', 'output', {'out': 0}),
- ])
-
- def swap_pad_and_unsqueeze(self, pad: Node, unsqueeze: Node):
- # insert additional items to the pads in the position specified by the Unsqueeze axis
- unsqueeze_axis = unsqueeze.in_port(1).data.get_value()
- for port_id in [1, 2]:
- current_value = pad.in_port(port_id).get_connection().data.get_value()
- new_value_node = Const(pad.graph, {'name': pad.soft_get('name', pad.id) + '/value_{}'.format(port_id),
- 'value': shape_insert(current_value, unsqueeze_axis.item(), 0),
- 'override_output_shape': True}).create_node()
- pad.in_port(port_id).disconnect()
- pad.in_port(port_id).connect(new_value_node.out_port(0))
-
- # swap Pad and Unsqueeze layers
- unsqueeze.in_port(0).disconnect()
- pad.in_port(0).get_connection().set_destination(unsqueeze.in_port(0))
- unsqueeze.out_port(0).get_connection().set_source(pad.out_port(0))
- unsqueeze.out_port(0).connect(pad.in_port(0))
-
- # output shapes of Pad and Unsqueeze changed so need to recalculate them
- pad['override_output_shape'] = True
- unsqueeze['override_output_shape'] = True
-
- def replace_pattern(self, graph: Graph, match: dict):
- conv = match['conv']
- stb = match['space_to_batch']
- bts = match['batch_to_space']
- unsqueeze = match['unsqueeze']
- squeeze = match['squeeze']
-
- if len(conv.in_port(0).data.get_shape()) != 4:
- log.debug('The convolution node "{}" input is not 4D'.format(conv.soft_get('name', conv.id)))
- return
-
- block_size = stb.in_port(1).data.get_value()
- if len(block_size) != 1:
- log.debug('The block size must contain 1 element')
- return
-
- unsqueeze_dims = mo_array(unsqueeze.in_port(1).data.get_value())
- if unsqueeze_dims.size != 1 or unsqueeze_dims.item() != 1:
- log.debug('The Unsqueeze dimension is not equal to 1')
- return
-
- # remove SpaceToBatch and BatchToSpace operations
- unsqueeze.in_port(0).get_connection().set_source(stb.in_port(0).get_source())
- bts.out_port(0).get_connection().set_source(squeeze.out_port(0))
- stb.in_port(0).disconnect()
- bts.in_port(0).disconnect()
-
- conv.dilation[conv.spatial_dims] = [1, block_size.item()]
-
- pad = match['stb_pad'].value - match['bts_crop'].value
- # update the pad value by inserting one zero element since the STB node consumes 3D tensor and have 1D pad value
- # but the successive convolution consumes 4D tensor
- pad = np.insert(pad, 0, 0, 0)
- conv.pad[conv.spatial_dims] = [[pad[x][0], pad[x][1]] for x in range(len(pad))]
- conv['auto_pad'] = None
-
- # the intermediate shapes will be changed after nodes relocation so mark nodes accordingly
- input_producer = unsqueeze.in_port(0).get_source().node
- input_producer['need_shape_inference'] = True
- input_producer['override_output_shape'] = True
- unsqueeze['need_shape_inference'] = True
- unsqueeze['override_output_shape'] = True
- conv['need_shape_inference'] = True
- conv['override_output_shape'] = True
-
- # if the input to SpaceToBatch is a Pad layer then we can swap it with Unsqueeze so the Pad will be fused to a
- # Convolution layer further in the pipeline
- if input_producer.soft_get('type') == 'Pad':
- self.swap_pad_and_unsqueeze(input_producer, unsqueeze)
diff --git a/tools/mo/openvino/tools/mo/middle/EltwiseChecker.py b/tools/mo/openvino/tools/mo/middle/EltwiseChecker.py
deleted file mode 100644
index 0a80f6f8cbae10..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/EltwiseChecker.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_insert
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import get_tensor_in_port, get_value_in_port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class EltwiseChecker(MiddleReplacementPattern):
- """
- Checks if element-wise operation can be converted to ScaleShift or not:
- decision gets made by verifying constant input value shape is like 1,N,1,1
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.EltwiseInputReshape import Eltwise1DInputReshape
- return [Eltwise1DInputReshape]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- @staticmethod
- def set_flags_to_false(node: Node, flags: list):
- for flag in flags:
- node[flag] = False
-
- def mark_eltwise_node(self, node, feature_channel=None):
- tensor_port, value_port = get_tensor_in_port(node), get_value_in_port(node)
- if tensor_port is None or value_port is None:
- self.set_flags_to_false(node, ['can_be_fused', 'can_be_scaleshift'])
- return
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- if len(connected_in_ports) != 2:
- return
-
- tensor_shape = tensor_port.data.get_shape()
- out_shape = node.out_port(0).data.get_shape()
- assert tensor_shape is not None and out_shape is not None
- if not np.array_equal(tensor_shape, out_shape):
- # ScaleShift operation doesn't support broadcasting
- self.set_flags_to_false(node, ['can_be_fused', 'can_be_scaleshift'])
- return
-
- value_shape = value_port.data.get_shape()
- assert value_shape is not None
- assert len(value_shape) <= len(tensor_shape), \
- "No broadcasting was done for elementwise node {} due to previous checks in EltwiseChecker class. " \
- "But constant input rank is larger than tensor input rank, that is inconsistent".format(node.name)
-
- # if both tensors are 0D they cannot be converted to scaleshift
- if len(tensor_shape) == 0 and len(value_shape) == 0:
- self.set_flags_to_false(node, ['can_be_scaleshift'])
- return
-
- broadcasted_value_shape = shape_insert(value_shape, 0, [1] * (len(tensor_shape) - len(value_shape)))
-
- feature_dim = min(1, tensor_shape.size - 1) if node.graph.graph['layout'] == 'NCHW' else -1
- if feature_channel is not None:
- feature_dim = feature_channel
- ones = np.ones(len(tensor_shape), dtype=np.float32)
- possible_shape = ones.copy()
- np.put(possible_shape, feature_dim, tensor_shape.item(feature_dim))
-
- if not np.array_equal(broadcasted_value_shape, ones) and \
- not np.array_equal(broadcasted_value_shape, possible_shape):
- # ScaleShift weights should have [1,C,1,1]-like or [1,1,1,1]-like shape
- self.set_flags_to_false(node, ['can_be_fused', 'can_be_scaleshift'])
- return
-
- if len(tensor_shape) not in [2, 4, 5]:
- # ScaleShift operation is supported for 2D, 4D or 5D tensor inputs
- self.set_flags_to_false(node, ['can_be_scaleshift'])
- return
-
- def find_and_replace_pattern(self, graph: Graph, feature_channel=None):
- for node in graph.get_op_nodes(is_eltwise=True):
- self.mark_eltwise_node(node)
diff --git a/tools/mo/openvino/tools/mo/middle/EltwiseInputReshape.py b/tools/mo/openvino/tools/mo/middle/EltwiseInputReshape.py
deleted file mode 100644
index 9b2503967a23b2..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/EltwiseInputReshape.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import get_features_dim, shape_for_layout
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_insert, is_fully_defined
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class Eltwise1DInputReshape(MiddleReplacementPattern):
- """
- Inserts Reshape before 1-D input to Eltwise if another input of Eltwise is multi-dimensional tensor with the
- same feature size as 1-D input
-
- Replacer is useful in cases of layout change in MO (for example NHWC-> NCHW translation of TensorFlow models)
-
- Example:
- Eltwise Mul operation in TF multiplies Tensors by feature dimension with shapes [1,375,500,24] and [24].
- After layout change in MO Eltwise Mul have input shapes [1,24,375,500] and [24]. It is a problem (500!=24).
- We have to insert Reshape layer for Tensor with [24] shape to correspond the feature dimension of
- Tensor [1,24,375,500] shape
-
- change of graph.graph['layout'] may cause an issue
- change in re-layout function: convert_nhwc_to_nchw(graph) may cause an issue
- """
- enabled = False
-
- def find_and_replace_pattern(self, graph: Graph):
- layout = graph.graph['layout']
- for eltwise_op_node in graph.get_op_nodes(is_eltwise=True):
- out_shape = eltwise_op_node.out_port().data.get_shape()
- if 4 <= len(out_shape) <= 5:
- out_features = out_shape[get_features_dim(layout, len(out_shape))]
- for port, node in eltwise_op_node.in_nodes().items():
- if len(node.shape) != len(out_shape) and len(node.shape) == 1 and out_features == node.shape[0]:
- new_shape = shape_for_layout(layout, batch=1, features=out_features, height=1, width=1,
- depth=1 if len(out_shape) == 5 else None)
- dim_const = Const(graph, {'value': new_shape, 'name': node.id + '/Dim'}).create_node()
- reshape_op = Reshape(graph, attrs={'dim': new_shape, 'name': node.id + '/Broadcast'}).create_node()
-
- eltwise_op_node.in_port(port).get_source().node.out_port(0).get_connection().set_destination(reshape_op.in_port(0))
- reshape_op.in_port(1).connect(dim_const.out_port(0))
-
- reshape_op.out_port(0).connect(eltwise_op_node.in_port(port))
-
-
-def compute_unsqueeze_map_for_eltwise(eltwise_node: Node):
- '''
- The function computes a map of unsqueeze_dims for each producer of eltwise node.
- These unsqueeze_dims are needed to normalize input shapes of eltwise node.
- '''
- eltwise_shape = eltwise_node.out_port(0).data.get_shape()
- max_dims = max(
- [len(port.data.get_shape()) for port in eltwise_node.in_ports().values() if port.data.get_shape() is not None])
- axis = eltwise_node.soft_get('axis', None)
- unsqueeze_dims_map = {}
- for consumer_port in eltwise_node.in_ports().values():
- producer_port = consumer_port.get_source()
- producer_shape = producer_port.data.get_shape()
- unsqueeze_dims = int64_array([])
-
- # 1. Compute unsqueeze dimensions in the tail
- if len(producer_shape) != max_dims and len(producer_shape) > 0 and axis is not None:
- num_unsqueeze_dims = max_dims - axis - len(producer_shape)
- if num_unsqueeze_dims > 0:
- unsqueeze_dims = np.arange(len(producer_shape), len(producer_shape) + num_unsqueeze_dims,
- dtype=np.int64)
-
- # 2. Compute unsqueeze dimensions in the head
- unsqueeze_dims_head = np.arange(len(eltwise_shape) - len(producer_shape) - len(unsqueeze_dims), dtype=np.int64)
-
- # Pay attention that unsqueeze dims order makes sense
- # since shape is normalized in the tail first and after in the head
- unsqueeze_dims = np.concatenate((unsqueeze_dims, unsqueeze_dims_head))
- unsqueeze_dims_map[producer_port] = unsqueeze_dims
-
- return unsqueeze_dims_map
-
-
-def normalize_eltwise_inputs(graph: Graph):
- '''
- The function normalizes input shapes for eltwise nodes.
- In the first step the function gets to know which shapes/unsqueeze dims for inputs are required for normalization.
- In the second step the function inserts Unsqueeze nodes between non-normalized inputs and eltwise nodes.
- '''
- # Generate a map for producers of eltwise nodes with non-normalized shapes
- # and in this map every producer has another map that reflects normalized shape
- # to a list of eltwise consumers
- mapping = {}
- for eltwise_node in graph.get_op_nodes(is_eltwise=True):
- unsqueeze_dims_map = compute_unsqueeze_map_for_eltwise(eltwise_node)
- for consumer_port in eltwise_node.in_ports().values():
- producer_port = consumer_port.get_source()
- unsqueeze_dims = unsqueeze_dims_map[producer_port]
- if unsqueeze_dims is not None and len(unsqueeze_dims) > 0:
- unsqueeze_dims = tuple([x for x in unsqueeze_dims])
- if producer_port not in mapping:
- mapping.update({producer_port: {unsqueeze_dims: [consumer_port]}})
- elif unsqueeze_dims not in mapping[producer_port]:
- mapping[producer_port].update({unsqueeze_dims: [consumer_port]})
- else:
- mapping[producer_port][unsqueeze_dims].append(consumer_port)
-
- # Walk through each produced in the map and insert Unsqueeze nodes between a producer and eltwise nodes
- for producer_port in mapping.keys():
- producer_node = producer_port.node
- for unsqueeze_dims in mapping[producer_port].keys():
- unsqueeze_name = producer_node.soft_get('name', producer_node.id) + '/EltwiseUnsqueeze'
- unsqueeze_node = create_op_with_const_inputs(graph, Unsqueeze, {1: int64_array(list(unsqueeze_dims))},
- {'name': unsqueeze_name})
- unsqueeze_node.in_port(0).connect(producer_port)
-
- # Insert Unsqueeze with determined unsqueeze dimensions between the current producer and eltwise node
- for consumer_port in mapping[producer_port][unsqueeze_dims]:
- consumer_port.connect(unsqueeze_node.out_port(0))
-
- # The shape and value adjustments must be explicitly done within the transformation
- # since the transformation is called from Fusing transformation that excludes
- # automatic call of shape inference pass
- producer_port_value = producer_port.data.get_value()
- producer_port_shape = producer_port.data.get_shape()
- new_shape = producer_port_shape.copy()
- for unsqueeze_dim in unsqueeze_dims:
- new_shape = shape_insert(new_shape, unsqueeze_dim, 1)
- if producer_port_value is not None and is_fully_defined(new_shape):
- unsqueeze_node.out_port(0).data.set_value(np.reshape(producer_port_value, new_shape))
- else:
- unsqueeze_node.out_port(0).data.set_shape(new_shape)
diff --git a/tools/mo/openvino/tools/mo/middle/FakeSplitOutputs.py b/tools/mo/openvino/tools/mo/middle/FakeSplitOutputs.py
deleted file mode 100644
index 9e86d406890a67..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/FakeSplitOutputs.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.op import Op
-
-
-class AddFakeOutputsToSplit(MiddleReplacementPattern):
- """
- Adding fake outputs for Split nodes in case when it has less output ports than split parts:
- This pass:
- 1. Looking for Split operations
- 2. Check that Split have less connected output ports than split parts
- 3. For every missed port adding this port, Output operation to this port
- """
-
- enabled = True
-
- def run_after(self):
- return [TensorIteratorMerge]
-
- def find_and_replace_pattern(self, graph: Graph):
- for split_node in graph.get_op_nodes(op='Split'):
- Op.normalize_outputs(split_node)
-
-
-class AddFakeOutputsToVariadicSplit(MiddleReplacementPattern):
- """
- Adding fake outputs for VariadicSplit nodes in case when it has less output ports than split parts:
- This pass:
- 1. Looking for VariadicSplit operations
- 2. Check that VariadicSplit have less connected output ports than split parts
- 3. For every missed port adding this port, Output operation to this port
- """
-
- enabled = True
-
- def run_after(self):
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(kind='op', op='VariadicSplit'))],
- edges=[],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- axis = node.in_port(1).data.get_value()
- size_splits = node.in_port(2).data.get_value()
-
- output_shape = sum([node.out_node(port).shape[axis] for port in node.out_nodes()])
-
- if output_shape == node.in_port(0).data.get_shape()[axis]:
- return
-
- if not node.has_valid('out_ports_count'):
- node['out_ports_count'] = len(size_splits)
-
- Op.normalize_outputs(node)
diff --git a/tools/mo/openvino/tools/mo/middle/FuseReshapesSequence.py b/tools/mo/openvino/tools/mo/middle/FuseReshapesSequence.py
deleted file mode 100644
index 35fd4cfdeed3e4..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/FuseReshapesSequence.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart, MiddleFinish
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.passes.fusing.helpers import get_next_operation
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class FuseReshapesSequence(MiddleReplacementPattern):
- """
- Finds sequence of Reshapes operations and merge them to a single Reshape operation.
- """
- # TODO the pass should be extended for Reshape with special symbols "0" or "-1"
- # For example: 1,100 -> Reshape(2,5,10) -> 2,5,10 -> Reshape(0,10,-1) -> 2,10,5
-
- enabled = True
- run_not_recursively = True # non-unified data nodes view in TI body (no Const ops, bare data node)
-
- def run_before(self):
- return [PostMiddleStart]
-
- def run_after(self):
- return [MiddleFinish]
-
- def find_and_replace_pattern(self, graph: Graph):
- reshape_nodes = graph.get_op_nodes(type='Reshape')
- for node in reshape_nodes:
- if not graph.has_node(node.id):
- # the Reshape node has been removed in the previous iteration
- continue
- if len(node.out_port(0).get_destinations()) == 1:
- log.debug('First phase for Reshape: {}'.format(node.soft_get('name')))
-
- next_op = get_next_operation(node)[0]
- log.debug('second node: id={}, type={}'.format(next_op.soft_get('id'), next_op.soft_get('type')))
- if next_op.has_valid('type') and next_op.type == 'Reshape':
- dim_value = next_op.in_port(1).data.get_value()
- if dim_value is None or 0 in dim_value or -1 in dim_value:
- # we do not fuse reshape sequences with special symbols: 0, -1
- continue
-
- # Detected Reshape1 --> data --> Reshape2 pattern without side edges. Remove Reshape1
- log.debug('Second phase for Reshape: {}'.format(node.soft_get('name')))
- remove_op_node_with_data_node(graph, node)
-
-
-class FuseReshapesSequenceKaldi(MiddleReplacementPattern):
- """
- Finds sequence of Reshapes operations of special type and remove them. It is enabled for Kaldi because
- such type of reshapes are created in add_reshape_around_convolution/pooling
- data(b, t, w, c) -> Reshape(0, -1) -> data(b, t*w*c) -> Reshape(br, tr, wr, cr)
- Check, that
- * br = b - taken from shape before Reshape as is;
- * tr = t and wr = w - that constants used in the second reshape is the same in shape before the first Reshape
- """
-
- enabled = True
- run_not_recursively = True # non-unified data nodes view in TI body (no Const ops, bare data node)
- graph_condition = [lambda graph: graph.graph['fw'] == 'kaldi']
-
- def run_before(self):
- from openvino.tools.mo.middle.MergeNodesPermutations import MergeNodesPermutations
- return [MergeNodesPermutations]
-
- def run_after(self):
- return [FuseReshapesSequence]
-
- def pattern(self):
- return dict(
- nodes=[
- ('reshape_in_dims', dict(kind='op', op='Const')),
- ('reshape_in_dims_d', dict(kind='data')),
- ('reshape_in', dict(kind='op', op='Reshape', special_zero=True)),
- ('reshape_in_d', dict(kind='data')),
- ('shape', dict(kind='op', op='ShapeOf')),
- ('shape_d', dict(kind='data')),
- ('gather_in_1', dict(kind='op', op='Const')),
- ('gather_in_1_d', dict(kind='data')),
- ('gather_in_2', dict(kind='op', op='Const')),
- ('gather_in_2_d', dict(kind='data')),
- ('gather_batch', dict(kind='op', op='Gather')),
- ('gather_batch_d', dict(kind='data')),
- ('time_dim', dict(kind='op', op='Const')),
- ('time_dim_d', dict(kind='data')),
- ('concat_dims', dict(kind='op', op='Concat')),
- ('concat_dims_d', dict(kind='data')),
- ('reshape_out', dict(kind='op', op='Reshape')),
- ],
- edges=[('reshape_in_dims', 'reshape_in_dims_d'), ('reshape_in_dims_d', 'reshape_in', {'in': 1}),
- ('reshape_in', 'reshape_in_d'), ('reshape_in_d', 'reshape_out', {'in': 0}),
- ('reshape_in_d', 'shape'), ('shape', 'shape_d'),
- ('shape_d', 'gather_batch', {'in': 0}),
- ('gather_in_1', 'gather_in_1_d'), ('gather_in_1_d', 'gather_batch', {'in': 1}),
- ('gather_in_2', 'gather_in_2_d'), ('gather_in_2_d', 'gather_batch', {'in': 2}),
- ('gather_batch', 'gather_batch_d'), ('gather_batch_d', 'concat_dims', {'in': 0}),
- ('time_dim', 'time_dim_d'), ('time_dim_d', 'concat_dims', {'in': 1}),
- ('concat_dims', 'concat_dims_d'), ('concat_dims_d', 'reshape_out', {'in': 1})
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- reshape_in = match['reshape_in']
-
- log.debug('First phase for Reshape: {}'.format(reshape_in.soft_get('name')))
- in_shape = reshape_in.in_port(0).get_source().data.get_shape()
- if not is_fully_defined(in_shape[1:]):
- return
-
- reshape_in_dims = match['reshape_in_dims']
- if not np.all(reshape_in_dims.out_port(0).data.get_value() == [0, -1]):
- return
-
- gather_in_1 = match['gather_in_1']
- if not np.all(gather_in_1.out_port(0).data.get_value() == [0]):
- return
-
- gather_in_2 = match['gather_in_2']
- if not np.all(gather_in_2.out_port(0).data.get_value() == [0]):
- return
-
- reshape_out = match['reshape_out']
- log.debug('second child_node: id={}, type={}'.format(reshape_out.soft_get('id'), reshape_out.soft_get('type')))
-
- concat_dims_node = match['concat_dims']
- shapeof_node = match['shape']
-
- # check that t and w is the same as before the first Reshape
- t_node = match['time_dim']
- w_node = concat_dims_node.in_port(3).get_source().node
- const_dim_2 = 3
- if w_node.op != 'Const':
- w_node = concat_dims_node.in_port(2).get_source().node
- const_dim_2 = 2
- if w_node.op != 'Const' or \
- not is_fully_defined(t_node.out_port(0).data.get_value()) or \
- not is_fully_defined(w_node.out_port(0).data.get_value()) or \
- not np.all(t_node.out_port(0).data.get_value() == [in_shape[1]]) or \
- not np.all(w_node.out_port(0).data.get_value() == [in_shape[const_dim_2]]):
- return
-
- # Detected Reshape1 --> data --> Reshape2 pattern without side edges. Remove Reshape1
- log.debug('Second phase for Reshape: {}'.format(reshape_in.soft_get('name')))
- shapeof_node.in_port(0).disconnect()
- concat_dims_node.out_port(0).disconnect()
- remove_op_node_with_data_node(graph, reshape_in)
- remove_op_node_with_data_node(graph, reshape_out)
diff --git a/tools/mo/openvino/tools/mo/middle/FusedBatchNormNonConstant.py b/tools/mo/openvino/tools/mo/middle/FusedBatchNormNonConstant.py
deleted file mode 100644
index 47d150e59182b0..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/FusedBatchNormNonConstant.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.elementwise import Mul, Add, Pow
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-
-
-class FusedBatchNormNonConstant(MiddleReplacementPattern):
- """
- Replaces FusedBatchNorm(input, beta, gamma, mean, variance) with non-constant mean and variance,
- but with constant beta and gamma to a sub-expression consisting of a combinatin of Eltwise layers and ScaleShift.
- """
-
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def pattern(self):
- return dict(
- nodes=[
- ('op', dict(kind='op', op=lambda op: op in ['FusedBatchNorm', 'FusedBatchNormV2',
- 'FusedBatchNormV3']))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- node = match['op']
- if (node.data_format != b'NHWC' or
- len(node.in_nodes()) != 5 or
- node.in_node(0).value is not None or # input
- node.in_node(1).value is None or # scale
- node.in_node(2).value is None or # offset
- node.in_node(3).value is not None or # mean
- node.in_node(4).value is not None or # variance
- node.in_node(1).value.ndim != 1 or
- node.in_node(2).value.ndim != 1):
- return
-
- scale_mul = Mul(graph, dict(name=node.name + '/scale_mul_'))
- shift_add = Add(graph, dict(name=node.name + '/shift_add_'))
- mean_add = Add(graph, dict(name=node.name + '/mean_add_'))
- variance_mul = Mul(graph, dict(name=node.name + '/variance_mul_'))
-
- neg_const = Const(graph, dict(value=mo_array(-1), name=node.name + '/mean_negate_'))
- mean_negate = Mul(graph, dict(name=node.name + '/mean_negate_'))
- mean_arg = mean_add.create_node_with_data([
- node.in_node(0),
- mean_negate.create_node_with_data([node.in_node(3),
- neg_const.create_node_with_data()
- ])])
-
- shift_const = Const(graph, dict(value=node.eps, name=node.name + '/variance_denom_shift_const_'))
- power_const = Const(graph, dict(value=-0.5, name=node.name + '/variance_denom_power_const_'))
- variance_denom_shift = Add(graph, dict(name=node.name + '/variance_denom_shift_'))
- variance_denom_power = Pow(graph, dict(name=node.name + '/variance_denom_power_'))
- variance_arg = variance_mul.create_node_with_data([
- mean_arg,
- variance_denom_power.create_node_with_data([
- variance_denom_shift.create_node_with_data([node.in_node(4), shift_const.create_node_with_data()]),
- power_const.create_node_with_data()]
- )])
-
- shift_add.create_node_with_data([
- scale_mul.create_node_with_data([
- variance_arg,
- node.in_node(1)]),
- node.in_node(2)],
- data_nodes=node.out_node())
-
- node.graph.remove_node(node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/FusedBatchNormTraining.py b/tools/mo/openvino/tools/mo/middle/FusedBatchNormTraining.py
deleted file mode 100644
index cf27c773e82319..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/FusedBatchNormTraining.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input, create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-
-
-class FusedBatchNormTraining(MiddleReplacementPattern):
- """
- Transformation looks for the BatchNorm layers in training mode and does the following:
- 1. Fuses batch dimension with one of the spatial dimensions of the input to BatchNorm because batch normalization is
- performed over batch dimension also (per channel(features) dimension).
- 2. Inserts MVN layer.
- 3. Reshape MVN output back to the original one.
- """
- enabled = True
- replacement_id = "Fused_Batch_Norm_is_training_true"
- force_shape_inference = True
- force_clean_up = True
- # transformation works for the NHWC layout because transformation inserts Reshape to fuse N and H dimensions
- graph_condition = [lambda graph: graph.graph['layout'] == 'NHWC']
-
- def pattern(self):
- return dict(
- nodes=[
- ('op', dict(kind='op', op=lambda op: op in ['FusedBatchNorm', 'FusedBatchNormV2', 'FusedBatchNormV3'],
- is_training=True))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- node = match['op']
- node_name = node.soft_get('name', node.id)
- node.is_training = False
-
- shape = node.in_port(1).data.get_shape()
- assert shape is not None, 'The shape of scale input of the BatchNorm node {} is not defined'.format(node.name)
-
- bn_mean = Const(graph, {'name': node_name + '/mean', 'value': np.zeros(shape, dtype=np.float32),
- 'override_output_shape': True}).create_node()
- bn_std = Const(graph, {'name': node_name + '/std', 'value': np.ones(shape, dtype=np.float32),
- 'override_output_shape': True}).create_node()
- node.in_port(3).get_connection().set_source(bn_mean.out_port(0))
- node.in_port(4).get_connection().set_source(bn_std.out_port(0))
-
- # save the original shape
- original_shape = Shape(graph, {'name': node.in_port(0).get_source().node.soft_get('name')}).create_node()
- original_shape.in_port(0).connect(node.in_port(0).get_source())
-
- input_rank = len(node.in_port(0).data.get_shape())
- rng = create_op_with_const_inputs(graph, Range,
- {0: int64_array(1), 1: int64_array(input_rank - 1), 2: int64_array(1)},
- {'name': node_name + '/Range', 'output_type': np.int64})
- mvn = MVN(graph, {'name': node_name + '/mvn_', 'eps': node.soft_get('eps', 1e-6), 'eps_mode': 'inside_sqrt',
- 'normalize_variance': 1, 'override_output_shape': True}).create_node()
- node.in_port(0).get_connection().insert_node(mvn)
- mvn.in_port(1).connect(rng.out_port(0))
-
- reshape_4d = create_op_node_with_second_input(graph, Reshape, int64_array([1, -1, 0, 0]),
- {'override_output_shape': True,
- 'name': node_name + '/fused_batch_and_channels'})
- mvn.in_port(0).get_connection().insert_node(reshape_4d)
-
- # restore original shape
- reshape_back = Reshape(graph, {'name': node_name + '/restore_shape',
- 'override_output_shape': True}).create_node()
- reshape_back.in_port(1).connect(original_shape.out_port(0))
- mvn.out_port(0).get_connection().insert_node(reshape_back)
diff --git a/tools/mo/openvino/tools/mo/middle/GRURNNSequenceToTensorIterator.py b/tools/mo/openvino/tools/mo/middle/GRURNNSequenceToTensorIterator.py
deleted file mode 100644
index 00ed6afdf3e44b..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/GRURNNSequenceToTensorIterator.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.tensor_iterator import TensorIterator
-from openvino.tools.mo.front.common.partial_infer.utils import shape_delete
-from openvino.tools.mo.graph.graph import Graph, add_opoutput
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class GRUAndRNNToTensorIterator(MiddleReplacementPattern):
- """ Converts normalized RNNSequence with op=GRU/RNN to TensorIterator.
-
- Normalized RNNSequence means that it should be processed by
- RNNSequenceNormalize transform that ensures its strict form.
-
- This transformation builds an alternative sub-graph for GRUSequence
- with TensorIterator connected in the same way as an original GRUSequence
- node and with internal body represented as GRUCell op node with necessary
- squeezes and unsqueezes around.
- """
-
- enabled = True
- id = 'gru_and_rnn_to_tensor_iterator'
-
- def run_after(self):
- from openvino.tools.mo.middle.RNNSequenceNormalizeToIE import RNNSequenceNormalize
- return [RNNSequenceNormalize]
-
- def run_before(self):
- from openvino.tools.mo.middle.permute_tensor_iterator import TransposeTensorIteratorLSTM
- return [TransposeTensorIteratorLSTM]
-
- def pattern(self):
- return dict(
- nodes=[
- ('rnn_layer', dict(kind='op', type='RNNSequence')),
- ('input', dict(kind='data')),
- ('weights', dict(kind='data')),
- ('biases', dict(kind='data')),
- # don't capture optional input initial states here
- ('output', dict(kind='data')),
- # don't capture optional output last states here
- ],
- edges=[
- ('input', 'rnn_layer', {'in': 0}),
- ('weights', 'rnn_layer', {'bin': 'weights', 'in': 1}),
- ('biases', 'rnn_layer', {'bin': 'biases', 'in': 2}),
- ('rnn_layer', 'output', {'out': 0}),
- ]
- )
-
- @staticmethod
- def get_rnn_cell(name: str):
- op = Op.get_op_class_by_name(name + 'Cell')
- return op
-
- def replace_pattern(self, graph: Graph, match: dict):
- if match['rnn_layer']['op'] == 'LSTM':
- return
-
- rnn_layer = match['rnn_layer']
-
- # Build TensorIterator body first
- body = Graph(name=rnn_layer.name + '/sub_graph')
- body.graph = graph.graph
-
- # 1. Input squeeze Reshape
- inputs = [Op._create_data_node(body, rnn_layer.name + '/inport/' + str(inp),
- {'shape': rnn_layer.in_node(inp).shape.copy(),
- 'value': rnn_layer.in_node(inp).value.copy()
- if rnn_layer.in_node(inp).value is not None and inp in [1, 2] else None})
- for inp in [0, 4, 1, 2]] # X, h_init, WR, B
-
- inputs[0].shape[rnn_layer.sequence_dim] = 1
- input_squeeze = Squeeze(body, dict(name=rnn_layer.name + '/input_squeeze', internal_layer_id=0))
- input_squeeze_dim = Const(body, dict(name=rnn_layer.name + '/input_squeeze_dim',
- value=rnn_layer.sequence_dim)).create_node_with_data()
- inputs[0] = input_squeeze.create_node_with_data([inputs[0], input_squeeze_dim],
- edge_attrs=[{'internal_port_id': 0}])
-
- # 2. Output unsqueeze Reshape
- outputs = [Op._create_data_node(body, rnn_layer.name + '/outport/' + str(out),
- {'shape': rnn_layer.out_node(out).shape.copy() if out in rnn_layer.out_nodes() else None})
- for out in [0]]
- for out in outputs:
- add_opoutput(body, out.id, 0, False)
-
- outputs[0].shape = shape_delete(outputs[0].shape, rnn_layer.sequence_dim)
- output_unsqueeze_dim = Const(body, dict(name=rnn_layer.name + '/output_unsqueeze_dim',
- value=rnn_layer.sequence_dim)).create_node_with_data()
- output_unsqueeze = Unsqueeze(body, dict(name=rnn_layer.name + '/output_unsqueeze/', internal_layer_id=2))
-
- additional_attrs = dict(activations=rnn_layer.activations,
- activation_alpha=rnn_layer.activation_alpha,
- activation_beta=rnn_layer.activation_beta,
- clip=rnn_layer.clip)
- if rnn_layer.op == 'GRU':
- additional_attrs['linear_before_reset'] = rnn_layer.linear_before_reset
-
- # 3. ***Cell
- rnn_cell_op = self.get_rnn_cell(rnn_layer['op'])(body, dict(hidden_size=rnn_layer.hidden_size,
- name=rnn_layer.name + '/{}Cell'.format(rnn_layer.op),
- **additional_attrs,
- internal_layer_id=1))
-
- gru_cell = rnn_cell_op.create_node_with_data(inputs, data_nodes=outputs,
- edge_attrs=[{}, {'internal_port_id': 1},
- {'internal_port_id': 2}, {'bin': 'weights'},
- {'bin': 'biases'}])
-
- # internal ports for outputs of cell
- gru_cell.in_node().out_edge(0)['internal_port_id'] = 4 # h_state
-
- gru_cell = output_unsqueeze.create_node_with_data([gru_cell, output_unsqueeze_dim])
- gru_cell.in_node().out_edge(0)['internal_port_id'] = 3
- add_opoutput(body, gru_cell.id, 0, False)
-
- # 4. TensorIterator layer creating
- assert rnn_layer.direction in ['forward', 'reverse']
- if rnn_layer.direction == 'forward':
- stride = 1
- start = None
- end = None
- else:
- assert rnn_layer.direction == 'reverse'
- stride = -1
- start = -1
- end = 0
-
- # stacked h_state
- output_port_map = [{
- 'external_port_id': 3,
- 'internal_layer_id': 2,
- 'internal_port_id': 3,
-
- 'axis': rnn_layer.sequence_dim,
- 'stride': stride,
- 'start': start,
- 'end': end,
- 'part_size': 1,
- }]
-
- # Adding last h_state to outputs
- if len(rnn_layer.out_nodes()) == 2:
- output_port_map.extend([{
- 'external_port_id': 4,
- 'internal_layer_id': 1,
- 'internal_port_id': 4,
- }])
-
- ti_op = TensorIterator(graph, {
- 'name': rnn_layer.name + '/TensorIterator',
- 'body': body,
- 'in_ports_count': 4,
- 'out_ports_count': len(rnn_layer.out_nodes()),
-
- 'input_port_map': [
- {
- 'external_port_id': 0,
- 'internal_layer_id': 0,
- 'internal_port_id': 0,
-
- 'axis': rnn_layer.sequence_dim,
- 'stride': stride,
- 'start': start,
- 'end': end,
- 'part_size': 1,
- },
- {
- 'external_port_id': 1,
- 'internal_layer_id': 1,
- 'internal_port_id': 1,
- },
- ],
-
- 'output_port_map': output_port_map,
- # only for h state
- 'back_edges': [
- {
- 'from_layer': 1,
- 'from_port': 4,
- 'to_layer': 1,
- 'to_port': 1,
- },
- ]
- })
-
- assert sorted(rnn_layer.out_nodes().keys()) == list(range(len(rnn_layer.out_nodes()))), \
- "There are gaps in output ports of GRUSequence operation. Node {}".format(rnn_layer.id)
-
- outs = ti_op.create_node_with_data([rnn_layer.in_node(i) for i in [0, 4]], # X, h_init
- data_nodes=[rnn_layer.out_node(i) for i in range(len(rnn_layer.out_nodes()))],
- edge_attrs=[{'external_port_id': 0}, {'external_port_id': 1}])
-
- if not isinstance(outs, list):
- outs = list([outs])
-
- graph.remove_node(rnn_layer.id)
- outs[0].in_edge(0)['external_port_id'] = 3
- for i, out in enumerate(outs[1:]):
- external_port_id = 4 + i
- out.in_edge()['external_port_id'] = external_port_id
-
- ti = outs[0].in_node()
- TensorIterator.cover_body_input_data_nodes_with_parameter_ops(ti)
- TensorIterator.cover_body_constant_data_nodes_with_const_ops(ti)
- TensorIterator.normalize_internal_ids(ti)
diff --git a/tools/mo/openvino/tools/mo/middle/GatherNDDecomposition.py b/tools/mo/openvino/tools/mo/middle/GatherNDDecomposition.py
deleted file mode 100644
index 2f08c651fefc29..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/GatherNDDecomposition.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input, create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class GatherNDDecomposition(MiddleReplacementPattern):
- """
- Hot fix for new speech-to-text model enabling while GatherND is not implemented in IE.
- We can replace GatherND to Reshape + Gather in case when GatherND indices have just one
- meaningful dimension.
- TODO: Investigate whether we must replace GatherND with Reshape + Gather always (due to performance benefits)
- for this particular case or only if the plugin does not support GatherND.
- And the best place for the transformation is nGraph so we need to move it.
- """
- enabled = True
- force_clean_up = True
-
- def run_before(self):
- from openvino.tools.mo.middle.BlockLSTMtoLSTMSequence import BlockLSTMtoLSTMSequence
- return [BlockLSTMtoLSTMSequence]
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[('GatherND', dict(kind='op', op='GatherND', batch_dims=0))],
- edges=[]
- )
-
- @staticmethod
- def indices_check(indices: np.array, input_shape: tuple):
- """
- Check that indices have just one meaningful dimension and all other dimensions of input have size 1.
- """
- n_dims = indices.shape[-1]
- non_zero = None
- for i in range(n_dims):
- if not np.all(np.take(indices, indices=[i], axis=-1) == 0):
- if non_zero is None:
- non_zero = i
- else:
- return None
- else:
- if input_shape[i] != 1:
- return None
- return non_zero
-
- def replace_pattern(self, graph: Graph, match: dict):
- gather = match['GatherND']
- gather_name = gather.soft_get('name', gather.id)
- input_shape = gather.in_node(0).shape
- indices = gather.in_node(1).value
- if indices is None:
- # We can't do such special pass without indices value
- return
-
- # 0. All needed checks that we can replace GatherND by Gather
- gather_idx = self.indices_check(indices, input_shape)
- if gather_idx is None:
- log.warning(
- 'Node {} with op=GatherND can\'t be normalized to op=Gather.'.format(gather_name))
- return
-
- # 1. Add Reshape and connect
- new_shape = int64_array([-1] + list(input_shape[indices.shape[-1]:]))
- reshape = create_op_node_with_second_input(graph, Reshape, new_shape,
- {'name': gather_name + '/Reshape_for_GatherND/'})
- gather.in_port(0).get_connection().set_destination(reshape.in_port(0))
-
- # 2. Eliminate last dim (n_dims values) from indices shape:
- new_indices = np.reshape(
- np.take(indices, indices=[gather_idx], axis=-1), indices.shape[:-1])
-
- rename_node(gather, gather_name + '/to_delete')
-
- # 3. Create new Gather operation and reconnect all inputs/outputs
- new_gather = create_op_with_const_inputs(graph, Gather, {1: new_indices, 2: int64_array(0)},
- {'name': gather_name})
- rename_node(new_gather, gather_name)
-
- reshape.out_port(0).connect(new_gather.in_port(0))
-
- gather.out_port(0).get_connection().set_source(new_gather.out_port(0))
-
- # 4. Remove old Gather node
- graph.remove_node(gather.id)
diff --git a/tools/mo/openvino/tools/mo/middle/GroupNorm.py b/tools/mo/openvino/tools/mo/middle/GroupNorm.py
deleted file mode 100644
index a879ec62dba840..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/GroupNorm.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from typing import Dict
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.utils.shape import node_to_get_spatial_dimensions_value, node_to_get_features_dimension_value, \
- node_to_get_batch_value, new_shape_node_from_shape_nodes, get_shape_and_rank_nodes_by_port
-
-
-class GroupNormToMVN(MiddleReplacementPattern):
- """
- Converts GroupNorm operation to Reshape + MVN + Reshape + Mul + Add
- """
- op = 'GroupNorm'
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.EltwiseChecker import EltwiseChecker
- # TODO the EltwiseChecker does not work correctly for eltwises with 1D inputs
- return [EltwiseChecker]
-
- def pattern(self):
- return dict(
- nodes=[
- ('op', dict(op='GroupNorm')),
- ],
- edges=[])
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- group_norm_node = match['op']
- group_norm_num_input_dims = len(group_norm_node.in_port(0).data.get_shape())
-
- # node computing initial GroupNorm input shape
- initial_shape_op_node = Shape(graph, {'name': group_norm_node.name + '/Shape'}).create_node()
- initial_shape_op_node.in_port(0).connect(group_norm_node.in_port(0).get_source())
-
- initial_shape_op_node_float = Cast(
- graph, {'name': initial_shape_op_node.name + '/to_float',
- 'dst_type': data_type_str_to_np(graph.graph['cmd_params'].data_type)}).create_node()
- initial_shape_op_node.out_port(0).connect(initial_shape_op_node_float.in_port(0))
-
- initial_batch_dim_node = node_to_get_batch_value(initial_shape_op_node_float)
- initial_features_dim_node = node_to_get_features_dimension_value(initial_shape_op_node_float)
- initial_spatial_dims_node_int = node_to_get_spatial_dimensions_value(initial_shape_op_node)
- initial_spatial_dims_node = Cast(
- graph, {'name': initial_spatial_dims_node_int.name + '/to_float',
- 'dst_type': data_type_str_to_np(graph.graph['cmd_params'].data_type)}).create_node()
- initial_spatial_dims_node_int.out_port(0).connect(initial_spatial_dims_node.in_port(0))
-
- group_size_node = Const(graph, {'value': int64_array([group_norm_node.num_groups]),
- 'name': group_norm_node.name + '/GroupSize'}).create_node()
-
- # calculate "features // group_size" value
- reciprocal_group_size_node = Const(graph, {'value': mo_array([1.0 / group_norm_node.num_groups]),
- 'name': group_norm_node.name + '/ReciprocalGroupSize'}).create_node()
-
- c_div_g_node = Mul(graph, {}).create_node()
- c_div_g_node.in_port(0).connect(initial_features_dim_node.out_port(0))
- c_div_g_node.in_port(1).connect(reciprocal_group_size_node.out_port(0))
-
- batch_mul_group_size_node = Mul(graph, {}).create_node()
- batch_mul_group_size_node.in_port(0).connect(initial_batch_dim_node.out_port(0))
- batch_mul_group_size_node.in_port(1).connect(group_size_node.out_port(0))
-
- # create new node which concatenates several dims to one
- new_shape_node_float = new_shape_node_from_shape_nodes([batch_mul_group_size_node, c_div_g_node,
- initial_spatial_dims_node])
- new_shape_node = Cast(graph,
- {'name': new_shape_node_float.name + '/to_int64', 'dst_type': np.int64}).create_node()
- new_shape_node_float.out_port(0).connect(new_shape_node.in_port(0))
-
- reshape_for_mvn_node = Reshape(graph, {}).create_node()
-
- group_norm_node.in_port(0).get_connection().set_destination(reshape_for_mvn_node.in_port(0))
- reshape_for_mvn_node.in_port(1).connect(new_shape_node.out_port(0))
-
- # Reshape the gamma and beta constants to correct layout from [C] to [1,C], [1,C,1], [1,C,1,1] etc
- gamma_beta_shape = np.ones([group_norm_num_input_dims], dtype=np.int64)
- gamma_beta_shape[1] = -1
-
- gamma_value = group_norm_node.in_port(1).get_source().data.get_value()
- beta_value = group_norm_node.in_port(2).get_source().data.get_value()
- assert gamma_value is not None, 'The gamma should be constant'
- assert beta_value is not None, 'The beta should be constant'
- gamma_value = np.reshape(gamma_value, gamma_beta_shape)
- group_norm_node.in_port(1).get_source().data.set_value(gamma_value)
- beta_value = np.reshape(beta_value, gamma_beta_shape)
- group_norm_node.in_port(2).get_source().data.set_value(beta_value)
-
- # MVN
- mvn_node = MVN(graph, {'name': group_norm_node.name + '/MVN',
- 'normalize_variance': 1,
- 'eps': group_norm_node.eps,
- 'eps_mode': 'inside_sqrt'}).create_node()
- mvn_node.in_port(0).connect(reshape_for_mvn_node.out_port(0))
-
- # MVN axes
- _, rank = get_shape_and_rank_nodes_by_port(mvn_node.in_port(0).get_connection().get_source(),
- return_as_a_scalar=True)
- rng = create_op_with_const_inputs(graph, Range, {0: int64_array(1), 2: int64_array(1)},
- {'name': group_norm_node.name + '/Range', 'output_type': np.int64})
- mvn_node.in_port(1).connect(rng.out_port(0))
- rng.in_port(1).connect(rank.out_port(0))
-
- # reshape to the initial shape before multiplying with gamma and adding beta
- reshape_to_initial_shape_node = Reshape(graph, {}).create_node()
- reshape_to_initial_shape_node.in_port(0).connect(mvn_node.out_port(0))
- reshape_to_initial_shape_node.in_port(1).connect(initial_shape_op_node.out_port(0))
-
- mul_node = Mul(graph, {'name': mvn_node.name + '/Mul'}).create_node()
- mul_node.in_port(0).connect(reshape_to_initial_shape_node.out_port(0))
- group_norm_node.in_port(1).get_connection().set_destination(mul_node.in_port(1))
-
- add_node = Add(graph, {'name': mul_node.name + '/Add'}).create_node()
- add_node.in_port(0).connect(mul_node.out_port(0))
- group_norm_node.in_port(2).get_connection().set_destination(add_node.in_port(1))
-
- group_norm_node.out_port(0).get_connection().set_source(add_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/InputCut.py b/tools/mo/openvino/tools/mo/middle/InputCut.py
deleted file mode 100644
index 03f5057ad676d5..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/InputCut.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import add_input_ops
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class MiddleInputCut(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
- run_not_recursively = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def find_and_replace_pattern(self, graph: Graph):
- add_input_ops(graph, graph.graph['user_shapes'], False)
diff --git a/tools/mo/openvino/tools/mo/middle/InsertLayoutPropagationTransposes.py b/tools/mo/openvino/tools/mo/middle/InsertLayoutPropagationTransposes.py
deleted file mode 100644
index 3ae82693619bf4..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/InsertLayoutPropagationTransposes.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph, Node, Port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.op import PermuteAttrs
-
-
-class InsertLayoutPropagationTranspose(MiddleReplacementPattern):
- """
- The transformation inserts Transpose layers before/after operations that change the interpretation of data, for
- example, Reshape from 3D to 4D or from 4D to 3D. These Transpose layers basically convert layout from N(D)HWC to
- NC(D)HW and in the reverse order.
- """
- enabled = True
- force_clean_up = True # need to run clean up after the transformation to update shapes
- graph_condition = [lambda graph: graph.graph['layout'] == 'NHWC']
-
- def run_after(self):
- return [PostMiddleStart]
-
- def run_before(self):
- return []
-
- @staticmethod
- def is_nchw_to_nhwc_transpose_needed(node: Node):
- """
- The function checks that it is necessary to insert Transpose from NCHW to NHWC before the node.
- The transpose is needed when all the following conditions are met:
- 1. The node is marked as 'reinterp_shape' attribute
- 2. The node is *not* marked as getting input in correct layout (implicitly imply that the input is on port 0)
- 3. The input shape rank is not less than 4
- 4. Node is not a part of shape sub-graph (layout permutation is handled separately for such a sub-graph)
-
- :param node: node to check
- :return: result of the check
- """
- return node.has_and_set('reinterp_shape') and \
- not is_input_data_in_correct_layout(node, 0) and \
- len(node.in_port(0).data.get_shape()) >= 4 and \
- all([port.data.get_value() is None for port in node.out_ports().values() if not port.disconnected()])
-
- @staticmethod
- def is_nhwc_to_nchw_transpose_needed(node: Node):
- """
- The function checks that it is necessary to insert Transpose from NHWC to NCHW after the node.
- The transpose is needed when all the following conditions are met:
- 1. The node is marked as 'reinterp_shape' attribute
- 2. The node is *not* marked as generating output in correct layout (implicitly imply that the output port is 0)
- 3. The output shape rank is not less than 4
- 4. Node is not a part of shape sub-graph (layout permutation is handled separately for such a sub-graph)
- :param node: node to check
- :return: result of the check
- """
- return node.has_and_set('reinterp_shape') and \
- not is_output_data_in_correct_layout(node, 0) and \
- len(node.out_port(0).data.get_shape()) >= 4 and \
- all([port.data.get_value() is None for port in node.out_ports().values() if not port.disconnected()])
-
- def find_and_replace_pattern(self, graph: Graph):
-
- # we need to import these functions here to avoid circular dependent imports
- from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-
- if graph.graph['layout'] != 'NHWC':
- # we check it here because this transformation is called explicitly from the pipeline
- return
-
- # reshape from 4D-5D -> ND. Insert Transpose(NC(D)HW->N(D)HWC) before Reshape
- for reinterp_shape_node_id in graph.get_nodes_with_attributes(reinterp_shape=True):
- reinterp_shape_node = Node(graph, reinterp_shape_node_id)
- assert 0 in reinterp_shape_node.in_nodes(), 'Node {} does not have 0 input. \n{}'.format(
- reinterp_shape_node_id, graph.dump_graph_for_graphviz())
- input_shape = reinterp_shape_node.in_node(0).shape
- if self.is_nchw_to_nhwc_transpose_needed(reinterp_shape_node):
- permute_node = create_op_node_with_second_input(
- graph, Transpose, PermuteAttrs().get_nchw_to_nhwc_permutation(len(input_shape)).perm,
- {'name': reinterp_shape_node.in_port(0).get_source().node.name + '/Transpose'}
- )
- reinterp_shape_node.in_port(0).get_connection().insert_node(permute_node)
-
- order_const = permute_node.in_port(1).get_source().node
- order_const.infer(order_const)
- # do not infer the Transpose node because it should have input data node in NCHW layout (but currently
- # it is NHWC because data node attributes has not been permuted yet) and produce output in NHWC layout
- # (which is true at this moment)
- permute_node['need_shape_inference'] = False
- # mark the Transpose output data node having correct layout so it's shape will not be permuted
- mark_output_as_in_correct_layout(permute_node, 0)
-
- # keep the reinterp_shape_node in NHWC layout
- for in_port_id, _ in reinterp_shape_node.in_ports().items():
- mark_input_as_in_correct_layout(reinterp_shape_node, in_port_id)
-
- # reshape from ND -> 4D-5D. Insert Transpose(N(D)HWC->NC(D)HW) after Reshape
- for reinterp_shape_node_id in graph.get_nodes_with_attributes(reinterp_shape=True):
- reinterp_shape_node = Node(graph, reinterp_shape_node_id)
- assert 0 in reinterp_shape_node.out_nodes(), 'Node {} does not have 0 output. \n{}'.format(
- reinterp_shape_node_id, graph.dump_graph_for_graphviz())
- output_shape = reinterp_shape_node.out_node(0).shape
- if self.is_nhwc_to_nchw_transpose_needed(reinterp_shape_node):
- permute_node = create_op_node_with_second_input(
- graph, Transpose, PermuteAttrs().get_nhwc_to_nchw_permutation(len(output_shape)).perm,
- {'name': reinterp_shape_node.id + '/Transpose'})
- reinterp_shape_node.out_port(0).get_connection().insert_node(permute_node)
-
- # the Reshape and Transpose operations should work in original (NHWC layout) so the Transpose
- # will convert it to the NCHW
- mark_input_as_in_correct_layout(permute_node, 0)
- mark_input_as_in_correct_layout(permute_node, 1)
- # do not set Transpose output data node 'correct_data_layout' attribute so the data node shape will be
- # permuted
-
- # keep the reinterp_shape_node in NHWC layout
- mark_output_as_in_correct_layout(reinterp_shape_node, 0)
- for in_port_id in reinterp_shape_node.in_ports().keys():
- if in_port_id:
- mark_input_as_in_correct_layout(reinterp_shape_node, in_port_id)
-
- # do not re-infer the Transpose node because it output data node should be in NHWC layout to make the
- # rest of the graph consistent
- permute_node['need_shape_inference'] = False
-
-
-def is_input_data_in_correct_layout(node: Node, port_ind: int):
- assert node.soft_get('kind') == 'op', 'The function work with operation nodes only'
- return 'correct_in_data_layout' in node.attrs() and port_ind in node.attrs()['correct_in_data_layout']
-
-
-def mark_input_as_in_correct_layout(node: Node, port_ind: int):
- assert node.soft_get('kind') == 'op', 'The function work with operation nodes only'
- graph = node.graph
- graph.node[node.id].setdefault('correct_in_data_layout', set())
- graph.node[node.id]['correct_in_data_layout'].add(port_ind)
-
-
-def is_output_data_in_correct_layout(node: Node, port_ind: int):
- assert node.soft_get('kind') == 'op', 'The function work with operation nodes only'
- return 'correct_out_data_layout' in node.attrs() and port_ind in node.attrs()['correct_out_data_layout']
-
-
-def mark_output_as_in_correct_layout(node: Node, port_ind: int):
- assert node.soft_get('kind') == 'op', 'The function work with operation nodes only'
- graph = node.graph
- graph.node[node.id].setdefault('correct_out_data_layout', set())
- graph.node[node.id]['correct_out_data_layout'].add(port_ind)
-
-
-def mark_as_correct_data_layout(node: Node):
- """
- The analogue of the attribute 'correct_data_layout' for the operation node
- :param node: node to mark it with attribute 'correct_data_layout'
- :return: None
- """
- assert node.soft_get('kind') == 'op', 'The function work with operation nodes only'
- for ind, port in node.in_ports().items():
- mark_input_as_in_correct_layout(node, ind)
-
- for ind, port in node.out_ports().items():
- mark_output_as_in_correct_layout(node, ind)
-
-
-def insert_transpose(graph: Graph, input_port: Port, before_input=True):
- from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-
- input_rank = len(input_port.data.get_shape())
- if input_rank > 3:
- if before_input:
- axis_order = np.concatenate((int64_array([0]),
- int64_array(list(range(2, input_rank))),
- int64_array([1])))
- source_node = input_port.get_source().node
- transpose_name = source_node.soft_get('name', source_node.id) + '/TransposeToNHWC'
- else:
- axis_order = np.concatenate(
- (int64_array([0]),
- int64_array([input_rank - 1]),
- int64_array(list(range(1, input_rank - 1)))))
- transpose_name = input_port.node.soft_get('name', input_port.node.id) + '/TransposeToNCHW'
- input_port.node['need_shape_inference'] = True
- input_port.node['override_output_shape'] = True
- transpose = create_op_with_const_inputs(graph, Transpose, {1: axis_order}, {'name': transpose_name})
- input_port.get_connection().insert_node(transpose)
- transpose['need_shape_inference'] = True
- transpose['override_output_shape'] = True
diff --git a/tools/mo/openvino/tools/mo/middle/InsertSelect.py b/tools/mo/openvino/tools/mo/middle/InsertSelect.py
deleted file mode 100644
index 072c5c6426a526..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/InsertSelect.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-import numpy as np
-
-from openvino.tools.mo.middle.MakeKaldiConstReshapable import create_const_with_batch_from_input
-from openvino.tools.mo.ops.elementwise import Equal
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.pattern_match import find_pattern_matches, inverse_dict
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.assign import Assign
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.read_value import ReadValue
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.utils.graph import bfs_search
-from openvino.tools.mo.utils.error import Error
-
-
-def check_inputs(graph: Graph):
- inputs = graph.get_op_nodes(op='Parameter')
- if len(inputs) == 1:
- return inputs[0]
- elif len(inputs) == 2:
- if inputs[0].name == 'ivector':
- return inputs[1]
- elif inputs[1].name == 'ivector':
- return inputs[0]
- else:
- raise Error("There are 2 inputs for Kaldi model but we can't find out which one is ivector. " +
- "Use name \'ivector\' for the corresponding input")
- else:
- raise Error("There are {} inputs for Kaldi model but we expect only 1 or 2".format(len(inputs)))
-
-
-class AddSelectBeforeMemoryNodePattern(MiddleReplacementPattern):
- """
- Add Select before saving state with Memory to avoid garbage saving.
- We need to know delay on each node where Select is adding. For that we traverse the whole graph and set frame time
- for each node using the following rules:
- * Splice increases frame time by length of its context. If Crop is following Splice - it takes one concrete
- moment of time, so frame time increases by its value
- Example:
- node ---> Splice(-5, -4, ... 0) ---> node
- frame time: 0 ---> 5 ---> 5
- node ---> Splice(-5, -4, ... 0) ---> Crop(offset = 2, dim = 1) ---> node
- frame time: 0 ---> 5 ---> 3 ---> 3
- * Nodes with several inputs have frame time= max (frame time of each input)
- * Node with one input have the same frame time as its input
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'kaldi']
-
- def run_after(self):
- from openvino.tools.mo.middle.ReplaceMemoryOffsetWithSplice import ReplaceMemoryOffsetWithMemoryNodePattern
- from openvino.tools.mo.middle.RemoveDuplicationMemory import MergeNeighborSplicePattern
- return [ReplaceMemoryOffsetWithMemoryNodePattern,
- MergeNeighborSplicePattern]
-
- def run_before(self):
- from openvino.tools.mo.middle.ReplaceSpliceNodePattern import ReplaceSpliceNodePattern
- return [ReplaceSpliceNodePattern]
-
- @staticmethod
- def calculate_frame_time(graph: Graph):
- # there are either one or two inputs in Kaldi. Only main input can change delay in network.
- # Usually ivector input has name 'ivector'.
- max_frame_time = -2
- inputs = graph.get_op_nodes(op='Parameter')
- inp = check_inputs(graph)
- inp_name = inp.soft_get('name', inp.id)
-
- # sort nodes to calculate delays
- nodes = list(bfs_search(graph, [inp_name]))
-
- for n in nodes:
- node = Node(graph, n)
-
- # just ignore data nodes
- if node.kind != 'op':
- continue
-
- # calculate frame_time (delay) that was not calculated
- if node.frame_time < 0:
- # Splice increases frame delay
- if node.op == "Splice":
- if node.in_port(0).get_source().node.frame_time == -1:
- continue
- node.frame_time = node.in_port(0).get_source().node.frame_time + len(node.context) - 1
- # crop often used to get concrete time frame, set frame_time correctly for this case
- elif node.op == 'Crop':
- if node.in_port(0).get_source().node.frame_time == -1:
- continue
- if node.in_port(0).get_connection().get_source().node.op == 'Splice':
- splice_node = node.in_port(0).get_source().node
- assert len(node.offset) == 1
- assert len(node.dim) == 1
- new_delay = splice_node.context[node.offset[0] // node.dim[0]] - splice_node.context[0]
- node.frame_time = splice_node.in_port(0).get_source().node.frame_time + new_delay
- else:
- node.frame_time = node.in_port(0).get_source().node.frame_time
- elif node.op == 'ShapeOf':
- # exclude shape path from time delay calculation using special value
- node.frame_time = max_frame_time
- elif node.op == 'Broadcast':
- # finished shape path
- node.frame_time = node.in_port(0).get_source().node.frame_time
- # for node with several inputs frame_time = maximum of delays from branches
- else:
- # find out maximum of delay and check that we have at least one branch with another delay
- node.frame_time = -1 if len(node.in_ports()) != 0 else 0
- min_in_frame_time = -1
- for inp in node.in_ports():
- if node.in_port(inp).disconnected():
- continue
- in_node = node.in_port(inp).get_source().node
- if in_node.frame_time < min_in_frame_time:
- min_in_frame_time = in_node.frame_time
- if in_node.frame_time > node.frame_time and in_node.frame_time != -1:
- node.frame_time = in_node.frame_time
- # if all inputs have special value for frame time, node have special value for frame time too
- # because it is on shape path
- if min_in_frame_time == max_frame_time:
- node.frame_time = max_frame_time
-
-
- @staticmethod
- def insert_select(graph: Graph, node: Node):
- context_len = node.frame_time + 1
-
- if context_len == 1:
- return
-
- in_node_port = node.in_port(0).get_source()
- in_node_shape = node.in_port(0).data.get_shape()
- node.in_port(0).disconnect()
-
- # add Select before saving state to avoid saving garbage
- select_node = Select(graph, {'name': 'select_' + node.name}).create_node()
- zero_else = create_const_with_batch_from_input(in_node_port, in_node_shape[1])
- select_node.in_port(1).connect(in_node_port)
- select_node.in_port(2).connect(zero_else.out_port(0))
-
- # check if we have already appropriate iteration counter
- existing_counters = find_pattern_matches(graph, nodes=[('mem_in', dict(op='ReadValue')),
- ('mem_in_data', dict(shape=int64_array([context_len]))),
- ('crop_mem_in', dict(op='Crop', axis=int64_array([1]),
- offset=int64_array([1]),
- dim=int64_array([context_len - 1]))),
- ('crop_mem_in_data', dict()),
- ('concat', dict(op='Concat', axis=1)),
- ('concat_data', dict()),
- ('const_1', dict(op='Const')),
- ('const_1_data', dict()),
- ('mem_out', dict(op='Assign')),
- ('crop_out', dict(op='Crop', axis=int64_array([1]),
- offset=int64_array([0]),
- dim=int64_array([1]))),
- ('crop_out_data', dict()),
- ('select', dict(op='Select'))
- ],
- edges=[('mem_in', 'mem_in_data'), ('mem_in_data', 'crop_mem_in'),
- ('crop_mem_in', 'crop_mem_in_data'),
- ('crop_mem_in_data', 'concat', {'in': 0}),
- ('const_1', 'const_1_data'),
- ('const_1_data', 'concat', {'in': 1}),
- ('concat', 'concat_data'), ('concat_data', 'mem_out'),
- ('concat_data', 'crop_out'), ('crop_out', 'crop_out_data'),
- ('crop_out_data', 'select')])
- counter_match = next(existing_counters, None)
- if counter_match is not None:
- ones = Node(graph, inverse_dict(counter_match)['const_1'])
- input_port = Node(graph, inverse_dict(counter_match)['crop_out']).out_port(0)
- else:
- init_value_mem_out = create_const_with_batch_from_input(in_node_port, context_len, precision=np.int32)
- mem_out = ReadValue(graph, {'name': 'iteration_number',
- 'variable_id': 'iteration_' + node.name,
- 'variable_shape': None,
- 'variable_type': None
- }).create_node()
- mem_out.in_port(0).connect(init_value_mem_out.out_port(0))
- cut_first = Crop(graph, {'name': 'cut_first', 'axis': int64_array([1]),
- 'offset': int64_array([1]), 'dim': int64_array([context_len - 1])}).create_node()
- cut_first.in_port(0).connect(mem_out.out_port(0))
- ones = create_const_with_batch_from_input(in_node_port, 1, 1, np.int32)
- concat = Concat(graph, {'name': 'concat_ones', 'in_ports_count': 2, 'axis': 1}).create_node()
- concat.in_port(0).connect(cut_first.out_port(0))
- concat.in_port(1).connect(ones.out_port(0))
- mem_in = Assign(graph, {'name': 'iteration_number_out',
- 'variable_id': 'iteration_' + node.name}).create_node()
- mem_in.in_port(0).connect(concat.out_port(0))
- res = Result(graph, {}).create_node()
- mem_in.out_port(0).connect(res.in_port(0))
- cut_last = Crop(graph, {'name': 'cut_last', 'axis': int64_array([1]),
- 'offset': int64_array([0]), 'dim': int64_array([1])}).create_node()
- cut_last.in_port(0).connect(concat.out_port(0))
- input_port = cut_last.out_port(0)
-
- # Check if data from memory is 1
- # if it is True, we have correct data and should proceed with saving it to memory
- # else we have not gathered context and have garbage here, shouldn't change initial state of memory
- cast_in = Equal(graph, {'name': input_port.node.name + '/cast_to_bool'}).create_node()
- cast_in.in_port(0).connect(ones.out_port(0))
- cast_in.in_port(1).connect(input_port)
- select_node.in_port(0).connect(cast_in.out_port(0))
- select_node.out_port(0).connect(node.in_port(0))
- select_node.out_port(0).data.set_shape(in_node_shape)
-
- def find_and_replace_pattern(self, graph: Graph):
- if np.all([node.soft_get('name', node.id) == 'iteration_number_out'
- for node in graph.get_op_nodes(op='Assign')]):
- return
-
- nx.set_node_attributes(G=graph, name='frame_time', values=-1)
- should_continue = True
- while should_continue:
- self.calculate_frame_time(graph)
- should_continue = False
- for node in graph.get_op_nodes(op='Assign'):
- if node.frame_time == -1:
- should_continue = True
-
- for node in graph.get_op_nodes(op='Assign'):
- if node.soft_get('name', node.id) == 'iteration_number_out':
- continue
- self.insert_select(graph, node)
-
- for node in graph.get_op_nodes():
- if 'frame_time' in node:
- del node['frame_time']
diff --git a/tools/mo/openvino/tools/mo/middle/InterpolateSequenceToInterpolate.py b/tools/mo/openvino/tools/mo/middle/InterpolateSequenceToInterpolate.py
deleted file mode 100644
index 6c1ee0458eb8eb..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/InterpolateSequenceToInterpolate.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from typing import List
-
-import numpy as np
-
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import group_by_with_binary_predicate
-
-
-def node_has_one_consumer(node: Node) -> bool:
- return len(node.out_port(0).get_destinations()) == 1
-
-
-def is_next(first: Node, second: Node) -> bool:
- """
- This function checks if 'first' is predecessor of 'second'. The node 'first' is called to be
- a predecessor of the node 'second', if an output of 'first' is an input of 'second', and
- number of destinations of 'first' is equal to 1.
- :param first: an Interpolate layer
- :param second: another Interpolate layer
- :return: True, if 'first' is an predecessor of 'second', and False otherwise.
- """
- dests = first.out_port(0).get_destinations()
- if node_has_one_consumer(first):
- return second.id == dests[0].node.id
- elif first.soft_get('maybe_part_of_sequence', False):
- return len(dests) == 2 and second.id in [d.node.id for d in dests]
- return False
-
-
-class CanBeFused:
- def __init__(self):
- # We need to accumulate set of axes of compared nodes, because there can be a sequence of a set of axes
- # {i}{j}{i}
- self.accumulated_axes = set()
- self.default_values_for_opset4 = {
- 'mode': None,
- 'shape_calculation_mode': None,
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'antialias': 0,
- 'cube_coeff': -0.75
- }
- self.default_pads = int64_array([0])
-
- def _compare_attributes_of_interpolate1(self, first: Node, second: Node) -> bool:
- """
- This function checks whether attributes of Interpolate-1 nodes first and second are identical
- (except attribute 'axes').
- :param first: the first of compared nodes
- :param second: the second of compared nodes
- :return: True, if attributes of nodes are identical and False otherwise
- """
- # If some of attributes 'mode', 'align_corners', 'antialias', 'pads_begin', 'pads_end' are different,
- # then attributes of nodes are not identical.
- op = Interpolate(graph=first.graph, attrs={})
- for attr in ['mode', 'align_corners', 'antialias', 'pads_begin', 'pads_end']:
- if first.soft_get(attr, default=op.attrs[attr]) != second.soft_get(attr, default=op.attrs[attr]):
- return False
- return True
-
- def _compare_attributes_of_interpolate4(self, first: Node, second: Node) -> bool:
- """
- This function checks whether attributes of Interpolate-4 nodes first and second are identical.
- :param first: the first of compared nodes
- :param second: the second of compared nodes
- :return: True, if attributes of nodes are identical and False otherwise
- """
- # If some of attributes 'mode', 'coordinate_transformation_mode', 'nearest_mode', 'antialias', 'cube_coeff'
- # are different, then attributes of first and second are not identical.
- for attr in self.default_values_for_opset4.keys():
- default_value = self.default_values_for_opset4[attr]
- if first.soft_get(attr, default=default_value) != second.soft_get(attr, default=default_value):
- return False
-
- # If attributes 'pads_begin' or 'pads_end' of nodes first and second are different, then attributes
- # of first and second are not identical.
- for attr in ['pads_begin', 'pads_end']:
- if not np.array_equal(first.soft_get(attr, default=self.default_pads),
- second.soft_get(attr, default=self.default_pads)):
- return False
- return True
-
- def _compare_attributes(self, first: Node, second: Node) -> bool:
- """
- This function checks whether attributes of nodes first and second are identical (except attribute 'axes').
- :param first: the first of compared nodes
- :param second: the second of compared nodes
- :return: True, if attributes of nodes are identical and False otherwise
- """
- # If opsets of nodes are different, then nodes have different attributes.
- fst_opset = first.get_opset()
- snd_opset = second.get_opset()
- if fst_opset != snd_opset:
- return False
-
- if fst_opset not in ['opset1', 'opset4']:
- fst_name = first.soft_get('name', first.id)
- snd_name = second.soft_get('name', second.id)
- raise Error('Unsupported opset {} for nodes with names {} and {}'.format(fst_opset, fst_name, snd_name))
-
- if fst_opset == 'opset1':
- return self._compare_attributes_of_interpolate1(first, second)
- else:
- return self._compare_attributes_of_interpolate4(first, second)
-
- def __call__(self, first: Node, second: Node) -> bool:
- """
- This function checks whether Interpolate nodes 'first' and 'second' can be fused.
- :param first: the first of fused nodes
- :param second: the second of fused nodes
- :return: True, if nodes can be fused, and False otherwise
- """
- if not (is_next(first, second) and self._compare_attributes(first, second)):
- self.accumulated_axes = set()
- return False
-
- fst_axes = set([a for a in Interpolate.get_axes(first)])
- snd_axes = set([a for a in Interpolate.get_axes(second)])
-
- self.accumulated_axes = self.accumulated_axes | fst_axes
-
- # If the set of accumulated axes and the set of axes of 'second' do not intersect then nodes can be fused,
- # because interpolations with respect to various axes do not affect each other.
- if not(self.accumulated_axes & snd_axes):
- return True
-
- # Otherwise, nodes cannot be fused.
- self.accumulated_axes = set()
- return False
-
-
-def get_interpolate_attributes(node: Node) -> dict:
- opset_to_default_values = {
- 'opset1': {
- 'mode': None,
- 'align_corners': 0,
- 'antialias': 0,
- 'pads_begin': 0,
- 'pads_end': 0,
- 'version': 'opset1'
- },
- 'opset4': {
- 'mode': None,
- 'shape_calculation_mode': None,
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4'
- },
- }
- opset = node.get_opset()
- result = {}
- if opset in opset_to_default_values:
- default_values = opset_to_default_values[opset]
- for attr in default_values.keys():
- value = node.soft_get(attr, default=default_values[attr])
- result[attr] = value
- return result
- else:
- raise Error('Unsupported opset {} for node with name {}.'.format(opset, node.soft_get('name', node.id)))
-
-
-def replace_sequence(seq: List[Node], graph: Graph):
- """
- This function replaces a sequence of consecutive Interpolate layers with one Interpolate layer,
- if modes of all nodes of a sequence are the same.
- :param seq: sequence of Interpolate layers
- :param graph: graph to which nodes of seq belong
- :return: Nothing
- """
- if not seq:
- return
- if len(seq) == 1:
- return
-
- modes = set([n.mode for n in seq])
- if len(modes) != 1:
- return
-
- dims_and_scales_ = []
- # Each element of the list dims_and_scales_ is a pair
- # (axis, output size for this axis) (opset1)
- # or
- # (axis, output size for this axis, output scales for this axis) (opset4)
- if seq[0].get_opset() == 'opset1':
- for interp in seq:
- dims_and_scales_.extend(zip(Interpolate.get_axes(interp),
- interp.in_port(1).get_connection().get_source().data.get_value()))
-
- axis_to_size = sorted(list(dict(dims_and_scales_).items()), key=lambda x: x[0])
- axes_of_node = int64_array([z[0] for z in axis_to_size])
- sizes = shape_array([z[1] for z in axis_to_size])
- scales = np.ones(len(axis_to_size), dtype=np.float32)
- else:
- for interp in seq:
- dims_and_scales_.extend(zip(Interpolate.get_axes(interp),
- interp.in_port(1).get_connection().get_source().data.get_value(),
- interp.in_port(2).get_connection().get_source().data.get_value()))
-
- axis_to_size = sorted(dims_and_scales_, key=lambda x: x[0])
- axes_of_node = int64_array([z[0] for z in axis_to_size])
- sizes = shape_array([z[1] for z in axis_to_size])
- scales = mo_array([z[2] for z in axis_to_size])
-
- fst_interp_node = seq[0]
- last_interp_node = seq[-1]
- last_interp_node_name = last_interp_node.soft_get('name', last_interp_node.id)
- attributes = get_interpolate_attributes(fst_interp_node)
-
- opset = fst_interp_node.get_opset()
- if opset == 'opset1':
- attributes['axes'] = axes_of_node
- interp_node = create_op_with_const_inputs(graph, Interpolate, {1: sizes}, attributes)
-
- fst_interp_connection = fst_interp_node.in_port(0).get_connection()
- fst_interp_connection.set_destination(interp_node.in_port(0))
-
- last_interp_node.out_port(0).get_connection().set_source(interp_node.out_port(0))
- else:
- attributes['in_ports_count'] = 4
- interp_node = create_op_with_const_inputs(graph, Interpolate,
- {1: sizes, 2: scales, 3: axes_of_node},
- attributes)
-
- fst_interp_connection = fst_interp_node.in_port(0).get_connection()
- fst_interp_connection.set_destination(interp_node.in_port(0))
-
- last_interp_node.out_port(0).get_connection().set_source(interp_node.out_port(0))
-
- rename_nodes([(last_interp_node, last_interp_node_name + '/delete'), (interp_node, last_interp_node_name)])
-
-
-class InterpolateSequenceToInterpolate(MiddleReplacementPattern):
- """
- This transformation replaces a sequence of Interpolate layers by one Interpolate layer.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.UpsampleToResample import UpsampleToResample
- return [UpsampleToResample]
-
- def find_and_replace_pattern(self, graph: Graph):
- log.debug('Enabled replacement of a sequence of Interpolate layers with one Interpolate layer.')
- interps = [n for n in graph.pseudo_topological_sort() if n.kind == 'op' and n.op == 'Interpolate']
- fuser = CanBeFused()
- sequences = group_by_with_binary_predicate(interps, fuser)
- for seq in sequences:
- replace_sequence(seq, graph)
diff --git a/tools/mo/openvino/tools/mo/middle/L2NormFusing.py b/tools/mo/openvino/tools/mo/middle/L2NormFusing.py
deleted file mode 100644
index 863f14207b7dd3..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/L2NormFusing.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.normalize_l2 import NormalizeL2Op
-from openvino.tools.mo.front.common.layout import get_features_dim
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class L2NormToNorm(MiddleReplacementPattern):
- """
- Transformation fuses sub-graph performing l2 normalization into the NormalizeL2 operation. OV plugins do not support
- NormalizeL2 operation and there is a nGraph transformation which converts NormalizeL2 to NormalizeIE. The latter one
- allows to normalize over just channel dimension or "channel + all spatial" dimensions for 2D, 3D or 4D cases.
- """
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[
- ('input', dict(kind='data')),
- ('l2_normalize', dict(kind='op', op='Mul')),
- ('l2_normalize_data', dict(kind='data')),
- ('maximum', dict(kind='op', op='Maximum')),
- ('maximum_data', dict(kind='data')),
- ('maximum_y_data', dict(kind='data')),
- ('rsqrt_pow', dict(kind='data', value=lambda x: np.all(x == -0.5) if x is not None else False)),
- ('rsqrt', dict(kind='op', op='Pow')),
- ('rsqrt_data', dict(kind='data')),
- ('square_pow', dict(kind='data', value=lambda x: np.all(x == 2) if x is not None else False)),
- ('square', dict(kind='op', op='Pow')),
- ('square_data', dict(kind='data')),
- ('sum', dict(kind='op', op='ReduceSum')),
- ('sum_data', dict(kind='data')),
- ],
- edges=[
- ('input', 'square', {'in': 0}),
- ('square_pow', 'square', {'in': 1}),
- ('square', 'square_data'),
- ('square_data', 'sum'),
- ('sum', 'sum_data'),
- ('maximum_y_data', 'maximum'),
- ('sum_data', 'maximum'),
- ('maximum', 'maximum_data'),
- ('maximum_data', 'rsqrt', {'in': 0}),
- ('rsqrt_pow', 'rsqrt', {'in': 1}),
- ('rsqrt', 'rsqrt_data'),
- ('rsqrt_data', 'l2_normalize'),
- ('input', 'l2_normalize'),
- ('l2_normalize', 'l2_normalize_data'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- y = match['maximum'].in_port(0).data.get_value()
- if y is None:
- y = match['maximum'].in_port(1).data.get_value()
-
- if y is None or y.shape != ():
- log.debug('The value of the "maximum_y_data" is not defined or is not constant')
- return
-
- # We need to check axes which performed reduction because OV supports only 2D, 3D, 4D inputs and
- # reduction only along spatial and channel dimensions.
- input_rank = len(match['sum'].in_port(0).data.get_shape())
- if input_rank not in [2, 3, 4]:
- log.debug('OV supports L2 normalization only for 2D, 3D and 4D tensors.')
- return
-
- axes = match['sum'].in_port(1).data.get_value()
- axes = int64_array(axes)
- if axes.shape == ():
- axes = int64_array([axes])
- axes = int64_array([axis if axis >= 0 else axis + input_rank for axis in axes])
- axes.sort()
-
- transformation_applicable = False
- # check for case C + all spatial dims. Works for 2D (NC), 3D (NCH) and 4D (NCHW and NHWC)
- if len(axes) + 1 == input_rank and np.array_equal(axes, int64_array(np.arange(start=1, stop=input_rank))):
- transformation_applicable = True
-
- # check for pure C channel normalization
- if len(axes) == 1 and ((input_rank == 4 and get_features_dim(graph.graph['layout'], input_rank) == axes[0]) or
- (input_rank != 4 and axes[0] == 1)):
- transformation_applicable = True
-
- if not transformation_applicable:
- log.debug('OV doesn\'t support l2 normalization with reduction along axes {}.'.format(axes))
- return
-
- output_name = match['l2_normalize'].soft_get('name', match['l2_normalize'].id)
- normalize_node = create_op_node_with_second_input(graph, NormalizeL2Op, axes, {'name': output_name,
- 'eps_mode': 'max', 'eps': y})
- match['square'].in_port(0).get_source().connect(normalize_node.in_port(0))
-
- match['square'].in_port(0).disconnect()
- if match['l2_normalize'].in_port(0).get_source().node.id == match['rsqrt'].id:
- match['l2_normalize'].in_port(1).disconnect()
- else:
- match['l2_normalize'].in_port(0).disconnect()
-
- match['l2_normalize'].out_port(0).get_connection().set_source(normalize_node.out_port(0))
- rename_nodes([(match['l2_normalize'], output_name + "/TBR"), (normalize_node, output_name)])
diff --git a/tools/mo/openvino/tools/mo/middle/LSTMRNNSequenceToTensorIterator.py b/tools/mo/openvino/tools/mo/middle/LSTMRNNSequenceToTensorIterator.py
deleted file mode 100644
index 8bd0d156d09a63..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/LSTMRNNSequenceToTensorIterator.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.RNNSequenceNormalizeToIE import RNNSequenceNormalize
-from openvino.tools.mo.ops.lstm_cell import LSTMCell
-from openvino.tools.mo.ops.tensor_iterator import TensorIterator
-from openvino.tools.mo.front.common.partial_infer.utils import shape_delete
-from openvino.tools.mo.graph.graph import Graph, add_opoutput
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class LSTMToTensorIterator(MiddleReplacementPattern):
- """ Converts normalized RNNSequence with op=LSTM to TensorIterator.
-
- Normalized RNNSequence means that it should be processed by
- RNNSequenceNormalize transform that ensures its strict form.
-
- This transformation builds an alternative sub-graph for LSTMSequence
- with TensorIterator connected in the same way as an original LSTMSequence
- node and with internal body represented as LSTMCell op node with necessary
- squeezes and unsqueezes around.
- """
-
- enabled = True
- force_clean_up = True
- id = 'lstm_to_tensor_iterator'
-
- def run_after(self):
- return [RNNSequenceNormalize]
-
- def run_before(self):
- from openvino.tools.mo.middle.permute_tensor_iterator import TransposeTensorIteratorLSTM
- return [TransposeTensorIteratorLSTM]
-
- def pattern(self):
- return dict(
- nodes=[
- ('lstm', dict(kind='op', op='LSTM', type='RNNSequence')),
- ('input', dict(kind='data')),
- ('weights', dict(kind='data')),
- ('biases', dict(kind='data')),
- # don't capture optional input initial states here
- ('output', dict(kind='data')),
- # don't capture optional output last states here
- ],
- edges=[
- ('input', 'lstm', {'in': 0}),
- ('weights', 'lstm', {'bin': 'weights', 'in': 1}),
- ('biases', 'lstm', {'bin': 'biases', 'in': 2}),
- ('lstm', 'output', {'out': 0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- lstm = match['lstm']
-
- # Build TensorIterator body first
- body = Graph(name=lstm.name + '/sub_graph')
- body.graph = graph.graph
-
- # 1. Input squeeze Reshape
- inputs = [Op._create_data_node(body, lstm.name + '/inport/' + str(inp),
- {'shape': lstm.in_node(inp).shape.copy(),
- 'value': lstm.in_node(inp).value.copy()
- if lstm.in_node(inp).value is not None and inp in [1, 2] else None})
- for inp in [0, 4, 5, 1, 2]] # X, WR, B, h_init, c_init
-
- inputs[0].shape[lstm.sequence_dim] = 1
- input_squeeze = Squeeze(body, dict(name=lstm.name + '/input_squeeze', internal_layer_id=0))
- squeeze_dim_data = Const(body, {'name': lstm.name + '/input_squeeze_dim',
- 'value': [lstm.sequence_dim]}).create_node_with_data()
- inputs[0] = input_squeeze.create_node_with_data([inputs[0], squeeze_dim_data],
- edge_attrs=[{'internal_port_id': 0}])
-
- # 2. Output unsqueeze Reshape
- outputs = [Op._create_data_node(body, lstm.name + '/outport/' + str(out),
- {'shape': lstm.out_node(out).shape.copy() if out in lstm.out_nodes()
- else lstm.in_node(4).shape.copy()}) for out in [0, 1]]
- for out in outputs:
- add_opoutput(body, out.id, 0, False)
-
- outputs[0].shape = shape_delete(outputs[0].shape, lstm.sequence_dim)
- output_unsqueeze = Unsqueeze(body, dict(name=lstm.name + 'output_unsqueeze', internal_layer_id=2))
- unsqueeze_dim_data = Const(body, {'name': lstm.name + '/output_unsqueeze_dim',
- 'value': [lstm.sequence_dim]}).create_node_with_data()
-
- # 3. LSTMCell
- lstm_cell_op = LSTMCell(body, dict(hidden_size=lstm.hidden_size,
- activations=lstm.activations,
- activation_alpha=lstm.activation_alpha,
- activation_beta=lstm.activation_beta,
- clip=lstm.clip,
- input_forget=lstm.input_forget,
- name=lstm.name + '/LSTMCell',
- internal_layer_id=1))
- lstm_cell_node = lstm_cell_op.create_node_with_data(inputs, data_nodes=outputs,
- edge_attrs=[{}, {'internal_port_id': 1},
- {'internal_port_id': 2}, {'bin': 'weights'},
- {'bin': 'biases'}])
- lstm_cell_node[0].in_node().out_edge(0)['internal_port_id'] = 4
- lstm_cell_node[0].in_node().out_edge(1)['internal_port_id'] = 5
- lstm_cell_node[0] = output_unsqueeze.create_node_with_data([lstm_cell_node[0], unsqueeze_dim_data])
- lstm_cell_node[0].in_node().out_edge(0)['internal_port_id'] = 3
- add_opoutput(body, lstm_cell_node[0].id, 0, False)
-
- # 4. TensorIterator layer creating
- assert lstm.direction in ['forward', 'reverse']
- if lstm.direction == 'forward':
- stride = 1
- start = None
- end = None
- else:
- assert lstm.direction == 'reverse'
- stride = -1
- start = -1
- end = 0
-
- output_port_map = [{
- 'external_port_id': 3,
- 'internal_layer_id': 2,
- 'internal_port_id': 3,
-
- 'axis': lstm.sequence_dim,
- 'stride': stride,
- 'start': start,
- 'end': end,
- 'part_size': 1,
- }]
-
- # Adding h_state, c_state to outputs
- if len(lstm.out_nodes()) == 3:
- output_port_map.extend([{
- 'external_port_id': 4,
- 'internal_layer_id': 1,
- 'internal_port_id': 4,
- }, {
- 'external_port_id': 5,
- 'internal_layer_id': 1,
- 'internal_port_id': 5,
- }])
-
- ti_op = TensorIterator(graph, {
- 'name': lstm.name + '/TensorIterator',
- 'body': body,
- 'in_ports_count': 3,
- 'out_ports_count': len(lstm.out_nodes()),
-
- 'input_port_map': [
- {
- 'external_port_id': 0,
- 'internal_layer_id': 0,
- 'internal_port_id': 0,
-
- 'axis': lstm.sequence_dim,
- 'stride': stride,
- 'start': start,
- 'end': end,
- 'part_size': 1,
- },
- {
- 'external_port_id': 1,
- 'internal_layer_id': 1,
- 'internal_port_id': 1,
- },
- {
- 'external_port_id': 2,
- 'internal_layer_id': 1,
- 'internal_port_id': 2,
- },
- ],
-
- 'output_port_map': output_port_map,
-
- 'back_edges': [
- {
- 'from_layer': 1,
- 'from_port': 4,
- 'to_layer': 1,
- 'to_port': 1,
- },
- {
- 'from_layer': 1,
- 'from_port': 5,
- 'to_layer': 1,
- 'to_port': 2,
- },
- ]
- })
-
- assert sorted(lstm.out_nodes().keys()) == list(range(len(lstm.out_nodes()))), \
- "There are gaps in output ports of LSTMSequence operation. Node {}".format(lstm.id)
-
- outs = ti_op.create_node_with_data([lstm.in_node(i) for i in [0, 4, 5]], # X, h_init, c_init
- data_nodes=[lstm.out_node(i) for i in range(len(lstm.out_nodes()))],
- edge_attrs=[{'external_port_id': 0}, {'external_port_id': 1},
- {'external_port_id': 2}])
-
- if not isinstance(outs, list):
- outs = list([outs])
-
- graph.remove_node(lstm.id)
- outs[0].in_edge(0)['external_port_id'] = 3
- for i, out in enumerate(outs[1:]):
- external_port_id = 4 + i
- out.in_edge()['external_port_id'] = external_port_id
-
- ti = outs[0].in_node()
- TensorIterator.cover_body_input_data_nodes_with_parameter_ops(ti)
- TensorIterator.cover_body_constant_data_nodes_with_const_ops(ti)
- TensorIterator.normalize_internal_ids(ti)
diff --git a/tools/mo/openvino/tools/mo/middle/LayoutChangeForConstantShapePaths.py b/tools/mo/openvino/tools/mo/middle/LayoutChangeForConstantShapePaths.py
deleted file mode 100644
index 894911adf15c3a..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/LayoutChangeForConstantShapePaths.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from collections import deque
-from typing import List, Set
-
-from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import is_output_data_in_correct_layout, \
- InsertLayoutPropagationTranspose, mark_input_as_in_correct_layout, mark_output_as_in_correct_layout
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class LayoutChangeForConstantShapePaths(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['layout'] == 'NHWC',
- lambda graph: not graph.graph['cmd_params'].static_shape]
- force_clean_up = True
-
- def run_after(self):
- return [InsertLayoutPropagationTranspose]
-
- def run_before(self):
- return []
-
- @staticmethod
- def get_next_in_ports(in_port: Port) -> Set[Port]:
- next_in_ports = set()
- for out_port in in_port.node.out_ports().values():
- next_in_ports.update(out_port.get_destinations())
- return next_in_ports
-
- def find_shape_subgraph_endpoints(self, out_ports: List[Port], visited: set = None,
- action: callable = None) -> Set[Port]:
- """
- Searches for input ports of data dependent operations starting from output ports passed to the function.
- Condition for data dependent operations is absence of node output value.
-
- :param out_ports: list of output ports to start search from
- :param visited: set of input ports that were visited to avoid visiting them more than once
- :param action: function to call on the each input port of shape sub-graph
- :return: set of input ports of data dependent operations
- """
- if visited is None:
- visited = set()
-
- deque_of_in_ports = deque()
- for out_port in out_ports:
- deque_of_in_ports.extend(out_port.get_destinations())
-
- end_points_in_ports = set()
- while len(deque_of_in_ports):
- in_port = deque_of_in_ports.popleft()
- if in_port in visited:
- continue
- next_in_ports = self.get_next_in_ports(in_port)
- if any([port.data.get_value() is None for port in next_in_ports]):
- end_points_in_ports.add(in_port)
- else:
- deque_of_in_ports.extend(next_in_ports)
- if action is not None:
- action(in_port)
- visited.add(in_port)
- return end_points_in_ports
-
- def find_and_replace_pattern(self, graph: Graph):
- shape_ops = graph.get_op_nodes(op='ShapeOf')
-
- # 1. Inserting Gather to N*C format on constant shape paths
- for shape in shape_ops:
- source_port = shape.in_port(0).get_source()
- if is_output_data_in_correct_layout(source_port.node, source_port.idx):
- continue # data is already in N*C format
-
- name = shape.soft_get('name', shape.id)
- rank = source_port.data.get_shape().size
-
- if rank in [4, 5]:
- index = int64_array([0, *list(range(2, rank)), 1])
- else:
- continue # data is layout independent
-
- gather = create_op_with_const_inputs(graph, op=Gather, port_value_dict={1: index, 2: int64_array(0)},
- op_attrs={'name': name + '/GatherNCHWtoNHWC'})
- shape.out_port(0).get_connection().insert_node(gather)
-
- # 2. Inserting Gather/Transpose to NC* format
- shape_sub_graph_end_points = self.find_shape_subgraph_endpoints([shape.out_port(0) for shape in shape_ops])
- for in_port in shape_sub_graph_end_points:
- name = in_port.node.soft_get('name', in_port.node.id)
- shape = in_port.data.get_shape()
-
- should_switch_layout = not any([is_output_data_in_correct_layout(port.node, port.idx)
- for port in in_port.node.out_ports().values() if not port.disconnected()])
- should_insert_gather = should_switch_layout and len(shape) == 1 and shape.item(0) in [4, 5]
- should_insert_transpose = should_switch_layout and len(shape) in [4, 5]
-
- if should_insert_gather:
- # we should turn input permutation off to perform it with the following gather insertion
- in_port.__setattr__('input_permutation', None)
- index = int64_array([0, shape.item(0) - 1, *list(range(1, shape.item(0) - 1))])
- gather = create_op_with_const_inputs(graph, op=Gather,
- port_value_dict={1: index, 2: int64_array(0)},
- op_attrs={'name': name + '/GatherNHWCtoNCHW'})
- in_port.get_connection().insert_node(gather)
- elif should_insert_transpose:
- # we should turn input permutation off to perform it with the following transpose insertion
- in_port.__setattr__('input_permutation', None)
- order = int64_array([0, len(shape) - 1, *list(range(1, len(shape) - 1))])
- transpose = create_op_with_const_inputs(graph, op=Transpose, port_value_dict={1: order},
- op_attrs={'name': name + '/TransposeNHWCtoNCHW',
- 'override_output_shape': True})
- mark_input_as_in_correct_layout(transpose, 0)
- mark_output_as_in_correct_layout(transpose, 0)
- in_port.get_connection().insert_node(transpose)
- else:
- continue # data is layout independent
diff --git a/tools/mo/openvino/tools/mo/middle/LayoutChangeForEinsum.py b/tools/mo/openvino/tools/mo/middle/LayoutChangeForEinsum.py
deleted file mode 100644
index 3b8ffe74f10826..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/LayoutChangeForEinsum.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import is_input_data_in_correct_layout, \
- is_output_data_in_correct_layout
-from openvino.tools.mo.ops.einsum import Einsum
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class LayoutChangeForEinsum(MiddleReplacementPattern):
- """
- The transformation adjusts Einsum equation to NCHW layout.
- Subscripts for tensor of rank greater than three must be adjusted
- to NCHW layout, meaning a label for the last dimension is moved
- to the second position in the subscript.
- There is an exception when the last label in the subscript is ellipsis
- and covers multiple dimensions. In this case subscript is not changed and
- Transpose to get original NHWC layout back is inserted.
- The transformation is only applicable to TensorFlow case.
- """
- enabled = True
- force_shape_inference = True
- graph_condition = [lambda graph: graph.graph['layout'] == 'NHWC']
-
- def run_after(self):
- from openvino.tools.mo.middle.MarkSubgraphsWithCorrectLayout import MarkSubGraphsWithCorrectLayout
- return [MarkSubGraphsWithCorrectLayout]
-
- def run_before(self):
- from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import InsertLayoutPropagationTranspose
- return [InsertLayoutPropagationTranspose]
-
- def find_and_replace_pattern(self, graph: Graph):
- import openvino.tools.mo.middle.InsertLayoutPropagationTransposes as InsertTransposes
- for einsum in graph.get_op_nodes(type='Einsum'):
- einsum_name = einsum.soft_get('name', einsum.id)
- assert einsum.has_valid('equation'), "Equation attribute is mandatory" \
- " for Einsum node {}".format(einsum_name)
- equation = einsum.equation
- connected_in_ports = [port for port in einsum.in_ports().values() if not port.disconnected()]
- num_inputs = len(connected_in_ports)
-
- # check if correct_data_layout attribute is set for inputs and output
- # this attribute can be set up within MarkSubgraphWithCorrectLayout transformation
- # for example, when Einsum is located near to MatMul operation in a graph
- input_correct_layout_mask = []
- for input_ind in range(num_inputs):
- input_correct_layout_mask.append(is_input_data_in_correct_layout(einsum, input_ind))
- is_output_layout_correct = is_output_data_in_correct_layout(einsum, 0)
-
- # compute a mask of which inputs/output are adjusted to the required layout
- # if they are not adjusted, it means to require transpose
- input_ranks = [len(einsum.in_port(port_idx).data.get_shape()) for port_idx in range(num_inputs)]
- output_rank = len(einsum.out_port(0).data.get_shape())
- permuted_equation, are_inputs_adjusted, is_output_adjusted = Einsum.adjust_equation_with_NCHW_layout(
- einsum_name,
- equation,
- input_ranks,
- output_rank, input_correct_layout_mask, is_output_layout_correct)
- assert len(are_inputs_adjusted) == num_inputs
-
- # setup adjusted equation
- einsum.equation = permuted_equation
-
- # insert Transpose node to get NHWC layout back (for inputs) that is required due to specifics of equation
- for input_ind in range(num_inputs):
- if not are_inputs_adjusted[input_ind]:
- # that means Einsum can only accept input in NHWC layout
- # so the inserted transpose before the Einsum will convert the layout to NHWC
- InsertTransposes.insert_transpose(graph, einsum.in_port(input_ind), before_input=True)
- if not is_output_adjusted:
- # that means Einsum can only generate output in NHWC layout
- # so the inserted transpose followed after the output will convert the layout back into NCHW layout
- InsertTransposes.insert_transpose(graph, einsum.out_port(0), before_input=False)
diff --git a/tools/mo/openvino/tools/mo/middle/LeakyReluPattern.py b/tools/mo/openvino/tools/mo/middle/LeakyReluPattern.py
deleted file mode 100644
index 457208ab43adeb..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/LeakyReluPattern.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from openvino.tools.mo.middle.fusings import Fusing
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart
-from openvino.tools.mo.ops.activation_ops import LeakyReLU
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class LeakyReLUFusion(MiddleReplacementPattern):
- """
- The transformation finds next subgraph:
-
- -->Data-------->Maximum-->Data
- `-->Mul---`
-
- and replaces with ReLU with negative slope (LeakyRelu)
- """
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- return [Fusing]
-
- def run_before(self):
- return [PostMiddleStart]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('data', dict(kind='data')),
- ('mul_data', dict(kind='data')),
- ('max_op', dict(kind='op', type='Maximum')),
- ('const_op', dict(kind='op', type='Const')),
- ('const_data', dict(kind='data')),
- ('mul_op', dict(kind='op', type='Multiply')),
- ],
- edges=[
- ('data', 'mul_op'),
- ('mul_op', 'mul_data'),
- ('data', 'max_op'),
- ('mul_data', 'max_op'),
- ('const_op', 'const_data'),
- ('const_data', 'mul_op')
- ],
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- mul_node = match['mul_op']
- const_node = match['const_op']
- max_node = match['max_op']
- max_name = max_node.soft_get('name', max_node.id)
-
- const_value = const_node.out_port(0).data.get_value()
- if const_value is None or const_value.size != 1:
- log.debug('Mul layer "{}" can not participate in conversion to the LeakyReLU because constant "{}" '
- 'contains more than one element: {}'.format(mul_node.id, const_node.id, const_value.size))
- return
-
- # Create new LeakyReLU operation
- leaky_relu_node = LeakyReLU(graph, dict(negative_slope=const_value.item(0))).create_node()
-
- data_in_port = int(mul_node.in_port(0).get_source().node.type == 'Const')
- mul_node.in_port(data_in_port).get_source().connect(leaky_relu_node.in_port(0))
- max_node.out_port(0).get_connection().set_source(leaky_relu_node.out_port(0))
-
- rename_nodes([(max_node, max_name + '/TBR'), (leaky_relu_node, max_name)])
-
- log.debug('Successful conversion from {} {} to ReLU with negative slope (leaky ReLU)'
- ''.format(max_node.id, mul_node.id))
diff --git a/tools/mo/openvino/tools/mo/middle/MXNetRNNSequenceNormalize.py b/tools/mo/openvino/tools/mo/middle/MXNetRNNSequenceNormalize.py
deleted file mode 100644
index b45ab8c03e8e2d..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MXNetRNNSequenceNormalize.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_insert, mo_array, shape_array, \
- unmask_shape
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.transpose import Transpose
-
-
-class MXNetRNNSequenceNormalize(MiddleReplacementPattern):
- """
- Convert blobs and shapes of MXNet-like RNN cell to OV compatible form.
-
- The target form of this operation is not normally covered by a dedicated
- layer in OV. It should be further transformed to some other layer
- that are supported by OV. This transformation pass involves weights and
- shapes processing only.
-
- Post-conditions:
- Inputs:
- 0: X input data, shape [batch_size, seq_len, input_size] (or [seq_len. bathc_size, int_size], depends on
- batch_dim param)
- 1: W weights blob, shape [num_dir, n_cells, M, hidden_size, input_size]
- 2: R weights blob, shape [num_dir, n_cells, M, hidden_size, hidden_size]
- 3: B biases blob, shape [num_dir, n_cells, 2, M, hidden_size]
- 4: (optional) sequence_length, shape [batch_size]
- 5: initial hidden state, shape [num_dir, batch_size, hidden_size]
- ([num_dir, n_cells, batch_size, hidden_size] if num_cells != 1)
- 6: (only for LSTM) initial cell state, shape [num_dir, batch_size, hidden_size]
- 7: (optional for LSTM) Peepholes weights, shape [num_dir, n_cells, (M - 1) * hidden_size]
-
- Outputs:
- 0: Y output blob, shape [batch_size, num_dir, seq_len, hidden_size]
- 1: (optional) Y_h, shape [num_dir, batch_size, hidden_size]
- 2: (optional for LSTM) Y_c, shape [num_dir, batch_size, hidden_size]
-
- Where:
- M -- number of gates in this cell (4 for LSTM, 3 for GRU, 1 for RNN).
- num_dir -- number of directions ('forvard', 'bidirectional', 'reverse')
- n_cells -- number of cells in layer (always 1 for ONNX).
-
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.MXNetSplitMultiLayers import MXNetSplitLayersToRNNSequence
- return [MXNetSplitLayersToRNNSequence]
-
- def pattern(self):
- return dict(
- nodes=[
- ('rnn_layer', dict(kind='op', type='RNNSequence', format='mxnet')),
- ('input', dict(kind='data')),
- ('params', dict(kind='data')),
- ],
- edges=[
- ('input', 'rnn_layer', {'in': 0}),
- ('params', 'rnn_layer', {'in': 1}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- rnn_layer = match['rnn_layer']
-
- self.check_init_states(graph, match)
- self.repack_weights(graph, match)
- self.add_output_reshape(graph, match)
- self.check_input_ports(graph, match)
- rnn_layer['normalized'] = True
-
- @staticmethod
- def repack_weights(graph: Graph, match: dict):
- input = match['input']
- rnn_layer = match['rnn_layer']
- params = match['params'].value.copy()
-
- graph.remove_edge(match['params'].id, rnn_layer.id)
-
- input_size = input.shape[2]
- direction = 2 if rnn_layer.has_num_directions else 1
- bsize = (2 * rnn_layer.hidden_size * direction * 1) * rnn_layer.multiplier
-
- W = mo_array(params[0:len(params) - bsize])
- B = mo_array(params[len(params) - bsize:])
-
- W = W.reshape((direction, -1))
- B = B.reshape((direction, -1))
-
- W, R = mo_array(W[:, 0:rnn_layer.hidden_size * rnn_layer.multiplier * input_size]), mo_array(W[:, rnn_layer.hidden_size * rnn_layer.multiplier* input_size:])
-
- W, R = [x.reshape([
- direction, # 0: num of directions
- 1, # 1: num_cells
- rnn_layer.multiplier, # 2: four output parts of the matrix for all gates
- rnn_layer.hidden_size, # 3: output size per direction and gate
- -1]) # 4: input size/hidden size in W/R correspondingly
- for x in (W, R)]
-
- assert W.shape[-1] == input_size
- assert R.shape[-1] == rnn_layer.hidden_size
-
- B = B.reshape([
- direction, # 0: num of directions, limitation: should be 1
- 1,
- 2, # 3: num of component B
- rnn_layer.multiplier, # 1: four output parts of the matrix for all gates in order: i, f, c, o
- rnn_layer.hidden_size, # 2: output size per direction and gate
- ])
-
- # Reorder gates: ifco --> fico
- gate_reorder = rnn_layer.gate_order
- W = np.take(W, gate_reorder, axis=2)
- R = np.take(R, gate_reorder, axis=2)
- B = np.take(B, gate_reorder, axis=3)
-
- # Add ports to rnn_layer
- rnn_layer.add_sequence_of_ports(type='in', rng=range(7))
-
- for blob, port in [(W, 1), (R, 2), (B, 3)]:
- Op.create_and_connect_input_data_node(
- graph,
- rnn_layer,
- {'value': blob, 'shape': int64_array(blob.shape)},
- {'in': port, 'permutation': None}
- )
-
- @staticmethod
- def check_init_states(graph: Graph, match: dict):
- """
- Check if cell have initial states and create zeros states if not.
- And renumber ports for this states.
- """
- rnn_cell = match['rnn_layer']
- num_directions = 2 if rnn_cell.direction == 'bidirectional' else 1
- batch_size = rnn_cell.in_node(0).shape[rnn_cell.batch_dim]
-
- h_init_port = 5
- c_init_port = 6
-
- if 2 not in rnn_cell.in_nodes():
- h_shape = [num_directions, batch_size, rnn_cell.hidden_size] # from ONNX spec
- h_init = np.full(h_shape, 0, dtype=np.float32)
- Op.create_and_connect_input_data_node(
- graph,
- rnn_cell,
- {'value': h_init, 'shape': int64_array(h_init.shape)},
- {'in': h_init_port, 'permutation': None}
- )
- else:
- hidden_state_edge = graph.get_edge_data(rnn_cell.in_node(2).id, rnn_cell.id)
- hidden_state_edge[0]['in'] = h_init_port
-
- if rnn_cell.op == 'LSTM':
- if 3 not in rnn_cell.in_nodes():
- c_shape = [num_directions, batch_size, rnn_cell.hidden_size] # from ONNX spec
- c_init = np.full(c_shape, 0, dtype=np.float32)
- Op.create_and_connect_input_data_node(
- graph,
- rnn_cell,
- {'value': c_init, 'shape': int64_array(c_init.shape)},
- {'in': c_init_port, 'permutation': None}
- )
- else:
- cell_state_edge = graph.get_edge_data(rnn_cell.in_node(3).id, rnn_cell.id)
- cell_state_edge[0]['in'] = c_init_port
-
- @staticmethod
- def add_output_reshape(graph: Graph, match: dict):
- """
- Since MXNet Y output shape is [batch_size, seq_len, hidden_size * num_directions] we need to add reshape
- from above common format [batch_size, num_directions, seq_len, hidden_size] to MXNet format.
- """
- lstm = match['rnn_layer']
- input = match['input']
- if not lstm.has_num_directions:
- return
- old_data_node = lstm.out_node(0)
- num_directions = 2 if lstm.direction in ['bidirectional'] else 1
- mxnet_shape = lstm.out_node(0).shape.copy()
-
- if lstm.batch_dim == 0:
- mo_shape = shape_array([input.shape[lstm.batch_dim], input.shape[lstm.sequence_dim], lstm.hidden_size])
- else:
- mo_shape = shape_array([input.shape[lstm.sequence_dim], input.shape[lstm.batch_dim], lstm.hidden_size])
-
- if lstm.has_num_directions:
- mo_shape = shape_insert(mo_shape, 1, np.int64(num_directions))
-
- lstm_name = lstm.soft_get('name', lstm.id)
-
- new_data = Op._create_data_node(graph, name=lstm_name + '/Data/Reshape_mxnet/', attrs={'shape': mo_shape})
- graph.remove_edge(lstm.id, old_data_node.id)
- graph.add_edge(lstm.id, new_data.id, key=0, out=0)
-
- # Add Transpose
- permute_order = Const(graph, {'name': lstm_name + '/Transpose_mxnet_order',
- 'value': int64_array([0, 2, 1, 3])}).create_node_with_data()
- permute_data = Transpose(graph, {'name': lstm_name + '/Transpose_mxnet/'}
- ).create_node_with_data([new_data, permute_order])
-
- # Add Reshape
- reshape = Reshape(graph, {'name': lstm_name + '/Reshape_mxnet/'})
- reshape_dim_data = Const(graph, {'name': lstm_name + '/Reshape_mxnet_dim',
- 'value': int64_array(unmask_shape(mxnet_shape))}).create_node_with_data()
-
- reshape.create_node_with_data([permute_data, reshape_dim_data], dict(), data_nodes=[old_data_node])
-
- @staticmethod
- def check_input_ports(graph: Graph, match: dict):
- """
- Check that all mandatory ports is present.
- """
- rnn_layer = match['rnn_layer']
- mandatory_ports = [0, 1, 2, 3, 5]
-
- if rnn_layer.op == 'LSTM':
- mandatory_ports.append(6)
-
- assert set(rnn_layer.in_nodes().keys()) >= set(mandatory_ports)
diff --git a/tools/mo/openvino/tools/mo/middle/MXNetSplitMultiLayers.py b/tools/mo/openvino/tools/mo/middle/MXNetSplitMultiLayers.py
deleted file mode 100644
index 02b5b4f3c4d99f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MXNetSplitMultiLayers.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_insert, int64_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-
-
-class MXNetSplitLayersToRNNSequence(MiddleReplacementPattern):
- """
- Split MXNet multilayer cell to multiple one-layers cells LSTM/GRU/RNN.
- Also concatenate output hiddens and cells states of this layers.
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('rnn_layer', dict(kind='op', type='RNNSequence', format='mxnet', multilayers=True)),
- ('input', dict(kind='data')),
- ('params', dict(kind='data')),
- ],
- edges=[
- ('input', 'rnn_layer', {'in': 0}),
- ('params', 'rnn_layer', {'in': 1}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- output_states = self.split_multilayer_cell(graph, match)
-
- rnn_layer = match['rnn_layer']
- self.concat_output_states(graph, match, output_states)
- rnn_layer.graph.remove_node(rnn_layer.id)
-
- @staticmethod
- def get_new_cell(multilayer_cell: Node, number: int):
- cell_class = Op.get_op_class_by_name(multilayer_cell.op)
- new_cell = lambda graph, attrs: cell_class(graph, attrs)
- attrs = multilayer_cell.attrs().copy()
- new_attrs = {
- 'num_layers': 1,
- 'multilayers': False,
- 'name': multilayer_cell.name + '/LayerSplittedLSTM/{}'.format(number),
- }
- attrs.update(new_attrs)
- return new_cell(multilayer_cell.graph, attrs)
-
- def split_multilayer_cell(self, graph: Graph, match: dict):
- """
- Split one multilayer type=RNNSequence cell to num_layers consecutive cells.
- All parameters splits to parts for new num_layers cells.
- """
- input = match['input']
- rnn_layer = match['rnn_layer']
- params = match['params'].value.copy()
-
- have_hidden = False
- if 2 in rnn_layer.in_nodes():
- hidden_state_value = rnn_layer.in_node(2).value
- have_hidden = True
-
- have_cell = False
- if 3 in rnn_layer.in_nodes():
- cell_state_value = rnn_layer.in_node(3).value
- have_cell = True
-
- direction = 2 if rnn_layer.has_num_directions else 1
- num_layers = rnn_layer.num_layers
- input_size = input.shape[2]
- bsize = (2 * rnn_layer.hidden_size * direction * num_layers) * rnn_layer.multiplier
-
- size = rnn_layer.hidden_size * direction * rnn_layer.multiplier
- first_layer_params_size = (input_size + rnn_layer.hidden_size + 2) * size
- other_layer_params_size = (rnn_layer.hidden_size * direction + rnn_layer.hidden_size + 2) * size
- assert params.size == (first_layer_params_size + (num_layers - 1) * other_layer_params_size)
-
- input_node = input
- params_layer_size_count = 0
- output_states = [[], []]
-
- param_w = params[0:len(params)-bsize]
- param_b = params[len(params) - bsize:]
- layer_bsize = (2 * rnn_layer.hidden_size * direction) * rnn_layer.multiplier
-
- for l in range(num_layers):
- params_layer_size = first_layer_params_size if l == 0 else other_layer_params_size
-
- layer_params_w = param_w[params_layer_size_count: params_layer_size_count +
- (params_layer_size - layer_bsize)].copy()
- layer_params_b = param_b[layer_bsize*l: layer_bsize*l+layer_bsize].copy()
- layer_params = np.concatenate((layer_params_w, layer_params_b), axis=0)
- params_layer_size_count = params_layer_size_count + params_layer_size - layer_bsize
-
- op = self.get_new_cell(rnn_layer, l)
- name = str(rnn_layer.soft_get('name', rnn_layer.id))
- params_value_node = Const(
- rnn_layer.graph,
- dict(name=name + '/LayerSplittedParamsLSTM/{}/'.format(l), value=layer_params)
- ).create_node_with_data()
-
- if have_hidden:
- layer_hidden_state = hidden_state_value[l * direction: l * direction + direction] # pylint: disable=possibly-used-before-assignment
- hidden_state_value_node = Const(
- rnn_layer.graph,
- dict(name=name + '/LayerSplittedHiddenState/{}/'.format(l), value=layer_hidden_state)
- ).create_node_with_data()
- else:
- hidden_state_value_node = None
-
- if have_cell:
- layer_cell_state = cell_state_value[l * direction: l * direction + direction] # pylint: disable=possibly-used-before-assignment
- cell_state_value_node = Const(
- rnn_layer.graph,
- dict(name=name + '/LayerSplittedCellState/{}/'.format(l), value=layer_cell_state)
- ).create_node_with_data()
- else:
- cell_state_value_node = None
-
- if l < num_layers-1:
- output_data = Op._create_data_node(
- rnn_layer.graph,
- name=rnn_layer.out_node(0).name + '/LayerSplit/' + str(l),
- attrs={'shape': rnn_layer.out_node(0).shape.copy()}
- )
- else:
- output_data = rnn_layer.out_node(0)
-
- # Output nodes creating:
- state_size = int64_array([input.shape[rnn_layer.batch_dim], rnn_layer.hidden_size])
- if rnn_layer.has_num_directions:
- state_size = shape_insert(state_size, 0, direction)
-
- output_hidden = Op._create_data_node(
- rnn_layer.graph,
- name=rnn_layer.out_node(1).name + '/LayerSplit/' + str(l),
- attrs={'shape': mo_array(state_size)}
- )
-
- current_data_nodes = [output_data, output_hidden]
-
- if rnn_layer.op == 'LSTM':
- output_cell = Op._create_data_node(
- rnn_layer.graph,
- name=rnn_layer.out_node(2).name + '/LayerSplit/' + str(l),
- attrs={'shape': mo_array(state_size)}
- )
- current_data_nodes.append(output_cell)
-
- data_nodes = op.create_node_with_data(
- inputs=[
- input_node,
- params_value_node,
- hidden_state_value_node,
- cell_state_value_node
- ],
- data_nodes=current_data_nodes,
- )
-
- input_node = data_nodes[0]
- output_states[0].append(data_nodes[1])
-
- if rnn_layer.op =='LSTM':
- output_states[1].append(data_nodes[2])
-
- return output_states
-
- @staticmethod
- def concat_output_states(graph: Graph, match: dict, new_states: list):
- """ Concatenates output states from multilayer layer. """
- rnn_layer = match['rnn_layer']
- original_states = [rnn_layer.out_node(i) if i in rnn_layer.out_nodes() else None for i in [1, 2]]
-
- concat_ops = [
- Concat(rnn_layer.graph, {
- 'name': rnn_layer.name + '/FinalLayerSplitConcat/HiddenState',
- 'axis': -1
- }),
- Concat(rnn_layer.graph, {
- 'name': rnn_layer.name + '/FinalLayerSplitConcat/CellState',
- 'axis': -1
- })
- ]
-
- for i in range(len(original_states)): # [0] or [0, 1]
- if original_states[i] is None:
- continue
- concat_ops[i].attrs.update({'in_ports_count': len(new_states[i])})
- concat_ops[i].create_node_with_data(inputs=new_states[i], data_nodes=[original_states[i]])
diff --git a/tools/mo/openvino/tools/mo/middle/MXTileReplacer.py b/tools/mo/openvino/tools/mo/middle/MXTileReplacer.py
deleted file mode 100644
index ce5848f45e77dc..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MXTileReplacer.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class MXTileReplacer(MiddleReplacementPattern):
- """
- Aligns Tile operation from MxNet framework with OpenVINO Tile
-
- MxNet has no restrictions for `tile_array` input of `Tile` operation.
- If len(tile_array) > rank(data), this transformation will insert Unsqueeze before Tile operation,
- because in this case output_shape > input_shape
-
- DOC link: https://beta.mxnet.io/api/ndarray/_autogen/mxnet.ndarray.tile.html#mxnet.ndarray.tile
- """
-
- enabled = True
-
- 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)
- in_shape = node.in_port(0).data.get_shape()
- out_shape = node.out_port(0).data.get_shape()
-
- tile_array_diff = len(out_shape) - len(in_shape)
- if tile_array_diff == 0:
- return
- assert tile_array_diff > 0,\
- 'Unexpected difference between rank(input) and rank(output) for node {}'.format(name)
- unsqueeze_dims = int64_array(range(tile_array_diff))
- unsqueeze = create_op_node_with_second_input(graph, Unsqueeze, unsqueeze_dims,
- dict(name=name + '/Unsqueeze', override_output_shape=True))
- node.in_port(0).get_connection().insert_node(unsqueeze)
diff --git a/tools/mo/openvino/tools/mo/middle/MakeKaldiConstReshapable.py b/tools/mo/openvino/tools/mo/middle/MakeKaldiConstReshapable.py
deleted file mode 100644
index 50fc9d6a7771a4..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MakeKaldiConstReshapable.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input, create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.shape import Shape
-
-
-def create_const_with_batch_from_input(producer_port: Port, second_dim, value=0, precision=np.float32):
- """
- Create const with batch taken from input_out_port and second dimension equals second_dim
- :param producer_port: take batch from this port
- :param second_dim: second dimension for created constant
- :param value: value to initialize constant
- :param precision: precision for constant
- :return created constant node
- """
- graph = producer_port.node.graph
- input_name = producer_port.node.soft_get('name', producer_port.node.id)
-
- shape_of_input = None
- for dest in producer_port.get_destinations():
- if dest.node.soft_get('op') == "ShapeOf":
- shape_of_input = dest.node
- break
-
- if shape_of_input is None:
- shape_of_input = Shape(graph, {'name': input_name + '/Shape'}).create_node()
- shape_of_input.in_port(0).connect(producer_port)
-
- get_batch = None
- for dest in shape_of_input.out_port(0).get_destinations():
- if dest.node.soft_get('op') == "Crop" and \
- dest.node.in_port(1).get_source().node.soft_get('value', []) == int64_array([1]):
- get_batch = dest.node
- break
-
- if get_batch is None:
- get_batch = create_op_node_with_second_input(graph, Crop, int64_array([1]),
- {'name': shape_of_input.name + '/Crop',
- 'axis': int64_array([0]), 'offset': int64_array([0])},
- shape_of_input)
-
- mem_shape = None
- for dest in get_batch.out_port(0).get_destinations():
- if dest.node.soft_get('op') == "Concat" and \
- dest.node.in_port(1).get_source().node.soft_get('value', []) == int64_array([second_dim]):
- mem_shape = dest.node
- break
-
- if mem_shape is None:
- mem_shape = create_op_node_with_second_input(graph, Concat, int64_array([second_dim]),
- {'name': get_batch.name + '/Concat', 'axis': 0,
- 'in_ports_count': 2}, get_batch)
-
- init_value_prev_lstm_output = None
- for dest in mem_shape.out_port(0).get_destinations():
- if dest.node.soft_get('op') == "Broadcast" and \
- dest.node.in_port(1).get_source().node.soft_get('value', []) == mo_array([value], dtype=precision):
- init_value_prev_lstm_output = dest.node
- break
-
- if init_value_prev_lstm_output is None:
- init_value_prev_lstm_output = create_op_with_const_inputs(graph, Broadcast,
- {0: mo_array([value], dtype=precision)},
- {'name': mem_shape.name + '/Broadcast'})
- init_value_prev_lstm_output.in_port(1).connect(mem_shape.out_port(0))
-
- return init_value_prev_lstm_output
-
-
-class MakeKaldiConstReshapable(MiddleReplacementPattern):
- """
- Add broadcasting of constant nodes based on batch from Parameter node. This approach works only for Kaldi,
- because it has the same batch in whole graph due to framework specific.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['fw'] == "kaldi"]
-
- def run_after(self):
- from openvino.tools.mo.middle.InsertSelect import AddSelectBeforeMemoryNodePattern
- from openvino.tools.mo.middle.ReplaceMemoryOffsetWithSplice import ReplaceMemoryOffsetWithMemoryNodePattern
- from openvino.tools.mo.middle.ReplaceSpliceNodePattern import ReplaceSpliceNodePattern
- return [AddSelectBeforeMemoryNodePattern, ReplaceMemoryOffsetWithMemoryNodePattern,
- ReplaceSpliceNodePattern]
-
- def find_and_replace_pattern(self, graph: Graph):
- params = graph.get_op_nodes(op="Parameter")
- batch = params[0].shape[0]
-
- # check that all Parameters have the same batch
- for p in params:
- assert p.shape[0] == batch, \
- "Parameter {} has batch different from the {}".format(p.soft_get('name', p.id),
- params[0].soft_get('name', params[0].id))
-
- # make constants for initialization of ReadValue reshapable
- for read in graph.get_op_nodes(op='ReadValue'):
- input_node = read.in_port(0).get_source().node
- if input_node.soft_get('op') == "Const":
- const_shape = input_node.out_port(0).data.get_shape()
- # extra check to be sure that we don't break shapes compatibility in graph
- # in Kaldi models we have only 2 dimensions
- # and batch should be set the same as we will get from Parameter
- # otherwise just skip such node
- if len(const_shape) != 2 or const_shape[0] != batch:
- continue
- new_const = create_const_with_batch_from_input(params[0].out_port(0),
- const_shape[1],
- value=input_node.value[0], precision=input_node.data_type)
- input_node.out_port(0).get_connection().set_source(new_const.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/MarkSubgraphsWithCorrectLayout.py b/tools/mo/openvino/tools/mo/middle/MarkSubgraphsWithCorrectLayout.py
deleted file mode 100644
index 80d4cdc1b6f7bb..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MarkSubgraphsWithCorrectLayout.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from collections import deque
-from typing import Set
-
-from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import InsertLayoutPropagationTranspose, \
- mark_as_correct_data_layout, mark_output_as_in_correct_layout, mark_input_as_in_correct_layout
-from openvino.tools.mo.middle.LayoutChangeForConstantShapePaths import LayoutChangeForConstantShapePaths
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class MarkSubGraphsWithCorrectLayout(MiddleReplacementPattern):
- """
- The transformation looks for the layout agnostic operations which does not have a layout (NCHW or NHWC) and makes
- necessary changes to infer the part of the topology in the original layout:
- 1. Prevents from adding Transpose operations before and after "reinterp_shape" like operations which change rank of
- the input and output tensors of this layout agnostic op.
- 2. Disable attributes permutation for all intermediate ops between these "reinterp_shape" nodes.
- 3. Marks nodes along the weight path of convolutions as in correct layout to not permute them from NHWC to NCHW.
- The latest is needed for TF NCHW graphs as well. In Conv/Deconv infer functions "set_permutation()"
- ads "permutation" attr to weights data node even for NCHW, it is needed to permute Conv weights from the
- original TF layout into OV even for NCHW graphs. Therefore for TF models
- to prevent unwarranted permutations need to mark weights path as having correct layout even for NCHW graphs.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'tf']
- op_conditions = [lambda n: n.soft_get('op') == 'MatMul' and
- any([len(port.data.get_shape()) in (4, 5) for port in n.in_ports().values()]),
- ]
-
- def run_after(self):
- return [PostMiddleStart]
-
- def run_before(self):
- return [InsertLayoutPropagationTranspose]
-
- @staticmethod
- def get_input_nodes(node: Node):
- return [src_port.get_source().node for src_port in node.in_ports().values() if not src_port.disconnected()]
-
- @staticmethod
- def get_output_nodes(node: Node):
- result = []
- for out_port in node.out_ports().values():
- if not out_port.disconnected():
- for dest_port in out_port.get_destinations():
- result.append(dest_port.node)
- return result
-
- @staticmethod
- def bfs(start_nodes: list, visited: set, condition: callable = None, forward: bool = True):
- """
- The function performs BFS starting from selected nodes in forward or backward direction adding nodes by an
- optional condition
- :param start_nodes: Nodes to start search from
- :param visited: set of already visited nodes where traversing should not happen
- :param condition: function getting a Node as input and returning whether the node should be included into the
- result or not. If the value is None then the node is added unconditionally.
- :param forward: boolean flag specifying the traverse direction
- :return: the list of Nodes visited
- """
- assert visited is not None, 'The "visited" set must be defined'
- assert start_nodes is not None, 'The list of start nodes must be specified'
-
- result = list()
- d = deque(start_nodes)
- while len(d) != 0:
- cur_node = d.popleft()
- result.append(cur_node)
- visited.add(cur_node)
- if forward:
- next_nodes = MarkSubGraphsWithCorrectLayout.get_output_nodes(cur_node)
- else:
- next_nodes = MarkSubGraphsWithCorrectLayout.get_input_nodes(cur_node)
- for next_node in next_nodes:
- if next_node not in visited and (condition is None or condition(next_node)):
- d.append(next_node)
- return result
-
- def find_and_replace_pattern(self, graph: Graph):
- visited = set()
- marked_nodes = set()
- condition_forward = lambda n: not InsertLayoutPropagationTranspose.is_nhwc_to_nchw_transpose_needed(n)
- condition_backward = lambda n: not InsertLayoutPropagationTranspose.is_nchw_to_nhwc_transpose_needed(n)
- for node_condition in self.op_conditions:
- for node in graph.get_op_nodes():
- if node_condition(node):
- log.debug('Detected node "{}" as a node which should be executed in the original layout'
- ''.format(node.soft_get('name', node.id)))
- forward_visited_nodes = self.bfs([node], visited, condition_forward, True)
- backward_visited_nodes = self.bfs([node], visited, condition_backward, False)
-
- # find "reinterp_shape" like ops which change rank of input to 4D or 5D from smaller dimensions
- for back_node in backward_visited_nodes:
- for input_node in self.get_input_nodes(back_node):
- if input_node not in backward_visited_nodes and not condition_forward(input_node):
- marked_nodes.add(input_node)
-
- # find "reinterp_shape" like ops which change rank of input from 4D or 5D to smaller dimensions
- for forward_node in forward_visited_nodes:
- for output_node in self.get_output_nodes(forward_node):
- if output_node not in forward_visited_nodes and not condition_backward(output_node):
- marked_nodes.add(output_node)
-
- marked_nodes.update(forward_visited_nodes + backward_visited_nodes)
-
- if len(marked_nodes):
- log.debug('The following nodes will be executed in the original layout: {}'
- ''.format([n.soft_get('name', n.id) for n in marked_nodes]))
-
- # mark all matched nodes as in correct layout and disable attributes permutation for them
- for visited_node in marked_nodes:
- mark_as_correct_data_layout(visited_node)
- visited_node['nchw_layout'] = True
-
- _, nodes_weigths, nodes_in_weights = self.get_ports_and_nodes_on_weights(graph)
- for node in nodes_weigths:
- if node in nodes_in_weights:
- for ind, port in node.in_ports().items():
- if ind not in nodes_in_weights[node]:
- mark_input_as_in_correct_layout(node, ind)
- for ind, port in node.out_ports().items():
- mark_output_as_in_correct_layout(node, ind)
- else:
- mark_as_correct_data_layout(node)
- node['nchw_layout'] = True
-
- for node in self.get_ports_and_nodes_on_shape_subgraphs(graph)[1]:
- mark_as_correct_data_layout(node)
- node['nchw_layout'] = True
-
- @staticmethod
- def get_weighted_layer_type_to_in_weights_port():
- get_weights_port_index = lambda node: node.weights_index if node.has_valid('weights_index') else 1
- weighted_layer_type_to_in_weights_port = {
- 'Convolution': get_weights_port_index,
- 'DeformableConvolution': get_weights_port_index,
- 'Deconvolution': get_weights_port_index,
- 'BinaryConvolution': get_weights_port_index,
- }
- return weighted_layer_type_to_in_weights_port
-
- @staticmethod
- def insert_permute_inputs_before_dynamic_weights_subgraph(dynamic_subgraphs: Set[Node] = None):
- """
- The function inserts permutations on input nodes in the weights subgraph
- :param dynamic_subgraphs: Set of Nodes belonging to weight path subgraphs
- :return: the list of Nodes which are inputs to weight path subgraphs
- """
- dynamic_in_nodes = dict()
- for node in dynamic_subgraphs:
- node_type = node.soft_get('type')
- if node_type not in ['Const', 'Parameter', 'ShapeOf']:
- idx_lst = list()
- for idx in [idx for idx, port in node.in_ports().items() if
- not port.disconnected() and port.get_source().node not in dynamic_subgraphs]:
- PermuteInputs().set_input_permutation(node.in_node(idx), node, 'input:{}'.format(idx),
- 'transpose_nchw_to_nhwc')
- idx_lst.append(idx)
- if len(idx_lst):
- dynamic_in_nodes[node] = idx_lst
- return dynamic_in_nodes
-
- @staticmethod
- def walk_up_from_in_ports_to_out_ports(in_ports: Set[Port], out_ports: Set[Port], port_condition=None):
- r""""
- Returns all intermediate ports and nodes of such a sub-graph:
-
- out_ports
- | |
- \/ \/
- . . .
- | |
- \/ \/
- in_ports
- """
- visited_ports = set()
- visited_nodes = set()
-
- deque_of_in_ports = deque(in_ports)
- while len(deque_of_in_ports):
- in_port = deque_of_in_ports.popleft()
- if in_port.get_source() is None:
- continue
- source_node = in_port.get_source().node
- if in_port in visited_ports: # do not check visited_nodes as search is based on ports
- continue
- visited_ports.update({in_port, in_port.get_source()})
- if in_port.get_source() in out_ports: # reached source marked to stop the search
- if not len(in_port.get_source().node.in_ports()): # for Constants and Parameters to be visited
- visited_nodes.add(in_port.get_source().node)
- continue
- for idx, port in source_node.in_ports().items():
- if not port.disconnected() and (not port_condition or port_condition(source_node, idx)):
- deque_of_in_ports.append(port)
- visited_nodes.add(source_node)
- return visited_ports, visited_nodes
-
- @staticmethod
- def is_not_weight_port(node: Node, idx: int):
- w_types_to_in_port_dict = MarkSubGraphsWithCorrectLayout.get_weighted_layer_type_to_in_weights_port()
- node_type = node.soft_get('type')
- return node_type in w_types_to_in_port_dict.keys() and idx != w_types_to_in_port_dict[node_type](node)
-
- @staticmethod
- def get_ports_and_nodes_on_weights(graph):
- nodes = graph.get_op_nodes()
-
- # collect all input ports with weights
- weight_ports = set()
- result_ports = set()
- start_ports = set()
- w_types_to_in_port_dict = MarkSubGraphsWithCorrectLayout.get_weighted_layer_type_to_in_weights_port()
- for node in nodes:
- node_type = node.soft_get('type', 'unknown')
- if node_type not in w_types_to_in_port_dict.keys():
- if node_type in ['Const', 'Parameter', 'ShapeOf', 'ExtractImagePatches']:
- start_ports.add(node.out_port(0))
- continue
- weight_port_idx = w_types_to_in_port_dict[node_type](node)
- assert node.is_in_port_connected(weight_port_idx), \
- 'Unexpected port configuration of {} node with name=`{}`'.format(node_type,
- node.soft_get('name', node.id))
- weight_ports.add(node.in_port(weight_port_idx))
- for result in graph.get_op_nodes(type='Result'):
- result_ports.update(result.in_ports().values())
-
- # collect all sub-graphs that start with Constant/Parameter/ShapeOf/ExtractImagePatches and end at in_port as
- # weights
- ports_w, nodes_w = MarkSubGraphsWithCorrectLayout.walk_up_from_in_ports_to_out_ports(weight_ports, start_ports)
- # collect all sub-graphs that start with Constant/Parameter/ShapeOf/ExtractImagePatches, end at Result nodes and
- # not contains branches that end as weights
- ports_d, nodes_d = MarkSubGraphsWithCorrectLayout.walk_up_from_in_ports_to_out_ports(
- result_ports, start_ports, MarkSubGraphsWithCorrectLayout.is_not_weight_port)
- nodes_dif = nodes_w.difference(nodes_d)
- nodes_in_w = MarkSubGraphsWithCorrectLayout.insert_permute_inputs_before_dynamic_weights_subgraph(nodes_dif)
- return ports_w.difference(ports_d), nodes_dif, nodes_in_w
-
- @staticmethod
- def get_ports_and_nodes_on_shape_subgraphs(graph):
- shape_sources = {shape_of.out_port(0) for shape_of in graph.get_op_nodes(type='ShapeOf')}
- end_points = LayoutChangeForConstantShapePaths().find_shape_subgraph_endpoints(
- [shape.out_port(0) for shape in graph.get_op_nodes(type='ShapeOf')])
- ports, nodes = MarkSubGraphsWithCorrectLayout.walk_up_from_in_ports_to_out_ports(end_points, shape_sources)
- return ports, nodes
diff --git a/tools/mo/openvino/tools/mo/middle/MergeNodesPermutations.py b/tools/mo/openvino/tools/mo/middle/MergeNodesPermutations.py
deleted file mode 100644
index a97e9d8c26dcc6..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MergeNodesPermutations.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.ApplyNHWCtoNCHWpermutation import ApplyNHWCtoNCHWpermutation
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-
-
-class MergeNodesPermutations(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- return [ApplyNHWCtoNCHWpermutation]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- self.merge_nodes_permutations(graph)
-
- @staticmethod
- def merge_nodes_permutations(graph: Graph):
- # Iterate over all data nodes and check all permutations for similarity
- # In case of equal permutations, this permutation will be set as attribute for data node
- # otherwise exception will be raised
- for node in graph.nodes():
- node = Node(graph, node)
- if node.kind != 'data':
- continue
-
- permutations = []
-
- # Get all permutations from in edges
- for in_node in node.in_nodes():
- edge_attrs = node.graph.get_edge_data(in_node.id, node.id)[0]
- if 'permutation' in edge_attrs:
- permutations.append(edge_attrs['permutation'])
-
- # Get all permutations from out edges
- for out_node in node.out_nodes():
- edge_attrs = node.graph.get_edge_data(node.id, out_node.id)[0]
- if 'permutation' in edge_attrs:
- permutations.append(edge_attrs['permutation'])
-
- final_permutations = []
- for p in permutations:
- if p is not None:
- final_permutations.append(p.perm)
- else:
- final_permutations.append(int64_array(np.arange(node.shape.size)))
-
- if len(final_permutations) == 0:
- continue
-
- # Check that all permutations are equal
- if not all([np.array_equal(final_permutations[0], perm) for perm in final_permutations]):
- raise Error('Permutations requested for {} data node are not equal! List of permutations: {}'
- ''.format(node.name, [p.perm for p in permutations]))
-
- assert not node.has_valid('permutation') or np.array_equal(node.permutation, permutations[0])
- node['permutation'] = permutations[0]
diff --git a/tools/mo/openvino/tools/mo/middle/MoveConstToLoopBody.py b/tools/mo/openvino/tools/mo/middle/MoveConstToLoopBody.py
deleted file mode 100644
index f30944a676e1c7..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MoveConstToLoopBody.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.graph.graph import Graph
-
-
-class MoveConstToLoopBody(MiddleReplacementPattern):
- """
- It moves constant producers for Loop node into the body graph and removes input ports for them.
- This transformations helps to continue constant folding inside the body graph if possible.
- The constant folding serves as optimization path and helps to avoid issue connecting with constants
- lying on weights path to Convolution node.
- """
- enabled = True
- force_shape_inference = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PostMiddleStart
- return [PostMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.ApplyPermutations import ApplyPermutation
- return [ApplyPermutation]
-
- def find_and_replace_pattern(self, graph: Graph):
- cleanup_called_once = False
-
- # walk through all Loop nodes and find Const inputs
- for loop_node in graph.get_op_nodes(op='Loop'):
- # call clean-up only once that performs constant folding
- if not cleanup_called_once:
- graph.clean_up()
- cleanup_called_once = True
-
- # move constant node into the body graph and removes body parameter nodes corresponding to them
- Loop.pull_constant_inputs_into_body(loop_node)
-
- # since some input ports can be removed after the pulling constants, normalization of Loop node is required
- Loop.normalize_input_output_ports(loop_node)
-
- # perform shape inference for the Loop node again since new constant can be appeared
- # and constant folding can be helpful for weights path to Convolution node inside the body graph
- loop_node['need_shape_inference'] = True
diff --git a/tools/mo/openvino/tools/mo/middle/MulFakeQuantizeFuse.py b/tools/mo/openvino/tools/mo/middle/MulFakeQuantizeFuse.py
deleted file mode 100644
index d1a568d604bade..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/MulFakeQuantizeFuse.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from collections import defaultdict
-from typing import Dict, List
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.fusing.helpers import get_tensor_in_port, get_value_in_port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-
-
-def resolve_shared_inputs(node: Node, port_ids_to_duplicate: List[int]):
- """
- Duplicates shared constants that are consumed by more than one node.
- If constant is consumed by several ports of one node - no duplication gets done
- """
- graph = node.graph
-
- for port_id in port_ids_to_duplicate:
- dst_port_map = defaultdict(list)
- for dst in node.in_port(port_id).get_source().get_connection().get_destinations():
- dst_port_map[dst.node].append(dst.idx)
- del dst_port_map[node]
- value = node.in_port(port_id).data.get_value()
- if value is None:
- log.debug('Can not duplicate due no data for in_port {} of node {}'.format(port_id, node.name))
- for node, idxs in dst_port_map.items():
- const = Const(graph, {'value': mo_array(value),
- 'name': node.soft_get('name', node.id) + '/duplicated_'}).create_node()
- for idx in idxs:
- node.in_port(idx).disconnect()
- const.out_port(0).connect(node.in_port(idx))
- const.infer(const)
-
-
-class MulFakeQuantizeFuse(MiddleReplacementPattern):
- """ Fuses Mul --> FakeQuantize sequence if possible
- """
- enabled = False
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def pattern(self):
- return dict(
- nodes=[
- ('preop', dict(op='Mul', can_be_fused=True)),
- ('preoped', dict()),
- ('quantize', dict(op='FakeQuantize')),
- ],
- edges=[
- ('preop', 'preoped'),
- ('preoped', 'quantize', {'in': 0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- quantize = match['quantize']
- preop = match['preop']
-
- tensor_port, value_port = get_tensor_in_port(preop), get_value_in_port(preop)
-
- if value_port is None or value_port.data.get_value() is None:
- log.debug('MulQuantizeFuse: cannot fuse because Mul op has dynamic inputs')
- return
-
- mul_val = value_port.data.get_value()
- if np.any(mul_val <= 0):
- return
-
- # Direct modifications to quantize 1-st and 2-nd port inputs are performed.
- # So the data nodes at those inputs shouldn't have more than 1 consumer maximum 2 consumers to the same
- # quantize op (consumed by 1st and 2nd ports). So we duplicate FakeQuantize in_port 1, 2 data if needed
- resolve_shared_inputs(node=quantize, port_ids_to_duplicate=[1, 2])
-
- # TODO: need some special processing for values that exactly equal to threshold
-
- quantize.in_port(1).data.set_value(quantize.in_port(1).data.get_value() / mul_val)
- if quantize.in_node(1).id != quantize.in_node(2).id:
- quantize.in_port(2).data.set_value(quantize.in_port(2).data.get_value() / mul_val)
-
- # Reconnect Mul as it no longer needed for current FakeQuantize
- in_mul_connection = quantize.in_port(0).get_source().node.in_port(0).get_connection()
- quantize.in_port(0).disconnect()
- in_mul_connection.add_destination(quantize.in_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/ONNXRNNSequenceNormalize.py b/tools/mo/openvino/tools/mo/middle/ONNXRNNSequenceNormalize.py
deleted file mode 100644
index 0e003ecda9a295..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ONNXRNNSequenceNormalize.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_dims
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.op import Op
-
-
-class ONNXRNNSequenceNormalize(MiddleReplacementPattern):
- """
- Convert blobs and shapes of ONNX-like LSTM, GRU, RNN cells to common form (internal for MO).
- After this normalization pass passes for splitting bidirectional calls and
- multilayer cells will be applied.
-
- This transformation pass involves weights and shapes processing only:
- 1. Weights reshaping and reordering
- 2. Gates reordering
-
-
- Inputs will have the following order after normalising:
- 0: X input data, shape [batch_size, seq_len, input_size]
- 1: W weights blob, shape [num_dir, n_cells, M, hidden_size, input_size]
- 2: R weights blob, shape [num_dir, n_cells, M, hidden_size, hidden_size]
- 3: B biases blob, shape [num_dir, n_cells, 2, M, hidden_size]
- 4: (optional) sequence_length, shape [batch_size]
- 5: initial hidden state, shape [num_dir, batch_size, hidden_size]
- ([num_dir, n_cells, batch_size, hidden_size] if num_cells != 1)
- 6: (only for LSTM) initial cell state, shape [num_dir, batch_size, hidden_size]
- 7: (optional for LSTM) Peepholes weights, shape [num_dir, n_cells, (M - 1) * hidden_size]
-
- Outputs:
- 0: Y output blob, shape [batch_size, num_dir, seq_len, hidden_size]
- 1: (optional) Y_h, shape [num_dir, batch_size, hidden_size]
- 2: (optional for LSTM) Y_c, shape [num_dir, batch_size, hidden_size]
-
- Where:
- M -- number of gates in this cell (4 for LSTM, 3 for GRU, 1 for RNN).
- num_dir -- number of directions ('forvard', 'bidirectional', 'reverse')
- n_cells -- number of cells in layer (always 1 for ONNX).
- """
-
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('rnn_layer', dict(kind='op', type='RNNSequence', format='onnx')),
- ('input', dict(kind='data')),
- ('W', dict(kind='data')),
- ('R', dict(kind='data')),
- ],
- # We are not handling optional inputs
- edges=[
- ('input', 'rnn_layer', {'in': 0}),
- ('W', 'rnn_layer', {'bin': 'W'}),
- ('R', 'rnn_layer', {'bin': 'R'}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- self.repack_weights(graph, match)
- self.check_init_states(graph, match)
- self.check_input_ports(graph, match)
- match['rnn_layer']['normalized'] = True
-
- @staticmethod
- def repack_weights(graph: Graph, match: dict):
- """
- Repack weights into general format (described above) and reorder gates.
- """
- rnn_layer = match['rnn_layer']
- W = match['W'].value.copy()
- R = match['R'].value.copy()
- num_directions = 2 if rnn_layer.direction == 'bidirectional' else 1
-
- graph.remove_edge(match['W'].id, rnn_layer.id)
- graph.remove_edge(match['R'].id, rnn_layer.id)
-
- # find optional 'B' biases blob
- if 3 in rnn_layer.in_nodes():
- # TODO: check if 'bin': 'B' attribute is assigned to this edge
- B = rnn_layer.in_node(3).value.copy()
- graph.remove_edge(rnn_layer.in_node(3).id, rnn_layer.id)
- else:
- B_shape = [num_directions, 2 * rnn_layer.multiplier * rnn_layer.hidden_size] # from ONNX spec
- B = np.full(B_shape, 0, dtype=np.float32)
-
- # Add extra dimensions for W, R and B for easier repacking and reordering
- B = B.reshape([
- num_directions, # 0: num of directions
- rnn_layer.num_layers, # 1: num_layers
- 2, # 2: two input parts of the matrix: W, R
- rnn_layer.multiplier, # 3: four output parts of the matrix for all gates in order: i, o, f, c
- rnn_layer.hidden_size, # 4: output size per direction and gate
- ])
-
- W, R = [x.reshape([
- num_directions, # 0: num of directions
- rnn_layer.num_layers, # 1: num_layers
- rnn_layer.multiplier, # 2: four output parts of the matrix for all gates in order: i, o, f, c
- rnn_layer.hidden_size, # 3: output size per direction and gate
- -1]) # 4: input size/hidden size in W/R correspondingly
- for x in (W, R)]
-
- input_size = match['input'].shape[2]
- assert compatible_dims(input_size, W.shape[-1])
-
- # Reorder gates: iofc --> fico
- gate_reorder = rnn_layer.gate_order
- W, R = (np.take(x, gate_reorder, axis=2) for x in (W, R))
- B = np.take(B, gate_reorder, axis=3)
-
- for blob, port in [(W, 1), (R, 2), (B, 3)]:
- Op.create_and_connect_input_data_node(
- graph,
- rnn_layer,
- {'value': blob, 'shape': int64_array(blob.shape)},
- {'in': port, 'permutation': None}
- )
-
- @staticmethod
- def check_init_states(graph: Graph, match: dict):
- """
- Check if cell have initial states and create zeros states if not.
- """
- rnn_layer = match['rnn_layer']
- num_directions = 2 if rnn_layer.direction == 'bidirectional' else 1
- batch_size = rnn_layer.in_node(0).shape[rnn_layer.batch_dim]
-
- h_init_port = 5
- c_init_port = 6
-
- if h_init_port not in rnn_layer.in_nodes():
- h_shape = [num_directions, batch_size, rnn_layer.hidden_size] # from ONNX spec
- h_init = np.full(h_shape, 0, dtype=np.float32)
- Op.create_and_connect_input_data_node(
- graph,
- rnn_layer,
- {'value': h_init, 'shape': int64_array(h_init.shape)},
- {'in': h_init_port, 'permutation': None}
- )
-
- if rnn_layer.op == 'LSTM':
- if c_init_port not in rnn_layer.in_nodes():
- c_shape = [num_directions, batch_size, rnn_layer.hidden_size] # from ONNX spec
- c_init = np.full(c_shape, 0, dtype=np.float32)
- Op.create_and_connect_input_data_node(
- graph,
- rnn_layer,
- {'value': c_init, 'shape': int64_array(c_init.shape)},
- {'in': c_init_port, 'permutation': None}
- )
-
- @staticmethod
- def check_input_ports(graph: Graph, match: dict):
- """
- Check that all mandatory ports is present.
- """
- rnn_layer = match['rnn_layer']
- mandatory_ports = [0, 1, 2, 3, 5]
-
- if rnn_layer.op == 'LSTM':
- mandatory_ports.extend([6])
-
- assert set(rnn_layer.in_nodes().keys()) >= set(mandatory_ports)
diff --git a/tools/mo/openvino/tools/mo/middle/ONNXResize11ToInterpolate.py b/tools/mo/openvino/tools/mo/middle/ONNXResize11ToInterpolate.py
deleted file mode 100644
index bf70528df55d7d..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ONNXResize11ToInterpolate.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.activation_ops import Floor
-from openvino.tools.mo.ops.elementwise import Add, Div, Mul
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.layout import get_depth_dim, get_height_dim, get_width_dim
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-def convert_mode(onnx_mode: str) -> str:
- return {'nearest': 'nearest', 'linear': 'linear_onnx', 'cubic': 'cubic'}[onnx_mode]
-
-
-def replace_resize(graph: Graph, resize: Node):
- log.debug("Converting of ONNX Resize-11 to Interpolate-4 "
- "is triggered for node {}.".format(resize.soft_get('name', resize.id)))
-
- input_shape = resize.in_port(0).data.get_shape()
- input_rank = len(input_shape)
- resize_name = resize.soft_get('name', resize.id)
- if input_rank not in {4, 5}:
- log.warning('The input shape is not 4D or 5D for op with name {}'.format(resize_name))
- return
-
- assert (resize.is_in_port_connected(0) and (resize.is_in_port_connected(2) or resize.is_in_port_connected(3))), \
- "Scales or sizes inputs must be connected to Node {} with op {}.".format(resize.soft_get("name", resize.id),
- resize.op)
-
- assert resize.soft_get('coordinate_transformation_mode') != 'tf_crop_and_resize', \
- 'Mode tf_crop_and_resize is not supported for op {} with name {}'.format(resize.op,
- resize.soft_get("name", resize.id))
-
- layout = graph.graph['layout']
-
- if input_rank == 4:
- begin_dim = get_height_dim(layout, input_rank)
- end_dim = get_width_dim(layout, input_rank) + 1
- else:
- begin_dim = get_depth_dim(layout, input_rank)
- end_dim = get_width_dim(layout, input_rank) + 1
-
- sizes_ss = create_op_with_const_inputs(graph, StridedSlice,
- {1: int64_array([begin_dim]),
- 2: int64_array([end_dim]),
- 3: int64_array([1])},
- {'name': resize_name + '/StridedSlice_sizes',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])})
- scales_ss = create_op_with_const_inputs(graph, StridedSlice,
- {1: int64_array([begin_dim]),
- 2: int64_array([end_dim]),
- 3: int64_array([1])},
- {'name': resize_name + '/StridedSlice_scales',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])})
- axes_node = Const(graph,
- {'name': resize_name + '/axis',
- 'value': int64_array(np.arange(begin_dim, end_dim))}).create_node()
-
- shape_calculation_mode = 'sizes' if resize.is_in_port_connected(3) else 'scales'
-
- interpolate_node = Interpolate(graph, {'version': 'opset4',
- 'mode': convert_mode(resize.mode),
- 'coordinate_transformation_mode': resize.coordinate_transformation_mode,
- 'cube_coeff': resize.cube_coeff,
- 'nearest_mode': resize.nearest_mode,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'antialias': 0,
- 'shape_calculation_mode': shape_calculation_mode,
- 'in_ports_count': 4}).create_node()
-
- axes_node.out_port(0).connect(interpolate_node.in_port(3))
- shape_of = Shape(graph, {'name': resize_name + '/ShapeOf'}).create_node()
-
- add_node = create_op_with_const_inputs(graph, Add,
- {1: float_array([1.0e-5])},
- {'name': resize_name + '/Add'})
-
- dst_dtype = np.float32 # even if data_type=FP16 use float32 for shape values
-
- if not resize.is_in_port_connected(3):
- cast_shape_to_float = Cast(graph, {'dst_type': dst_dtype}).create_node()
- mul_node = Mul(graph, {'name': resize_name + '/Mul'}).create_node()
- shape_of.out_port(0).connect(cast_shape_to_float.in_port(0))
- cast_shape_to_float.out_port(0).connect(mul_node.in_port(0))
- cast_add_result_to_int = Cast(graph, {'dst_type': np.int64}).create_node()
- floor_node = Floor(graph, {'name': resize_name + '/Floor'}).create_node()
- mul_node.out_port(0).connect(add_node.in_port(0))
- add_node.out_port(0).connect(floor_node.in_port(0))
- floor_node.out_port(0).connect(cast_add_result_to_int.in_port(0))
- cast_add_result_to_int.out_port(0).connect(sizes_ss.in_port(0))
- sizes_ss.out_port(0).connect(interpolate_node.in_port(1))
- scales_ss.out_port(0).connect(interpolate_node.in_port(2))
-
- connection_of_resize_input = resize.in_port(0).get_connection()
- connection_of_resize_input.set_destination(interpolate_node.in_port(0))
-
- connection_of_scales = resize.in_port(2).get_connection()
- connection_of_scales.set_destination(scales_ss.in_port(0))
-
- connection_of_resize_input.get_source().connect(shape_of.in_port(0))
- connection_of_scales.get_source().connect(mul_node.in_port(1))
- else:
- cast_shape_to_float = Cast(graph, {'dst_type': dst_dtype}).create_node()
- cast_sizes_to_float = Cast(graph, {'dst_type': dst_dtype}).create_node()
- div_node = Div(graph, {'name': resize_name + '/Div'}).create_node()
- cast_sizes_to_float.out_port(0).connect(div_node.in_port(0))
- cast_shape_to_float.out_port(0).connect(div_node.in_port(1))
- shape_of.out_port(0).connect(cast_shape_to_float.in_port(0))
- div_node.out_port(0).connect(add_node.in_port(0))
- add_node.out_port(0).connect(scales_ss.in_port(0))
- scales_ss.out_port(0).connect(interpolate_node.in_port(2))
- sizes_ss.out_port(0).connect(interpolate_node.in_port(1))
-
- connection_of_resize_input = resize.in_port(0).get_connection()
- connection_of_resize_input.set_destination(interpolate_node.in_port(0))
-
- connection_of_sizes = resize.in_port(3).get_connection()
- connection_of_sizes.set_destination(sizes_ss.in_port(0))
-
- connection_of_resize_input.get_source().connect(shape_of.in_port(0))
- connection_of_sizes.get_source().connect(cast_sizes_to_float.in_port(0))
-
- rename_nodes([(resize, resize_name + '/delete'), (interpolate_node, resize_name)])
- resize.out_port(0).get_connection().set_source(interpolate_node.out_port(0))
-
-
-class ONNXResize11ToInterpolate(MiddleReplacementPattern):
- """
- The transformation replaces ONNX Resize 11 with Interpolate-4.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.InterpolateSequenceToInterpolate import InterpolateSequenceToInterpolate
- return [InterpolateSequenceToInterpolate]
-
- def find_and_replace_pattern(self, graph: Graph):
- resize11_ops = graph.get_op_nodes(op='ONNXResize11')
- for resize in resize11_ops:
- replace_resize(graph, resize)
diff --git a/tools/mo/openvino/tools/mo/middle/PartialInfer.py b/tools/mo/openvino/tools/mo/middle/PartialInfer.py
deleted file mode 100644
index d930baa45b19ad..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/PartialInfer.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import logging as log
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, shape_array, \
- dynamic_dimension_value, unmask_shape
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class PartialInfer(MiddleReplacementPattern):
- enabled = True
- run_not_recursively = True
-
- def run_after(self):
- from openvino.tools.mo.front.create_tensor_nodes import CreateTensorNodes
- return [CreateTensorNodes]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- dynamic_inputs = {}
- for parameter in graph.get_op_nodes(op='Parameter'):
- param_shape = parameter.soft_get('shape', shape_array(dynamic_dimension_value))
- if not is_fully_defined(param_shape):
- parameter_name = parameter.soft_get('name', parameter.id)
- dynamic_inputs[parameter_name] = param_shape
- partial_infer(graph)
diff --git a/tools/mo/openvino/tools/mo/middle/PoolV2ToAttributedPool.py b/tools/mo/openvino/tools/mo/middle/PoolV2ToAttributedPool.py
deleted file mode 100644
index 463b3daeacb78f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/PoolV2ToAttributedPool.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.pooling import Pooling
-
-
-class PoolV2ToAttributedPool(MiddleReplacementPattern):
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for pool_v2_node in graph.get_op_nodes(op='PoolingV2'):
- pool_v2_name = pool_v2_node.soft_get('name', pool_v2_node.id)
-
- pool_v1_node = Pooling(graph, {'window': pool_v2_node.in_port(1).data.get_value(),
- 'stride': pool_v2_node.in_port(2).data.get_value(),
-
- 'pad': pool_v2_node.pad,
- 'spatial_dims': pool_v2_node.spatial_dims,
- 'auto_pad': pool_v2_node.auto_pad,
- 'output_spatial_shape': pool_v2_node.output_spatial_shape,
- 'pad_spatial_shape': pool_v2_node.pad_spatial_shape,
-
- 'pool_method': pool_v2_node.pool_method,
- 'permute_attrs': pool_v2_node.permute_attrs,}).create_node()
-
- rename_nodes([(pool_v2_node, pool_v2_name + '/to_be_removed'), (pool_v1_node, pool_v2_name)])
-
- pool_v2_node.in_port(0).get_connection().set_destination(pool_v1_node.in_port(0))
- pool_v2_node.out_port(0).get_connection().set_source(pool_v1_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/PreserveRuntimeInfo.py b/tools/mo/openvino/tools/mo/middle/PreserveRuntimeInfo.py
deleted file mode 100644
index 259872c45bd17c..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/PreserveRuntimeInfo.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.MergeNodesPermutations import MergeNodesPermutations
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.runtime_info import OldAPIMapOrder
-
-
-class PreserveRuntimeInfo(MiddleReplacementPattern):
- """ This transformation preserves original layout for Parameter and Result nodes
- and adds old_api_map_order attribute in rt_info which stores the following information:
-
- Parameter:
- Order of the transpose which should be applied to Parameter with old API layout to
- obtain Parameter with new API layout.
-
- Result:
- Order of the transpose which should be applied to Result with new API layout to
- obtain Result with old API layout.
-
- This transformation shouldn't be applied for Parameter or Result nodes inside
- body graphs of any operations like If, TensorIterator, Loop etc. For this reason
- transformation should be executed non-recursively.
- """
- enabled = True
- run_not_recursively = True
-
- def run_after(self):
- return [MergeNodesPermutations]
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- self.preserve_rt_info(graph)
-
- @staticmethod
- def add_old_api_map_order_into_rt_info(op: Node):
- # rt info update
- assert op.has('rt_info'), 'Unable to preserve runtime information for node with name={}'.format(op)
-
- old_api_map = OldAPIMapOrder(version=0)
- attr_name = old_api_map.get_name()
- if (attr_name, old_api_map.get_version()) not in op.rt_info.info:
- op.rt_info.info[(attr_name, old_api_map.get_version())] = old_api_map
- return attr_name, old_api_map.get_version()
-
- @staticmethod
- def preserve_rt_info(graph: Graph):
- for op in graph.get_op_nodes(type='Parameter'):
- op_name = op.soft_get('name', op.id)
- if 'auto_disable_nhwc_to_nchw' in graph.graph['cmd_params'] and \
- graph.graph['cmd_params'].auto_disable_nhwc_to_nchw:
- rank = op.out_port(0).data.get_shape().size
- if rank < 4:
- continue
- order = list(range(rank))
- order.remove(1)
- order.append(1)
- order = int64_array(order)
- elif op.has_valid('permute_attrs') and not op.has_and_set('nchw_layout') and \
- op.out_node(0).has_valid('permutation'):
- permutation = op.out_node(0).permutation
- order = permutation.inv
- if np.array_equal(order, range(len(permutation.inv))):
- continue
-
- # keep input in the framework format
- transpose = create_op_node_with_second_input(
- graph, Transpose, permutation.perm,
- {'name': op_name + '/Transpose({})'.format(permutation.perm)})
-
- # source mode is used to keep tensor names at Parameter node
- op.out_port(0).get_connection().insert_node(transpose, "source")
-
- if op.has_valid('permute_attrs'):
- del op['permute_attrs']
- if op.out_node(0).has_valid('permutation'):
- del op.out_node(0)['permutation']
- else:
- continue
-
- rt_info_key = PreserveRuntimeInfo.add_old_api_map_order_into_rt_info(op)
- op.rt_info.info[rt_info_key].old_api_transpose_parameter(order)
-
- for op in graph.get_op_nodes(type='Result'):
- if op.in_ports():
- prev_node_out_port = op.in_port(0).get_connection().get_source()
- if prev_node_out_port is None:
- continue
- in_node = prev_node_out_port.node
- in_data_node = in_node.out_node(prev_node_out_port.idx)
-
- if 'auto_disable_nhwc_to_nchw' in graph.graph['cmd_params'] and \
- graph.graph['cmd_params'].auto_disable_nhwc_to_nchw:
- rank = prev_node_out_port.data.get_shape().size
- if rank < 4:
- continue
- order = list(range(rank - 1))
- order.insert(1, rank - 1)
- order = int64_array(order)
- elif in_data_node.has_and_set('permutation'):
- permutation = in_data_node['permutation']
- order = permutation.perm
-
- if np.array_equal(order, range(len(permutation.perm))):
- continue
-
- # keep result in the framework format
- transpose = create_op_node_with_second_input(graph, Transpose, permutation.inv)
- # preserve output node name as it is used as output name in legacy IE API
- transpose.name = in_node.name
- in_node.name += "/prev"
-
- op.in_port(0).get_connection().insert_node(transpose)
- else:
- continue
-
- rt_info_key = PreserveRuntimeInfo.add_old_api_map_order_into_rt_info(op)
- op.rt_info.info[rt_info_key].old_api_transpose_result(order)
diff --git a/tools/mo/openvino/tools/mo/middle/RNNSequenceNormalizeToIE.py b/tools/mo/openvino/tools/mo/middle/RNNSequenceNormalizeToIE.py
deleted file mode 100644
index c35fb3f39cd973..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RNNSequenceNormalizeToIE.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_delete, mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from openvino.tools.mo.utils.shape import node_to_get_shape_value_of_indices
-
-
-class RNNSequenceNormalize(MiddleReplacementPattern):
- """
- This class normalize RNNSequence layers to IE-compatible from of weights, inputs and outputs.
-
- In this pass next will be done:
- 1. Weights repack (squeeze all useless shapes in all blobs and concatenate W and R together, also add
- bin param and all similar staff )
- 1. UNSqueeze num directions (in states and )
- 2. Initial states squeeze
- 4. Renumbering inputs
- 5. Ports checks
-
- After this normalization this layer will have next format of inputs:
- 0: X input data, shape [batch_size, seq_len, input_size]
- 1: WR weights blob, shape [M * hidden_size, hidden_size + input_size]
- 2: B biases blob, shape [M * hidden_size]
- 3: (optional) sequence_length, shape [batch_size]
- 4: initial hidden state, shape [batch_size, hidden_size]
- 5: (only for LSTM) initial cell state, shape [batch_size, hidden_size]
- 6: (optional for LSTM) Peepholes weights, shape [(M - 1) * hidden_size]
-
- """
- force_shape_inference = True
-
- def run_after(self):
- from openvino.tools.mo.middle.DecomposeBidirectionalRNNSequence import DecomposeBidirectionalRNNSequence
- return [DecomposeBidirectionalRNNSequence]
-
- def pattern(self):
- return dict(
- nodes=[
- ('rnn_layer', dict(kind='op', type='RNNSequence')),
- ('input', dict(kind='data')),
- ('W', dict(kind='data')),
- ('R', dict(kind='data')),
- ('B', dict(kind='data')),
- ],
- edges=[
- ('input', 'rnn_layer', {'in': 0}),
- ('W', 'rnn_layer', {'in': 1}),
- ('R', 'rnn_layer', {'in': 2}),
- ('B', 'rnn_layer', {'in': 3}),
- ],
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- self.repack_weights(graph, match)
- if match['rnn_layer'].has_num_directions:
- self.unsqueeze_num_directions(graph, match)
- self.squeeze_initial_states(graph, match)
- self.reordering_inputs(graph, match)
- # some additional checks for ports number and similar stuff
-
- def repack_weights(self, graph: Graph, match: dict):
- # Concat W, R in IE- format
- # Delete useless num_dir dimensions and n_cells dimensions in W, R, B (peepholes?)
- lstm = match['rnn_layer']
- W, R, B = match['W'].value.copy(), match['R'].value.copy(), match['B'].value.copy()
-
- graph.remove_edge(match['W'].id, lstm.id)
- graph.remove_edge(match['R'].id, lstm.id)
- graph.remove_edge(match['B'].id, lstm.id)
-
- # Sum component of B that correspond to W and R
- if lstm.op == 'GRU' and lstm.linear_before_reset:
- B_shape = mo_array(B.shape)
- B_shape[3] = 4
- B_shape[2] = 1
- B_tmp = np.zeros(shape=B_shape, dtype=np.float32)
- B_tmp[:, :, :, 0, :] = B[:, :, 0, 0, :] + B[:, :, 1, 0, :]
- B_tmp[:, :, :, 1, :] = B[:, :, 0, 1, :] + B[:, :, 1, 1, :]
- B_tmp[:, :, :, 2, :] = B[:, :, 0, 2, :][:, :, np.newaxis, :]
- B_tmp[:, :, :, 3, :] = B[:, :, 1, 2, :][:, :, np.newaxis, :]
- B = B_tmp
- else:
- B = np.sum(B, axis=2, keepdims=True)
-
- # Concatenate W, R to IE-compatible format
- assert len(W.shape) == 5
- assert len(R.shape) == 5
- WR = np.concatenate([W, R], axis=4)
-
- # Squeeze useless dimensions
- assert WR.shape[0] == 1 # num_dir == 1
- assert WR.shape[1] == 1 # num_cells == 1
- assert B.shape[0] == 1
- assert B.shape[1] == 1
- WR = WR.squeeze(axis=(0, 1))
- B = B.squeeze(axis=(0, 1))
-
- # Flatten all output (0, 1) and input dimensions (2, 3)
- final_shape_WR = [WR.shape[0] * WR.shape[1], -1]
- assert final_shape_WR[0] == lstm.hidden_size * lstm.multiplier
- WR = WR.reshape(final_shape_WR)
-
- final_shape_B = final_shape_WR
- if lstm.op == 'GRU' and lstm.linear_before_reset:
- final_shape_B[0] = lstm.hidden_size * 4
- B = B.reshape(final_shape_B)
-
- # Squeeze fake dimension in B
- B = B.squeeze(axis=-1)
-
- for blob, port, name in [(WR, 1, 'weights'), (B, 2, 'biases')]:
- Op.create_and_connect_input_data_node(
- graph,
- lstm,
- {'value': blob, 'shape': int64_array(blob.shape)},
- {'in': port, 'bin': name, 'permutation': None}
- )
-
- @staticmethod
- def unsqueeze_num_directions(graph: Graph, match: dict):
- """ Assuming considered LSTM/GRU/RNN node should has num_directions in output shape and add Unsqueeze
- to match it.
- """
-
- rnn_layer = match['rnn_layer']
- rnn_layer_name = rnn_layer.soft_get('name', rnn_layer.id)
- # num_directions is at 1st position in output shape, and in 0st position in hidden and cell states
- # please refer to docs in this transform
-
- direction_dim = [1, 0, 0] # index of dimension with direction index
- for i in rnn_layer.out_nodes():
- old_data_node = rnn_layer.out_node(i)
- old_shape = old_data_node.shape.copy()
- new_shape = shape_delete(old_shape, direction_dim[i])
-
- data = Op._create_data_node(graph, name=rnn_layer.name + '/Out/{}/'.format(i), attrs={'shape': new_shape})
- graph.remove_edge(rnn_layer.id, old_data_node.id)
- graph.add_edge(rnn_layer.id, data.id, key=0, out=i)
-
- unsqueeze = Unsqueeze(graph, dict())
-
- unsqueeze_dim_data = Const(graph, {'name': rnn_layer.name + '/UnsqueezeNumDirections/{}/Dim'.format(i),
- 'value': int64_array([direction_dim[i]])}).create_node_with_data()
-
- unsqueeze.create_node_with_data([data, unsqueeze_dim_data],
- dict(name=rnn_layer_name + '/UnsqueezeNumDirections/{}'.format(i)),
- data_nodes=[old_data_node])
- @staticmethod
- def squeeze_initial_states(graph: Graph, match: dict):
- """
- Squeeze input initial states of recurrent node to 2-D shape.
- """
- hidden_init_port = 5
- cell_init_port = 6
-
- rnn_layer = match['rnn_layer']
- # Add input ports to rnn_layer
- rnn_layer.add_sequence_of_ports(type='in', rng=range(7))
- rnn_layer_name = rnn_layer.soft_get('name', rnn_layer.id)
-
- assert hidden_init_port in rnn_layer.in_nodes()
- hidden_size = rnn_layer.hidden_size
- shape = Shape(graph, dict(name=rnn_layer_name + '/ShapeOf')).create_node()
- rnn_layer.in_port(0).get_source().connect(shape.in_port(0))
-
- reshape_h = create_op_node_with_second_input(graph, Reshape, second_input_value=int64_array([-1, hidden_size]),
- op_attrs={'name': rnn_layer_name + '/HiddenStateResize',
- 'override_output_shape': True})
- rnn_layer.in_port(hidden_init_port).get_connection().insert_node(reshape_h)
-
- if rnn_layer.op == 'LSTM':
- assert cell_init_port in rnn_layer.in_nodes()
- reshape_c = create_op_node_with_second_input(graph, Reshape,
- second_input_value=int64_array([-1, hidden_size]),
- op_attrs={'name': rnn_layer_name + '/CellStateResize',
- 'override_output_shape': True})
- rnn_layer.in_port(cell_init_port).get_connection().insert_node(reshape_c)
-
- @staticmethod
- def reordering_inputs(graph: Graph, match: dict):
- """
- Reorder (renumbering) inputs to described format. We need to renumber initial states ports.
- """
- rnn_layer = match['rnn_layer']
- assert 5 in rnn_layer.in_nodes()
- hidden_state_edge = graph.get_edge_data(rnn_layer.in_node(5).id, rnn_layer.id)
- hidden_state_edge[0]['in'] = 4
-
- if rnn_layer.op == 'LSTM':
- assert 6 in rnn_layer.in_nodes()
- cell_state_edge = graph.get_edge_data(rnn_layer.in_node(6).id, rnn_layer.id)
- cell_state_edge[0]['in'] = 5
-
- @staticmethod
- def ports_checks(graph: Graph, match: dict):
- """
- Check that all mandatory ports is present.
- """
- rnn_layer = match['rnn_layer']
- mandatory_ports = [0, 1, 2, 4]
-
- if rnn_layer.op == 'LSTM':
- mandatory_ports.append(5)
-
- assert set(rnn_layer.in_nodes().keys()) >= set(mandatory_ports)
diff --git a/tools/mo/openvino/tools/mo/middle/ReluQuantizeFuse.py b/tools/mo/openvino/tools/mo/middle/ReluQuantizeFuse.py
deleted file mode 100644
index a9dbf849ff8ab4..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ReluQuantizeFuse.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from typing import Dict
-
-import numpy as np
-
-from openvino.tools.mo.middle.BinarizeWeightsM1P1 import BinarizeWeightsM1P1
-from openvino.tools.mo.middle.MulFakeQuantizeFuse import resolve_shared_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ReluFakeQuantizeMark(MiddleReplacementPattern):
- """
- This pass marks Relu operations that can be fused to FakeQuantize op with `removable_before_quantize` flag.
-
- 1. We count the number of Relu outputs that are Quantize and can absorb Relu (`quantized_to_fuse_count` attribute).
- 2. Relu is fusible if all its outputs can absorb it.
-
- """
- enabled = True
-
- def run_after(self):
- return [BinarizeWeightsM1P1]
-
- def run_before(self):
- from openvino.tools.mo.middle.SharedWeightsDuplication import SharedWeightsDuplication
- return [SharedWeightsDuplication]
-
- def pattern(self):
- return dict(
- nodes=[
- ('relu', dict(op='ReLU')),
- ('relu_d', dict()),
- ('quantize', dict(op='FakeQuantize')),
- ],
- edges=[
- ('relu', 'relu_d'),
- ('relu_d', 'quantize', {'in': 0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- relu = match['relu']
- quantize = match['quantize']
-
- if not relu.has_valid('quantized_to_fuse_count'):
- relu['quantized_to_fuse_count'] = 0
-
- if quantize.in_node(1).id == quantize.in_node(2).id:
- # Provisional limitation that related to binary quantization
- assert quantize.has_valid('levels') and quantize.levels == 2
-
- threshold = quantize.in_port(1).data.get_value()
- if threshold is None:
- log.debug('ReluQuantizeFuse: cannot fuse because FakeQuantize op has dynamic input on the 1st port. '
- 'levels=`{}`'.format(quantize.levels))
- return
-
- relu['quantized_to_fuse_count'] += 1
-
- else:
- assert quantize.has_valid('levels') and quantize.levels != 2
- min_value = quantize.in_port(1).data.get_value()
- if min_value is None:
- log.debug('ReluQuantizeFuse: cannot fuse because FakeQuantize op has dynamic input on the 1st port, '
- 'levels=`{}`'.format(quantize.levels))
- return
- if np.all(min_value >= 0):
- relu['quantized_to_fuse_count'] += 1
-
- relu['removable_before_quantize'] = relu['quantized_to_fuse_count'] == len(relu.out_port(0).get_destinations())
-
-
-class ClampQuantizeMark(MiddleReplacementPattern):
- """
- This pass marks Clamp operations that can be fused to FakeQuantize op with `removable_before_quantize` flag.
-
- 1. We count the number of Clamp outputs that are FakeQuantize and can absorb Clamp (`quantized_to_fuse_count` attribute)
- 2. Clamp is fusible if all its outputs can absorb it.
-
- """
- enabled = True
-
- def run_after(self):
- return [BinarizeWeightsM1P1]
-
- def run_before(self):
- from openvino.tools.mo.middle.SharedWeightsDuplication import SharedWeightsDuplication
- return [SharedWeightsDuplication]
-
- def pattern(self):
- return dict(
- nodes=[
- ('clamp', dict(op='Clamp')),
- ('clamp_d', dict()),
- ('quantize', dict(op='FakeQuantize')),
- ],
- edges=[
- ('clamp', 'clamp_d'),
- ('clamp_d', 'quantize', {'in': 0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- clamp = match['clamp']
- quantize = match['quantize']
- clamp_min = clamp.in_port(1).data.get_value()
- clamp_max = clamp.in_port(2).data.get_value()
- if clamp_min is None or clamp_max is None:
- log.debug('ReluQuantizeFuse: cannot fuse because Clamp op has dynamic input on the 1st or 2nd port')
- return
-
- if not clamp.has_valid('quantized_to_fuse_count'):
- clamp['quantized_to_fuse_count'] = 0
-
- if quantize.in_node(1).id == quantize.in_node(2).id:
- # Binary case is not tested so we won't fuse Clamp
- assert quantize.has_valid('levels') and quantize.levels == 2
- clamp['removable_before_quantize'] = False
- else:
- assert quantize.has_valid('levels') and quantize.levels != 2
- min_value = quantize.in_port(1).data.get_value()
- if min_value is None:
- log.debug('ReluQuantizeFuse: cannot fuse because FakeQuantize op has dynamic input on the 1st port, '
- 'levels=`{}`'.format(quantize.levels))
- return
- max_value = quantize.in_port(2).data.get_value()
- if max_value is None:
- log.debug('ReluQuantizeFuse: cannot fuse because FakeQuantize op has dynamic input on the 2nd port, '
- 'levels=`{}`'.format(quantize.levels))
- return
- if np.all(min_value >= clamp_min) and np.all(max_value <= clamp_max):
- clamp['quantized_to_fuse_count'] += 1
-
- clamp['removable_before_quantize'] = clamp['quantized_to_fuse_count'] == len(clamp.out_port(0).get_destinations())
-
-
-class ReluQuantizeFuse(MiddleReplacementPattern):
- """ Fuses ReLU --> FakeQuantize sequence if possible
-
- Relu --> FakeQuantize fusion is possible if:
- 1. Relu is consumed to 0-th port of FakeQuantize
- 2. FakeQuantize ports 1 and 2 defines such input range that 0 is not included
- """
- enabled = True
-
- def run_after(self):
- return [ReluFakeQuantizeMark]
-
- def run_before(self):
- from openvino.tools.mo.middle.SharedWeightsDuplication import SharedWeightsDuplication
- return [SharedWeightsDuplication]
-
- def pattern(self):
- return dict(
- nodes=[
- ('relu', dict(removable_before_quantize=True)),
- ('relu_d', dict()),
- ('quantize', dict(op='FakeQuantize')),
- ],
- edges=[
- ('relu', 'relu_d'),
- ('relu_d', 'quantize', {'in': 0}),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- quantize = match['quantize']
-
- if quantize.levels == 2:
- # extra logic due to special 1 & 2 port input meaning in binary case - it is threshold separating two quants
- threshold = quantize.in_port(1).data.get_value()
-
- # Direct modifications to quantize 1-st port input are performed.
- # So the data node at this input shouldn't have more than 1 consumer maximum 2 consumers to the same
- # quantize op (consumed by 1st and 2nd ports). So we duplicate FakeQuantize in_port 1 data if needed
- resolve_shared_inputs(node=quantize, port_ids_to_duplicate=[1])
-
- # As we restricted to binarization case only, so we need to detect from
- # which side of 0 FakeQuantize threshold resides:
- # if the threshold > 0, it remains the same;
- # if the threshold == 0, it also remains the same;
- # if the threshold < 0, it should be modified to -infinity that means that all inputs map to output_high
- modification_mask = threshold < 0
- threshold[modification_mask] = float('-inf')
-
- # Reconnect ReLU as it no longer needed for current FakeQuantize
- in_relu_connection = quantize.in_port(0).get_source().node.in_port(0).get_connection()
- quantize.in_port(0).disconnect()
- in_relu_connection.add_destination(quantize.in_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveDuplicationMemory.py b/tools/mo/openvino/tools/mo/middle/RemoveDuplicationMemory.py
deleted file mode 100644
index f62a5928b907f0..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveDuplicationMemory.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.crop import Crop
-
-
-class RemoveMemoryDuplicationPattern(MiddleReplacementPattern):
- """
- Remove Splice nodes with context that is included in context of another Splice with the same input
- """
- enabled = True
-
- def run_before(self):
- return [MergeNeighborSplicePattern]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(op='Splice'))],
- edges=[])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- mem = match['op']
- mem_shape = mem.in_port(0).data.get_shape()
- mem_parent = mem.in_port(0).get_source()
- context = mem['context']
-
- for child_port in mem_parent.get_destinations():
- child = child_port.node
- # check if we find Splice containing context 'context'
- if child['op'] == 'Splice' and child.id != mem.id and set(child['context']).issubset(set(context)):
- left_cont_out = child['context'][0]
- left_cont = context[0]
-
- for child_of_child in child.out_port(0).get_destinations():
- out_transfer = child_of_child.node
- out_transfer_port = child_of_child
- if out_transfer['op'] == 'Crop':
- # modify existing Crop to get right data from larger Splice
- out_transfer['offset'] = out_transfer['offset'] + (left_cont_out - left_cont) * mem_shape[-1]
- else:
- # insert Crop if we have not one
- child_of_child.disconnect()
- crop_node = Crop(graph, {'name': graph.unique_id(prefix='Splice_crop_'),
- 'offset': (left_cont_out - left_cont) * mem_shape[-1],
- 'dim': mo_array([len(child['context']) * mem_shape[-1]]),
- 'axis': mo_array([-1])}).create_node()
- child.out_port(0).connect(crop_node.in_port(0))
- crop_node.out_port(0).connect(child_of_child)
- crop_node.out_port(0).data.set_shape(child.out_port(0).data.get_shape())
-
- out_transfer_port = crop_node.in_port(0)
-
- # move edge to child from old Splice to larger
- out_transfer_port.disconnect()
- mem.out_port(0).connect(out_transfer_port)
-
- graph.remove_node(child.id)
-
-
-class MergeNeighborSplicePattern(MiddleReplacementPattern):
- """
- Merge Splices with neighbor contexts, for example: [-5, 0] and [0, 3] to context [-5, 3]
- """
- enabled = True
-
- def run_after(self):
- return [RemoveMemoryDuplicationPattern]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(op='Splice'))],
- edges=[])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- mem = match['op']
- mem_shape = mem.in_port(0).data.get_shape()
- mem_parent = mem.in_port(0).get_source()
- context = mem['context']
-
- for child_port in mem_parent.get_destinations():
- child = child_port.node
- if child['op'] == 'Splice' and child.id != mem.id and \
- (child['context'][0] == context[-1] or child['context'][0] == context[-1]):
-
- new_context = list(context)
- new_context.extend(list(child['context']))
- new_context = list(set(new_context))
- new_context.sort()
- if child['context'][0] == context[-1]:
- new_node = mem
- rem_node = child
- else:
- new_node = child
- rem_node = mem
-
- # reset edges from rem_node to new_node
- for out_port_rem in rem_node.out_port(0).get_destinations():
- out_transfer = out_port_rem.node
- out_transfer_shape = out_port_rem.data.get_shape().copy()
-
- out_port_rem.disconnect()
-
- if out_transfer['op'] == 'Crop':
- # modify existing Crop to get right data from larger Splice
- out_transfer['offset'] = out_transfer['offset'] + (len(new_context) - len(rem_node.context)) * mem_shape[-1]
- out_port_rem.connect(new_node.out_port(0))
- else:
- # insert Crop if we have not one
- crop_node = Crop(graph, {'name': graph.unique_id(prefix='Splice_crop_'),
- 'offset': (len(new_context) - len(rem_node.context)) * mem_shape[-1],
- 'dim': mo_array([len(rem_node['context']) * mem_shape[-1]]),
- 'axis': mo_array([-1])}).create_node()
- new_node.out_port(0).connect(crop_node.in_port(0))
- crop_node.out_port(0).connect(out_port_rem)
- crop_node.out_port(0).data.set_shape(out_transfer_shape)
-
- for out_port_rem in new_node.out_port(0).get_destinations():
- out_transfer = out_port_rem.node
- out_transfer_shape = out_port_rem.data.get_shape().copy()
-
- if out_transfer['op'] != 'Crop':
- # insert Crop if we have not one
- crop_node = Crop(graph, {'name': graph.unique_id(prefix='Splice_crop_'),
- 'offset': mo_array([0]),
- 'dim': mo_array([len(new_node['context']) * mem_shape[-1]]),
- 'axis': mo_array([-1])}).create_node()
- new_node.out_port(0).connect(crop_node.in_port(0))
- out_port_rem.disconnect()
- crop_node.out_port(0).connect(out_port_rem)
- crop_node.out_port(0).data.set_shape(out_transfer_shape)
-
- new_shape = new_node.out_port(0).data.get_shape()
- new_shape[1] += rem_node.out_port(0).data.get_shape()[1] - rem_node.in_port(0).data.get_shape()[1]
- new_node.out_port(0).data.set_shape(new_shape)
- new_node.context = new_context
-
- graph.remove_node(rem_node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveIdentity.py b/tools/mo/openvino/tools/mo/middle/RemoveIdentity.py
deleted file mode 100644
index ad887f0a96d06f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveIdentity.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class RemoveIdentity(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.InputCut import MiddleInputCut
- return [MiddleInputCut]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op', identity=True))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- remove_op_node_with_data_node(graph, match['op'])
-
-
-class RemoveDropout(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.InputCut import MiddleInputCut
- return [MiddleInputCut]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(op='Dropout'))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- remove_op_node_with_data_node(graph, match['op'])
-
-
-class RemoveNodesWithZeroPhase(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.InputCut import MiddleInputCut
- return [MiddleInputCut]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op', phase=0))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- remove_op_node_with_data_node(graph, match['op'])
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveRedundantReshapeAfterCropAndResize.py b/tools/mo/openvino/tools/mo/middle/RemoveRedundantReshapeAfterCropAndResize.py
deleted file mode 100644
index 022c91e4f3e121..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveRedundantReshapeAfterCropAndResize.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.middle.FuseReshapesSequence import FuseReshapesSequence
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class RemoveRedundantReshapeAfterCropAndResize(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def run_before(self):
- return [FuseReshapesSequence]
-
- def pattern(self):
- return dict(
- nodes=[
- ('crop_and_resize', dict(kind='op', op='CropAndResize')),
- ('crop_and_resize_data', dict(kind='data')),
- ('reshape_1', dict(kind='op', op='Reshape')),
- ('reshape_1_data', dict(kind='data')),
- ('reshape_2', dict(kind='op', op='Reshape')),
- ],
- edges=[
- ('crop_and_resize', 'crop_and_resize_data'),
- ('crop_and_resize_data', 'reshape_1'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_1_data', 'reshape_2'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- car_node = match['crop_and_resize']
- reshape_2_node = match['reshape_2']
-
- shape_1 = match['crop_and_resize_data'].shape
- shape_2 = match['reshape_2'].out_node().shape
- if not np.all(shape_1 == shape_2):
- log.debug('Cannot remove reshape operations after CropAndResize due to different shapes: {} vs {}'.format(
- shape_1, shape_2
- ))
- return
-
- car_node.out_port(0).disconnect()
- consumer_port_node = reshape_2_node.out_port(0).get_connection().get_destination()
- consumer_port_node.disconnect()
- car_node.out_port(0).connect(consumer_port_node)
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveRedundantReshapes.py b/tools/mo/openvino/tools/mo/middle/RemoveRedundantReshapes.py
deleted file mode 100644
index 70b96c73e7ca64..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveRedundantReshapes.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.middle.FuseReshapesSequence import FuseReshapesSequence
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class RemoveRedundantReshapes(MiddleReplacementPattern):
- """
- Finds Reshape layers that does nothing and removes them.
- """
- enabled = True
- force_clean_up = True
- run_not_recursively = True # non-unified data nodes view in TI body (no Const ops, bare data node)
-
- def run_after(self):
- return [FuseReshapesSequence]
-
- def run_before(self):
- return [PostMiddleStart]
-
- def find_and_replace_pattern(self, graph: Graph):
- for reshape_node in graph.get_op_nodes(type='Reshape'):
- in_ports = [port for port in reshape_node.in_ports().values() if not port.disconnected()]
- assert len(in_ports) == 2, "`Reshape` node must have 2 inputs"
- previous_dim_op = reshape_node.in_port(1).get_source().node.op
- if previous_dim_op != 'Const':
- continue
- dim = reshape_node.in_port(1).get_connection().data.get_value()
-
- in_shape = reshape_node.in_port(0).data.get_shape()
-
- if np.array_equal(dim, in_shape) and len(reshape_node.out_nodes()):
- log.debug("Useless reshape with dim {} was deleted: {}".format(str(dim), reshape_node.name))
- reshape_node.out_port(0).get_connection().set_source(reshape_node.in_port(0).get_source())
- graph.remove_nodes_from([reshape_node.out_node(0).id, reshape_node.id])
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveUselessConcatSplit.py b/tools/mo/openvino/tools/mo/middle/RemoveUselessConcatSplit.py
deleted file mode 100644
index 2fd5668b57a7a0..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveUselessConcatSplit.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class RemoveUselessConcatSplitPattern(MiddleReplacementPattern):
- r"""
- Remove useless construction with concat and split like follows:
- / / | \ \
- br1 br2 .. br(n-1)br(n)
- \ \ | / /
- concat
- |
- split
- / / | \ \
- br1 br2 .. br(n-1)br(n)
-
- """
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.ReplaceSpliceNodePattern import ReplaceSpliceNodePattern
- return [ReplaceSpliceNodePattern]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('concat', dict(op='Concat')),
- ('data', dict(kind='data')),
- ('split', dict(op='Split'))],
- edges=[('concat', 'data'),
- ('data', 'split')])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- concat_node = match['concat']
- split_node = match['split']
-
- # don't apply pass if concat have another outputs except split
- if len(concat_node.out_port(0).get_destinations()) != 1:
- return
-
- inputs = list(concat_node.in_ports().values())
- outputs = list(split_node.out_ports().values())
-
- if len(inputs) != len(outputs):
- return
-
- for i in range(len(inputs)):
- if not all(inputs[i].data.get_shape() == outputs[i].data.get_shape()):
- return
-
- for i in range(len(inputs)):
- outputs[i].get_connection().set_source(inputs[i].get_source())
- inputs[i].disconnect()
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveUselessCrops.py b/tools/mo/openvino/tools/mo/middle/RemoveUselessCrops.py
deleted file mode 100644
index b4a1e2bb82ad7b..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveUselessCrops.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class RemoveUselessCropsPattern(MiddleReplacementPattern):
- r"""
- Remove useless construction with crops and concat like follows:
- in_node
- / / | \ \
- crop crop .. crop crop
- \ \ | / /
- out_node
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.RemoveDuplicationMemory import MergeNeighborSplicePattern
- return [MergeNeighborSplicePattern]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('crop', dict(op='Crop')),
- ('data', dict(kind='data')),
- ('concat', dict(op='Concat'))],
- edges=[('crop', 'data'),
- ('data', 'concat', {'in': 0})])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- crop_node = match['crop']
- crop_node_parent_port = crop_node.in_port(0).get_source()
- concat_node = match['concat']
-
- if len(crop_node.out_port(0).get_destinations()) != 1:
- return
-
- outs = crop_node_parent_port.get_destinations()
- offsets_dims = list([])
- crop_list = list([])
- axis = crop_node['axis']
- for in_port in outs:
- out = in_port.node
- if out['op'] == 'Crop' and out['axis'] == axis and \
- len(out.out_port(0).get_destinations()) == 1 and \
- out.out_port(0).get_destination().node == concat_node:
- # crop type 1
- if 'dim' in out:
- offsets_dims.append((out['offset'], out['dim']))
- # crop type 3
- elif 'crop_begin' in out and 'crop_end' in out:
- offsets_dims.append((out['crop_begin'], out['crop_end']-out['crop_begin']))
- # crop type 2 with const dim
- elif not out.in_port(1).disconnected() and out.in_port(1).data.get_value() is not None:
- offsets_dims.append((out['offset'], out.in_port(1).data.get_value()))
- # crop type 2 with non-const dim or strange type of crop
- else:
- return
- crop_list.append(out)
-
- offsets_dims.sort(key=lambda off_dim: off_dim[0])
- size = 0
- for off_d in offsets_dims:
- if size != off_d[0]:
- return
- size = size + off_d[1]
-
- if size != crop_node_parent_port.data.get_shape()[axis]:
- return
-
- remove_concat = True
- free_port = None
- for inp in concat_node.in_ports():
- if not concat_node.in_port(inp).disconnected():
- in_node = concat_node.in_port(inp).get_source().node
- if in_node not in crop_list:
- remove_concat = False
- else:
- in_node.out_port(0).disconnect()
- free_port = inp
-
- if remove_concat:
- concat_outs = concat_node.out_port(0).get_destinations()
- for out in concat_outs:
- out.disconnect()
- crop_node_parent_port.connect(out)
- else:
- crop_node_parent_port.connect(concat_node.in_port(free_port))
diff --git a/tools/mo/openvino/tools/mo/middle/RemoveUselessPad.py b/tools/mo/openvino/tools/mo/middle/RemoveUselessPad.py
deleted file mode 100644
index 06c62c3bfb7c37..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/RemoveUselessPad.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class RemoveUselessPad(MiddleReplacementPattern):
- """
- The Pad layer is removed if all padding values are equal to 0 (Constant values).
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='Pad'):
- all_pads_zeros = True
- for in_port_ind in range(1, 3):
- input_node = node.in_port(in_port_ind).get_source().node
- value = input_node.soft_get('value', None)
- all_pads_zeros &= input_node.soft_get('type') == 'Const' and value is not None and np.all(value == 0)
-
- if all_pads_zeros:
- remove_op_node_with_data_node(graph, node)
diff --git a/tools/mo/openvino/tools/mo/middle/ReplaceMemoryOffsetWithSplice.py b/tools/mo/openvino/tools/mo/middle/ReplaceMemoryOffsetWithSplice.py
deleted file mode 100644
index e71bd6eaa9075b..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ReplaceMemoryOffsetWithSplice.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.splice import Splice
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.assign import Assign
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.read_value import ReadValue
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.utils.error import Error
-
-
-class ReplaceMemoryOffsetNodePattern(MiddleReplacementPattern):
- """
- Replace MemoryOffset with Splice
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.RemoveDuplicationMemory import RemoveMemoryDuplicationPattern
- return [RemoveMemoryDuplicationPattern]
-
- def run_after(self):
- from openvino.tools.mo.middle.split_tdnn_memoryoffset import SplitTdnnMemoryOffset
- return [SplitTdnnMemoryOffset]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(op='MemoryOffset', has_default=False))],
- edges=[])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- pair_node = Node(graph, node.pair_name)
-
- if pair_node.has_default:
- return
-
- if node.in_port(0).get_source() is not None:
- input_node_out_port = node.in_port(0).get_source()
- op_output_id = node.out_port(0).get_destination().node.id
- out_node_in_ports = pair_node.out_port(0).get_destinations()
- else:
- input_node_out_port = pair_node.in_port(0).get_source()
- op_output_id = pair_node.out_port(0).get_destination().node.id
- out_node_in_ports = node.out_port(0).get_destinations()
-
- in_shape = input_node_out_port.data.get_shape().copy()
-
- node_id = node.id
- node_name = node.name
- node_t = node.t
-
- splice = Splice(graph, {'name': node_name,
- 'id': node_id,
- 'context': int64_array(range(node_t, 1))
- if node_t < 0 else int64_array(range(0, node_t+1))}).create_node()
- splice.in_port(0).connect(input_node_out_port)
-
- # offset of Crop will be 0 (first element) if node_t < 0 and in_shape[1]*node_t (last element) if node_t > 0
- crop = Crop(graph, {'name': 'Splice_Crop',
- 'axis': int64_array([1]),
- 'offset': int64_array([max(0, in_shape[1] * node_t)]),
- 'dim': int64_array([in_shape[1]])}).create_node()
-
- splice.out_port(0).connect(crop.in_port(0))
- splice.out_port(0).data.set_shape(int64_array([in_shape[0], (abs(node_t) + 1) * in_shape[1]]))
-
- outs = input_node_out_port.get_destinations()
- for in_port in outs:
- out_ = in_port.node
- if out_.op == 'Concat' and out_ == out_node_in_ports[0].node:
- crop_input = Crop(graph, {'name': 'Splice_Crop',
- 'axis': int64_array([1]),
- 'offset': int64_array([-min(0, in_shape[1] * node_t)]),
- 'dim': int64_array([in_shape[1]])}).create_node()
- splice.out_port(0).connect(crop_input.in_port(0))
-
- in_port.disconnect()
- crop_input.out_port(0).connect(in_port)
- crop_input.out_port(0).data.set_shape(in_shape)
-
- for dest_port in out_node_in_ports:
- dest_port.connect(crop.out_port(0))
-
- graph.remove_node(op_output_id)
- graph.remove_node(node.id)
- graph.remove_node(pair_node.id)
-
-
-class ReplaceMemoryOffsetWithMemoryNodePattern(MiddleReplacementPattern):
- """
- Replace MemoryOffset with Memory if IfDefined used with it to avoid cycles
- """
- enabled = True
- force_shape_inference = True
-
- def run_before(self):
- from openvino.tools.mo.middle.RemoveDuplicationMemory import RemoveMemoryDuplicationPattern
- return [RemoveMemoryDuplicationPattern]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(op='MemoryOffset', has_default=True))],
- edges=[])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- pair_node = Node(graph, node.pair_name)
-
- if node.t >= 0:
- raise Error('Does not support IfDefined with t > 0')
-
- if node.in_port(0).get_source() is not None:
- input_port = node.in_port(0).get_source()
- op_output_id = node.out_port(0).get_destination().node.id
- out_port = pair_node.out_port(0)
- node_name = node.name
- pair_name = pair_node.name
- else:
- input_port = pair_node.in_port(0).get_source()
- op_output_id = pair_node.out_port(0).get_destination().node.id
- out_port = node.out_port(0)
- node_name = pair_node.name
- pair_name = node.name
-
- in_shape = input_port.data.get_shape()
- node_t = abs(node.t)
-
- init_value_memory_out = Const(graph, {'name': 'init_value_' + pair_name,
- 'value': np.zeros(int64_array([in_shape[0], in_shape[1]*node_t]), dtype=np.float32),
- 'shape': int64_array([in_shape[0], in_shape[1]*node_t])}).create_node()
- memory_out = ReadValue(graph, {'name': pair_name,
- 'variable_id': node_name+pair_name,
- 'variable_shape': None,
- 'variable_type': None
- }).create_node()
- init_value_memory_out.out_port(0).connect(memory_out.in_port(0))
-
- if node_t > 1:
- crop_concat = Crop(graph, {'name': 'Memory_crop', 'dim': mo_array([in_shape[1]*(node_t-1)]),
- 'offset': mo_array([in_shape[1]]), 'axis': mo_array([1])}).create_node()
- memory_out.out_port(0).connect(crop_concat.in_port(0))
- concat = Concat(graph, {'name': 'Memory_concat'}).create_node()
- concat.add_sequence_of_ports('in', range(2))
- crop_concat.out_port(0).connect(concat.in_port(0))
- concat.in_port(1).connect(input_port)
-
- memory_in = Assign(graph, {'name': node_name, 'variable_id': node_name + pair_name}).create_node()
- concat.out_port(0).connect(memory_in.in_port(0))
- out = Result(graph, {'name': 'Memory_output'}).create_node()
- memory_in.out_port(0).connect(out.in_port(0))
-
- crop_out = Crop(graph, {'name': 'Memory_crop_out', 'dim': mo_array([in_shape[1]]),
- 'offset': mo_array([0]), 'axis': mo_array([1])}).create_node()
- memory_out.out_port(0).connect(crop_out.in_port(0))
- out_port.get_connection().set_source(crop_out.out_port(0))
- else:
- memory_in = Assign(graph, {'name': node_name, 'variable_id': node_name + pair_name}).create_node()
- memory_in.in_port(0).connect(input_port)
- out = Result(graph, {'name': 'Memory_output'}).create_node()
- memory_in.out_port(0).connect(out.in_port(0))
- out_port.get_connection().set_source(memory_out.out_port(0))
-
- graph.remove_node(op_output_id)
- graph.remove_node(node.id)
- graph.remove_node(pair_node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/ReplacePNorm.py b/tools/mo/openvino/tools/mo/middle/ReplacePNorm.py
deleted file mode 100644
index a61254c32a338e..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ReplacePNorm.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.ReduceOps import ReduceSum
-from openvino.tools.mo.ops.elementwise import Pow
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class ReplacePNormNodePattern(MiddleReplacementPattern):
- """
- PNorm operation should be replaced by operations: Power(P) -> Reshape(n,c*g->n,g,c)-> ReduceSum(axis=1)-> Power(1/P)
- """
- enabled = True
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(op='pnorm'))],
- edges=[])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- shape = node.in_port(0).data.get_shape().copy()
-
- assert shape[1] % node.group == 0
-
- power_node = create_op_node_with_second_input(graph, Pow, node.p, {'name': node.id + '_power'})
-
- reshape_node = create_op_node_with_second_input(graph, Reshape,
- int64_array([shape[0], shape[1] / node.group, node.group]),
- {'name': node.id + '_reshape'})
- reshape_node.in_port(0).connect(power_node.out_port(0))
-
- reducesum_node = create_op_node_with_second_input(graph, ReduceSum,
- int64_array([2]),
- {'name': node.id + '_sum', 'keep_dims': False})
- reducesum_node.in_port(0).connect(reshape_node.out_port(0))
-
- invpower_node = create_op_node_with_second_input(graph, Pow, 1.0 / node.p, {'name': node.id + '_invpower'})
-
- invpower_node.in_port(0).connect(reducesum_node.out_port(0))
-
- node.in_port(0).get_connection().set_destination(power_node.in_port(0))
- node.out_port(0).get_connection().set_source(invpower_node.out_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/ReplaceSpliceNodePattern.py b/tools/mo/openvino/tools/mo/middle/ReplaceSpliceNodePattern.py
deleted file mode 100644
index ec34aa53b99b51..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ReplaceSpliceNodePattern.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.replace_lstm_node_pattern import unique_id
-from openvino.tools.mo.ops.split import VariadicSplit
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.assign import Assign
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.read_value import ReadValue
-from openvino.tools.mo.ops.result import Result
-
-
-class ReplaceSpliceNodePattern(MiddleReplacementPattern):
- r"""
- This pass decomposes Splice layer to the sequence Slice Concat and Memory layers
- For example:
- Let's suppose we have next graph:
-
- Input (N, H) -> Slice -> Next_Layer (N, k*H)
-
- Where (N, k*H) is is real input of subsequent topology.
- Splice is used for accumulation next (k-1)/2 and previous (k-1)/2 input data
-
- So this pass will convert this graph to the next one:
-
- Input [N, H] __
- / /
- Concat [N, k*H]
- / \
- Memory [N, k*H] -> Slice [N, (k-1)*H] Memory [N, k*H]
-
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.RemoveDuplicationMemory import MergeNeighborSplicePattern, RemoveMemoryDuplicationPattern
- return [MergeNeighborSplicePattern,
- RemoveMemoryDuplicationPattern]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[('op', dict(op='Splice'))],
- edges=[])
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- node = match['op']
- in_shape = node.in_port(0).data.get_shape().copy()
- memory_element = in_shape[1] - node.const_dim
- memory_size = memory_element * len(node.context)
-
- memory_pair_id = unique_id('id')
- # Memory(in)
- input_memory = ReadValue(graph, {'name': 'prev_splice_memory',
- 'variable_id': memory_pair_id,
- 'variable_shape': None,
- 'variable_type': None
- }).create_node()
-
- # Memory(in) \
- # Crop
- # Input(temp) /
- crop = Crop(graph, {'name': 'Splice_Crop',
- 'axis': int64_array([1]),
- 'offset': int64_array([memory_element]),
- 'dim': int64_array([memory_size - memory_element])}).create_node()
- crop.in_port(0).connect(input_memory.out_port(0))
-
- # Crop \
- # Concat
- # Input /
- concat_node = Concat(graph, {'name': 'Splice_Concat',
- 'in_ports_count': 2,
- 'axis': 1}).create_node()
- concat_node.in_port(0).connect(crop.out_port(0))
-
- # Concat -> Memory(out)
- mem_out = Assign(graph, {'name': 'out_splice_memory', 'variable_id': memory_pair_id}).create_node()
- mem_out.in_port(0).connect(concat_node.out_port(0))
- Result(graph).create_node().in_port(0).connect(mem_out.out_port(0))
-
- if node.const_dim != 0:
- memory_element_constdim = node.const_dim
- memory_size_constdim = memory_element_constdim * len(node.context)
-
- split = create_op_with_const_inputs(
- graph, VariadicSplit, {1: int64_array(1), 2: int64_array([memory_element, memory_element_constdim])},
- {'name': node.id + '_split_const', 'out_ports_count': 2})
-
- split.out_port(0).connect(concat_node.in_port(1))
-
- # create separate splice construction for const_dim
- memory_pair_id = unique_id('memory_for_const_dim')
- init_value_input_memory_const_dim = Const(graph, {'name': 'init_value_const_dim_in_memory',
- 'value': np.zeros(int64_array([in_shape[0],
- memory_size_constdim]), dtype=np.float32),
- 'shape': int64_array([in_shape[0],
- memory_size_constdim])}).create_node()
- input_memory_const_dim = ReadValue(graph, {'name': 'const_dim_in_memory',
- 'variable_id': memory_pair_id,
- 'variable_shape': None,
- 'variable_type': None
- }).create_node()
- init_value_input_memory_const_dim.out_port(0).connect(input_memory_const_dim.in_port(0))
-
- crop_const_dim = Crop(graph, {'name': 'const_dim_crop',
- 'axis': int64_array([1]),
- 'offset': int64_array([memory_element_constdim]),
- 'dim': int64_array(
- [memory_size_constdim - memory_element_constdim])}).create_node()
- crop_const_dim.in_port(0).connect(input_memory_const_dim.out_port(0))
-
- concat_node_const_dim = Concat(graph, {'name': 'const_dim_concat',
- 'in_ports_count': 2,
- 'axis': 1}).create_node()
- concat_node_const_dim.in_port(0).connect(crop_const_dim.out_port(0))
-
- mem_out_const_dim = Assign(graph, {'name': 'const_dim_out_memory',
- 'variable_id': memory_pair_id}).create_node()
- mem_out_const_dim.in_port(0).connect(concat_node_const_dim.out_port(0))
- Result(graph).create_node().in_port(0).connect(mem_out_const_dim.out_port(0))
-
- # connect splice to Split as begin and Concat as the end
- split.out_port(1).connect(concat_node_const_dim.in_port(1))
- crop_first = Crop(graph, {'name': 'const_dim_crop_first',
- 'axis': int64_array([1]),
- 'offset': int64_array([0]),
- 'dim': int64_array([memory_element_constdim])}).create_node()
- crop_first.in_port(0).connect(concat_node_const_dim.out_port(0))
-
- concat_const = Concat(graph, {'name': node.id + '_concat_const', 'axis': 1,
- 'in_ports_count': 2}).create_node()
- concat_const.in_port(1).connect(crop_first.out_port(0))
- concat_const.in_port(0).connect(concat_node.out_port(0))
-
- init_value_input_memory = Const(graph, {'name': 'init_value_' + node.name,
- 'value': np.zeros(int64_array([in_shape[0], memory_size]), dtype=np.float32),
- 'shape': int64_array([in_shape[0], memory_size])}).create_node()
- init_value_input_memory.out_port(0).connect(input_memory.in_port(0))
- node.in_port(0).get_connection().set_destination(split.in_port(0))
- node.out_port(0).get_connection().set_source(concat_const.out_port(0))
- else:
- init_value_input_memory = Const(graph, {'name': 'init_value_' + node.name,
- 'value': np.zeros(int64_array([in_shape[0], memory_size]), dtype=np.float32),
- 'shape': int64_array([in_shape[0], memory_size])}).create_node()
- init_value_input_memory.out_port(0).connect(input_memory.in_port(0))
- node.in_port(0).get_connection().set_destination(concat_node.in_port(1))
- node.out_port(0).get_connection().set_source(concat_node.out_port(0))
-
- # to avoid re-inference of shape and touching in next replacements
- graph.remove_node(node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/ReverseTransposeNormalization.py b/tools/mo/openvino/tools/mo/middle/ReverseTransposeNormalization.py
deleted file mode 100644
index fe1a9ff40a8ba0..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ReverseTransposeNormalization.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-
-
-class ReverseTransposeNormalization(MiddleReplacementPattern):
- enabled = True
- force_shape_inference = True
-
- def pattern(self):
- return dict(
- nodes=[('transpose', dict(type='Transpose', reverse_order=True))],
- edges=[],
- )
-
- def replace_pattern(self, graph: Graph, match: [str, Node]):
- node = match['transpose']
- assert len(node.in_nodes()) == 1
- order = np.arange(len(node.in_port(0).data.get_shape()))[::-1]
- const = Const(graph, {'value': order, 'name': node.soft_get('name', node.id) + '/Order'}).create_node()
- node.add_input_port(1, skip_if_exist=True)
- const.out_port(0).connect(node.in_port(1))
- node['reverse_order'] = False
diff --git a/tools/mo/openvino/tools/mo/middle/ReverseV2ToReverseSequence.py b/tools/mo/openvino/tools/mo/middle/ReverseV2ToReverseSequence.py
deleted file mode 100644
index 18b0e9ff0609e3..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/ReverseV2ToReverseSequence.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.reverse_sequence import ReverseSequence
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, rename_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.broadcast import Broadcast
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from openvino.tools.mo.utils.shape import node_to_get_shape_value_of_indices
-
-
-class ReverseToReverseSequence(MiddleReplacementPattern):
- """
- Transformation converts Reverse to ReverseSequence operation.
- Parameters for ReverseSequence calculates in the following way:
- * seq_axis - set axis value from Reverse operation
- * batch_axis - set 0 if seq_axis is not 0 otherwise set 1
- * seq_lengths - take from shape shape[seq_axis] value and broadcast it to vector with shape[batch_axis] length
- If input is 1D tensor then we add one more dimension to set different seq_axis and batch_axis.
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.PartialInfer import PartialInfer
- return [PartialInfer]
-
- def run_before(self):
- from openvino.tools.mo.middle.reverse_tensor_iterator import ReverseTensorIteratorLSTM
- return [ReverseTensorIteratorLSTM]
-
- def find_and_replace_pattern(self, graph: Graph):
- reverse_nodes = graph.get_op_nodes(op='Reverse')
- for reverse in reverse_nodes:
- reverse_name = reverse.soft_get('name', reverse.id)
-
- assert reverse.in_port(1).disconnected()
- assert reverse.has_valid('axis')
-
- in_shape_rank = len(reverse.in_port(0).data.get_shape())
- # 1. Add new dimension as batch for rank = 1 to have batch != seq_axis
- if in_shape_rank == 1:
- unsq_node = create_op_node_with_second_input(graph, Unsqueeze, int64_array([0]),
- {'name': reverse_name+"/Unsqueeze"})
- reverse.in_port(0).get_source().connect(unsq_node.in_port(0))
- new_in = unsq_node.out_port(0)
- batch_axis = 0
- seq_axis = 1
- else:
- new_in = reverse.in_port(0).get_source()
- seq_axis = reverse['axis']
- batch_axis = 0 if seq_axis != 0 else 1
-
- # 2. For ReverseSequence 1-port input is seq_lengths => create this input node as
- # shape[seq_axis] broadcasted to shape[batch_axis]
- # in ---> ShapeOf ----> Gather(seq_axis) ----> Broadcast----->
- # | |
- # | -------> Gather(batch_axis)----------|
- shape_node = Shape(graph, {'name': reverse_name + "/Shape"}).create_node()
- new_in.connect(shape_node.in_port(0))
- seq_axis_node = node_to_get_shape_value_of_indices(shape_node, [seq_axis])
- batch_node = node_to_get_shape_value_of_indices(shape_node, [batch_axis])
- broadcast_node = Broadcast(graph, {'name': reverse_name + "/Broadcast"}).create_node()
- broadcast_node.in_port(0).connect(seq_axis_node.out_port(0))
- broadcast_node.in_port(1).connect(batch_node.out_port(0))
-
- # 3. Create new ReverseSequence node and reconnect all inputs/outputs to it
- rename_node(reverse, reverse_name + '/to_delete')
- reverse_sequence = ReverseSequence(graph, {'name': reverse_name, 'seq_axis': seq_axis,
- 'batch_axis': batch_axis}).create_node()
- reverse_sequence.in_port(0).connect(new_in)
- reverse_sequence.in_port(1).connect(broadcast_node.out_port(0))
-
- # 4. remove added dimension for rank = 1
- if in_shape_rank == 1:
- rename_node(reverse_sequence, reverse_name + '/ReverseSequence')
- squeeze_node = create_op_node_with_second_input(graph, Squeeze, int64_array([0]),
- {'name': reverse_name})
- squeeze_node.in_port(0).connect(reverse_sequence.out_port(0))
- reverse.out_port(0).get_connection().set_source(squeeze_node.out_port(0))
- else:
- reverse.out_port(0).get_connection().set_source(reverse_sequence.out_port(0))
-
- # 5. Delete old Reverse node
- graph.remove_nodes_from([reverse.id for reverse in reverse_nodes])
diff --git a/tools/mo/openvino/tools/mo/middle/SSliceComplex.py b/tools/mo/openvino/tools/mo/middle/SSliceComplex.py
deleted file mode 100644
index d7c5abd5cce882..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/SSliceComplex.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from typing import Dict
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import add_constant_to_negative_values, create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.transpose import Transpose
-
-
-class SSliceComplex(MiddleReplacementPattern):
- """
- Some TF models contain the sub-graph
- SomeOp
- |
- --------------------------
- | |
- StridedSlice StridedSlice
- | |
- ------------------------
- Complex
- |
- | other inputs
- | | ... |
- -------------------
- SomeOp1
-
- Here SomeOp is some node with the real output and with the shape [N_0, ..., N_{k - 1}, 2, N_{k +1}, ..., N_{r - 1}],
- and StridedSlice nodes have output shapes [N_0, ..., N_{k - 1}, N_{k +1}, ..., N_{r - 1}].
-
- But MO and OpenVINO do not support complex tensors. Hence, we need to replace this sub-graph with.
- 1. If k == r - 1, then the replacement should be the subgraph
-
- SomeOp other inputs
- | | ... |
- -------------------
- SomeOp1
-
- 2. In the other case, that is if 0 <= k and k < r - 1 the replacement should be the subgraph
-
- SomeOp
- |
- Transpose -- input_order
- |
- |
- | other inputs
- | | ... |
- -------------------
- SomeOp1
-
- where the input_order is a Constant, and the value of input_order is [0, ..., k - 1, k + 1, ..., r - 1, k].
- """
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[
- ('strided_slice_real', dict(kind='op', op='StridedSlice')),
- ('strided_slice_real_data', dict(kind='data')),
- ('strided_slice_imag', dict(kind='op', op='StridedSlice')),
- ('strided_slice_imag_data', dict(kind='data')),
- ('complex', dict(op='Complex')),
- ],
- edges=[
- ('strided_slice_real', 'strided_slice_real_data'),
- ('strided_slice_imag', 'strided_slice_imag_data'),
- ('strided_slice_real_data', 'complex', {'in': 0}),
- ('strided_slice_imag_data', 'complex', {'in': 1}),
- ])
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- strided_slice_real = match['strided_slice_real']
- strided_slice_imag = match['strided_slice_imag']
-
- real_input = strided_slice_real.in_port(0).get_source().node
- imag_input = strided_slice_imag.in_port(0).get_source().node
- if real_input.id != imag_input.id:
- log.debug('The pattern does not correspond to operation for complex tensor. Different inputs.')
- return
-
- real_slices = np.array(strided_slice_real.slices)
- imag_slices = np.array(strided_slice_imag.slices)
-
- zeros_in_real_input_slices = np.argwhere(real_slices==0).flatten()
- ones_in_imag_input_slices = np.argwhere(imag_slices==1).flatten()
-
- if len(zeros_in_real_input_slices) != 1 or len(ones_in_imag_input_slices) != 1:
- return
-
- slice_dim_for_real_part = zeros_in_real_input_slices[0]
- slice_dim_for_imag_part = ones_in_imag_input_slices[0]
- if slice_dim_for_real_part != slice_dim_for_imag_part:
- return
-
- emulated_complex_tensor_shape = strided_slice_real.in_port(0).data.get_shape()
- if emulated_complex_tensor_shape is None:
- return
-
- emulated_complex_tensor_rank = len(emulated_complex_tensor_shape)
- complex_node = match['complex']
-
- for dst in complex_node.out_port(0).get_connection().get_destinations():
- after_complex_node = dst.node
- # TODO: now it does not support adjustment of `axis` inputs for other operations such Gather, Concat, etc.
- # It does not traverse the full path affected by complex numbers for adjusting the corresponding operations.
- # It can affect other models with complex numbers for which we can generate incorrect IRs or offline transformation fails.
- if after_complex_node.type == 'Roll':
- add_constant_to_negative_values(after_complex_node, 2, int64_array(emulated_complex_tensor_rank))
-
- input_slices_have_ellipsis = len(np.argwhere(real_slices == Ellipsis).flatten()) != 0
-
- # If output of SomeOp is sliced on the last dimension on the last dimension (like described in 1 case), skipping Complex op is enough.
- # Otherwise, (like described in 2 case) Transpose insertion is needed to align data arrangement.
- if slice_dim_for_real_part == emulated_complex_tensor_rank - 1 or input_slices_have_ellipsis:
- complex_node.out_port(0).get_connection().set_source(strided_slice_real.in_port(0).get_source())
- else:
- complex_node_name = complex_node.soft_get('name', complex_node.id)
- perm = int64_array([*range(0, slice_dim_for_real_part),
- *range(slice_dim_for_real_part + 1, emulated_complex_tensor_rank),
- slice_dim_for_real_part])
- transpose = create_op_with_const_inputs(graph, Transpose, {1: perm},
- {'name': complex_node_name + '/cmplx'})
- complex_node.out_port(0).get_connection().set_source(transpose.out_port(0))
- strided_slice_real.in_port(0).get_source().connect(transpose.in_port(0))
- rename_nodes([(complex_node, complex_node_name + '/to_be_removed'), (transpose, complex_node_name)])
diff --git a/tools/mo/openvino/tools/mo/middle/SharedWeightsDuplication.py b/tools/mo/openvino/tools/mo/middle/SharedWeightsDuplication.py
deleted file mode 100644
index aa29c4cdd02a13..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/SharedWeightsDuplication.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.op import Op
-
-
-class SharedWeightsDuplication(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.CheckForCycle import CheckForCycle
- return [CheckForCycle]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def find_and_replace_pattern(self, graph: Graph):
- """
- This function finds all const data nodes that have more that one consumer and then duplicate them
- """
- data_nodes = [Node(graph, id) for id in graph.nodes() if Node(graph, id).soft_get('kind') == 'data']
- for node in data_nodes:
- # Check that node has const values and more than one consumer
- if len(node.in_nodes()) and node.in_node().soft_get('type') == 'Const' and len(node.out_nodes()) > 1 and \
- node.value is not None:
- # Here we delete all edges between base node and it's consumers (except first), and then duplicate this
- # node to connect with other consumers
- for v, d in node.get_outputs():
- out_node = Node(graph, v)
- e_attrs = d
- graph.remove_edge(node.id, out_node.id)
- data = Op.create_input_data_node(graph, "Copy_{}".format(node.id), mo_array(node.value),
- graph.node[node.id])
-
- graph.add_edges_from([(data.id, out_node.id, e_attrs)])
-
diff --git a/tools/mo/openvino/tools/mo/middle/SliceConverter.py b/tools/mo/openvino/tools/mo/middle/SliceConverter.py
deleted file mode 100644
index 0b679cab332139..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/SliceConverter.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.clamp import Clamp
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-def create_ss_interval_border(graph: Graph, slice_border_port: Port, shape: np.ndarray, axes: np.ndarray, node_name: str):
- """
- This function creates "begin"/"end" parameters for the StridedSlice based on Slice's "starts"/"ends"
-
- :param graph: graph to operate on.
- :param slice_border_port: node output port that provides "starts"/"ends" values for the Slice.
- :param shape: input shape of the Slice
- :param axes: axes that "starts" and "ends" apply to
- :param node_name: Slice node name
- :return: Concat node that forms "begin"/"end" values for the StridedSlice
- """
- # the value for 'starts' or 'ends' might be maximum/minimum possible value of int64. This
- # value must be converted to maximum/minimum of int32 because such big values do not fit into the int32 which is
- # supported by the StridedSlice layer
- clamp = create_op_with_const_inputs(
- graph, Clamp, port_value_dict={1: np.iinfo(np.int32).min, 2: np.iinfo(np.int32).max},
- op_attrs=dict(name=node_name + '/Clamp'))
- clamp.in_port(0).connect(slice_border_port)
- # we have to convert "starts"/"ends" values from the network to one data type with constant values that are created
- # here to prevent type errors in Concat node
- cast = Cast(graph, dict(name=node_name + '/CastToI64', dst_type=np.int64)).create_node()
- cast.in_port(0).connect(clamp.out_port(0))
- concat = Concat(graph, dict(name=node_name + '/Concat', axis=0)).create_node()
- for value_idx, port_idx in enumerate(axes):
- concat.add_input_port(port_idx)
- # "axes" may not be sorted, so we need to split "starts"/"ends" values and connect each value to the correct
- # Concat input port
- value = create_op_with_const_inputs(
- graph, Gather, port_value_dict={1: int64_array([value_idx]), 2: int64_array(0)},
- op_attrs={'name': node_name + '/Gather'})
- cast.out_port(0).connect(value.in_port(0))
- value.out_port(0).connect(concat.in_port(port_idx))
- for port_idx in range(len(shape)):
- if not concat.is_in_port_connected(port_idx):
- concat.add_input_port(port_idx)
- # This border value would be ignored in StridedSlice because of the begin_mask\end_mask
- const = Const(graph, dict(name=node_name + '/Const', value=int64_array([0]))).create_node()
- const.out_port(0).connect(concat.in_port(port_idx))
-
- return concat
-
-
-class ConvertSlice(MiddleReplacementPattern):
- """
- This class converts a Slice operation to StridedSlice in reshape-able way by parsing the 'starts' and 'ends'
- parameters based on the 'axes' parameter
- """
-
- enabled = True
- force_clean_up = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='Slice'):
- node_name = node.soft_get('name', node.id)
-
- input_shape = node.in_port(0).data.get_shape()
- if node.is_in_port_connected(3):
- axes = node.in_port(3).data.get_value().copy()
- assert axes is not None, 'The input with axes is not constant for node {}'.format(node_name)
- for i, val in enumerate(axes):
- axes[i] = get_canonical_axis_index(input_shape, val)
- else:
- axes = int64_array(range(len(input_shape)))
-
- ss_begin = create_ss_interval_border(graph, node.in_port(1).get_source(), input_shape, axes, node_name)
- ss_end = create_ss_interval_border(graph, node.in_port(2).get_source(), input_shape, axes, node_name)
- node.in_port(1).disconnect()
- node.in_port(2).disconnect()
- rename_nodes([(ss_begin, node_name + '/Begin'), (ss_end, node_name + '/End')])
-
- if node.is_in_port_connected(4):
- steps = node.in_port(4).data.get_value()
- assert steps is not None, 'The input with steps is not constant for node {}'.format(node_name)
- else:
- steps = np.ones([axes.size], dtype=np.int64)
-
- ss_begin_mask = np.zeros(len(input_shape), dtype=np.int64)
- ss_end_mask = np.zeros(len(input_shape), dtype=np.int64)
- ss_step = np.ones(len(input_shape), dtype=np.int64)
-
- for i, axis in enumerate(axes):
- ss_begin_mask[axis] = 1
- ss_end_mask[axis] = 1
- ss_step[axis] = steps[i]
-
- ss_strides = Const(graph, dict(name=node_name + '/Strides', value=ss_step)).create_node()
-
- ss = StridedSlice(graph, dict(name='ss', new_axis_mask=np.zeros(len(input_shape), dtype=np.int64),
- shrink_axis_mask=np.zeros(len(input_shape), dtype=np.int64),
- ellipsis_mask=np.zeros(len(input_shape), dtype=np.int64),
- begin_mask=ss_begin_mask,
- end_mask=ss_end_mask)).create_node()
-
- node.in_port(0).get_connection().set_destination(ss.in_port(0))
- ss.in_port(1).connect(ss_begin.out_port(0))
- ss.in_port(2).connect(ss_end.out_port(0))
- ss.in_port(3).connect(ss_strides.out_port(0))
- node.out_port(0).get_connection().set_source(ss.out_port(0))
-
- rename_nodes([(node, node_name + '/ShouldBeDeleted'), (ss, node_name)])
diff --git a/tools/mo/openvino/tools/mo/middle/SliceLikeToStridedSlice.py b/tools/mo/openvino/tools/mo/middle/SliceLikeToStridedSlice.py
deleted file mode 100644
index 7712e10f750b15..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/SliceLikeToStridedSlice.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-from typing import Dict
-
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-from openvino.tools.mo.utils.shape import get_shape_values_by_range_idxs, new_shape_node_from_shape_nodes, \
- get_shape_and_rank_nodes_by_port
-
-
-class SliceLikeToStridedSlice(MiddleReplacementPattern):
- """
- Replace mxnet slice_like operation with StridedSlice in reshapable way.
- The begin parameter for StridedSlice is always a zero vector.
- The end parameter depends on the slice_like inputs and axes.
-
- 1. If slice_like inputs has the same ranks, we can use second input shape (shape_like) as the end parameter for
- StridedSlice. Axes parameter will form end_mask, that allows to use slice only on the desired axes.
- Example:
- input_shape = [1, 64, 128, 256], shape_like = [1, 2, 3, 4], axes = [2, 3].
- In that case end = shape_like = [1, 2, 3, 4], but end_mask = [0, 0, 1, 1], so output_shape = [1, 64, 3, 4]
-
- 2. Axes parameter has the last dimension of the first input shape (in that case shape_like >= input_shape).
- Here we can use only a part of shape_like as the end parameter.
- Example:
- input_shape = [1, 64, 128, 256], shape_like = [1, 2, 3, 4, 5], axes = [2, 3].
- end = shape_like[:4] = [1, 2, 3, 4], end_mask = [0, 0, 1, 1], output_shape = [1, 64, 3, 4]
-
- 3. Usual case, where we form end parameter by concatenate parts of shape_like and input_shape.
- Examples:
- input_shape = [1, 64, 128, 256, 512], shape_like = [1, 2, 3, 4], axes = [2, 3].
- end = shape_like[:4] + input_shape[4:] = [1, 2, 3, 4, 512],
- end_mask = [0, 0, 1, 1, 0], output_shape = [1, 64, 3, 4, 512]
-
- input_shape = [1, 64, 128, 256], shape_like = [1, 2, 3, 4, 5], axes = [0, 2].
- end = shape_like[:3] + input_shape[3:] = [1, 2, 3, 256],
- end_mask = [1, 0, 1, 0], output_shape = [1, 64, 3, 256]
- """
-
- enabled = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'mxnet']
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('op', dict(kind='op', op='slice_like'))
- ],
- edges=[]
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: Dict[str, Node]):
- node = match['op']
- name = node.soft_get('name', node.id)
- input_shape = node.in_port(0).data.get_shape()
- second_input_shape = node.in_port(1).data.get_shape()
-
- begin_mask = np.zeros(len(input_shape), dtype=np.int64)
- end_mask = np.zeros(len(input_shape), dtype=np.int64)
-
- for i in node.axes:
- end_mask[i] = np.int64(1)
-
- new_axis_mask = np.zeros(len(input_shape), dtype=np.int64)
- shrink_axis_mask = np.zeros(len(input_shape), dtype=np.int64)
- ellipsis_mask = np.zeros(len(input_shape), dtype=np.int64)
-
- ss = create_op_with_const_inputs(graph, StridedSlice,
- port_value_dict={1: np.zeros(len(input_shape), dtype=np.int64)},
- op_attrs={'name': 'StridedSlice', 'begin_mask': begin_mask,
- 'end_mask': end_mask, 'new_axis_mask': new_axis_mask,
- 'shrink_axis_mask': shrink_axis_mask,
- 'ellipsis_mask': ellipsis_mask})
- if input_shape.size == second_input_shape.size:
- end = Shape(graph, dict(name=name + '/End')).create_node()
- end.in_port(0).connect(node.in_port(1).get_source())
- ss.in_port(2).connect(end.out_port(0))
- else:
- shape_like, rank_like = get_shape_and_rank_nodes_by_port(node.in_port(1).get_source())
- end_first_part = get_shape_values_by_range_idxs(shape_like, rank_like, 0, node.axes[-1], include_end=True)
- if input_shape.size - 1 == node.axes[-1]:
- ss.in_port(2).connect(end_first_part.out_port(0))
- else:
- shape, rank = get_shape_and_rank_nodes_by_port(node.in_port(0).get_source())
- end_second_part = get_shape_values_by_range_idxs(shape, rank, node.axes[-1], -1, include_begin=False,
- include_end=True)
- end = new_shape_node_from_shape_nodes([end_first_part, end_second_part])
- ss.in_port(2).connect(end.out_port(0))
-
- node.in_port(0).get_connection().set_destination(ss.in_port(0))
- node.in_port(1).disconnect()
- node.out_port(0).get_connection().set_source(ss.out_port(0))
-
- rename_nodes([(node, name + '/ShouldBeDeleted'), (ss, name)])
diff --git a/tools/mo/openvino/tools/mo/middle/SplitConcatPairToInterpolate.py b/tools/mo/openvino/tools/mo/middle/SplitConcatPairToInterpolate.py
deleted file mode 100644
index 477fdccbcba335..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/SplitConcatPairToInterpolate.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from typing import Optional
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.activation_ops import Floor
-from openvino.tools.mo.ops.elementwise import Mul
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-def get_concat_after_split(split: Node) -> Optional[Node]:
- """
- This function gets consumers of the 'split' node, checks that the following conditions are fulfilled:
- 1) 'split' node has only one consumer;
- 2) for any output port of 'split', number of corresponding input ports of the consumer is the same;
- 3) for any output port 'i' of the 'split', corresponding input ports of the consumer are
- [i * m, ..., i * m + (m - 1)], where 'm' is the same for all 'i';
- 4) the consumer operation is 'Concat';
- 5) 'split' is a unique producer for this 'Concat';
- and, if all these conditions are fulfilled, returns the above mentioned 'Concat' node. Otherwise, if some of these
- conditions is false, this functions returns None.
- :param split: Split node
- :return: Concat node, if all conditions are fulfilled, or None otherwise
- """
- # If number of output nodes of 'split' is not equal to 1, then the transformation is not applicable.
- split_outputs = [d.node for _, p in split.out_ports().items() for d in p.get_connection().get_destinations()]
- names_of_split_outputs = set([n.name for n in split_outputs])
- if len(names_of_split_outputs) != 1:
- return
-
- groups_of_inputs = [[d.idx for d in p.get_connection().get_destinations()] for _, p in split.out_ports().items()]
- sizes_of_groups = set([len(g) for g in groups_of_inputs])
- # If numbers of consumer ports are various for various output ports of 'split', then the transformation
- # is not applicable.
- if len(sizes_of_groups) != 1:
- return
- # The transformation is applicable iff output port 0 of 'split' goes to ports [0, ..., m-1] of next node,
- # output port 1 of 'split' goes to ports [m, ..., m + (m-1)] of next node, ..., output port i of 'split'
- # goes to ports [i * m, ..., i * m + (m - 1)], and so on.
- flatten_groups = [i for g in groups_of_inputs for i in g]
- if flatten_groups != list(range(0, len(flatten_groups))):
- return
-
- dest = split.out_port(0).get_destinations()[0].node
- # The transformation is applicable, only if next node is Concat.
- if dest.soft_get('type') != 'Concat':
- return
-
- # The transformation is applicable, only if Split is a unique producer for Concat.
- dest_inputs = [p.get_source().node for p in dest.in_ports().values() if not p.disconnected()]
- names_of_concat_inputs = set([n.soft_get('name', n.id) for n in dest_inputs])
- expected_number_of_unique_inputs = 1 if dest.has_valid('axis') else 2
- if len(names_of_concat_inputs) != expected_number_of_unique_inputs:
- return
-
- return dest
-
-
-def get_interpolate_pattern(split: Node) -> dict:
- split_shape = split.in_port(0).data.get_shape()
- if len(split_shape) not in {4, 5}:
- return {}
- concat = get_concat_after_split(split)
- if concat is None:
- return {}
- return {'split': split, 'concat': concat}
-
-
-def get_split_scale(split: Node) -> int:
- split_dests = [d.node for _, p in split.out_ports().items() for d in p.get_connection().get_destinations()]
- num_of_split_dests = len(split_dests)
- num_of_split_out_ports = len(split.out_ports())
- fractional_part = num_of_split_dests / num_of_split_out_ports - num_of_split_dests // num_of_split_out_ports
- assert fractional_part == 0, "Number of output ports of Split must be multiple of number of inputs of Concat"
- return len(split_dests) // len(split.out_ports())
-
-
-def replace_interpolate_pattern(graph: Graph, match: dict):
- split = match['split']
- scale = float32_array([get_split_scale(split)])
- axis = int(split.in_port(1).get_connection().get_source().node.value)
- split_node_name = split.name
- axis_node = Const(graph, {'name': split_node_name + '/axis', 'value': int64_array([axis])}).create_node()
-
- shape_node = Shape(graph, dict(name=split_node_name + '/Shape')).create_node()
- scales_node = Const(graph, dict(name=split_node_name + '/scales', value=scale)).create_node()
- mul_node = Mul(graph, dict(name=split_node_name + '/Mul')).create_node()
- scales_node.out_port(0).connect(mul_node.in_port(1))
-
- strided_slice_node = create_op_with_const_inputs(graph,
- StridedSlice,
- {1: int64_array([axis]), 2: int64_array([axis + 1])},
- {
- 'name': split_node_name + '/StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])
- })
- shape_node.out_port(0).connect(strided_slice_node.in_port(0))
-
- cast_shape_to_float = Cast(graph, {'dst_type': np.float32}).create_node()
-
- strided_slice_node.out_port(0).connect(cast_shape_to_float.in_port(0))
- cast_shape_to_float.out_port(0).connect(mul_node.in_port(0))
-
- interp_node = Interpolate(graph,
- dict(name=split_node_name + '/Interpolate',
- mode='nearest',
- antialias=0, pads_begin=int64_array([0]), pads_end=int64_array([0]),
- coordinate_transformation_mode='half_pixel', nearest_mode='round_prefer_floor',
- cube_coeff=-0.75, version='opset4', shape_calculation_mode='scales',
- in_ports_count=4, maybe_part_of_sequence=True)).create_node()
-
- floor_node = Floor(graph, {'name': split_node_name + '/Floor'}).create_node()
- cast_mul_result_to_int = Cast(graph, {'dst_type': np.int64}).create_node()
-
- mul_node.out_port(0).connect(floor_node.in_port(0))
- floor_node.out_port(0).connect(cast_mul_result_to_int.in_port(0))
-
- cast_mul_result_to_int.out_port(0).connect(interp_node.in_port(1))
- scales_node.out_port(0).connect(interp_node.in_port(2))
- axis_node.out_port(0).connect(interp_node.in_port(3))
-
- match['concat'].out_port(0).get_connection().set_source(interp_node.out_port(0))
-
- split_connection = split.in_port(0).get_connection()
- split_connection.set_destination(interp_node.in_port(0))
- split_connection.get_source().connect(shape_node.in_port(0))
-
-
-class SplitConcatPairToInterpolate(MiddleReplacementPattern):
- """
- This transformation looks for Interpolation layer implemented using simple operations, i.e. Split and Concat,
- and replaces found pattern with a sequence of Shape, StridedSlice, Const, Mul, Interpolate.
-
- Found pattern:
- nodes=[
- ('split', dict(kind='op', op='Split')),
- ('concat', dict(kind='op', op='Concat')),
- ],
- edges=[
- ('split', 'concat'),
- ]
-
- Here we assume that
- 1) 'split' is in NDHWC layout and is a 5D-tensor;
- 2) split dimensions for 'split' belongs to {1, 2, 3};
- 3) all outputs of 'split' go to only inputs of 'concat';
- 4) 'concat' takes inputs only from 'split';
- 5) split_dim of 'split' is equal to axis of 'concat'.
-
- Found pattern will be replaced with
- nodes=[
- ('shape', dict(kind='op', op='Shape')),
- ('strided_slice', dict(kind='op', op='StridedSlice')),
- ('scales', dict(kind='op', op='Const')),
- ('scaled_shape', dict(kind='op', op='Mul')),
- ('interp', dict(kind='op', op='Interpolate'))
- ],
- edges=[
- ('shape', 'strided_slice', {'in': 0}),
- ('strided_slice', 'scaled_shape', {'in': 0}),
- ('scales', 'scaled_shape', {'in': 1}),
- ('scaled_shape', 'interp', {'in': 1}),
- ]
-
- Here scaling factor in Interpolate is equal to a quotient of dividing number of input ports of 'concat'
- by number of output ports of 'split'.
- """
- enabled = True
- force_clean_up = True
-
- def run_before(self):
- from openvino.tools.mo.middle.InterpolateSequenceToInterpolate import InterpolateSequenceToInterpolate
- return [InterpolateSequenceToInterpolate]
-
- def find_and_replace_pattern(self, graph: Graph):
- log.debug('Enabled replacement of a pair of Split and Concat with Interpolate.')
- splits = graph.get_op_nodes(op='Split')
- patterns = []
-
- for split_node in splits:
- interpolate_pattern = get_interpolate_pattern(split_node)
- if interpolate_pattern:
- patterns.append(interpolate_pattern)
-
- for pattern in patterns:
- replace_interpolate_pattern(graph, pattern)
diff --git a/tools/mo/openvino/tools/mo/middle/StridedSliceNormalizer.py b/tools/mo/openvino/tools/mo/middle/StridedSliceNormalizer.py
deleted file mode 100644
index 6853294eca0646..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/StridedSliceNormalizer.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.split import VariadicSplit
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension, dynamic_dimension_value, \
- is_dynamic_slice
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import PermuteAttrs
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-from openvino.tools.mo.utils.error import Error
-
-
-class StridedSliceNormalizer(MiddleReplacementPattern):
- r"""
- StridedSlice is not normal if it cannot be permuted by ApplyPermutations. This normalizer
- inserts blank colons ':' in slice expression so that it can be correctly permuted
- from NHWC to NCHW layout. It changes masks and inserts blank begin, end and strides values.
- In order to successfully handle StridedSlice in ShapeOf subgraphs
- changes must be done by inserting nodes not just by overwriting constants.
-
- StridedSlice is not normal in 2 cases:
- 1. rank of a slice expression is less than rank of input tensor
- 2. there is an ellipsis
-
- 1st case example
- BEFORE:
- |
- begin
- value=[0, 0]
- |
-
- AFTER:
- |
- begin Const
- value=[0, 0] value=[0, 0]
- \ /
- \ /
- Concat
- value=[0, 0, 0, 0]
- |
-
- Input of a shape [16, 100, 100, 3] in NHWC layout, output = input[:, 0:50].
- StridedSlice will be extended to input[:, 0:50, :, :].
- After permutation to NCHW output = input[:, :, 0:50, :].
- Example for 'begin' input transformation is shown above on the picture.
- 'end' and 'strides' inputs will be transformed the same way.
-
- 2nd case example
- BEFORE:
- |
- begin
- value=[1, 50]
- |
-
- AFTER:
- |
- begin
- value=[1, 1, 1]
- |
- VariadicSplit
- / \
- / \
- / Const \
- \ val=[0, 0] /
- \ | /
- \ | /
- Concat
- value=[1, 0, 0, 1, 1]
- |
-
- Input of a shape [16, 10, 100, 100, 3] in NDHWC layout, output = input[1:4, ..., 1:51, 1:3],
- output_shape = [3, 10, 100, 50, 2]. In order to perform correct layout permutation
- ellipsis must be replaced with colons: input[1:4, ..., 1:51, 1:3] => input[1:4, :, :, 1:51, 1:3].
- After layour permutation input[1:4, 1:3, :, : 1:5].
-
- In the places of colons blank begin, end and strides values should be inserted.
- In order to do that we split input and insert blank zeros to the middle.
- Example for 'begin' input transformation is shown above on the picture.
- 'end' and 'strides' inputs will be transformed the same way.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.LayoutChangeForConstantShapePaths import LayoutChangeForConstantShapePaths
- return [LayoutChangeForConstantShapePaths]
-
- def run_after(self):
- from openvino.tools.mo.middle.SliceConverter import ConvertSlice
- return [ConvertSlice]
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(type='StridedSlice'):
- StridedSliceNormalizer.normalize_strided_slice(graph, node)
- PermuteAttrs.create_permute_attrs(node,
- attrs=[('begin_mask', 'input:0'), # but indeed depends from slice_rank
- ('end_mask', 'input:0'),
- ('new_axis_mask', 'input:0'),
- ('shrink_axis_mask', 'input:0'),
- ('ellipsis_mask', 'input:0')])
-
- # StridedSliceNormalizer inserted nodes that changed original begin, end, and strides data nodes
- # Until now it was not possible to set correct permutations
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:1', 'slice', 'dim_size')
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:2', 'slice', 'dim_size')
- if node.is_in_port_connected(3):
- PermuteInputs().set_input_permutation(node.in_node(3), node, 'input:3', 'slice', 'dim_size')
-
- # If there are new_axis_mask or shrink_axis_mask then StridedSlice should be performed in the
- # original layout, same as for Squeeze, Unsqueeze, Reshape, Gather
- if np.count_nonzero(node['new_axis_mask']) > 0 or np.count_nonzero(node['shrink_axis_mask']) > 0:
- node['reinterp_shape'] = True
- node['nchw_layout'] = True
-
- @staticmethod
- def normalize_strided_slice(graph: Graph, node: Node):
- input_shape = node.in_port(0).data.get_shape()
- input_rank = len(input_shape)
- begin = node.in_port(1).data.get_value()
- if begin is not None:
- slice_rank = len(begin)
- else:
- slice_rank = input_rank + np.count_nonzero(node.new_axis_mask) - np.count_nonzero(node.shrink_axis_mask)
-
- StridedSlice.align_mask_with_slice_rank(node, slice_rank) # if StridedSlice is created after partial_infer
- StridedSliceNormalizer.normalize_slices_attr(node)
-
- num_insertions = input_rank - slice_rank + np.count_nonzero(node.new_axis_mask)
- assert num_insertions >= 0, 'slice_rank - num_new_axis must <= input rank. Got instead: ' \
- 'input_rank = {}, slice_rank = {}, num_new_axis = {}'. \
- format(input_rank, slice_rank, np.count_nonzero(node.new_axis_mask))
-
- if np.any(node.ellipsis_mask):
- assert np.count_nonzero(node.ellipsis_mask) == 1, 'only one ellipsis_mask nonzero value is allowed'
- ellipsis_start = np.nonzero(node.ellipsis_mask)[0][0]
- # since we don't expect values in begin and end: take the whole range along ellipsis_start
- node.begin_mask[ellipsis_start] = 0
- node.end_mask[ellipsis_start] = 0
- node.ellipsis_mask[ellipsis_start] = 0
- insertion_start_idx = ellipsis_start + 1
-
- StridedSliceNormalizer.unroll_ellipsis_for_inputs(graph, node, ellipsis_start, num_insertions)
- elif num_insertions > 0:
- insertion_start_idx = slice_rank # insert blank values to mask ends
- StridedSliceNormalizer.extend_inputs(node, num_insertions)
-
- if num_insertions > 0:
- # insert blank values for ellipsis unrolling and extending
- for mask_name in StridedSlice.get_mask_names():
- node[mask_name] = np.insert(node[mask_name], insertion_start_idx, [0] * num_insertions).astype(int) # pylint: disable=possibly-used-before-assignment
-
- @staticmethod
- def unroll_ellipsis_for_inputs(graph: Graph, node: Node, ellipsis_start: int, num_insertions: int):
- node_name = node.soft_get('name', node.id)
-
- for i, input_name in [(1, 'begin'), (2, 'end'), (3, 'strides')]:
- if i == 3 and not node.is_in_port_connected(3):
- continue # no need to extend strides if they are not connected
-
- blank_values_arr = np.zeros(num_insertions) if input_name != 'strides' else np.ones(num_insertions)
- blank_values_node = Const(graph, {'name': node_name + '/const_to_unroll_{}_ellipsis'.format(input_name),
- 'value': int64_array(blank_values_arr)}).create_node()
-
- concat_in_ports_count = 3 if ellipsis_start != 0 else 2
- concat = Concat(graph, {'axis': 0, 'name': node_name + '/concat_{}'.format(input_name),
- 'in_ports_count': concat_in_ports_count}).create_node()
-
- if ellipsis_start != 0:
- split = create_op_with_const_inputs(graph, VariadicSplit, {1: int64_array(0),
- 2: int64_array([ellipsis_start, -1])},
- {'name': node_name + '/split_for_{}_ellipsis'.format(input_name),
- 'out_ports_count': 2})
- node.in_port(i).get_connection().set_destination(split.in_port(0))
-
- concat.in_port(0).connect(split.out_port(0))
- concat.in_port(1).connect(blank_values_node.out_port(0))
- concat.in_port(2).connect(split.out_port(1))
- else:
- concat.in_port(0).connect(blank_values_node.out_port(0))
- node.in_port(i).get_connection().set_destination(concat.in_port(1))
-
- concat.out_port(0).get_connection().set_destination(node.in_port(i))
-
- @staticmethod
- def extend_inputs(node: Node, num_insertions: int):
- graph = node.graph
- node_name = node.soft_get('name', node.id)
-
- for i, input_name in [(1, 'begin'), (2, 'end'), (3, 'strides')]:
- if i == 3 and not node.is_in_port_connected(3):
- continue # no need to extend strides if they are not connected
-
- blank_values_arr = np.zeros(num_insertions) if input_name != 'strides' else np.ones(num_insertions)
- blank_values_node = Const(graph, {'name': node_name + '/extend_{}_const'.format(input_name),
- 'value': int64_array(blank_values_arr)}).create_node()
-
- if node.in_port(i).get_source().node.soft_get('type') == 'Concat':
- # concat already exists
- concat = node.in_port(i).get_source().node
- # because output data node shape will be changed
- # while shapes will be reinferred no need to check consistency
- concat['override_output_shape'] = True
-
- last_in_port = max(concat.in_ports().keys())
- assert not concat.in_port(last_in_port).disconnected(), 'The last in_port of Concat node {} ' \
- 'should be connected'. \
- format(concat.soft_get('name', node.id))
-
- concat.add_input_port(last_in_port + 1)
- concat.in_port(last_in_port + 1).connect(blank_values_node.out_port(0))
- else:
- # have to create concat
- concat = Concat(graph, {'axis': 0, 'name': node_name + '/concat_{}'.format(input_name),
- 'in_ports_count': 2}).create_node()
- node.in_port(i).get_connection().set_destination(concat.in_port(0))
- concat.in_port(1).connect(blank_values_node.out_port(0))
- concat.out_port(0).get_connection().set_destination(node.in_port(i))
-
- @staticmethod
- def normalize_slices_attr(node: Node):
- # removes negative starts, ends and magic numbers from 'slice' attr which is used by ConvertGroupedStridedSlice
- slice_rank = len(node['slices'])
- data_shape = node.in_port(0).data.get_shape()
-
- node_name = node.soft_get('name', node.id)
- if node.is_in_port_connected(3):
- strides = node.in_port(3).data.get_value()
- if strides is None:
- raise Error('StridedSlice operation for node {} supports only constant strides input'.format(node_name))
- else:
- strides = np.ones(len(node['slices']), dtype=np.int32)
-
- num_ellipsis_inserts = len(data_shape) - slice_rank + np.count_nonzero(node.new_axis_mask) + 1
- res_slices = []
-
- in_idx = 0
- for i, s in enumerate(node['slices']):
- if node.new_axis_mask[i]:
- res_slices.append(slice(0, 1, 1))
- elif node.shrink_axis_mask[i]:
- res_slices.append(slice(s, s + 1, strides[i])) # need strides if shrink index is negative
- elif node.ellipsis_mask[i]:
- for idx in range(num_ellipsis_inserts):
- res_slices.append(slice(0, data_shape[in_idx], 1))
- in_idx += 1
- else:
- res_slices.append(s)
-
- if not (node.new_axis_mask[i] or node.ellipsis_mask[i]):
- if res_slices[-1] != dynamic_dimension_value and data_shape[in_idx] is not dynamic_dimension and \
- res_slices[-1] is not None and not is_dynamic_slice(res_slices[-1]):
- res_slices[-1] = slice(*res_slices[-1].indices(data_shape[in_idx])) # convert negative begins/ends
- in_idx += 1
- node.slices = mo_array(res_slices)
diff --git a/tools/mo/openvino/tools/mo/middle/SwapAxesMiddleReplacer.py b/tools/mo/openvino/tools/mo/middle/SwapAxesMiddleReplacer.py
deleted file mode 100644
index c44520197e16ce..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/SwapAxesMiddleReplacer.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-
-
-class SwapAxisMiddleReplacer(MiddleReplacementPattern):
- enabled = True
-
- def pattern(self):
- return dict(
- nodes=[('op', dict(kind='op', op='SwapAxis'))],
- edges=[],
- )
-
- def replace_pattern(self, graph: Graph, match: [str, Node]):
- swapaxis = match['op']
- assert len(swapaxis.in_ports()) == 1
- assert swapaxis.has_and_set('order')
- order = swapaxis.order
-
- swapaxis.add_input_port(1)
- const = Const(graph, {'value': order, 'name': swapaxis.soft_get('name', swapaxis.id) + '/Order'}).create_node()
- const.out_port(0).connect(swapaxis.in_port(1))
-
- Transpose.update_node_stat(swapaxis, {'need_shape_inference': True})
-
- del swapaxis['order']
diff --git a/tools/mo/openvino/tools/mo/middle/TF_lstm_cell_to_generic.py b/tools/mo/openvino/tools/mo/middle/TF_lstm_cell_to_generic.py
deleted file mode 100644
index 574c49438e78f1..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TF_lstm_cell_to_generic.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class TensorFlowLSTMtoGeneric(MiddleReplacementPattern):
- """
- Resolves all differences in TensorFlow LSTMCell and OpenVINO LSTMCell:
- - weights transposing
- - shift_const value addition to biases
- - extra inputs deletion
- """
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.permute_tensor_iterator import TransposeTensorIteratorLSTM
- return [TransposeTensorIteratorLSTM]
-
-
- def pattern(self):
- return dict(
- nodes=[('lstm', dict(op='LSTMCell', tf=True))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- weights_node = match['lstm'].in_node(3)
- biases_node = match['lstm'].in_node(4)
- node = match['lstm']
- shift_const = node.shift_const
-
- # make sure that the node is the only consumer or weights and biases
- # to let us modify them without hassle
- assert len(weights_node.out_nodes()) == 1
- assert len(biases_node.out_nodes()) == 1
-
- # Assign temporary shape for them for easier manipulation
- # TF stores weights in IO order
- input_size = node.in_node(0).shape[1]
- hidden_size = node.in_node(1).shape[1]
- weights = weights_node.value
- biases = biases_node.value
- assert weights.shape[0] == input_size + hidden_size, \
- "weights.shape={} input_size={} hidden_size={}".format(weights.shape, input_size, hidden_size)
- assert weights.shape[1] == biases.shape[0] == 4 * hidden_size, \
- "weights.shape={} biases.shape={} hidden_size={}".format(weights.shape, biases.shape, hidden_size)
-
- weights = weights.reshape([
- weights.shape[0],
- 4, # gates
- hidden_size
- ])
-
- biases = biases.reshape([
- 4, # gates
- hidden_size
- ])
-
- # Reorder gates icfo --> fico for both weights and biases
- gate_reorder = [2, 0, 1, 3]
- weights = np.take(weights, gate_reorder, axis=1)
- biases = np.take(biases, gate_reorder, axis=0)
-
- # shift_const.value should be added to the first 1/4th part of the biases (f-gate: 0)
- # Note: in case of moving this code up before gate reordering, the addition
- # should be applied at different place
- biases[0] += shift_const
-
- # Return to the original shapes
- weights = weights.reshape([weights.shape[0], -1])
- biases = biases.flatten()
-
- # TF stores weights in IO, but OV requires it in OI: transpose
- weights = weights.transpose()
-
- weights_node.value = weights
- weights_node.shape = int64_array(weights.shape)
- biases_node.value = biases
- biases_node.shape = int64_array(biases.shape)
-
- # Cut all extra inputs off
- for i in range(len(node.inputs), len(node.inputs) + len(node.extra_inputs)):
- node.graph.remove_edge(node.in_node(i).id, node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorBackEdge.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorBackEdge.py
deleted file mode 100644
index 4e7867011b5b2b..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorBackEdge.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.middle.TensorIteratorCondition import DynamicDecoderConditionMatcher
-from openvino.tools.mo.ops.TensorIterator_ops import TensorIteratorBackEdge, TensorIteratorOutput
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class BackEdgesMatching(MiddleReplacementPattern):
- """
- This pattern are needed for matching back edges in while loops in TF graphs.
- Back edge is a chain of nodes in while loop that iterate one variable in graph over loop steps. It consist of
- nodes:
- Exit (optional)
- ^
- |
- Enter () -> Merge -> Switch -> Identity -> SOME OPERATIONS -> NextIteration ->
- ^ |
- | |
- ------------------------------------------------------------------
- The structure of pattern without Data nodes between ops (every node is named as op attribute of this node):
- Data--
- |
- NextIteration -> Merge--
- |
- ->Switch (out=1) -> Identity
- |
- TensorIteratorCondition--
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- # since the pattern of this transformation contains TensorIteratorCondition,
- # condition matchers must be applied first
- from openvino.tools.mo.middle.TensorIteratorCondition import DynamicDecoderConditionMatcher, LoopConditionMatcher, \
- SimpleConditionMatcher
- return [DynamicDecoderConditionMatcher, SimpleConditionMatcher, LoopConditionMatcher]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('Enter_1_data', dict(kind='data')),
-
- ('Merge_1', dict(kind='op', op='Merge')),
- ('Merge_1_data', dict(kind='data')),
-
- ('Switch_1', dict(kind='op', op='Switch')),
- ('Switch_1_data', dict(kind='data')),
-
- ('Identity_1', dict(kind='op', op='Identity')),
- ('Identity_1_data', dict(kind='data')),
-
- ('NextIteration', dict(kind='op', op='NextIteration')),
- ('NextIteration_data', dict(kind='data')),
-
- ('condition', dict(kind='op', op='TensorIteratorCondition')),
- ('condition_cond_data', dict(kind='data')),
- ],
- edges=[
- ('Enter_1_data', 'Merge_1'),
- ('Merge_1', 'Merge_1_data'),
-
- ('Merge_1_data', 'Switch_1'),
- ('Switch_1', 'Switch_1_data', {'out': 1}),
- ('Switch_1_data', 'Identity_1'),
- ('Identity_1', 'Identity_1_data'),
-
- ('NextIteration', 'NextIteration_data'),
- ('NextIteration_data', 'Merge_1'),
-
- ('condition', 'condition_cond_data'),
- ('condition_cond_data', 'Switch_1'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- log.debug('================== BackEdgeFind ===============')
-
- nodes_for_remove = []
- from_body_data = match['NextIteration'].in_node()
-
- # If Exit path is exist -> create TensorIteratorOutput for this
- if 0 in match['Switch_1'].out_nodes():
- Exit = match['Switch_1'].out_node(0).out_node(0) # Switch -> Switch_data -> Exit
- assert Exit.has_valid('op') and Exit.op == 'Exit'
- output_data = Exit.out_node(0)
-
- nodes_for_remove.append(match['Switch_1'].out_node(0).id)
- nodes_for_remove.append(Exit.id)
-
- # Creating TensorIteratorOutput without partition
- output = TensorIteratorOutput(graph, dict(external_port_id=None,
- internal_layer_id=None, \
- name=Exit.name + '/TensorIteratorOutput_'
- ))
- output.create_node_with_data(inputs=[from_body_data, match['condition_cond_data']],
- data_nodes=[output_data])
-
- assert match['NextIteration_data'].id != match['Enter_1_data'].id
- backedge = TensorIteratorBackEdge(graph, dict(name=match['Identity_1'].name + '/TensorIteratorBackEdge_'))
- backedge.create_node_with_data(inputs=[match['Enter_1_data'], from_body_data, match['condition_cond_data']],
- data_nodes=[match['Identity_1_data']])
-
- # Delete useless nodes
- safe_nodes = ['Identity_1_data', 'condition', 'condition_cond_data', 'Enter_1_data']
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorCondition.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorCondition.py
deleted file mode 100644
index fcdbe88401c612..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorCondition.py
+++ /dev/null
@@ -1,547 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.middle.pattern_match import apply_pattern
-from openvino.tools.mo.middle.TensorIterator_utils import delete_selects_from
-from openvino.tools.mo.ops.TensorIterator_ops import TensorIteratorCondition, TensorIteratorBackEdge
-from openvino.tools.mo.ops.identity import Identity
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, int64_array
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-def make_nodes_1D(nodes: list):
- """
- Reshape every node from nodes from 0D to 1D (nodes should have shape attribute).
- """
- for node in nodes:
- assert node.shape is None or len(node.shape) == 0
- node.shape = int64_array([1])
- if node.value is not None:
- node.value = np.reshape(node.value, node.shape)
-
-
-def looking_for_op_in_list(nodes: list, op: str):
- for node in nodes:
- if node.has_valid('op') and node.op == op:
- return node
-
- return None
-
-
-class LoopConditionMatcher(MiddleReplacementPattern):
- """
- This pattern match condition for TensorIterator in while loops in TF.
- The structure of pattern without Data nodes between ops. Every node is named as op attribute of this node
- (data nodes is marked by (data)):
- Const----
- |
- v
- Const -> Enter -> Merge ---------------------> Switch -> Identity -> Add -> NextIteration
- | ^
- ---> Less ----| |
- ^ | |
- Maximum -> Minimum -> Enter-| | |
- ^ v |
-Shape -> StridedSlice -> Enter -| LogicalAnd --> LoopCond (data)
- v ^ |
- ---> Less ----| |
- | v
- Const -> Enter -> Merge ---------------------> Switch -> Identity -> Add -> NextIteration
- ^
- |
- Const----
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return []
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern(variation):
- log.debug('+++++++++++++++ ConditionMatching ++++++++++++++++')
- nodes = [
- ('Enter_1_less', dict(kind='op', op='Enter')),
- ('Strided_slice', dict(kind='op', op='StridedSlice')),
- ('Strided_slice_data', dict(kind='data')),
- ('Enter_1_less_data', dict(kind='data')),
-
- ('Less_1', dict(kind='op', op='Less')),
- ('Merge_1', dict(kind='op', op='Merge')),
- ('Merge_1_data', dict(kind='data')),
- ('Less_1_data', dict(kind='data')),
-
- ('Less_2', dict(kind='op', op='Less')),
- ('Merge_2', dict(kind='op', op='Merge')),
- ('Merge_2_data', dict(kind='data')),
- ('Less_2_data', dict(kind='data')),
-
- ('and', dict(kind='op', op='LogicalAnd')),
- ('and_data', dict(kind='data')),
- ('loop_cond', dict(kind='op', op='LoopCond')),
- ('loop_cond_data', dict(kind='data')),
-
- ('init_1', dict(kind='op', op='Const')),
- ('init_1_data', dict(kind='data')),
- ('Enter_1', dict(kind='op', op='Enter')),
- ('Enter_1_data', dict(kind='data')),
-
- ('init_2', dict(kind='op', op='Const')),
- ('init_2_data', dict(kind='data')),
- ('Enter_2', dict(kind='op', op='Enter')),
- ('Enter_2_data', dict(kind='data')),
-
- ('Switch_1', dict(kind='op', op='Switch')),
- ('Switch_1_data', dict(kind='data')),
- ('Identity_1', dict(kind='op', op='Identity')),
- ('Identity_1_data', dict(kind='data')),
- ('add_1', dict(kind='op', op='Add')),
- ('add_1_y', dict(kind='op', op='Const')),
- ('add_1_y_data', dict(kind='data')),
- ('add_1_data', dict(kind='data')),
- ('NextIteration_1', dict(kind='op', op='NextIteration')),
-
- ('Switch_2', dict(kind='op', op='Switch')),
- ('Switch_2_data', dict(kind='data')),
- ('Identity_2', dict(kind='op', op='Identity')),
- ('Identity_2_data', dict(kind='data')),
- ('add_2', dict(kind='op', op='Add')),
- ('add_2_y', dict(kind='op', op='Const')),
- ('add_2_y_data', dict(kind='data')),
- ('add_2_data', dict(kind='data')),
- ('NextIteration_2', dict(kind='op', op='NextIteration')),
-
- ]
- edges = [
- ('Strided_slice', 'Strided_slice_data'),
- ('Strided_slice_data', 'Enter_1_less'),
- ('Enter_1_less', 'Enter_1_less_data'),
- ('Enter_1_less_data', 'Less_1'),
- ('Less_1', 'Less_1_data'),
- ('Less_1_data', 'and'),
-
- ('and', 'and_data'),
- ('and_data', 'loop_cond'),
- ('loop_cond', 'loop_cond_data'),
- ('loop_cond_data', 'Switch_1'),
- ('loop_cond_data', 'Switch_2'),
-
- ('init_1', 'init_1_data'),
- ('init_1_data', 'Enter_1'),
- ('Enter_1', 'Enter_1_data'),
- ('Enter_1_data', 'Merge_1'),
- ('Merge_1', 'Merge_1_data'),
- ('Merge_1_data', 'Less_1'),
-
- ('Merge_1_data', 'Switch_1'),
- ('Switch_1', 'Switch_1_data'),
- ('Switch_1_data', 'Identity_1'),
- ('Identity_1', 'Identity_1_data'),
- ('Identity_1_data', 'add_1'),
- ('add_1_y', 'add_1_y_data'),
- ('add_1_y_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'NextIteration_1'),
-
- ('Merge_2_data', 'Switch_2'),
- ('Switch_2', 'Switch_2_data'),
- ('Switch_2_data', 'Identity_2'),
- ('Identity_2', 'Identity_2_data'),
- ('Identity_2_data', 'add_2'),
- ('add_2_y', 'add_2_y_data'),
- ('add_2_y_data', 'add_2'),
- ('add_2', 'add_2_data'),
- ('add_2_data', 'NextIteration_2'),
-
- ('init_2', 'init_2_data'),
- ('init_2_data', 'Enter_2'),
- ('Enter_2', 'Enter_2_data'),
- ('Enter_2_data', 'Merge_2'),
-
- ('Merge_2', 'Merge_2_data'),
- ('Merge_2_data', 'Less_2'),
- ('Less_2', 'Less_2_data'),
- ('Less_2_data', 'and'),
- ]
- if variation == 1:
- nodes.extend([
- ('Enter_2_less', dict(kind='op', op='Enter')),
- ('Enter_2_less_data', dict(kind='data')),
- ('minimum_data', dict(kind='data'))
- ])
- edges.extend([
- ('minimum_data', 'Enter_2_less'),
- ('Enter_2_less', 'Enter_2_less_data'),
- ('Enter_2_less_data', 'Less_2'),
- ])
- elif variation == 2:
- edges.append(('Enter_1_less_data', 'Less_2'))
- else:
- raise Exception('Wrong pattern variation')
- return dict(nodes=nodes, edges=edges)
-
- @staticmethod
- def looking_for_iteration_counter(graph: Graph, match: dict):
- types = ['TensorIteratorInput', 'TensorIteratorOutput']
- candidates = [match['Identity_1_data'], match['Identity_2_data']]
- results = []
- for candidate in candidates:
- for node in candidate.out_nodes():
- if node['op'] in types:
- results.append(candidate)
- break
- assert len(results) == 1
- return results[0]
-
- @staticmethod
- def check_dynamic_seq_len(graph: Graph, match: dict):
- """
- Cycle is dynamic if at least one of the boundaries isn't constant OR this boundaries is different from tensor
- shape.
- """
- dynamic_seq_len = match['Enter_1_less_data'].value is None
- if 'Enter_2_less_data' in match:
- dynamic_seq_len = dynamic_seq_len or match['Enter_2_less_data'].value is None or \
- not np.array_equal(match['Enter_1_less_data'].value, match['Enter_2_less_data'].value)
-
- return dynamic_seq_len
-
- def find_and_replace_pattern(self, graph: Graph):
- apply_pattern(graph, **self.pattern(1), action=self.replace_pattern) # pylint: disable=no-member
- apply_pattern(graph, **self.pattern(2), action=self.replace_pattern) # pylint: disable=no-member
-
- def replace_pattern(self, graph: Graph, match: dict):
- log.debug('================== ConditionFind ===============')
- # init_1
- init_1 = match['init_1_data'].value
- assert init_1 is not None
- init_1 = int(init_1)
-
- # init_2
- init_2 = match['init_2_data'].value
- assert init_2 is not None
- init_2 = int(init_2)
-
- # step_1
- assert match['add_1_y_data'].value is not None
- step_1 = int(match['add_1_y_data'].value)
-
- # step_2
- assert match['add_2_y_data'].value is not None
- step_2 = int(match['add_2_y_data'].value)
-
- dynamic_seq_len = self.check_dynamic_seq_len(graph, match)
-
- # Create condition node and delete all useless nodes from condition pattern
- loop_condition = match['loop_cond_data']
- iterator_data = self.looking_for_iteration_counter(graph, match)
-
- condition_attrs = dict(time=dict(init=init_2, step=step_2), iter=dict(init=init_1, step=step_1),
- name=match['loop_cond'].name + '/TensorIteratorCondition_')
- condition = TensorIteratorCondition(graph, attrs=condition_attrs)
- if 'minimum_data' in match:
- condition_inp = [match['Strided_slice_data'], match['minimum_data']]
- else:
- condition_inp = [match['Strided_slice_data']]
- condition_data = condition.create_node_with_data(inputs=condition_inp,
- data_nodes=[loop_condition, iterator_data])
-
- safe_nodes = ['loop_cond_data', 'Identity_1_data', 'Identity_2_data', 'Strided_slice', 'Strided_slice_data',
- 'minimum', 'minimum_data']
-
- identity_ops = [n.op for n in iterator_data.out_nodes()]
- if 'GreaterEqual' in identity_ops:
- greater_equal_id = [n.id for n in iterator_data.out_nodes() if n.op == 'GreaterEqual'][0]
-
- if dynamic_seq_len:
- # Add BackEdge for time iterator node
- backedge = TensorIteratorBackEdge(graph, dict(name='/TimeIterator/TensorIteratorBackEdge_'))
- backedge_data = backedge.create_node_with_data(inputs=[match['init_2_data'], match['add_2_data'],
- condition_data[0]], )
-
- graph.remove_edge(match['add_2'].in_node(0).id, match['add_2'].id)
- graph.add_edge(backedge_data.id, match['add_2'].id, **{'in': 0})
-
- graph.remove_edge(iterator_data.id, greater_equal_id)
- graph.add_edge(backedge_data.id, greater_equal_id, **{'in': 0})
-
- # nodes for time iterator
- safe_nodes += ['init_2_data', 'init_2', 'Identity_2_data', 'add_2_data', 'add_2', 'add_2_y',
- 'add_2_y_data']
-
- # Manually reshape all iterator nodes (for time) from 0D to 1D
- iterator_data_nodes = [backedge_data, match['add_2_data'], match['add_2_y_data'], match['add_2_y'],
- match['init_2_data'], match['init_2']]
- make_nodes_1D(iterator_data_nodes)
- else:
- # Delete Selects from this cycle to make it not dynamic:
- greater_equal_idxs = [n.id for n in iterator_data.out_nodes() if n.op == 'GreaterEqual']
- delete_selects_from(graph, greater_equal_idxs)
-
- # Delete useless nodes
- nodes_for_remove = []
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
-
-
-class SimpleConditionMatcher(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return [LoopConditionMatcher]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- log.debug('+++++++++++++++ SimpleConditionMatching ++++++++++++++++')
- return dict(
- nodes=[
- ('Enter_1_less', dict(kind='op', op='Enter')),
- ('Strided_slice', dict(kind='op', op='StridedSlice')),
- ('Strided_slice_data', dict(kind='data')),
- ('Enter_1_less_data', dict(kind='data')),
-
- ('Less_1', dict(kind='op', op='Less')),
- ('Merge_1', dict(kind='op', op='Merge')),
- ('Merge_1_data', dict(kind='data')),
- ('Less_1_data', dict(kind='data')),
-
- ('loop_cond', dict(kind='op', op='LoopCond')),
- ('loop_cond_data', dict(kind='data')),
-
- ('init_1', dict(kind='op', op='Const')),
- ('init_1_data', dict(kind='data')),
- ('Enter_1', dict(kind='op', op='Enter')),
- ('Enter_1_data', dict(kind='data')),
-
- ('Switch_1', dict(kind='op', op='Switch')),
- ('Switch_1_data', dict(kind='data')),
- ('Identity_1', dict(kind='op', op='Identity')),
- ('Identity_1_data', dict(kind='data')),
- ('add_1', dict(kind='op', op='Add')),
- ('add_1_y', dict(kind='op', op='Const')),
- ('add_1_y_data', dict(kind='data')),
- ('add_1_data', dict(kind='data')),
- ('NextIteration_1', dict(kind='op', op='NextIteration')),
- ],
- edges=[
- ('Strided_slice', 'Strided_slice_data'),
- ('Strided_slice_data', 'Enter_1_less'),
- ('Enter_1_less', 'Enter_1_less_data'),
- ('Enter_1_less_data', 'Less_1'),
- ('Less_1', 'Less_1_data'),
- ('Less_1_data', 'loop_cond'),
-
- ('loop_cond', 'loop_cond_data'),
- ('loop_cond_data', 'Switch_1'),
-
- ('init_1', 'init_1_data'),
- ('init_1_data', 'Enter_1'),
- ('Enter_1', 'Enter_1_data'),
- ('Enter_1_data', 'Merge_1'),
- ('Merge_1', 'Merge_1_data'),
- ('Merge_1_data', 'Less_1'),
-
- ('Merge_1_data', 'Switch_1'),
- ('Switch_1', 'Switch_1_data'),
- ('Switch_1_data', 'Identity_1'),
- ('Identity_1', 'Identity_1_data'),
- ('Identity_1_data', 'add_1'),
- ('add_1_y', 'add_1_y_data'),
- ('add_1_y_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'NextIteration_1'),
-
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== SimpleConditionFind ===============')
- # init_1
- init_1 = match['init_1_data'].value
- assert init_1 is not None
- init_1 = int(init_1)
-
- # step_1
- assert match['add_1_y_data'].value is not None
- step_1 = int(match['add_1_y_data'].value)
-
- match['loop_cond_data'].value = None
-
- # compute destination (or consumer) ports for time node
- identity_node_name = match['Identity_1'].soft_get('name', match['Identity_1'].id)
- time_dsts = match['Identity_1'].out_port(0).get_destinations()
-
- # Create condition node and delete all useless nodes from condition pattern
- condition_attrs = dict(iter=dict(init=init_1, step=step_1),
- name=match['loop_cond'].name + '/TensorIteratorCondition_')
- condition = TensorIteratorCondition(graph, attrs=condition_attrs)
- condition.create_node_with_data(inputs=[match['Strided_slice_data']],
- data_nodes=[match['loop_cond_data'], match['Identity_1_data']])
-
- safe_nodes = ['loop_cond_data', 'Identity_1_data', 'Strided_slice', 'Strided_slice_data']
-
- # check if time node has other consumers different from increment node,
- # input slicing and output concatenation nodes
- other_time_consumers = False
- for time_consumer in time_dsts:
- if time_consumer.node.soft_get('op') not in ['TensorIteratorInput', 'TensorIteratorOutput'] and \
- time_consumer.node.id != match['add_1'].id:
- other_time_consumers = True
- break
- if other_time_consumers:
- # save time related nodes since they have other consumers different from
- # input slicing and output concatenation nodes
- safe_nodes += ['init_1', 'init_1_data', 'Enter_1', 'Enter_1_data', 'Merge_1', 'Merge_1_data',
- 'Switch_1', 'Switch_1_data', 'add_1', 'add_1_y', 'add_1_y_data', 'add_1_data',
- 'NextIteration_1']
- switch_node = match['Switch_1']
- new_identity_node = Identity(graph, dict(name=identity_node_name)).create_node()
- switch_node.out_port(1).connect(new_identity_node.in_port(0))
-
- # make the graph consistent to avoid multiple producers by the same input port
- graph.remove_nodes_from([match['Identity_1'].id])
- rename_nodes([(new_identity_node, identity_node_name)])
-
- for time_consumer in time_dsts:
- if time_consumer.node.soft_get('op') not in ['TensorIteratorInput', 'TensorIteratorOutput']:
- time_consumer.get_connection().set_source(new_identity_node.out_port(0))
-
- # Delete useless nodes
- nodes_for_remove = []
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
-
-
-class DynamicDecoderConditionMatcher(MiddleReplacementPattern):
- """
- This pattern match condition for dynamic decoder and create TensorIteratorCondition node instead of it.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return [SimpleConditionMatcher]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- log.debug('+++++++++++++++ DynamicDecoderConditionMatching ++++++++++++++++')
- return dict(
- nodes=[
- ('loop_cond', dict(kind='op', op='LoopCond')),
- ('loop_cond_data', dict(kind='data')),
-
- ('logical_not', dict(kind='op', op='LogicalNot')),
- ('logical_not_data', dict(kind='data')),
-
- ('all', dict(kind='op', op='ReduceAnd')),
- ('all_data', dict(kind='data')),
-
- ('Merge_16', dict(kind='op', op='Merge')),
- ('merge_16_data', dict(kind='data')),
-
- ('NextIteration_16', dict(kind='op', op='NextIteration')),
- ('nextIteration_data', dict(kind='data')),
-
- ('Switch', dict(kind='op', op='Switch')),
- ('switch_data', dict(kind='data')),
-
- ('Identity', dict(kind='op', op='Identity')),
- ('identity_data', dict(kind='data')),
-
- ('add', dict(kind='op', op='Add')),
- ('add_data', dict(kind='data')),
-
- ('Less_enter', dict(kind='op', op='Enter')),
- ('Less_enter_data', dict(kind='data')),
-
- ('And', dict(kind='op', op='LogicalAnd')),
- ('And_data', dict(kind='data')),
-
- ('Less', dict(kind='op', op='Less')),
- ('Less_data', dict(kind='data')),
-
- ('TensorIteratorOutput', dict(kind='op', op='TensorIteratorOutput')),
- ('TensorIteratorOutput_1', dict(kind='op', op='TensorIteratorOutput')),
- ],
- edges=[
- ('NextIteration_16', 'nextIteration_data'),
- ('nextIteration_data', 'Merge_16'),
- ('Merge_16', 'merge_16_data'),
- ('merge_16_data', 'all'),
- ('all', 'all_data'),
- ('all_data', 'logical_not'),
- ('logical_not', 'logical_not_data'),
-
- ('Less_enter', 'Less_enter_data'),
- ('Less_enter_data', 'Less'),
-
- ('Less', 'Less_data'),
- ('Less_data', 'And'),
-
- ('logical_not_data', 'And'),
- ('And', 'And_data'),
- ('And_data', 'loop_cond'),
-
- ('loop_cond', 'loop_cond_data'),
-
- ('loop_cond_data', 'Switch'),
-
- ('Switch', 'switch_data'),
-
- ('switch_data', 'Identity'),
-
- ('Identity', 'identity_data'),
-
- ('identity_data', 'add'),
- ('add', 'add_data'),
-
- ('identity_data', 'TensorIteratorOutput'),
- ('identity_data', 'TensorIteratorOutput_1'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- """
- Create condition node and delete all useless nodes (like Switch/Merge/Identity) from condition pattern
- """
- log.debug('================== DynamicDecoderConditionFind ==================')
- # Create and connect condition node for dynamic decoder in TF
- loop_condiiton = match['loop_cond_data']
- iterator_data = match['identity_data']
-
- condition_attrs = dict(name=match['loop_cond'].name + '/TensorIteratorCondition_')
- condition = TensorIteratorCondition(graph, attrs=condition_attrs)
- condition.create_node_with_data(inputs=[match['Less_enter'].in_node()],
- data_nodes=[loop_condiiton, iterator_data])
-
- # Delete useless nodes
- safe_nodes = ['loop_cond_data', 'identity_data', 'TensorIteratorOutput', 'TensorIteratorOutput_1']
- nodes_for_remove = []
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorConditionChecker.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorConditionChecker.py
deleted file mode 100644
index 69e629beed4885..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorConditionChecker.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_dims
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ConditionChecks(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- from openvino.tools.mo.middle.TensorIteratorBackEdge import BackEdgesMatching
- return [BackEdgesMatching]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- log.debug('+++++++++++++++ ConditionCheckerMatching ++++++++++++++++')
- return dict(
- nodes=[
- ('condition', dict(kind='op', op='TensorIteratorCondition')),
- ('Strided_slice', dict(kind='op', op='StridedSlice')),
- ('Strided_slice_data', dict(kind='data')),
- ('shape', dict(kind='op', op='ShapeOf')),
- ('shape_data', dict(kind='data')),
-
- ('minimum', dict(kind='op', op='Minimum')),
- ('minimum_data', dict(kind='data')),
- ('Maximum', dict(kind='op', op='Maximum')),
- ('Maximum_data', dict(kind='data')),
- ],
- edges=[
- ('shape', 'shape_data'),
- ('shape_data', 'Strided_slice'),
- ('Strided_slice', 'Strided_slice_data'),
- ('Strided_slice_data', 'condition'),
- ('Strided_slice_data', 'minimum'),
-
- ('Maximum', 'Maximum_data'),
- ('Maximum_data', 'minimum'),
- ('minimum', 'minimum_data'),
- ('minimum_data', 'condition'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph, match: dict):
- # Check for SS params
- # Sanity check that we iterate over axis of some tensor
- ss = match['Strided_slice']
- params = ss.in_nodes()
- assert np.all(params[1].in_node().value == 0)
- assert np.all(params[2].in_node().value == 1)
- assert np.all(params[3].in_node().value == 1)
-
- # Check for comparing SS and seq_length source (it should be one tensor)
- # SIMPLE CHECK
- assert match['Strided_slice_data'].value is not None
- if match['minimum_data'].value is None:
- log.warning('TF loop doesn\'t have a constant upper bound produced by node {}, or ModelOptimizer '
- 'cannot detect a constant in this case. Loops with a dynamic number of iterations are not '
- 'supported, so in the resulting IR, generated TensorIterator will have '
- 'a maximum number of iterations determined by input tensor size: {}'
- ''.format(match['minimum_data'].soft_get('name'), match['Strided_slice_data'].value)
- )
- else:
- assert compatible_dims(match['Strided_slice_data'].value, match['minimum_data'].value), \
- 'Values do not match: {} and {}'.format(match['Strided_slice_data'].value, match['minimum_data'].value)
-
- # Check that bound for Condition and Inputs/Outputs sizes match
- condition_time = match['condition'].out_node(0)
- inputs_and_outputs = condition_time.out_nodes()
- type_list = ['TensorIteratorInput']
-
- for ta in inputs_and_outputs:
- if ta.has_valid('kind') and ta['kind'] == 'op' and ta['op'] in type_list:
- assert ta.in_node(0).id == ss.id
-
- log.debug('+++++++++++++++ Condition Check was successful ++++++++++++++++')
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorInput.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorInput.py
deleted file mode 100644
index 1b558bf2b608d2..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorInput.py
+++ /dev/null
@@ -1,420 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.middle.AddIsCyclicAttribute import AddIsCyclicAttribute
-from openvino.tools.mo.ops.TensorIterator_ops import TensorIteratorInput
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class SmartInputMatcher(MiddleReplacementPattern):
- """
- This pattern match partitioned inputs for TensorIterator in dynamic_rnn loops in TF.
- The structure of pattern without Data nodes between ops. Every node is named as op attribute of this node
- (data nodes is marked by (data)):
- TensorArray
- | |
- v v Condition (data)
- Flow(data) Handle(data)-------------- |
- | | | |
- v v v v
- Value (data) -> StridedSlice () -> Range(0;1) -> TensorArrayScatter -> Enter -> TensorArrayRead
- | ^
- |__________________________________________________|
- """
-
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return [AddIsCyclicAttribute]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('TensorArray', dict(kind='op', op='TensorArrayV3')),
- ('TensorArray_handle', dict(kind='data')),
- ('TensorArray_flow', dict(kind='data')),
- ('Enter', dict(kind='op', op='Enter')),
- ('Enter_data', dict(kind='data')),
-
- ('stack', dict(kind='op', op='Const')),
- ('stack_data', dict(kind='data')),
- ('stack_1', dict(kind='op', op='Const')),
- ('stack_1_data', dict(kind='data')),
- ('stack_2', dict(kind='op', op='Const')),
- ('stack_2_data', dict(kind='data')),
-
- ('start', dict(kind='op', op='Const')),
- ('start_data', dict(kind='data')),
-
- ('delta', dict(kind='op', op='Const')),
- ('delta_data', dict(kind='data')),
-
- ('StridedSlice', dict(kind='op', op='StridedSlice')),
- ('StridedSlice_data', dict(kind='data')),
- ('range', dict(kind='op', op='Range')),
- ('range_data', dict(kind='data')),
-
- ('TensorArrayScatter', dict(kind='op', op='TensorArrayScatterV3')),
- ('TensorArrayScatter_data', dict(kind='data')),
- ('Enter_1', dict(kind='op', op='Enter')),
- ('Enter_1_data', dict(kind='data')),
-
- ('TensorArrayRead', dict(kind='op', op='TensorArrayReadV3')),
- ('TensorArrayRead_data', dict(kind='data')),
-
- ('Condition_data', dict(kind='data')),
- ],
- edges=[
- ('TensorArray', 'TensorArray_handle'),
- ('TensorArray', 'TensorArray_flow'),
- ('TensorArray_handle', 'Enter'),
- ('Enter', 'Enter_data'),
-
- ('stack', 'stack_data'),
- ('stack_1', 'stack_1_data'),
- ('stack_2', 'stack_2_data'),
- ('stack_data', 'StridedSlice', {'in': 1}),
- ('stack_1_data', 'StridedSlice', {'in': 2}),
- ('stack_2_data', 'StridedSlice', {'in': 3}),
-
- ('StridedSlice', 'StridedSlice_data'),
- ('StridedSlice_data', 'range', {'in': 1}),
- ('start', 'start_data'),
- ('delta', 'delta_data'),
-
- ('start_data', 'range', {'in': 0}),
- ('delta_data', 'range', {'in': 2}),
- ('range', 'range_data'),
- ('range_data', 'TensorArrayScatter'),
-
- ('TensorArray_handle', 'TensorArrayScatter'),
- ('TensorArray_flow', 'TensorArrayScatter'),
- ('TensorArrayScatter', 'TensorArrayScatter_data'),
- ('TensorArrayScatter_data', 'Enter_1'),
- ('Enter_1', 'Enter_1_data'),
-
- ('Enter_data', 'TensorArrayRead'),
- ('Enter_1_data', 'TensorArrayRead'),
- ('Condition_data', 'TensorArrayRead'),
- ('TensorArrayRead', 'TensorArrayRead_data'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== SmartInputFind ===============')
-
- assert match['Enter_data'].value is not None
- assert match['stack_data']['value'][0] == 0 and match['stack_1_data']['value'][0] == 1 and \
- match['stack_2_data']['value'][0] == 1
- assert match['start_data']['value'] == 0 and match['delta_data']['value'] == 1
-
- ta_size_data = match['TensorArray'].in_node()
- ta_size = ta_size_data.in_node()
- value = match['TensorArrayScatter'].in_node(2)
-
- start, end = None, None
- if 0 in ta_size.in_nodes():
- shape = match['StridedSlice'].in_node(0).in_node(0)
- # Case when value for Strided slice is Const, not Shape
- if shape['kind'] == 'op' and shape['op'] == 'Const':
- start = 0
- end = shape.value[0]
- log.warning("Your network cannot be reshaped since shapes of placeholders are constants. "
- "Please, provide non-constant shapes. ")
-
- # Create input node with params
- # axis == 0 because in TensorArray we ALWAYS iterate over 0 axis, other params will be fill later (with
- # condition)
- input_node = TensorIteratorInput(graph, dict(axis=0, start=start, stride=None, part_size=None,
- external_port_id=str(match['Enter_data'].value),
- internal_layer_id=match['TensorArrayRead_data'].id,
- name=match['TensorArrayRead'].name + '/TensorIteratorInput_'
- ))
- input_node.create_node_with_data(inputs=[ta_size_data, value, match['Condition_data']],
- data_nodes=[match['TensorArrayRead_data']])
- # Delete useless nodes
- safe_nodes = ['TensorArrayRead_data', 'Condition', 'Condition_data']
-
- nodes_for_remove = []
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
-
-
-class SimpleInputMatcher(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- from openvino.tools.mo.middle.DeleteNotExecutable import DeleteNotExecutable
- return [DeleteNotExecutable]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- """
- This pattern match simple inputs (without partitions) in while loops in TF (this inputs are set by Enter nodes).
- """
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('Enter', dict(kind='op', op='Enter')),
- ],
- edges=[
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== SimpletInputFind ===============')
-
- input_node = TensorIteratorInput(graph, dict(external_port_id=None,
- internal_layer_id=None,
- name=match['Enter'].name + '/TensorIteratorInput_'
- ))
- input_node.create_node_with_data(inputs=[match['Enter'].in_node()], data_nodes=[match['Enter'].out_node()])
-
- # Delete useless nodes
- graph.remove_nodes_from([match['Enter'].id])
-
-
-class BackEdgeSimpleInputMatcher(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return [SimpleInputMatcher]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('BackEdge', dict(kind='op', op='TensorIteratorBackEdge')),
- ],
- edges=[
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== SimpleBackEdgeInputFind ===============')
-
- assert len(match['BackEdge'].in_nodes()) == 3
- condition = match['BackEdge'].in_node(2)
- init_input = match['BackEdge'].in_node(0)
- cycle_input = match['BackEdge'].in_node(1)
-
- # We need to create new TensorItertorInput node only if this node doesn't exist already.
- if (len(init_input.in_nodes()) == 0 or \
- (len(init_input.in_nodes()) == 1 and init_input.has_valid('value') and
- init_input.in_node(0).soft_get('op') != 'TensorIteratorInput')):
-
- input_node = TensorIteratorInput(graph, dict(external_port_id=None,
- internal_layer_id=None,
- name=match['BackEdge'].name + '/TensorIteratorInput_'
- ))
-
- # In case if data node has Constant producer
- if len(init_input.in_nodes()) == 1:
- graph.remove_edge(init_input.in_node(0).id, init_input.id)
-
- input_data_node = input_node.create_node_with_data(inputs=[init_input])
- input_data_node.shape = int64_array(init_input.shape)
- graph.remove_edges_from([(init_input.id, match['BackEdge'].id)])
- graph.add_edges_from([(input_data_node.id, match['BackEdge'].id, {'in': 0, 'out': 0})])
-
-
-class SmartMatcherInputSlicingWithGather(MiddleReplacementPattern):
- r"""
- The transformation matches a sub-graph where input tensor is consequently sliced along some axis
- for each time step (or index) inside TensorFlow 1.x while_loop operation.
- In the original graph StridedSlice with non-constant begin and end attributes performs this slicing.
- NonConstBeginStridedSliceReplacement, a front transformation, replaces this StridedSlice with Gather operation
- after which the following sub-graph is obtained (Note: no data node is displayed):
-
- NextIteration <------- Add <--- Time Step
- | /\
- \/ |
- InitTime ----> Enter --> Merge ---> Switch ---> Identity ------
- | /\ |
- \/ | |
- MaxTime ---> Less ---> LoopCond Unsqueeze (axis=0)
- | |
- \/ \/
- Input ---> Enter ----> Merge ---> Switch ---> Identity ---> Gather ---> Squeeze --> Ops (Need Slice at i-th time)
- /\ | /\ /\
- | \/ |----Axis----|
- -------------------- NextIteration
-
- Some part of the sub-graph above is replaced with TensorIteratorInput and the following graph is obtained
- after the transformation:
-
- NextIteration <------- Add <--- Time Step
- | /\
- \/ |
- InitTime ----> Enter --> Merge ---> Switch ---> Identity ------|
- | /\ |
- \/ | |
- MaxTime ---> Less ---> LoopCond |
- | |
- | |-----------------------------------------
- \/ \/
- Input --> TensorIteratorInput(InitTime, TimeStep, Axis) ---> Ops (Need Slice at i-th time)
-
- Details about TensorIterator (inputs, outputs, and attributes) will be finally used by TensorIteratorMerge
- transformation during construction of TensorIterator operation.
- """
-
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return [AddIsCyclicAttribute]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorBackEdge import BackEdgesMatching
- from openvino.tools.mo.middle.TensorIteratorCondition import LoopConditionMatcher
- return [BackEdgesMatching, LoopConditionMatcher]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- # LoopCond node and related Condition node
- ('EnterMaxIndex', dict(kind='op', op='Enter')),
- ('EnterMaxIndexData', dict(kind='data')),
- ('Less', dict(kind='op', op='Less')),
- ('LessData', dict(kind='data')),
- ('LoopCond', dict(kind='op', op='LoopCond')),
- ('LoopCondData', dict(kind='data')),
-
- # a list of Input specific nodes
- ('EnterInput', dict(kind='op', op='Enter')),
- ('EnterInputData', dict(kind='data')),
- ('MergeInput', dict(kind='op', op='Merge')),
- ('MergeInputData', dict(kind='data')),
- ('SwitchInput', dict(kind='op', op='Switch')),
- ('SwitchInputData', dict(kind='data')),
- ('IdentityInput', dict(kind='op', op='Identity')),
- ('IdentityInputData', dict(kind='data')),
- ('NextIterationInput', dict(kind='op', op='NextIteration')),
-
- # a list of Index specific nodes
- ('InitIndex', dict(kind='op', op='Const')),
- ('InitIndexData', dict(kind='data')),
- ('EnterIndex', dict(kind='op', op='Enter')),
- ('EnterIndexData', dict(kind='data')),
- ('MergeIndex', dict(kind='op', op='Merge')),
- ('MergeIndexData', dict(kind='data')),
- ('SwitchIndex', dict(kind='op', op='Switch')),
- ('SwitchIndexData', dict(kind='data')),
- ('IdentityIndex', dict(kind='op', op='Identity')),
- ('IdentityIndexData', dict(kind='data')),
- ('UnsqueezeIndex', dict(kind='op', op='Unsqueeze')),
- ('UnsqueezeIndexData', dict(kind='data')),
- ('AddIndex', dict(kind='op', op='Add')),
- ('AddIndexData', dict(kind='data')),
- ('NextIterationIndex', dict(kind='op', op='NextIteration')),
- ('IndexDelta', dict(kind='op', op='Const')),
- ('IndexDeltaData', dict(kind='data')),
-
- # a list of nodes responsible for slicing
- ('Axis', dict(kind='op', op='Const')),
- ('AxisData', dict(kind='data')),
- ('Gather', dict(kind='op', op='Gather')),
- ('GatherData', dict(kind='data')),
- ('SqueezeSlice', dict(kind='op', op='Squeeze')),
- ('SqueezeSliceData', dict(kind='data')),
- ],
- edges=[
- ('EnterMaxIndex', 'EnterMaxIndexData'),
- ('EnterMaxIndexData', 'Less', {'in': 1}),
- ('Less', 'LessData'),
- ('LessData', 'LoopCond'),
- ('LoopCond', 'LoopCondData'),
- ('LoopCondData', 'SwitchInput', {'in': 1}),
-
- ('EnterInput', 'EnterInputData'),
- ('EnterInputData', 'MergeInput', {'in': 0}),
- ('MergeInput', 'MergeInputData'),
- ('MergeInputData', 'SwitchInput', {'in': 0}),
- ('SwitchInput', 'SwitchInputData', {'out': 1}),
- ('SwitchInputData', 'IdentityInput'),
- ('IdentityInput', 'IdentityInputData'),
- ('IdentityInputData', 'Gather', {'in': 0}),
- ('IdentityInputData', 'NextIterationInput'),
-
- ('InitIndex', 'InitIndexData'),
- ('InitIndexData', 'EnterIndex'),
- ('EnterIndex', 'EnterIndexData'),
- ('EnterIndexData', 'MergeIndex', {'in': 0}),
- ('MergeIndex', 'MergeIndexData'),
- ('MergeIndexData', 'SwitchIndex', {'in': 0}),
- ('MergeIndexData', 'Less', {'in': 0}),
- ('LoopCondData', 'SwitchIndex', {'in': 1}),
- ('SwitchIndex', 'SwitchIndexData', {'out': 1}),
- ('SwitchIndexData', 'IdentityIndex'),
- ('IdentityIndex', 'IdentityIndexData'),
- ('IdentityIndexData', 'AddIndex', {'in': 0}),
- ('AddIndex', 'AddIndexData'),
- ('AddIndexData', 'NextIterationIndex'),
- ('IndexDelta', 'IndexDeltaData'),
- ('IndexDeltaData', 'AddIndex', {'in': 1}),
-
- ('IdentityIndexData', 'UnsqueezeIndex'),
- ('UnsqueezeIndex', 'UnsqueezeIndexData'),
- ('UnsqueezeIndexData', 'Gather', {'in': 1}),
- ('Axis', 'AxisData'),
- ('AxisData', 'Gather', {'in': 2}),
- ('Gather', 'GatherData'),
- ('GatherData', 'SqueezeSlice'),
- ('SqueezeSlice', 'SqueezeSliceData'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- # retrieve attribute values for TensorIteratorInput node
- init_time = match['InitIndex'].value.item(0)
- time_step = match['IndexDelta'].value.item(0)
- axis = match['Axis'].value.item(0)
-
- # retrieve input and output nodes for TensorIteratorInput node
- initial_input_node = match['EnterInput']
- current_index_node = match['IdentityIndex']
- size_node = match['EnterMaxIndex']
- resulted_slice_node = match['SqueezeSlice']
- resulted_slice_node_name = resulted_slice_node.soft_get('name', resulted_slice_node.id)
-
- # create TensorIteratorInput node that reflects slicing of input for each time step along axis
- ti_input_node = TensorIteratorInput(graph, dict(axis=axis, start=init_time, stride=time_step,
- name=resulted_slice_node_name + '/TensorIteratorInput')
- ).create_node()
- size_node.in_port(0).get_connection().add_destination(ti_input_node.in_port(0))
- initial_input_node.in_port(0).get_connection().set_destination(ti_input_node.in_port(1))
- current_index_node.out_port(0).connect(ti_input_node.in_port(2))
- resulted_slice_node.out_port(0).get_connection().set_source(ti_input_node.out_port(0))
-
- # delete no longer needed nodes responsible for slicing of input in the original graph
- node_names_for_remove = ['EnterInput', 'MergeInput', 'SwitchInput',
- 'IdentityInput', 'NextIterationInput', 'SqueezeSlice', 'UnsqueezeIndex', 'Gather']
- graph.remove_nodes_from([match[node_name].id for node_name in node_names_for_remove])
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorLSTMToLSTMSequence.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorLSTMToLSTMSequence.py
deleted file mode 100644
index bb01b0a1214c56..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorLSTMToLSTMSequence.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.ONNXRNNSequenceNormalize import ONNXRNNSequenceNormalize
-from openvino.tools.mo.middle.TF_lstm_cell_to_generic import TensorFlowLSTMtoGeneric
-from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.pattern_match import find_isomorphisms
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-
-
-class TensorIteratorLSTM(MiddleReplacementPattern):
- """ Detects TensorIterator with LSTMCell of supported form.
-
- Collect original operation names of supported LSTMCells in
- the list LSTMCell.instances_supported_by_IE. It will be used at the second
- round of the network translation. Mark all supported LSTMCell with flag
- supported_by_IE to have a chance to detect all not-supported instances
- in a separate pass.
- """
-
- enabled = False
-
- def run_after(self):
- return [TensorIteratorMerge, ONNXRNNSequenceNormalize, TensorFlowLSTMtoGeneric]
-
- def pattern(self):
- return dict(
- nodes=[
- ('ti', dict(kind='op', op='TensorIterator')),
- ],
- edges=[
- ]
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- nodes = [
- ('input_unsqueezed'),
- ('squeeze', dict(op='Reshape')),
- ('input_squeezed'),
- ('input_hidden'),
- ('input_cell'),
- ('weights'),
- ('biases'),
-
- ('lstm', dict(op='LSTMCell')),
-
- ('output_hidden'),
- ('output_cell'),
- ('unsqueeze', dict(op='Reshape')),
- ('output_unsqueezed'),
- ]
- edges = [
- ('input_unsqueezed', 'squeeze'),
- ('squeeze', 'input_squeezed'),
-
- ('input_squeezed', 'lstm', {'in': 0}),
- ('input_hidden', 'lstm', {'in': 1}),
- ('input_cell', 'lstm', {'in': 2}),
- ('weights', 'lstm', {'in': 3}),
- ('biases', 'lstm', {'in': 4}),
-
- ('lstm', 'output_hidden', {'out': 0}),
- ('lstm', 'output_cell', {'out': 1}),
-
- ('output_hidden', 'unsqueeze'),
- ('unsqueeze', 'output_unsqueezed'),
- ]
- ti = match['ti']
- isomorphisms = find_isomorphisms(ti.body, nodes, edges)
- if len(list(isomorphisms)) != 1:
- raise Error('Unsupported TensorIterator layer {} was found: either its body, ports or '
- 'edges are not supported by OpenVINO. '
- 'Only TensorIterator with LSTMCell in a body of strict form is supported. '
- 'Please modify the original network '
- 'to meet the requirements.'.format(ti.soft_get('name')))
- body_match = isomorphisms[0]
- if body_match['input_hidden'].has_valid('value') or body_match['input_cell'].has_valid('value'):
- raise Error('Unsupported TensorIterator layer {} was found: initial hidden and/or cell states '
- 'for LSTMCell are constants. This is not supported. '
- 'Only TensorIterator with LSTMCell in a body of strict form is supported. '
- 'Please modify the original network '
- 'to meet the requirements.'.format(ti.soft_get('name')))
- # TODO Additional checks for port indices
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorMerge.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorMerge.py
deleted file mode 100644
index 4a3294745c6fb1..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorMerge.py
+++ /dev/null
@@ -1,368 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from collections import deque
-from copy import deepcopy
-
-from openvino.tools.mo.ops.tensor_iterator import TensorIterator
-from openvino.tools.mo.front.common.partial_infer.utils import shape_insert
-from openvino.tools.mo.graph.graph import Node, Graph, add_opoutput
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from openvino.tools.mo.utils.graph import sub_graph_between_nodes, invert_sub_graph_between_nodes
-
-stop_nodes = ['TensorIteratorInput', 'TensorIteratorOutput', 'TensorIteratorBackEdge', 'TensorIteratorCondition']
-
-
-def op_type(graph, node_name: str):
- node = Node(graph, node_name)
- if node.has_valid('kind') and node['kind'] == 'op':
- return node['op']
- else:
- return None
-
-
-def update_inputs(graph, inputs: list, node_name: str):
- node = Node(graph, node_name)
- if node.has_valid('kind') and node['kind'] == 'op' and node['op'] == 'TensorIteratorInput':
- if node_name not in inputs:
- inputs.append(node_name)
-
-
-def reverse_dfs(graph: Graph, node_name: str, stop_nodes: list, inputs: list, visited: set = None):
- d = deque()
-
- if visited is None:
- visited = set()
- visited.add(node_name)
- d.appendleft(node_name)
- while len(d) != 0:
- cur_node = d.popleft()
- for in_node_name, _ in graph.in_edges(cur_node):
- if in_node_name not in visited:
- if op_type(graph, in_node_name) not in stop_nodes:
- visited.add(in_node_name)
- d.append(in_node_name)
- else:
- update_inputs(graph, inputs, in_node_name)
-
-
-def dfs(graph: Graph, node_name: str, stop_nodes: list, visited: set = None):
- d = deque()
-
- visited.add(node_name)
- d.appendleft(node_name)
- while len(d) != 0:
- cur_node = d.popleft()
- for _, out_node_name in graph.out_edges(cur_node):
- if out_node_name not in visited:
- if op_type(graph, out_node_name) not in stop_nodes:
- visited.add(out_node_name)
- d.append(out_node_name)
-
-
-def get_body(graph, inputs, outputs):
- if len(inputs) == 0:
- nodes, extra_inputs = invert_sub_graph_between_nodes(
- graph,
- outputs,
- inputs,
- lambda node: node.soft_get('op') == 'TensorIteratorInput'
- )
- else:
- nodes, extra_inputs = sub_graph_between_nodes(
- graph,
- inputs,
- outputs,
- lambda node: node.soft_get('op') == 'TensorIteratorInput'
- )
- nodes = list(set(nodes) - set(inputs) - set(outputs) - set(extra_inputs))
- return nodes, extra_inputs
-
-
-class TensorIteratorMerge(MiddleReplacementPattern):
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('condition', dict(kind='op', op='TensorIteratorCondition')),
- ],
- edges=[],
- )
-
- @staticmethod
- def replace_pattern(graph, match: dict):
- # Here we will found all parts of TI: condition, inputs/outputs, back edges, body and create TensorIterator Op
- # and make all checks needed for TensorIterator work
- cond_data = match['condition'].out_node(0) if not match['condition'].out_port(0).disconnected() else None
- time_data = match['condition'].out_node(1) if len(match['condition'].out_nodes()) >= 1 else None
- name = match['condition'].name
-
- back_edges = []
- inputs = []
- outputs = []
-
- if cond_data is not None:
- for node in cond_data.out_nodes():
- if node['kind'] == 'op' and node['op'] == 'TensorIteratorBackEdge':
- back_edges.append(node.id)
- elif node['kind'] == 'op' and node['op'] == 'TensorIteratorInput':
- inputs.append(node.id)
- elif node['kind'] == 'op' and node['op'] == 'TensorIteratorOutput':
- outputs.append(node.id)
-
- if time_data is not None:
- for node in time_data.out_nodes():
- if node['kind'] == 'op' and node['op'] == 'TensorIteratorInput':
- inputs.append(node.id)
- elif node['kind'] == 'op' and node['op'] == 'TensorIteratorOutput':
- outputs.append(node.id)
- else:
- # something goes wrong here
- assert False
- condition = match['condition']
- tensor_sequence_length = condition.in_node(0)
-
- nodes_to_remove = [n.id for n in (condition, cond_data, time_data, tensor_sequence_length) if n is not None]
- graph.remove_nodes_from(nodes_to_remove)
-
- body_nodes, extra_inputs = get_body(graph, inputs, outputs)
-
- if cond_data is not None:
- body_nodes = list(set(body_nodes) - set([cond_data]))
-
- inputs += extra_inputs
-
- assert all([node in graph.nodes() for node in body_nodes])
-
- inputs = [Node(graph, node) for node in inputs]
- outputs = [Node(graph, node) for node in outputs]
- back_edges = [Node(graph, node) for node in back_edges]
-
- external_inputs = [
- {
- 'external_data_id': node.in_node(1 if node.has_valid('axis') else 0),
- 'internal_data_id': node.out_node(0),
- 'axis': node.axis,
- 'start': node.start,
- 'end': node.end,
- 'stride': node.stride,
- 'part_size': node.part_size
- } for node in inputs]
-
- external_outputs = [
- {
- 'external_data_id': node.out_node(0),
- 'internal_data_id': node.in_node(1 if node.has_valid('axis') else 0),
- 'axis': node.axis,
- 'start': node.start,
- 'end': node.end,
- 'stride': node.stride,
- 'part_size': node.part_size
- } for node in outputs]
-
- back_edges_data = [
- {
- 'from_data_id': node.in_node(1),
- 'to_data_id': node.out_node(0),
- 'init_data_id': node.in_node(0),
- } for node in back_edges
- ]
-
- body = Graph(name='body')
- body.graph = graph.graph
- body.add_nodes_from([(node, graph.node[node]) for node in body_nodes])
- body.add_edges_from(
- [(u, v, k, d) for u, v, k, d in graph.edges(data=True, keys=True) if u in body_nodes and v in body_nodes])
-
- graph.remove_nodes_from(
- body_nodes + [match['condition'].id] + [inp.id for inp in inputs] + [out.id for out in outputs])
- internal_id_count = 0
- real_back_edges = []
- for edge in back_edges_data:
- assert edge['from_data_id'].id in body.nodes()
- assert edge['to_data_id'].id in body.nodes()
- assert edge['init_data_id'].id in body.nodes()
- edge['from_data_id'] = Node(body, edge['from_data_id'].id)
- edge['to_data_id'] = Node(body, edge['to_data_id'].id)
- edge['init_data_id'] = Node(body, edge['init_data_id'].id)
- add_opoutput(body, edge['from_data_id'].id, 0, False)
-
- # Assign/reuse ids for the back-edge start; it comes from from_data_id
- assert len(edge['from_data_id'].in_nodes()) == 1
- # layer id
- if not edge['from_data_id'].in_node().has_valid('internal_layer_id'):
- edge['from_data_id'].in_node()['internal_layer_id'] = internal_id_count
- internal_id_count += 1
- edge['from_layer'] = edge['from_data_id'].in_node()['internal_layer_id']
-
- # port id
- if 'internal_port_id' not in edge['from_data_id'].in_edge():
- edge['from_data_id'].in_edge()['internal_port_id'] = internal_id_count
- internal_id_count += 1
- edge['from_port'] = edge['from_data_id'].in_edge()['internal_port_id']
-
- # Look at all consumers for a data that ends a back-edge
- # For each such consumer, there will be a separate back-edge (and input)
- current_real_back_edges = []
- for _, consumer, key, edge_attrs in body.out_edges(edge['to_data_id'].id, data=True, keys=True):
-
- real_edge = {}
- real_edge.update(edge) # all real back_edges have the same back-edge start
-
- consumer = Node(body, consumer)
-
- if real_edge['to_data_id'].in_node().has_valid('internal_layer_id'):
- assert False
- real_edge['to_data_id'].out_node()['internal_layer_id'] = \
- real_edge['to_data_id'].in_node().internal_layer_id
- elif not consumer.has_valid('internal_layer_id'):
- consumer['internal_layer_id'] = internal_id_count
- internal_id_count += 1
- real_edge['to_layer'] = consumer['internal_layer_id']
-
- assert 'internal_port_id' not in edge_attrs
- assert len(real_edge['init_data_id'].out_edges()) == 1
- assert not 'internal_port_id' in real_edge['init_data_id'].out_edge()
- edge_attrs['internal_port_id'] = internal_id_count
- internal_id_count += 1
- real_edge['to_port'] = edge_attrs['internal_port_id']
- real_edge['consumer'] = consumer
- real_edge['consumer_key'] = key
-
- real_edge['attrs'] = deepcopy(edge_attrs)
- current_real_back_edges.append(real_edge)
-
- # connect initial data node with each consumer providing actual edge attributes
- body.add_edges_from([
- (
- real_edge['init_data_id'].id,
- real_edge['consumer'].id,
- real_edge['consumer_key'],
- real_edge['attrs'])
- for real_edge in current_real_back_edges])
-
- body.remove_nodes_from([edge['to_data_id'].id, edge['to_data_id'].in_node().id])
- real_back_edges += current_real_back_edges
-
- real_external_inputs = []
-
- for ext_inp in external_inputs:
- assert ext_inp['external_data_id'].id not in body.nodes()
- assert ext_inp['internal_data_id'].id in body.nodes()
- ext_inp['internal_data_id'] = Node(body, ext_inp['internal_data_id'].id)
-
- if ext_inp['axis'] is not None:
- # Insert squeezing resize at input port that has partitioning
- shape = ext_inp['internal_data_id'].shape.copy()
- assert not ext_inp['internal_data_id'].has_valid('value')
- new_input_data = Op._create_data_node(body, ext_inp['internal_data_id'].name + '/UnsqueezedInput',
- dict(shape=shape_insert(shape, ext_inp['axis'], 1)))
-
- reshape_op = Squeeze(body, dict(name=ext_inp['internal_data_id'].name + '/InputSqueeze'))
- reshape_dim_data = Const(body, {'name': ext_inp['internal_data_id'].name + '/ReshapeDim',
- 'value': ext_inp['axis']}).create_node_with_data()
- reshape_op.create_node_with_data([new_input_data, reshape_dim_data],
- data_nodes=[ext_inp['internal_data_id']])
- ext_inp['internal_data_id'] = new_input_data
-
- ext_inp['internal_data_id']['is_input'] = True
- assert len(ext_inp['internal_data_id'].in_nodes()) == 0
- ext_inp['external_port_id'] = internal_id_count
- internal_id_count += 1
- for _, consumer, edge_attrs in body.out_edges(ext_inp['internal_data_id'].id, data=True):
- real_ext_inp = {}
- real_ext_inp.update(ext_inp)
- consumer = Node(body, consumer)
- if not consumer.has_valid('internal_layer_id'):
- consumer['internal_layer_id'] = internal_id_count
- internal_id_count += 1
- if not 'internal_port_id' in edge_attrs:
- edge_attrs['internal_port_id'] = internal_id_count
- internal_id_count += 1
- real_ext_inp['internal_layer_id'] = consumer['internal_layer_id']
- real_ext_inp['internal_port_id'] = edge_attrs['internal_port_id']
- real_external_inputs.append(real_ext_inp)
-
- for ext_out in external_outputs:
- assert ext_out['external_data_id'].id not in body.nodes()
- assert ext_out['internal_data_id'].id in body.nodes()
- ext_out['internal_data_id'] = Node(body, ext_out['internal_data_id'].id)
-
- if ext_out['axis'] is not None:
- # Insert unsqueezing resize at output port that has partitioning
- reshape_op = Unsqueeze(body, dict(name=ext_out['internal_data_id'].name + '/OutputUnsqueeze'))
- reshape_dim_data = Const(body, {'name': ext_out['internal_data_id'].name + '/ReshapeDim',
- 'value': ext_out['axis']}).create_node_with_data()
- ext_out['internal_data_id'] = reshape_op.create_node_with_data([ext_out['internal_data_id'],
- reshape_dim_data])
-
- # TODO: add here working with simple outputs
-
- if not any([out_node.soft_get('op', None) == 'Result' for out_node in ext_out['internal_data_id'].out_nodes()]):
- add_opoutput(body, ext_out['internal_data_id'].id, 0, False)
-
- # assert len(ext_out['internal_data_id'].out_nodes()) == 0
- assert len(ext_out['internal_data_id'].in_nodes()) == 1
- if not 'internal_layer_id' in ext_out['internal_data_id'].in_node():
- ext_out['internal_data_id'].in_node()['internal_layer_id'] = internal_id_count
- internal_id_count += 1
- if not 'internal_port_id' in ext_out['internal_data_id'].in_edge():
- ext_out['internal_data_id'].in_edge()['internal_port_id'] = internal_id_count
- internal_id_count += 1
- ext_out['internal_layer_id'] = ext_out['internal_data_id'].in_node()['internal_layer_id']
- ext_out['internal_port_id'] = ext_out['internal_data_id'].in_edge()['internal_port_id']
- ext_out['external_port_id'] = internal_id_count
- internal_id_count += 1
-
- # create TensorIterator layer with pre-computed components
- ti_op = TensorIterator(graph, {
- 'name': name + '/TensorIterator',
- 'body': body,
- 'in_ports_count': len(external_inputs),
- 'out_ports_count': len(external_outputs),
-
- 'input_port_map': [
- {field: external_input[field] for field in
- ['external_port_id', 'internal_layer_id', 'internal_port_id', 'axis', 'stride', 'part_size', 'start',
- 'end']}
- for external_input in real_external_inputs],
-
- 'output_port_map': [
- {field: external_output[field] for field in
- ['external_port_id', 'internal_layer_id', 'internal_port_id', 'axis', 'stride', 'part_size', 'start',
- 'end']}
- for external_output in external_outputs],
- 'back_edges': [
- {field: edge[field] for field in ['from_layer', 'from_port', 'to_layer', 'to_port']}
- for edge in real_back_edges],
- })
-
- ti_outs = ti_op.create_node_with_data(
- inputs=[inp['external_data_id'] for inp in external_inputs],
- edge_attrs=[{'external_port_id': inp['external_port_id']} for inp in external_inputs],
- data_nodes=[out['external_data_id'] for out in external_outputs]
- )
-
- if not isinstance(ti_outs, list):
- ti_outs = [ti_outs]
-
- for i, out in enumerate(ti_outs):
- out.in_edge()['external_port_id'] = external_outputs[i]['external_port_id']
-
- ti = ti_outs[0].in_node()
- TensorIterator.cover_body_input_data_nodes_with_parameter_ops(ti)
- TensorIterator.cover_body_constant_data_nodes_with_const_ops(ti)
- TensorIterator.normalize_internal_ids(ti)
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIteratorOutput.py b/tools/mo/openvino/tools/mo/middle/TensorIteratorOutput.py
deleted file mode 100644
index 7910a425068bf7..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIteratorOutput.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.ops.TensorIterator_ops import TensorIteratorOutput
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class SmartOutputMatcher(MiddleReplacementPattern):
- """
- This pattern match partitioned outputs for TensorIterator in dynamic_rnn loops in TF.
- The structure of pattern without Data nodes between ops. Every node is named as op attribute of this node
- (data nodes is marked by (data)):
- TensorArray
- | | Condition(data)
- Flow(data) Handle(data)--------------------------------------------------------------- |
- | | | | |
- v v v v v
- Enter -> Merge -> Switch -> Exit -> TensorArraySize -> Range(0;1) -> TensorArrayGather
- | | ^
- | | |
- | ---------------------------------------------
- |
- --------> Identity -> TensorArrayWrite -> NextIteration
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- from openvino.tools.mo.middle.TensorIteratorInput import SmartInputMatcher
- return [SmartInputMatcher]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- return [TensorIteratorMerge]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('TensorArray', dict(kind='op', op='TensorArrayV3')),
- ('TensorArray_data', dict(kind='data')),
- ('TensorArray_flow_data', dict(kind='data')),
- ('TensorArrayGather', dict(kind='op', op='TensorArrayGatherV3')),
- ('TensorArrayGather_data', dict(kind='data')),
- ('range', dict(kind='op', op='Range')),
- ('range_data', dict(kind='data')),
- ('size', dict(kind='op', op='TensorArraySizeV3')),
- ('size_data', dict(kind='data')),
- ('start', dict(kind='op', op='Const')),
- ('start_data', dict(kind='data')),
- ('delta', dict(kind='op', op='Const')),
- ('delta_data', dict(kind='data')),
- ('TensorArrayWrite', dict(kind='op', op='TensorArrayWriteV3')),
- ('TensorArrayWrite_data', dict(kind='data')),
- ('NextIteration', dict(kind='op', op='NextIteration')),
- ('Condition_data', dict(kind='data')),
- ('Identity_2_data', dict(kind='data')),
- ('Identity_2', dict(kind='op', op='Identity')),
- ('Switch_2', dict(kind='op', op='Switch')),
- ('Switch_2_data', dict(kind='data')),
- ('Switch_2_data_exit', dict(kind='data')),
- ('Merge_2', dict(kind='op', op='Merge')),
- ('Merge_2_data', dict(kind='data')),
- ('Enter_2', dict(kind='op', op='Enter')),
- ('Enter_2_data', dict(kind='data')),
- ('WriteEnter', dict(kind='op', op='Enter')),
- ('WriteEnter_data', dict(kind='data')),
- ('Exit', dict(kind='op', op='Exit')),
- ('Exit_data', dict(kind='data')),
- ],
- edges=[
- ('TensorArray', 'TensorArray_data'),
- ('TensorArray', 'TensorArray_flow_data'),
- ('TensorArray_flow_data', 'Enter_2'),
- ('TensorArray_data', 'WriteEnter'),
- ('TensorArray_data', 'TensorArrayGather'),
- ('TensorArrayGather', 'TensorArrayGather_data'),
- ('TensorArray_data', 'size'),
-
- ('size', 'size_data'),
- ('start', 'start_data'),
- ('delta', 'delta_data'),
-
- ('size_data', 'range', {'in': 1}),
- ('start_data', 'range', {'in': 0}),
- ('delta_data', 'range', {'in': 2}),
- ('range', 'range_data'),
- ('range_data', 'TensorArrayGather'),
-
- ('Enter_2', 'Enter_2_data'),
- ('Enter_2_data', 'Merge_2'),
- ('Merge_2', 'Merge_2_data'),
- ('Merge_2_data', 'Switch_2'),
- ('Switch_2', 'Switch_2_data'),
- ('Switch_2', 'Switch_2_data_exit'),
- ('Switch_2_data', 'Identity_2'),
- ('Identity_2', 'Identity_2_data'),
-
- ('Switch_2_data_exit', 'Exit'),
- ('Exit', 'Exit_data'),
- ('Exit_data', 'size'),
- ('Exit_data', 'TensorArrayGather'),
-
- ('WriteEnter', 'WriteEnter_data'),
- ('WriteEnter_data', 'TensorArrayWrite', {'in': 0}),
-
- ('Identity_2_data', 'TensorArrayWrite', {'in': 3}),
-
- ('TensorArrayWrite', 'TensorArrayWrite_data'),
- ('TensorArrayWrite_data', 'NextIteration'),
- ('Condition_data', 'Switch_2'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== SmartOutputFind ===============')
-
- assert match['WriteEnter_data'].value is not None
- assert match['start_data']['value'] == 0 and match['delta_data']['value'] == 1
-
- ta_size = match['TensorArray'].in_node()
-
- index = match['TensorArrayWrite'].in_node(1)
- value = match['TensorArrayWrite'].in_node(2)
-
- # axis == 0 because in TensorArray we ALWAYS iterate over 0 axis, other params will be fill later (with
- # condition)
- output = TensorIteratorOutput(graph, dict(axis=0, start=None, stride=None, part_size=None,
- external_port_id=str(match['WriteEnter_data'].value),
- internal_layer_id=value.id,
- name=match['TensorArrayWrite'].name + '/TensorIteratorOutput_'
- ))
- output.create_node_with_data(inputs=[ta_size, value, index],
- data_nodes=[match['TensorArrayGather_data']])
-
- # Delete useless nodes
- safe_nodes = ['TensorArrayGather_data', 'Condition_data']
- nodes_for_remove = []
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
-
-
-class SimpleOutputMatcher(MiddleReplacementPattern):
- """
- This pattern match partitioned outputs for TensorIterator in dynamic_rnn loops in TF.
- The structure of pattern without Data nodes between ops. Every node is named as op attribute of this node
- (data nodes is marked by (data)):
- TensorArray
- | |
- Flow(data) Handle(data)------------------------------
- | | |
- v v v
- Enter -> Merge -> Switch -> Exit -> TensorArrayRead
- |
- |
- |
- |
- --------> Identity -> TensorArrayWrite -> NextIteration
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['is_cyclic']]
-
- def run_after(self):
- return [SmartOutputMatcher]
-
- def run_before(self):
- from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
- from openvino.tools.mo.middle.TensorIteratorCondition import LoopConditionMatcher
- return [TensorIteratorMerge, LoopConditionMatcher]
-
- @staticmethod
- def pattern():
- return dict(
- nodes=[
- ('TensorArray', dict(kind='op', op='TensorArrayV3')),
- ('TensorArray_data', dict(kind='data')),
- ('TensorArray_flow_data', dict(kind='data')),
-
- ('TensorArrayWrite', dict(kind='op', op='TensorArrayWriteV3')),
- ('TensorArrayWrite_data', dict(kind='data')),
-
- ('NextIteration', dict(kind='op', op='NextIteration')),
- ('NextIteration_data', dict(kind='data')),
-
- ('Condition_data', dict(kind='data')),
-
- ('Identity_2', dict(kind='op', op='Identity')),
- ('Identity_2_data', dict(kind='data')),
-
- ('Switch_2', dict(kind='op', op='Switch')),
- ('Switch_2_data', dict(kind='data')),
- ('Switch_2_data_exit', dict(kind='data')),
-
- ('Merge_2', dict(kind='op', op='Merge')),
- ('Merge_2_data', dict(kind='data')),
-
- ('Enter_2', dict(kind='op', op='Enter')),
- ('Enter_2_data', dict(kind='data')),
-
- ('WriteEnter', dict(kind='op', op='Enter')),
- ('WriteEnter_data', dict(kind='data')),
-
- ('Exit', dict(kind='op', op='Exit')),
- ('Exit_data', dict(kind='data')),
- #
- ('TensorArrayRead', dict(op='TensorArrayReadV3')),
- ('TensorArrayRead_data', dict(kind='data')),
- ],
- edges=[
- ('TensorArray', 'TensorArray_data'),
- ('TensorArray', 'TensorArray_flow_data'),
- ('TensorArray_flow_data', 'Enter_2'),
- ('TensorArray_data', 'WriteEnter'),
-
-
- ('Enter_2', 'Enter_2_data'),
- ('Enter_2_data', 'Merge_2'),
- ('Merge_2', 'Merge_2_data'),
- ('Merge_2_data', 'Switch_2'),
- ('Switch_2', 'Switch_2_data'),
- ('Switch_2', 'Switch_2_data_exit'),
- ('Switch_2_data', 'Identity_2'),
- ('Identity_2', 'Identity_2_data'),
-
- ('Switch_2_data_exit', 'Exit'),
- ('Exit', 'Exit_data'),
- ('Exit_data', 'TensorArrayRead'),
-
- ('WriteEnter', 'WriteEnter_data'),
- ('WriteEnter_data', 'TensorArrayWrite', {'in': 0}),
-
- ('Identity_2_data', 'TensorArrayWrite', {'in': 3}),
- #
- ('TensorArrayWrite', 'TensorArrayWrite_data'),
- ('TensorArrayWrite_data', 'NextIteration'),
- ('Condition_data', 'Switch_2'),
- #
- ('TensorArray_data', 'TensorArrayRead'),
- ('TensorArrayRead', 'TensorArrayRead_data'),
- ('NextIteration', 'NextIteration_data'),
- ('NextIteration_data', 'Merge_2'),
- ],
- )
-
- @staticmethod
- def replace_pattern(graph: Graph, match: dict):
- log.debug('================== SimpleOutputFind ===============')
- assert match['WriteEnter_data'].value is not None
-
- index = match['TensorArrayWrite'].in_node(1)
- value = match['TensorArrayWrite'].in_node(2)
-
- # axis == 0 because in TensorArray we ALWAYS iterate over 0 axis, other params will be fill later (with
- # condition)
- output = TensorIteratorOutput(graph, dict(
- external_port_id=str(match['WriteEnter_data'].value),
- internal_layer_id=value.id,
- name=match['TensorArrayWrite'].name + '/TensorIteratorOutput_'
- ))
- output.create_node_with_data(inputs=[value, index],
- data_nodes=[match['TensorArrayRead_data']])
-
- # Delete useless nodes
- safe_nodes = ['TensorArrayRead_data', 'Condition_data']
- nodes_for_remove = []
- for node in match.keys():
- if node not in safe_nodes:
- nodes_for_remove.append(match[node].id)
- graph.remove_nodes_from(nodes_for_remove)
diff --git a/tools/mo/openvino/tools/mo/middle/TensorIterator_utils.py b/tools/mo/openvino/tools/mo/middle/TensorIterator_utils.py
deleted file mode 100644
index 7083b8704f761c..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/TensorIterator_utils.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-
-
-def delete_selects_from(graph: Graph, node_idxs: list):
- for node_id in node_idxs:
- greater_equal = Node(graph, node_id)
- for port in greater_equal.out_port(0).get_destinations():
- port_node = port.node
- if port_node.soft_get('op') == 'Select':
-
- port_node.in_port(1).disconnect()
- port_node.in_port(0).disconnect()
-
- # Reconnect select input to next op
- next_op_input_port = port_node.out_port(0).get_destination()
- select_input = port_node.in_port(2).get_source()
- next_op_input_port.get_connection().set_source(select_input)
- graph.remove_node(port_node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/UnsqueezeTileReshapeBlockToInterpolate.py b/tools/mo/openvino/tools/mo/middle/UnsqueezeTileReshapeBlockToInterpolate.py
deleted file mode 100644
index 9496b8ac966ebc..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/UnsqueezeTileReshapeBlockToInterpolate.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Mul
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.utils.shape import node_to_get_shape_value_of_indices
-
-
-class UnsqueezeTileReshapeBlockToInterpolate(MiddleReplacementPattern):
- """
- The transformation looks for a sub-graph performing unsqueeze-ing input tensor by some "axis" and then tiling over
- it fixed number of "times". This pattern can be represented with the Interpolate operation of mode "nearest"
- performing interpolation over specific "axis" with fixed output dimension size equal to "times".
-
- Note, that the transformation expects that the output from Tile is reshaped back to the tensor with rank equal to
- the input tensor rank. This constraints occurs because the pattern appears in the models where these patterns appear
- one after another, performing unsqueeze-ing over different dimensions, effectively performing interpolation over
- several dimensions.
-
- These sequences are merged in the 'optimizer/extensions/middle/InterpolateSequenceToInterpolate.py' transformation
- into a single Interpolate operation.
-
- The transformation is applicable only when all following conditions are fulfilled:
-
- 1. 'Unsqueeze' must be performed with respect to only one axis.
- 2. The length of the value of the second input of 'Tile' must be equal to the input rank of 'Unsqueeze' plus 1.
- 3. All elements of the value of the second input of 'Tile' must be equal to 1,
- except the value corresponding the interpolated axis.
- 4. The input rank of 'Unsqueeze' and the output rank of 'Reshape' must be equal.
-
- Finally, because plugins support only Interpolate-4 with 4D or 5D tensor with interpolated data,
- we need to check that the input rank of 'Unsqueeze' is equal to 4 or 5.
-
- Example.
-
- Let data = np.arange(0, 1 * 2 * 3 * 4).reshape((1, 2, 3, 4)).astype(np.float32), that is
- data = mo_array([[[[ 0, 1, 2, 3],
- [ 4, 5, 6, 7],
- [ 8, 9, 10, 11]],
- [[12, 13, 14, 15],
- [16, 17, 18, 19],
- [20, 21, 22, 23]]]], dtype=np.float32)
- After np.tile(np.expand_dims(data, 3), [1, 1, 1, 2, 1]).reshape((1, 2, 3 * 2, 4)) we get
- array([[[[ 0, 1, 2, 3],
- [ 0, 1, 2, 3],
- [ 4, 5, 6, 7],
- [ 4, 5, 6, 7],
- [ 8, 9, 10, 11],
- [ 8, 9, 10, 11]],
- [[12, 13, 14, 15],
- [12, 13, 14, 15],
- [16, 17, 18, 19],
- [16, 17, 18, 19],
- [20, 21, 22, 23],
- [20, 21, 22, 23]]]], dtype=np.float32)
- This result is equal to nearest interpolation along with axis = 2 (the second argument of 'expand_dims')
- and scale = 2 (the element from the second argument of 'tile' that is not equal to 1).
- """
- enabled = True
- force_shape_inference = True
-
- def run_before(self):
- from openvino.tools.mo.middle.InterpolateSequenceToInterpolate import InterpolateSequenceToInterpolate
- return [InterpolateSequenceToInterpolate]
-
- def pattern(self):
- log.debug('Enabled replacement of a sequence of Unsqueeze, Tile, Reshape with Interpolate.')
- return dict(
- nodes=[
- ('unsqueeze', dict(kind='op', op='Unsqueeze')),
- ('unsqueeze_data', dict(kind='data')),
- ('tile', dict(kind='op', op='Tile')),
- ('tile_data', dict(kind='data')),
- ('reshape', dict(kind='op', op='Reshape')),
- ],
- edges=[
- ('unsqueeze', 'unsqueeze_data'),
- ('unsqueeze_data', 'tile', {'in': 0}),
- ('tile', 'tile_data'),
- ('tile_data', 'reshape', {'in': 0}),
- ]
- )
-
- @staticmethod
- def is_applicable(match: dict) -> bool:
- """
- This function checks whether this transformation is applicable.
- :param match: dictionary with nodes from the found pattern
- :return: True, if the transformation is applicable
- False, otherwise
- """
- unsqueeze_node = match['unsqueeze']
- second_input_of_unsqueeze = unsqueeze_node.in_port(1).get_connection().get_source().node
- if not second_input_of_unsqueeze.has_valid('value') or len(second_input_of_unsqueeze.value) != 1:
- return False
-
- d_idx = int(second_input_of_unsqueeze.value)
- if d_idx == 0:
- return False
-
- second_input_of_tile = match['tile'].in_port(1).get_connection().get_source().node
- if not second_input_of_tile.has_valid('value'):
- return False
-
- input_shape_of_unsqueeze = unsqueeze_node.in_port(0).data.get_shape()
- input_rank_of_unsqueeze = len(input_shape_of_unsqueeze)
- if input_rank_of_unsqueeze not in {4, 5}:
- return False
-
- if input_rank_of_unsqueeze + 1 != len(second_input_of_tile.value):
- return False
-
- expected_tile_constant = np.ones(input_rank_of_unsqueeze + 1, dtype=np.float32)
- expected_tile_constant[d_idx] = float(second_input_of_tile.value[d_idx])
-
- if not np.array_equal(expected_tile_constant, float32_array(second_input_of_tile.value)):
- return False
-
- reshape_node = match['reshape']
- new_shape = reshape_node.in_port(1).data.get_value()
- if new_shape is None or input_rank_of_unsqueeze != len(new_shape):
- return False
-
- return True
-
- def replace_pattern(self, graph: Graph, match: dict):
- if not self.is_applicable(match):
- return
-
- unsqueeze_node = match['unsqueeze']
- unsqueeze_name = unsqueeze_node.soft_get('name', unsqueeze_node.id)
- second_input_of_unsqueeze = unsqueeze_node.in_port(1).get_connection().get_source().node
- d_idx = int(second_input_of_unsqueeze.value)
- axis = d_idx - 1
-
- shape_node = Shape(graph, dict(name=unsqueeze_name + '/Shape')).create_node()
- axis_len_node = node_to_get_shape_value_of_indices(shape_node, [axis])
-
- second_input_of_tile = match['tile'].in_port(1).get_connection().get_source().node
- scale = int64_array([second_input_of_tile.value[d_idx]])
- float_scale = float32_array([second_input_of_tile.value[d_idx]])
- mul_node = create_op_with_const_inputs(graph, Mul, {1: scale}, {'name': unsqueeze_name + '/Mul'})
-
- axis_len_node.out_port(0).connect(mul_node.in_port(0))
-
- interp_node = create_op_with_const_inputs(graph,
- Interpolate,
- {
- 2: float_scale,
- 3: int64_array([axis])},
- {
- 'mode': 'nearest',
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4',
- 'shape_calculation_mode': 'scales',
- 'in_ports_count': 4,
- 'maybe_part_of_sequence': True
- })
- mul_node.out_port(0).connect(interp_node.in_port(1))
-
- reshape_node = match['reshape']
- reshape_node.out_port(0).get_connection().set_source(interp_node.out_port(0))
- reshape_name = reshape_node.soft_get('name', reshape_node.id)
- rename_nodes([(reshape_node, reshape_name + '/delete'), (interp_node, reshape_name)])
-
- unsqueeze_connection = unsqueeze_node.in_port(0).get_connection()
- unsqueeze_connection.set_destination(interp_node.in_port(0))
- unsqueeze_connection.get_source().connect(shape_node.in_port(0))
diff --git a/tools/mo/openvino/tools/mo/middle/UpsampleToResample.py b/tools/mo/openvino/tools/mo/middle/UpsampleToResample.py
deleted file mode 100644
index 17f12352e69697..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/UpsampleToResample.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import math
-from typing import Dict
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Mul
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.layout import get_height_dim, get_width_dim, get_depth_dim
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs, create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, Node, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-
-
-class UpsampleToResample(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def pattern(self):
- return dict(
- nodes=[
- ('upsample', dict(kind='op', op='Upsample')),
- ('output', dict(kind='data'))],
- edges=[('upsample', 'output')]
- )
-
- def replace_pattern(self, graph: Graph, match: Dict[str, Node]):
- log.debug('UpsampleToResample is triggered')
- upsample = match['upsample']
- upsample_name = upsample.soft_get('name', upsample.id)
- input_shape = upsample.in_port(0).data.get_shape()
- input_shape_rank = len(input_shape)
- if input_shape_rank not in [4, 5]:
- log.warning('The input shape is not 4D or 5D for op {}'.format(upsample.soft_get('name')))
- return
-
- depth_scale = None
- layout = graph.graph['layout']
-
- if len(upsample.in_nodes()) == 2:
- if upsample.in_node(1).value is None:
- return
- scales = upsample.in_node(1).value
- assert len(scales) in (4, 5), 'Supported scales rank is 4 or 5, but it is {} for node {}'.format(
- len(scales), upsample_name)
- if not (math.isclose(scales[0], 1, rel_tol=1e-5) and math.isclose(scales[1], 1, rel_tol=1e-5)):
- return
- height_scale = scales[get_height_dim(layout, input_shape_rank)]
- width_scale = scales[get_width_dim(layout, input_shape_rank)]
- if len(scales) == 5:
- depth_scale = scales[get_depth_dim(layout, input_shape_rank)]
- else:
- height_scale = upsample['height_scale']
- width_scale = upsample['width_scale']
-
- if 1 in upsample.in_ports() and not upsample.in_port(1).disconnected():
- upsample.in_port(1).disconnect()
-
- upsample_name = upsample.soft_get('name', upsample.id)
- shape = Shape(graph, {'name': upsample_name + '/0_port'}).create_node()
-
- layout = graph.graph['layout']
-
- if input_shape_rank == 4:
- begin_value = int64_array([get_height_dim(layout, input_shape_rank)])
- factor_value = float32_array([height_scale, width_scale])
- else:
- begin_value = int64_array([get_depth_dim(layout, input_shape_rank)])
- factor_value = float32_array([depth_scale, height_scale, width_scale])
-
- ss = create_op_with_const_inputs(graph, StridedSlice,
- {1: begin_value,
- 2: int64_array([get_width_dim(layout, input_shape_rank) + 1]),
- 3: int64_array([1])
- },
- {'name': upsample_name + '/ss_0_port',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0])
- })
-
- mul = create_op_node_with_second_input(graph, Mul, factor_value, {'name': upsample_name + '/factor_mul'})
-
- source = upsample.in_port(0).get_connection().get_source()
- source.connect(shape.in_port(0))
- shape.out_port(0).connect(ss.in_port(0))
-
- ss.out_port(0).connect(mul.in_port(0))
-
- # Create Interpolate operation
- if input_shape_rank == 4:
- axes = int64_array([get_height_dim(layout, input_shape_rank),
- get_width_dim(layout, input_shape_rank)])
- else:
- axes = int64_array([get_depth_dim(layout, input_shape_rank),
- get_height_dim(layout, input_shape_rank),
- get_width_dim(layout, input_shape_rank)])
-
- axes_node = Const(graph, {'name': upsample_name + '/axis', 'value': axes}).create_node()
-
- interpolate = Interpolate(graph, {'mode': upsample.attrs()['mode'], 'antialias': 0,
- 'pads_begin': int64_array([0]), 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor', 'cube_coeff': -0.75,
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4', 'in_ports_count': 4}).create_node()
-
- upsample.add_input_port(1, skip_if_exist=True)
- assert upsample.in_port(1).disconnected()
- mul.out_port(0).connect(interpolate.in_port(1))
- axes_node.out_port(0).connect(interpolate.in_port(3))
-
- scales_node = Const(graph, {'name': upsample_name + '/scales',
- 'value': factor_value}).create_node()
- scales_node.out_port(0).connect(interpolate.in_port(2))
-
- upsample.in_port(0).get_connection().set_destination(interpolate.in_port(0))
- upsample.out_port(0).get_connection().set_source(interpolate.out_port(0))
-
- rename_nodes([(upsample, upsample_name + '/delete'), (interpolate, upsample_name)])
-
- convert_to_float = Cast(graph, dict(dst_type=np.float32)).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/tools/mo/openvino/tools/mo/middle/UselessMerge.py b/tools/mo/openvino/tools/mo/middle/UselessMerge.py
deleted file mode 100644
index 5d2429448be669..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/UselessMerge.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-from openvino.tools.mo.middle.ConstSwitchResolver import ConstSwitchEraser
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class UselessMergeEraser(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- return [ConstSwitchEraser]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def pattern(self):
- return dict(
- nodes=[('merge', dict(kind='op', op='Merge'))],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- if len(graph.in_edges(match['merge'].id)) <= 1:
- remove_op_node_with_data_node(graph, match['merge'], list(match['merge'].in_nodes().values())[0])
- log.info("Useles Merge op and data nodes was deleted op='{}'".format(match['merge'].id))
diff --git a/tools/mo/openvino/tools/mo/middle/UselessSplitEraser.py b/tools/mo/openvino/tools/mo/middle/UselessSplitEraser.py
deleted file mode 100644
index b3d8291027981e..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/UselessSplitEraser.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class UselessSplitEraser(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import PreMiddleStart
- return [PreMiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def pattern(self):
- return dict(
- nodes=[('split', {'op': 'Split', 'num_splits': 1})],
- edges=[]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- node = match['split']
- name = node.soft_get('name', node.id)
-
- assert node.soft_get('input_port', 0) == 0, \
- 'Internal attribute `input_port` was not resolved on front phase, broken Split {}'.format(name)
- assert len(node.out_ports()) == 1
-
- node.out_port(0).get_connection().set_source(node.in_port(0).get_connection().get_source())
diff --git a/tools/mo/openvino/tools/mo/middle/__init__.py b/tools/mo/openvino/tools/mo/middle/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/middle/dequantize_linear_resolver.py b/tools/mo/openvino/tools/mo/middle/dequantize_linear_resolver.py
deleted file mode 100644
index d646014fd4f017..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/dequantize_linear_resolver.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Mul, Sub
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-class DequantizeLinearResolver(MiddleReplacementPattern):
- """
- Transformation result depends on the axis value.
- If the axis is not set or x_scale input is scalar or 1D tensor with one element then DequantizeLinear is
- replaced with the sub-graph which can be expressed with the following formula:
- y = (x - x_zero_point) * x_scale
- In other cases DequantizeLinear can be replace to formula with addition reshape x_zero_point and x_scale.
- Target shape for reshape depend on axis.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['layout'] == 'NCHW']
-
- def run_after(self):
- from openvino.tools.mo.middle.quantize_dequantize_linear_resolver import QuantizeDequantizeLinearResolver
- return [QuantizeDequantizeLinearResolver]
-
- def find_and_replace_pattern(self, graph: Graph):
- for dequantize_node in graph.get_op_nodes(op='DequantizeLinear'):
- node_name = dequantize_node.soft_get('name', dequantize_node.id)
- axis = dequantize_node.soft_get('axis', None)
- scale_y_shape = dequantize_node.in_port(1).data.get_shape()
- model_data_type = data_type_str_to_np(graph.graph['cmd_params'].data_type)
- cast = Cast(graph, {'dst_type': model_data_type, 'name': node_name + '/Cast'}).create_node()
- dequantize_node.in_port(0).get_connection().set_destination(cast.in_port(0))
- mul = Mul(graph, {'can_be_fused': False}).create_node()
-
- is_second_port_connected = dequantize_node.is_in_port_connected(2)
- if is_second_port_connected:
- # its is necessary not to replace subrtract for pattern in offline transformations
- # See ConvertQuantizeDequantize transformation in ngraph
- sub = Sub(graph, {'name': node_name + '/Sub', 'zero_point_sub': True}).create_node()
- cast.out_port(0).connect(sub.in_port(0))
- dequantize_node.in_port(2).get_connection().set_destination(sub.in_port(1))
- sub.out_port(0).connect(mul.in_port(0))
- else:
- cast.out_port(0).connect(mul.in_port(0))
-
- dequantize_node.in_port(1).get_connection().set_destination(mul.in_port(1))
- dequantize_node.out_port(0).get_connection().set_source(mul.out_port(0))
- rename_nodes([(dequantize_node, node_name + '/TBD'), (mul, node_name)])
-
- assert scale_y_shape is not None
- if axis is not None and len(scale_y_shape) > 0 and scale_y_shape[0] > 1:
- input_shape = cast.in_port(0).data.get_shape()
- target_shape = np.ones(len(input_shape), np.int64)
- target_shape[axis] = input_shape[axis]
-
- mul_reshape = create_op_with_const_inputs(graph, Reshape, {1: int64_array(target_shape)},
- {'name': node_name + '/Reshape/Mul'})
- mul.in_port(1).get_connection().set_destination(mul_reshape.in_port(0))
- mul_reshape.out_port(0).connect(mul.in_port(1))
-
- if is_second_port_connected:
- sub_reshape = create_op_with_const_inputs(graph, Reshape, {1: int64_array(target_shape)},
- {'name': node_name + '/Reshape/Sub'})
- sub.in_port(1).get_connection().set_destination(sub_reshape.in_port(0))
- sub_reshape.out_port(0).connect(sub.in_port(1))
diff --git a/tools/mo/openvino/tools/mo/middle/fusings.py b/tools/mo/openvino/tools/mo/middle/fusings.py
deleted file mode 100644
index 9d29853560df63..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/fusings.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.div import Div
-from openvino.tools.mo.front.sub import Sub
-from openvino.tools.mo.middle.AddFakeQuantizeFuse import AddFakeQuantizeFuse
-from openvino.tools.mo.middle.EltwiseInputReshape import normalize_eltwise_inputs
-from openvino.tools.mo.middle.MulFakeQuantizeFuse import MulFakeQuantizeFuse
-from openvino.tools.mo.middle.RemoveRedundantReshapes import RemoveRedundantReshapes
-
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart
-from openvino.tools.mo.middle.quantize_fuses import MarkNodesToFuseUpToFakeQuantize, FakeQuantizeFuse
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.conv import fuse_pad
-from openvino.tools.mo.middle.passes.fusing.decomposition import convert_scale_shift_to_mul_add, convert_batch_norm
-from openvino.tools.mo.middle.passes.fusing.fuse_grouped_conv import grouped_convolutions_fusing
-from openvino.tools.mo.middle.passes.fusing.fuse_linear_ops import fuse_linear_ops
-from openvino.tools.mo.middle.passes.fusing.fuse_linear_seq import fuse_mul_add_sequence
-from openvino.tools.mo.middle.passes.fusing.mark_unfused_nodes import mark_unfused_nodes, mark_shape_of_sugraph_as_unfusable
-from openvino.tools.mo.middle.passes.fusing.resnet_optimization import stride_optimization
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class Fusing(MiddleReplacementPattern):
- enabled = True
- replacement_id = "fusing"
- force_clean_up = True
- run_not_recursively = True
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def run_before(self):
- # the Fusing transformation adds Reshape layers in some cases which could be removed by the
- # RemoveRedundantReshapes transformation
- return [PostMiddleStart, RemoveRedundantReshapes]
-
- def find_and_replace_pattern(self, graph: Graph):
- fw = graph.graph['fw']
- argv = graph.graph['cmd_params']
- layout = graph.graph['layout']
-
- mark_shape_of_sugraph_as_unfusable(graph)
- for_graph_and_each_sub_graph_recursively(graph, fuse_pad)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- # Converting FusedBatchNorm layer to Mul->Add->Mul->Add sequence
- # IE doesn't support batchNormInference with 4 inputs, so we have to split it to two ScaleShift
- for_graph_and_each_sub_graph_recursively(graph, convert_batch_norm)
-
- if fw == 'caffe':
- # Converting ScaleShift layer to Mul->Add
- for_graph_and_each_sub_graph_recursively(graph, convert_scale_shift_to_mul_add)
-
- for_graph_and_each_sub_graph_recursively(graph, Div().find_and_replace_pattern)
- for_graph_and_each_sub_graph_recursively(graph, Sub().find_and_replace_pattern)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- if fw != 'caffe':
- # Converting ScaleShift layer to Mul->Add
- for_graph_and_each_sub_graph_recursively(graph, convert_scale_shift_to_mul_add)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- # Fusing the sequences of Mul/Add operations
- for_graph_and_each_sub_graph_recursively(graph, fuse_mul_add_sequence)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- normalize_eltwise_inputs(graph)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- # Fusing linear operation to Convolution
- for_graph_and_each_sub_graph_recursively(graph, fuse_linear_ops)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- for_graph_and_each_sub_graph_recursively(graph, grouped_convolutions_fusing)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- for_graph_and_each_sub_graph_recursively(graph, fuse_linear_ops)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- for_graph_and_each_sub_graph_recursively(graph, normalize_eltwise_inputs)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- MarkNodesToFuseUpToFakeQuantize().find_and_replace_pattern(graph)
- FakeQuantizeFuse().find_and_replace_pattern(graph)
- AddFakeQuantizeFuse().find_and_replace_pattern(graph)
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- mark_shape_of_sugraph_as_unfusable(graph)
- for_graph_and_each_sub_graph_recursively(graph, fuse_pad)
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- if layout != 'NHWC':
- stride_optimization(graph)
diff --git a/tools/mo/openvino/tools/mo/middle/layer_normalization.py b/tools/mo/openvino/tools/mo/middle/layer_normalization.py
deleted file mode 100644
index 7c16aa23c24390..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/layer_normalization.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import logging as log
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from openvino.tools.mo.utils.error import Error
-
-
-class LayerNormalization(MiddleReplacementPattern):
- """
- Decompose LayerNorm(x) to MVN(x) * gamma + beta
-
- LayerNorm is supported with only 1 output.
- """
- enabled = True
-
- def find_and_replace_pattern(self, graph: Graph):
- for node in graph.get_op_nodes(op='LayerNorm'):
- node_name = node.soft_get('name', node.id)
-
- if node.output_mean_var is True:
- if not node.out_port(1).disconnected() or not node.out_port(2).disconnected():
- raise Error("Node {} is supported with only one output".format(node_name))
- log.error('LayerNorm node {} with attribute "output_mean_var" = True is not supported.'
- 'But since the node has one output, the conversion will continue.'.format(node_name),
- extra={'is_warning': True})
-
- input_shape = node.in_port(0).data.get_shape()
- assert node.has_valid('axis'), 'Incorrect axis value for the node {}'.format(node_name)
- axis = node.axis
-
- mvn = create_op_node_with_second_input(graph, MVN, int64_array([axis]),
- dict(eps=node.epsilon, name=node_name + '/LayerNorm/MVN_',
- across_channels=1, normalize_variance=1, eps_mode='inside_sqrt'))
-
- mul = Mul(graph, {'name': node_name + '/LayerNorm/mul_'}).create_node()
- add = Add(graph, {'name': mul.name + '/LayerNorm/add_'}).create_node()
-
- node.in_port(0).get_connection().set_destination(mvn.in_port(0))
- node.in_port(1).get_connection().set_destination(mul.in_port(1))
- node.in_port(2).get_connection().set_destination(add.in_port(1))
-
- mvn.out_port(0).connect(mul.in_port(0))
- mul.out_port(0).connect(add.in_port(0))
- node.out_port(0).get_connection().set_source(add.out_port(0))
-
- # MXNet LayerNorm gamma and beta attributes are 1D tensors with shape = [input_shape[axis]]
- # We have to unsqueeze values for Mul and Add operations to avoid shapes incompatibility problems
- # if axis != -1
- canonical_axis = get_canonical_axis_index(input_shape, axis)
- unsqueeze_value = []
- for idx, val in enumerate(input_shape):
- if idx != canonical_axis:
- unsqueeze_value.append(idx)
-
- mul_const_unsqueeze = create_op_node_with_second_input(graph, Unsqueeze,
- int64_array(unsqueeze_value),
- dict(name=mul.name + '/Unsqueeze',
- override_output_shape=True))
- add_const_unsqueeze = create_op_node_with_second_input(graph, Unsqueeze,
- int64_array(unsqueeze_value),
- dict(name=add.name + '/Unsqueeze',
- override_output_shape=True))
-
- mul.in_port(1).get_connection().insert_node(mul_const_unsqueeze)
- add.in_port(1).get_connection().insert_node(add_const_unsqueeze)
-
- rename_nodes([(node, node_name + '/ShouldBeDeleted'), (add, node_name)])
diff --git a/tools/mo/openvino/tools/mo/middle/pass_separator.py b/tools/mo/openvino/tools/mo/middle/pass_separator.py
deleted file mode 100644
index 2c03c0cebae89f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/pass_separator.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class PreMiddleStart(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
-
-class MiddleStart(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
-
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
-
-class MiddleFinish(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
-
-class PostMiddleStart(MiddleReplacementPattern):
- enabled = True
-
- def run_after(self):
- return []
-
- def run_before(self):
- return []
-
- def find_and_replace_pattern(self, graph: Graph):
- pass
-
diff --git a/tools/mo/openvino/tools/mo/middle/passes/__init__.py b/tools/mo/openvino/tools/mo/middle/passes/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/middle/passes/conv.py b/tools/mo/openvino/tools/mo/middle/passes/conv.py
deleted file mode 100644
index 774218768f1e3e..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/conv.py
+++ /dev/null
@@ -1,197 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import get_batch_dim, get_features_dim
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.extractor import add_attrs_props
-from openvino.tools.mo.front.extractor import update_ie_fields
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import get_value_id, get_tensor_id
-from openvino.tools.mo.middle.pattern_match import apply_pattern
-
-
-def pad_op_transform(graph: Graph, match: dict):
- op = match['op']
- pad_op: Node = match['pad_op']
-
- # to keep reshape-ability if Pad receives pads_begin/pads_end from shape subgraph
- if pad_op.in_port(1).get_source().node.soft_get('can_be_fused') is False:
- return
-
- if pad_op.mode != 'constant':
- log.info('The pad node "{}" with pad mode "{}" cannot be fused.'.format(pad_op.soft_get('name'), pad_op.mode))
- return
-
- if op.type == 'Pooling' and op.pool_method == 'max':
- return
-
- if pad_op.mode == 'constant':
- fill_value = pad_op.in_port(3).data.get_value()
- if fill_value is None or fill_value != 0.0:
- log.info('The pad node "{}" with non-zero fill value cannot be fused.'.format(pad_op.soft_get('name')))
- return
-
- input_tensor_dims = len(match['pad_output'].shape)
- for in_port in [1, 2]:
- pads = pad_op.in_port(in_port).data.get_value()
- if pads[get_features_dim(op.graph.graph['layout'], input_tensor_dims)] != 0 or \
- pads[get_batch_dim(op.graph.graph['layout'], input_tensor_dims)] != 0:
- log.info('The pad node "{}" with padding over feature/batch dimension cannot be fused.'.format(
- pad_op.soft_get('name')))
- return
-
- op.pad += np.concatenate([pad_op.in_port(1).data.get_value().reshape([-1, 1]),
- pad_op.in_port(2).data.get_value().reshape([-1, 1])], axis=1)
- op.pad_spatial_shape = op.pad[op.spatial_dims]
- op['auto_pad'] = None
- if op.type == 'Pooling':
- op['exclude_pad'] = False
- assert (graph[match['pad_output'].node][match['op'].node][0]['in'] == 0)
-
- match['op'].in_port(0).disconnect()
- pad_op.in_port(0).get_connection().add_destination(match['op'].in_port(0))
-
-
-def fuse_pad(graph: Graph):
- for op_type in ['Convolution', 'Pooling', 'Deconvolution']:
- apply_pattern(
- graph,
- nodes=[
- ('pad_op', dict(kind='op', op='Pad')),
- ('pad_output', dict(kind='data')),
- ('op', dict(kind='op', type=op_type))],
- edges=[('pad_op', 'pad_output'),
- ('pad_output', 'op', {'in': 0})],
- action=pad_op_transform
- )
-
-
-def muladd_to_scaleshift_action(graph: Graph, match: dict):
- mul = match['mul']
- add = match['add']
- output = match['output']
-
- # Pass works correctly only in case when node have only 1 output
- if len(mul.out_port(0).get_destinations()) > 1:
- return
-
- if mul.soft_get('can_be_scaleshift') is False or add.soft_get('can_be_scaleshift') is False:
- return
-
- mul_weights_id = get_value_id(mul)
- mul_input_id = get_tensor_id(mul)
- add_weights_id = get_value_id(add)
-
- if mul_weights_id is None:
- log.debug("Mul->Add to ScaleShift: Mul {} has no weights".format(mul.name))
- return
- if mul_input_id is None:
- log.debug("Mul->Add to ScaleShift: Mul {} has no input".format(mul.name))
- return
- if add_weights_id is None:
- log.debug("Mul->Add to ScaleShift: Add {} has no weights".format(add.name))
- return
-
- input = mul.in_node(mul_input_id)
- weights = mul.in_node(mul_weights_id)
- bias = add.in_node(add_weights_id)
-
- # Transform values
- weights.value = np.squeeze(weights.value)
- weights.shape = int64_array(weights.value.shape)
-
- bias.value = np.squeeze(bias.value)
- bias.shape = int64_array(bias.value.shape)
-
- # Broadcast weights if they are scalar
- if weights.value.ndim == 0 and bias.value.ndim == 1:
- weights.value = np.full(bias.shape, weights.value.item(), dtype=weights.value.dtype)
- weights.shape = int64_array(weights.value.shape)
-
- if bias.shape != weights.shape:
- log.warning('Mul->Add to ScaleShift conversion stopped {} != {}'.format(weights.shape, bias.shape))
- return
-
- if bias.value.ndim != weights.value.ndim or bias.value.size != weights.value.size:
- log.debug("Skipping Mul->Add to ScaleShift conversion for nodes {}, {} because of different weights "
- "and biases".format(mul.name, add.name))
- return
-
- if bias.value.size == 1 and weights.value.size == 1:
- log.debug("Skipping Mul->Add to ScaleShift conversion for nodes {}, {}. Will be converted to Power"
- "".format(mul.name, add.name))
- return
-
- op_name = "ScaleShift"
-
- log.debug("Fusing Mul->Add to {}. Input nodes: {} and {}, bias.shape = {}, weights.shape = {}"
- "".format(op_name, mul.id, add.id, bias.shape, weights.shape))
-
- graph.remove_edge(input.node, mul.id)
- graph.remove_edge(weights.node, mul.id)
- graph.remove_edge(bias.node, add.id)
- graph.remove_edge(add.node, output.id)
-
- op_node = graph.unique_id(mul.name + '/Fused{}_'.format(op_name))
-
- graph.add_node(op_node, **add_attrs_props(dict(kind='op', type=op_name, name=op_node, op=op_name,
- data_type=input.data_type)))
- scsh = Node(graph, op_node)
- scsh.add_input_port(0)
- scsh.add_input_port(1)
- scsh.add_input_port(2)
- scsh.add_output_port(0)
-
- update_ie_fields(graph.node[op_node])
-
- graph.add_edges_from([
- (input.node, op_node, {'in': 0}),
- (weights.node, op_node, {'in': 1, 'bin': 'weights'}),
- (bias.node, op_node, {'in': 2, 'bin': 'biases'}),
- (op_node, output.node, {'out': 0})
- ])
-
- return
-
-
-def batch_norm_fuse_action(graph: Graph, match: dict):
- """
- Multiply convolution kernel by batch normalization coefficient and remove mul op.
- """
- if match['norm'].value is None or match['kernel'].value is None:
- # cannot fuse non-const normalization coefficients
- return
- if len(graph.out_edges(match['conv_output'].node)) > 1 or len(graph.out_edges(match['kernel'].node)) > 1:
- # we cannot modify original kernel or convolution, if they are used multiple times
- # TODO make a copy of conv and kernel instead of this check
- return
- match['kernel'].value = match['kernel'].value * match['norm'].value
- graph.remove_edge(match['conv_output'].node, match['mul'].node)
- graph.remove_edge(match['mul'].node, match['mul_output'].node)
- # graph.remove_node(match['mul'].node) # if we remove a node, next iteration over isomorphisms gives an error
- graph.add_edge(match['conv'].node, match['mul_output'].node, out=0)
-
-
-def batch_norm_fuse(graph: Graph):
- apply_pattern(
- graph,
- nodes=[
- ('kernel', dict(kind='data')),
- ('conv', dict(kind='op', op='Conv2D')),
- ('conv_output', dict(kind='data')),
- ('norm', dict(kind='data')),
- ('mul', dict(kind='op', op='Mul')),
- ('mul_output', dict(kind='data'))],
- edges=[
- ('kernel', 'conv', {'in': 1}),
- ('conv', 'conv_output'),
- ('conv_output', 'mul', {'in': 0}), # TODO get rid of explicit input port number, mul is a commutative op
- ('norm', 'mul', {'in': 1}), # TODO get rig of explicit input port number, mul is a commutative op
- ('mul', 'mul_output')],
- action=batch_norm_fuse_action
- )
- return graph
diff --git a/tools/mo/openvino/tools/mo/middle/passes/convert_data_type.py b/tools/mo/openvino/tools/mo/middle/passes/convert_data_type.py
deleted file mode 100644
index 5971e6b5c29a61..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/convert_data_type.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.extractor import get_new_placeholder_name
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-"""
-Packed data of custom types are stored in numpy uint8 data type.
-To distinguish true uint8 and custom data we introduce this class not to store,
-but to have unique data type in SUPPORTED_DATA_TYPES map
-"""
-
-
-class packed_U1(np.generic):
- pass
-
-
-class packed_U4(np.generic):
- pass
-
-
-class packed_I4(np.generic):
- pass
-
-
-SUPPORTED_DATA_TYPES = {
- 'float': (np.float32, 'FP32', 'f32'),
- 'half': (np.float16, 'FP16', 'f16'),
- 'FP32': (np.float32, 'FP32', 'f32'),
- 'FP64': (np.float64, 'FP64', 'f64'),
- 'FP16': (np.float16, 'FP16', 'f16'),
- 'I32': (np.int32, 'I32', 'i32'),
- 'I64': (np.int64, 'I64', 'i64'),
- 'int8': (np.int8, 'I8', 'i8'),
- 'int32': (np.int32, 'I32', 'i32'),
- 'int64': (np.int64, 'I64', 'i64'),
- 'bool': (bool, 'BOOL', 'boolean'),
- 'uint8': (np.uint8, 'U8', 'u8'),
- 'uint32': (np.uint32, 'U32', 'u32'),
- 'uint64': (np.uint64, 'U64', 'u64'),
-
- # custom types
- 'U1': (packed_U1, 'U1', 'u1'),
- 'int4': (packed_I4, 'I4', 'i4'),
- 'uint4': (packed_U4, 'U4', 'u4'),
- 'I4': (packed_I4, 'I4', 'i4'),
- 'U4': (packed_U4, 'U4', 'u4'),
-}
-
-
-def data_type_str_to_np(data_type_str: str):
- return SUPPORTED_DATA_TYPES[data_type_str][0] if data_type_str in SUPPORTED_DATA_TYPES else None
-
-
-def data_type_str_to_precision(data_type_str: str):
- return SUPPORTED_DATA_TYPES[data_type_str][1] if data_type_str in SUPPORTED_DATA_TYPES else None
-
-
-def data_type_str_to_destination_type(data_type_str: str):
- return SUPPORTED_DATA_TYPES[data_type_str][2] if data_type_str in SUPPORTED_DATA_TYPES else None
-
-
-def np_data_type_to_precision(np_data_type):
- for np_t, precision, _ in SUPPORTED_DATA_TYPES.values():
- if np_t == np_data_type:
- return precision
- raise Error('Data type "{}" is not supported'.format(np_data_type))
-
-
-def np_data_type_to_destination_type(np_data_type):
- for np_t, _, destination_type in SUPPORTED_DATA_TYPES.values():
- if np_t == np_data_type:
- return destination_type
- raise Error('Data type "{}" is not supported'.format(np_data_type))
-
-
-def destination_type_to_np_data_type(dst_type):
- for np_t, _, destination_type in SUPPORTED_DATA_TYPES.values():
- if destination_type == dst_type:
- return np_t
- raise Error('Destination type "{}" is not supported'.format(dst_type))
-
-
-def precision_to_destination_type(data_type_str):
- for _, precision, destination_type in SUPPORTED_DATA_TYPES.values():
- if precision == data_type_str:
- return destination_type
- raise Error('Data type "{}" is not supported'.format(data_type_str))
-
-
-def convert_blob(blob: np.ndarray, dst_type: type):
- if blob.dtype == dst_type:
- return blob, None, None
-
- converted_blob = blob.astype(dtype=dst_type, casting="unsafe")
- if dst_type in (np.int32, np.int64, np.uint8, np.int8) and not np.array_equal(blob, converted_blob):
- raise Error('The conversion of blob with value "{}" to dst_type "{}" results in rounding'.format(
- blob, dst_type))
-
- finite_match = (np.isfinite(blob) != np.isfinite(converted_blob))
- zero_match = ((blob == 0) != (converted_blob == 0))
- finite_match_count = np.count_nonzero(finite_match)
- zero_match_count = np.count_nonzero(zero_match)
-
- return converted_blob, finite_match_count, zero_match_count
-
-
-def convert_node_blobs(graph: Graph, node: Node, data_type: type):
- out_edges = graph.out_edges(node.node, data=True)
-
- # if the data.value is used as binary weights
- if any('bin' in d for _, __, d in out_edges):
- blob = node.value
- if blob.dtype != data_type:
- new_blob, finite_match_count, zero_match_count = convert_blob(blob, data_type)
- consumers = [x.name if x.has_valid('name') else '' for x in node.out_nodes()]
- log.debug(
- 'Blob was converted to {} while dumping to the bin file. This blob is an input for {} nodes.'.format(
- data_type, consumers))
- if finite_match_count:
- log.error(
- ("{} elements of {} were clipped to infinity while converting a blob for node [{}] to {}. " +
- refer_to_faq_msg(76)).format(finite_match_count, blob.size, consumers, data_type))
- if zero_match_count:
- log.warning(
- ("{} elements of {} were clipped to zero while converting a blob for node [{}] to {}. " +
- refer_to_faq_msg(77)).format(zero_match_count, blob.size, consumers, data_type))
-
- node.value = new_blob
- # for the constant node need to propagate the converted value to the node output because there is a fake
- # input data for the 'Const' nodes being generated in the CreateConstNodesReplacement
- if len(node.out_nodes()) == 1 and node.out_node(0).op == 'Const':
- const_node = node.out_node(0)
- const_node.value = new_blob
- const_node.infer(const_node)
- const_node.type_infer(const_node)
-
-
-def convert_parameters_data_type(graph: Graph, data_type_str: str):
- inputs = graph.get_op_nodes(op='Parameter')
- data_type = data_type_str_to_np(data_type_str)
- user_defined_data_types = graph.graph['user_shapes'] if 'user_shapes' in graph.graph else None
- for input in inputs:
- user_defined_type = None
- name = input.soft_get('initial_node_name', input.id)
-
- # override data type for Parameter specified by the user. This is a workaround for the issue in the
- # extensions.middle.ChangePlaceholderTypes transformation which has an incorrect condition and always overrides
- # Parameter data type to np.float32. When the transformation is fixed the code below must be updated
- if user_defined_data_types is not None and name in user_defined_data_types:
- for desc in user_defined_data_types[name]:
- if 'port' in desc and desc['port'] is None: # neither input nor output port specified
- user_defined_type = desc.get('data_type', None)
- else: # need to check the particular port the Parameter was created for
- p_name = get_new_placeholder_name(name, 'out' in desc, desc['out'] if 'out' in desc else desc['in'])
- if p_name == input.soft_get('name'):
- user_defined_type = desc.get('data_type', None)
- if user_defined_type is not None:
- log.info('Overriding Parameter node {} data type to {}'.format(name, user_defined_type))
- input['data_type'] = user_defined_type
- input.out_port(0).set_data_type(user_defined_type, True)
- elif not input.has_valid('data_type') or input.data_type == np.float32:
- input['data_type'] = data_type
- input.out_port(0).set_data_type(data_type, True)
- else:
- log.info('Do not change data type for node {}'.format(input.soft_get('name')))
-
-
-def convert_blobs(graph: Graph, data_type_str: str):
- for node in graph.get_data_nodes():
- if node.value is not None:
- try:
- if node.value.dtype in [np.float32, np.float64, np.float16] and not node.has_and_set('correct_data_type'):
- convert_node_blobs(graph, node, data_type_str_to_np(data_type_str))
- except Exception as e:
- raise Error('Coudn\'t convert blob {}, details: {}', node.soft_get('name'), e) from e
diff --git a/tools/mo/openvino/tools/mo/middle/passes/debug.py b/tools/mo/openvino/tools/mo/middle/passes/debug.py
deleted file mode 100644
index 8b7e3971db6012..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/debug.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import *
-
-
-def print_attributes_in_col(attrs: dict, indent: int, exclude_attrs: list):
- for key in sorted(attrs.keys()):
- if key not in exclude_attrs:
- print(' ' * indent + key + ': ' + str(attrs[key]))
-
-
-def debug_ir_emitter(graph, exclude_attrs: list = []):
- print("--- DEBUG IR BEGIN ---")
- # print nodes in topological order; print all attributes except 'pb'
- nodes = nx.topological_sort(graph)
- np.set_printoptions(threshold=10)
- for node in nodes:
- attrs = graph.node[node]
- print('Node:', node)
- if attrs['kind'] == 'op':
- for idx, value in Node(graph, node).in_nodes().items():
- print('input', idx, ':', value.node,
- ': ' + str(graph.in_edges(value.node)[0][0]) if len(graph.in_edges(value.node)) else '')
- if 'op' in attrs:
- print('Op:', attrs['op'])
- print_attributes_in_col(attrs, 4, exclude_attrs)
- if attrs['kind'] == 'op':
- for idx, value in Node(graph, node).out_nodes().items():
- print('output', idx, ':', value.node,
- ': ' + str(graph.out_edges(value.node)[0][1]) if len(graph.out_edges(value.node)) else '')
- print('')
- print("--- DEBUG IR END ---")
-
-
-def get_output_node_names(graph: Graph):
- result = []
- for node in graph.nodes():
- node = Node(graph, node)
- if len(node.out_nodes()) == 0:
- result.append(node.in_node().name)
- return result
diff --git a/tools/mo/openvino/tools/mo/middle/passes/eliminate.py b/tools/mo/openvino/tools/mo/middle/passes/eliminate.py
deleted file mode 100644
index b9d05e784b17df..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/eliminate.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import re
-from collections import deque
-
-import networkx as nx
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, compatible_shapes
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import deprecated_api
-
-
-# TODO: dep warning
-def get_nodes_with_attributes(graph, **attrs: dict):
- node_attrs = graph.nodes(data=True)
- return [n for n, d in node_attrs if all(a in d.items() for a in attrs.items())]
-
-
-def reverse_dfs(graph, node_name: str, update_func: callable, visited: set = None):
- d = deque()
-
- if visited is None:
- visited = set()
- visited.add(node_name)
- d.appendleft(node_name)
- while len(d) != 0:
- cur_node = d.popleft()
- update_func(graph, cur_node)
- for in_node_name, _ in graph.in_edges(cur_node):
- if in_node_name not in visited:
- visited.add(in_node_name)
- d.append(in_node_name)
-
-
-def mark_input_nodes(graph, node_name: str, key: str, value):
- for input, _ in graph.in_edges(node_name):
- graph.node[input][key] = value
-
-
-def mark_output_nodes(graph, node_name: str, key: str, value):
- for output, _ in graph.out_edges(node_name):
- graph.node[output][key] = value
-
-
-def mark_output_reachable_nodes(graph):
- """
- Mark nodes whether they are outputs reachable or not. The node is considered output reachable if it is connected to
- one of the nodes that has attribute op=Result.
- """
- nx.set_node_attributes(G=graph, name='is_output_reachable', values=False)
- outputs = graph.get_nodes_with_attributes(op='Result')
- log.debug('The following nodes are seeded as output reachable:\n{}'.format('\n'.join(sorted(map(str, outputs)))))
- nx.set_node_attributes(G=graph, name='is_output_reachable', values={n: True for n in outputs})
- visited = set()
- for output_name in outputs:
- reverse_dfs(graph, output_name,
- lambda graph, node_name: mark_input_nodes(graph, node_name, 'is_output_reachable', True), visited)
-
-
-def mark_undead_nodes(graph, undead_types: list):
- """
- Mark output nodes and nodes of the specific type as undead, meaning that they should survive the dead nodes
- elimination phase. Then mark all children nodes of the undead nodes (except children of inputs) as undead.
- :param graph: graph to operate on.
- :param undead_types: list of node types that should be marked as undead.
- :return: updated graph where each has attribute 'is_undead'.
- """
- from openvino.tools.mo.utils.graph import bfs_search
-
- nx.set_node_attributes(G=graph, name='is_undead', values=False)
-
- undead_types_with_result = undead_types + ['Result']
- undead_nodes = []
- for node in graph.get_op_nodes():
- node_type = node.soft_get('type', node.soft_get('op'))
- if node_type in undead_types_with_result:
- undead_nodes.append(node.id)
-
- nx.set_node_attributes(G=graph, name='is_undead', values={n: True for n in undead_nodes})
- # propagate 'undead' attribute to children nodes of undead nodes if the node produces constant value
- for node_name in bfs_search(graph, undead_nodes):
- if graph.node[node_name]['is_undead']:
- for _, dst_node_name in graph.out_edges(node_name):
- node_attrs = graph.node[dst_node_name]
- if 'kind' in node_attrs and (
- node_attrs['kind'] == 'data' and node_attrs['value'] is not None or node_attrs['kind'] == 'op'):
- graph.node[dst_node_name]['is_undead'] = True
-
- # mark input nodes as undead
- inputs = graph.get_nodes_with_attributes(is_input=True)
- nx.set_node_attributes(G=graph, name='is_undead', values={n: True for n in inputs})
-
-
-def mark_const_producer_nodes(graph):
- """
- Mark nodes that produce constant values.
- :param graph: graph to operate on.
- :return: .
- """
- nx.set_node_attributes(G=graph, name='is_const_producer', values=True)
-
- for node in graph.pseudo_topological_sort():
- for input, output, attrs in graph.in_edges(node.id, data=True):
- if 'control_flow_edge' in attrs and attrs['control_flow_edge']:
- graph.node[input]['is_const_producer'] = False
- graph.node[output]['is_const_producer'] = False
-
- if not node.has('value') or node.value is None or not is_fully_defined(node.value):
- for input, _ in graph.in_edges(node.id):
- graph.node[input]['is_const_producer'] = False
-
-
-def eliminate_dead_nodes(graph):
- from openvino.tools.mo.graph.graph import Node
- nodes_to_remove = set()
- for node_name, node_attrs in graph.nodes(data=True):
- # The Const operation node may have set an attribute 'nchw_layout' attribute to prevent shape permutation.
- # During graph clean-up the operation node is removed and the attribute is lost.
- # This results in permutation of the Const shape in the IR and wrong inference results.
- # Here we explicitly save the 'nchw_layout' attribute in the data node to prevent permutation."
- if node_attrs.get('type', None) == 'Const':
- if node_attrs.get('nchw_layout', False):
- Node(graph, node_name).out_node()['nchw_layout'] = True
- if np.all(node_attrs.get('force_shape', False)):
- Node(graph, node_name).out_node()['force_shape'] = node_attrs['force_shape']
- if node_attrs.get('force_type', False):
- Node(graph, node_name).out_node()['force_type'] = node_attrs['force_type']
-
- if not node_attrs['is_output_reachable'] or \
- (node_attrs['is_const_producer'] and (not node_attrs['is_undead'] or
- node_attrs.get('force_dead_node', False))):
- nodes_to_remove.add(node_name)
- log.debug('Removing the following dead nodes: {}'.format('\n'.join(sorted(map(str, nodes_to_remove)))))
- graph.remove_nodes_from(nodes_to_remove)
-
-
-def add_constant_operations(graph):
- data_nodes = graph.get_data_nodes(has_value=True)
- for node in data_nodes:
- # If data node has no producers we create Const operation
- if len(node.in_nodes()) == 0 and len(node.out_nodes()) != 0:
- # It's necessary to import here due to cycle dependencies
- from openvino.tools.mo.ops.const import Const
- from openvino.tools.mo.utils.runtime_info import RTInfo
- name = node.soft_get('name', node.id)
- new_name = re.sub(r'\/Output_\d+\/Data_(.?)+', '', name)
- const_node = Const(graph, dict(value=node.value, name=new_name,
- force_shape=node.soft_get('force_shape', None),
- override_output_shape=node.has_valid('force_shape'),
- force_type=node.soft_get('force_type', None),
- correct_data_type=node.soft_get('correct_data_type', False),
- rt_info=node.soft_get('rt_info', RTInfo()),
- )).create_node()
- graph.add_edges_from([(const_node.id, node.id, {'out': 0})])
-
-
-def shape_inference(graph):
- for node in graph.pseudo_topological_sort():
- if node.has_and_set('need_shape_inference'):
- old_out_shapes = [port.data.get_shape() for port in node.out_ports().values() if not port.disconnected()]
- node.infer(node)
- new_out_shapes = [port.data.get_shape() for port in node.out_ports().values() if not port.disconnected()]
- if not node.has_and_set('override_output_shape'):
- for shape1, shape2 in zip(old_out_shapes, new_out_shapes):
- # do not use strict shapes comparison because after applying transformation the output shape may be
- # specialized and some dynamic dimension become static
- if shape1 is not None and not compatible_shapes(shape1, shape2):
- raise Error("After partial shape inference were found shape collision for node {} (old shape: "
- "{}, new shape: {})".format(node.name, shape1, shape2))
- else:
- del node['override_output_shape']
- node.need_shape_inference = False
-
-
-@deprecated_api('Graph', 'clean_up')
-def graph_clean_up(graph, undead_node_types: list = None):
- graph.clean_up(undead_node_types)
-
-
-@deprecated_api('Graph', 'clean_up')
-def graph_clean_up_tf(graph):
- graph.clean_up()
-
-
-@deprecated_api('Graph', 'clean_up')
-def graph_clean_up_onnx(graph):
- graph.clean_up()
-
-
-# TODO: unit tests
-def merge_data_nodes(graph, survived, removed):
- if survived.has_and_set('op') and survived.op == 'Result':
- graph.node[removed.id].update({'op': 'Result'})
-
- for u, v, d in list(graph.in_edges(removed.id, data=True)):
- graph.add_edges_from([(u, survived.id, d)])
- graph.remove_edge(u, v)
-
- for u, v, d in list(graph.out_edges(removed.id, data=True)):
- graph.add_edges_from([(survived.id, v, d)])
- graph.remove_edge(u, v)
-
- for attr in graph.node[removed.id]:
- if not attr in ['name']:
- # We need to save debug info from removed data node
- if attr == 'fw_tensor_debug_info':
- if not survived.has_valid(attr):
- survived[attr] = []
- for fw_tensor_debug_info in removed[attr]:
- survived[attr].append(fw_tensor_debug_info)
- else:
- survived[attr] = removed[attr]
-
-
-# TODO: unit tests
-def remove_op_node_with_data_node(graph, node_to_remove, input_data_node=None):
- from openvino.tools.mo.graph.graph import Node
- assert node_to_remove.kind == 'op'
- if input_data_node is None:
- input_data_node = node_to_remove.in_node()
- output_node = [v for _, v in graph.out_edges(node_to_remove.id)]
- assert len(output_node) == 1, "Cannot remove node producing two or more output tensors"
- output_node = Node(graph, output_node[0])
- assert output_node.kind == 'data', "The function must be used after partial infer"
-
- graph.remove_edge(input_data_node.id, node_to_remove.id)
- graph.remove_edge(node_to_remove.id, output_node.id)
-
- merge_data_nodes(graph, output_node, input_data_node)
-
- # we just have saved all output edges from 'input' by reconnecting them to 'output', now we can delete 'input'
- log.debug('Removing op node: {}'.format(node_to_remove.id))
- graph.remove_nodes_from([node_to_remove.id, input_data_node.id])
-
-
-def remove_op_nodes(graph, attrs: dict):
- for node in graph.get_op_nodes(**attrs):
- remove_op_node_with_data_node(graph, node)
-
-
-def remove_edges_for_nodes(graph, node_attrs: dict, edge_attrs: dict):
- from openvino.tools.mo.graph.graph import Node
- for node in graph.nodes():
- node = Node(graph, node)
- if all([node.has(attr) and node[attr] == node_attrs[attr] for attr in node_attrs]):
- nodes_edges = node.in_nodes_edges()
- for port in nodes_edges:
- src_node, edge = nodes_edges[port]
- if all([attr in edge and edge[attr] == edge_attrs[attr] for attr in edge_attrs]):
- graph.remove_edge(src_node.id, node.id)
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/__init__.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/decomposition.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/decomposition.py
deleted file mode 100644
index d0afff7b9ca2ad..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/decomposition.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-
-
-def expand_node_shape(port: Port, broadcast_dims_cnt):
- value = mo_array(port.data.get_value())
- for idx in range(broadcast_dims_cnt):
- value = np.expand_dims(value, axis=-1)
- port.data.set_value(value)
-
-
-def convert_batch_norm(graph: Graph):
- """
- This function finds FusedBatchNorm layer (or BatchNorm for MXNet) and replaces with Mul->Add->Mul->Add sequence.
- """
- nodes = graph.get_op_nodes()
- for node in nodes:
- if node.has_valid('op') and (node.op in ['FusedBatchNorm', 'FusedBatchNormV2', 'FusedBatchNormV3',
- 'BatchNorm', 'BatchNormalization', 'batchNormInference']):
-
- if any([node.in_port(i).data.get_value() is None for i in range(1, len(node.in_ports()))]):
- log.warning('Cannot translate FusedBatchNorm {} node with non-constant weights'.format(
- node.name if node.has_valid('name') else ''))
- continue
-
- const = node.in_port(1).get_source()
- node.in_port(1).disconnect()
-
- beta = node.in_port(2).get_source()
- node.in_port(2).disconnect()
-
- mean = node.in_port(3).get_source()
- node.in_port(3).disconnect()
-
- variance = node.in_port(4).get_source()
- node.in_port(4).disconnect()
-
- eps = node.eps
-
- if node.has_valid('fix_gamma') and node.fix_gamma:
- const.data.get_value().fill(1.)
-
- can_be_fused = False if not node.soft_get('can_be_fused') else True
-
- scale = 1. / np.sqrt(variance.data.get_value() + eps)
- shift = (mean.data.get_value() * (-1)) * scale
-
- # Expand dims for current layout
- layout = node.soft_get('data_format', graph.graph['layout'])
- broadcast_dims_cnt = len(node.in_port(0).data.get_shape()) - 2 if layout in ['NCHW', "NCDHW"] else 0
-
- # Update values and shapes with new shape
- expand_node_shape(const, broadcast_dims_cnt)
- expand_node_shape(beta, broadcast_dims_cnt)
-
- for idx in range(broadcast_dims_cnt):
- scale = np.expand_dims(scale, axis=-1)
- shift = np.expand_dims(shift, axis=-1)
-
- _fused_batch_norm_decomposition(graph, node.in_port(0), node.out_port(0), const, beta, scale, shift, can_be_fused)
-
-
-def _fused_batch_norm_decomposition(graph: Graph, tinput: Port, toutput: Port, gamma: Port, beta: Port,
- mean: np.ndarray, variance: np.ndarray, can_be_fused=True):
- """
- This is common function for TF and Caffe
- It creates Mul->Add->Mul->Add sub graph
- """
- batch_norm_name = tinput.get_connection().get_destination().node.name
-
- # Create first Mul & Add operations
- mul1_node = Mul(graph, dict(name=batch_norm_name + "/mean", can_be_fused=can_be_fused)).create_node()
- add1_node = Add(graph, dict(name=batch_norm_name + "/variance", can_be_fused=can_be_fused)).create_node()
-
- const_mul1_node = Const(graph, dict(name="data_mul_", value=mo_array(mean))).create_node()
- const_add1_node = Const(graph, dict(name="data_add_", value=mo_array(variance))).create_node()
-
- # Broadcast const from scalar
- # We can broadcast only when const.value is scalar
- if gamma.data.get_shape()[0] != gamma.data.get_value().shape[0]:
- value = gamma.data.get_value()
- value.resize(gamma.data.get_shape()).fill(value[0])
- gamma.data.set_value(value)
-
- # Create second Mul & Add
- mul2_node = Mul(graph, dict(name=batch_norm_name + "/gamma", can_be_fused=can_be_fused)).create_node()
- add2_node = Add(graph, dict(name=batch_norm_name + "/beta", can_be_fused=can_be_fused)).create_node()
-
- # Connect edges Mul1->Add1->Mul2->Add2
- tinput.get_connection().set_destination(mul1_node.in_port(0))
- mul1_node.in_port(1).get_connection().set_source(const_mul1_node.out_port(0))
-
- add1_node.in_port(0).get_connection().set_source(mul1_node.out_port(0))
- add1_node.in_port(1).get_connection().set_source(const_add1_node.out_port(0))
-
- mul2_node.in_port(0).get_connection().set_source(add1_node.out_port(0))
- gamma.get_connection().set_destination(mul2_node.in_port(1))
-
- add2_node.in_port(0).get_connection().set_source(mul2_node.out_port(0))
- beta.get_connection().set_destination(add2_node.in_port(1))
-
- toutput.get_connection().set_source(add2_node.out_port(0))
-
-
-def convert_scale_shift_to_mul_add(graph: Graph):
- nodes = graph.get_op_nodes(op='ScaleShift')
- for node in nodes:
- if node.soft_get('can_be_fused') is False:
- continue
-
- ports_count = len(node.in_ports())
-
- input_port = node.in_port(0)
- scale_port = node.in_port(1) if ports_count > 1 and not node.in_port(1).disconnected() else None
- shift_port = node.in_port(2) if ports_count > 2 and not node.in_port(2).disconnected() else None
- output_port = node.out_port(0)
-
- has_biases = True
- has_weights = True
-
- # We don't need zero biases
- if shift_port is None or (shift_port.data.get_value() is not None and all([x == 0 for x in shift_port.data.get_value()])):
- has_biases = False
-
- # We don't need weights with ones
- if scale_port is None or (scale_port.data.get_value() is not None and all([x == 1 for x in scale_port.data.get_value()])):
- has_weights = False
-
- mul_op = Mul(graph, dict(name=node.name + "/Mul_"))
- add_op = Add(graph, dict(name=node.name + "/Add_"))
-
- # Expand dims for current layout
- broadcast_dims_cnt = len(input_port.data.get_shape()) - 2 if graph.graph['layout'] == 'NCHW' else 0
-
- # In case if we have constant weights/biases we have to broadcast them according to graph layout
- # otherwise we insert Reshape with broadcast dim attribute.
- def broadcast_value(port):
- value = mo_array(port.data.get_value())
- for idx in range(broadcast_dims_cnt):
- value = np.expand_dims(value, axis=-1)
- port.data.set_value(value)
-
- def broadcast_with_reshape(port):
- input_shape = input_port.data.get_shape()
- reshape_dims = np.zeros(len(input_shape), dtype=np.int64)
- for i in range(0, node.axis):
- reshape_dims[i] = 1
- data_shape = port.data.get_shape()
- for i in range(node.axis, node.axis + len(data_shape)):
- reshape_dims[i] = data_shape[i - node.axis]
- for i in range(node.axis + len(data_shape), len(input_shape)):
- reshape_dims[i] = 1
- reshape = create_op_node_with_second_input(graph, Reshape, reshape_dims,
- dict(name=port.node.name + "/Broadcast_"))
- port.get_connection().set_destination(reshape.in_port(0))
- reshape.out_port(0).connect(port)
-
- if has_weights and scale_port.data.get_value() is not None:
- broadcast_value(scale_port)
- elif has_weights:
- broadcast_with_reshape(scale_port)
-
- if has_biases and shift_port.data.get_value() is not None:
- broadcast_value(shift_port)
- elif has_biases:
- broadcast_with_reshape(shift_port)
-
- if has_biases and has_weights:
- # Connect input->mul->out->add->out
- add_node = add_op.create_node()
- mul_node = mul_op.create_node()
-
- # Connect Mul operation with inputs
- input_port.get_connection().set_destination(mul_node.in_port(0))
- scale_port.get_connection().set_destination(mul_node.in_port(1))
-
- # Connect Add operation with inputs
- mul_node.out_port(0).connect(add_node.in_port(0))
- shift_port.get_connection().set_destination(add_node.in_port(1))
-
- output_port.get_connection().set_source(add_node.out_port(0))
- elif has_weights:
- # Connect input->mul->out
- mul_node = mul_op.create_node()
-
- # Connect Mul operation with inputs
- input_port.get_connection().set_destination(mul_node.in_port(0))
- scale_port.get_connection().set_destination(mul_node.in_port(1))
-
- output_port.get_connection().set_source(mul_node.out_port(0))
- elif has_biases:
- # Connect input->add->out
- add_node = add_op.create_node()
-
- # Connect Add operation with inputs
- input_port.get_connection().set_destination(add_node.in_port(0))
- shift_port.get_connection().set_destination(add_node.in_port(1))
-
- output_port.get_connection().set_source(add_node.out_port(0))
- else:
- # Connect input->out
- producer_port = input_port.get_source()
- input_port.disconnect()
- output_port.get_connection().set_source(producer_port)
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_grouped_conv.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_grouped_conv.py
deleted file mode 100644
index 4a08692aaa4cc8..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_grouped_conv.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import get_next_operation
-
-
-# TODO: unit tests
-def concat_convolutions(graph: Graph, start_node: Node, last_node: Node):
- """
- This function converts group of convolutions into one
- """
-
- # Check that concatenation makes in the same order
- conv_nodes = get_next_operation(start_node)
- assert len(conv_nodes) == len(last_node.in_nodes())
- gconv = conv_nodes[0]
-
- for id in range(len(conv_nodes)):
- conv = conv_nodes[id]
- if conv.out_node().id != last_node.in_node(id).id:
- return False
- # Check that all convolutions have same weights shapes
- if not np.array_equal(conv.in_node(1).shape, gconv.in_node(1).shape):
- log.debug('Grouped convolutions fusion : convolutions have different weights shape')
- return False
-
- # Check that split and concat dims are valid
- channel_dim = gconv.channel_dims[0]
- split_axis = start_node.in_port(1).data.get_value()
- if channel_dim != split_axis or channel_dim != last_node.axis:
- log.debug('Grouped convolutions fusion : split or concat has weird axis!')
- return False
-
- # Check that all convolutions has the same parameters
- conv_attrs = ['pad', 'stride']
- for attr in conv_attrs:
- for id in range(len(conv_nodes)):
- conv = conv_nodes[id]
- if not np.array_equal(gconv[attr], conv[attr]):
- log.debug('Grouped convolutions fusion : attrs {} doesn\'t match'.format(attr))
- return False
-
- # Check that all Convolutions has biases (if exists)
- has_biases = False
- for id in range(len(conv_nodes)):
- conv = conv_nodes[id]
- if len(conv.in_nodes()) == 3:
- if not has_biases:
- has_biases = True
- elif has_biases:
- return False # All convolution mast have biases
-
- # Check that all biases have same shape
- if has_biases:
- for id in range(len(conv_nodes)):
- conv = conv_nodes[id]
- if conv.in_node(2).shape != gconv.in_node(2).shape:
- log.debug('Group convolutions fusion : convolutions have different biases shape {} and {}'.format(
- conv.in_node(2).shape, gconv.in_node(2).shape))
- return False
-
- graph.remove_edge(gconv.in_node(0).id, gconv.id)
- graph.remove_edge(gconv.id, gconv.out_node().id)
-
- input = start_node.in_node(0)
- output = last_node.out_node()
-
- # Removing edges from data nodes to Split and Concat
- graph.remove_edge(input.id, start_node.id)
- graph.remove_edge(last_node.id, output.id)
-
- # Add edges to grouped convolution
- graph.add_edges_from([
- (input.id, gconv.id, {'in': 0}),
- (gconv.id, output.id, {'out': 0})
- ])
-
- # Concatenation of convolutions
- weights_node = gconv.in_node(1)
- bias_node = gconv.in_node(2) if has_biases else None
-
- weights_value = mo_array(weights_node.value)
- bias_value = mo_array(bias_node.value) if has_biases else None
-
- # gconv.get_weights_permute.perm contains permutation indices
- # where feature dimension is set to zero position, so 0 value
- # in gconv.get_weights_permute.inv indicates original feature dimension index
- feature_dim = np.where(gconv.get_weights_permute.inv == 0)[0][0]
-
- for conv in conv_nodes[1:]:
- weights_value = np.concatenate((weights_value, conv.in_node(1).value), axis=feature_dim)
- if has_biases:
- bias_value = np.concatenate((bias_value, conv.in_node(2).value), axis=-1) # Not validated
-
- weights_node.value = mo_array(weights_value)
- weights_node.shape = mo_array(weights_value.shape)
-
- if has_biases:
- bias_node.value = mo_array(bias_value)
- bias_node.shape = mo_array(bias_value.shape)
-
- log.debug('Start node : {} Last node : {} Nodes inside : {}'.format(start_node.id, last_node.id,
- len(start_node.out_nodes())))
- log.debug('Output shape : {}'.format(weights_value.shape))
-
- gconv.group = len(conv_nodes)
- gconv.output = weights_node.shape[feature_dim]
- gconv.output_shape[feature_dim] = weights_node.shape[feature_dim]
-
- return True
-
-
-# TODO: unit tests
-def grouped_convolutions_fusing(graph: Graph):
- while True:
- is_fused = False
- graph.clean_up()
- for node in graph.pseudo_topological_sort():
- if node.kind == 'op' and len(node.out_nodes()) > 1:
- if node.soft_get('can_be_fused') == False:
- continue
-
- is_valid_convolutions = True
- last_layer = None
-
- next_nodes = get_next_operation(node)
- # Check that all operation after this one are Convolutions
- # and all convolutions has same output
- if len(next_nodes) > 1 and all(_node.soft_get('type') in ['Convolution', 'Deconvolution'] for _node in next_nodes):
- for conv in next_nodes:
- conv_outputs = get_next_operation(conv)
- if conv.soft_get('can_be_fused') == False:
- is_valid_convolutions = False
- if len(conv_outputs) != 1:
- is_valid_convolutions = False
- if last_layer is None:
- last_layer = conv_outputs[0].id
- # TODO: this check is not working for V10 where Biases appears as separate operations
- elif conv_outputs[0].id != last_layer:
- is_valid_convolutions = False
-
- if is_valid_convolutions:
- is_fused = concat_convolutions(graph, node, Node(graph, last_layer))
- if is_fused:
- break
-
- if not is_fused:
- break
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_linear_ops.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_linear_ops.py
deleted file mode 100644
index d45c5453ea5341..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_linear_ops.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, shape_array, dynamic_dimension
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import backward_bfs, forward_bfs, get_value_in_port, \
- get_tensor_in_port
-from openvino.tools.mo.ops.const import Const
-
-
-def _fuse_mul(graph: Graph, node: Node, fuse_nodes: list, backward: bool = True):
- """
- This function takes Mul node and array of convolution/fc nodes for further fusion
- Parameters
- ----------
- x : bool
- If backward is False, that means that Convolution/FC goes after Mul node
- else means that Mul goes after Convolutions/FC
- :param backward:
- :param fuse_nodes:
- :param node:
- :param graph:
- """
- 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_mul for node {} because this node has wrong inputs'.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 because attr can_be_fused = False'.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
-
- if not backward and not fuse_node.has_valid('layout'):
- log.warning('Node {} has no layout attr'.format(fuse_node.name))
- 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'):
- log.warning(
- 'Cannot do fuse_mul for node {} because there is no field ' +
- 'output_channel_dim and/or input_channel_dim in weights.'
- .format(fuse_node.soft_get('name'))
- )
- return False
-
- 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
-
- for fuse_node in fuse_nodes:
- weights_port = fuse_node.in_port(1)
- value = mo_array(const_port.data.get_value())
-
- value = np.squeeze(value)
-
- # 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 'input_channel_dim')
- shape = shape_array([weights_port.data.get_shape()[ch_dim]])
-
- # no fusing is possible in case dynamic weights
- if weights_port.data.get_shape()[ch_dim] is dynamic_dimension:
- return False
-
- # Scalar broadcast
- if value.size == 1:
- value = np.full(shape, value.item(), dtype=value.dtype)
-
- # Common broadcast for forward fusion
- if not backward:
- cnt = shape[-1] / value.shape[0]
- if fuse_node.layout == 'NCHW':
- tmp = mo_array([], dtype=value.dtype)
- for val in value:
- tmp = np.concatenate((tmp, np.repeat(val, cnt)))
- value = mo_array(tmp)
- else:
- value = np.tile(value, int(cnt))
-
- # Expand dims for multiplication (ex. [38] to [38, 1, 1])
- wdims_number = weights_port.data.get_attr('dims_number')
- for x in range(wdims_number - ch_dim - 1):
- shape = np.append(shape, 1)
-
- mul_val = mo_array(value)
- # If the value fails to reshape to the provided shape, skip fusing.
- # This can happen in case of group != 1 of the convolution.
- try:
- value = np.reshape(value, shape)
- except ValueError:
- log.error("Cannot fuse const from {} to {}. Reshape failed. Skipping.".format(
- node.soft_get('name', node.id), fuse_node.soft_get('name', fuse_node.id)), extra={'is_warning': True})
- return False
-
- # Weights multiplication
- mul_name = node.name + '_copy'
- mul_const = Const(graph, {'value': value, 'name': mul_name + '/const'}).create_node()
- w_mul = node.copy_node({'name': mul_name, 'in_ports_count': len(node.in_ports()),
- 'out_ports_count': len(node.out_ports()), 'can_be_fused': False})
- w_mul.in_port(const_port.idx).connect(mul_const.out_port(0))
- w_const = weights_port.get_source()
- weights_port.get_connection().set_source(w_mul.out_port(0))
- w_const.connect(w_mul.in_port(tensor_port.idx))
-
- fuse_node_in_data = fuse_node.in_node(weights_port.idx)
- w_const_out_data = w_const.node.out_node(w_const.idx)
-
- # During this reconnection new data node name is copied from the data node
- # outgoing from w_const port. Duplicate names of data nodes lead to appearing
- # of duplicate op node names after constant folding. So we should manually
- # set a unique name for the new data node.
- if fuse_node_in_data.soft_get('name') == w_const_out_data.soft_get('name') and \
- fuse_node_in_data.soft_get('name', None) is not None:
- fuse_node.in_node(weights_port.idx)['name'] = graph.unique_id(mul_name)
-
- # If we fuse in backward direction we should multiply biases if they exists
- if backward and len(fuse_node.in_ports()) == 3 and not fuse_node.in_port(2).disconnected() and \
- not fuse_node.has_and_set('shape_input'):
- conv_bias = fuse_node.in_port(2)
- conv_bias.data.set_value(conv_bias.data.get_value() * np.squeeze(mul_val))
-
- mul_const.infer(mul_const)
- w_mul.infer(w_mul)
-
- log.debug('Fused: {} to {}'.format(node.name, fuse_node.name))
- is_fused = True
-
- if is_fused:
- # Delete Mul node
- producer_port = tensor_port.get_source()
- tensor_port.disconnect()
- const_port.disconnect()
- # as Mul node is added before convolution, output tensor from Convolution node
- # corresponds to original Mul node
- if producer_port.node.soft_get('type') == 'Parameter':
- node.out_port(0).get_connection().set_source(producer_port, "source")
- else:
- node.out_port(0).get_connection().set_source(producer_port, "dest")
-
- return is_fused
-
-
-def fuse_linear_ops(graph: Graph):
- """
- This function makes fusing of linear operations (Mul,Add) to Convolution/FC.
- """
- fuse_count = 0
-
- # Fusion in backward direction
- nodes = graph.pseudo_topological_sort()
- for node in nodes:
- 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.has_and_set('can_be_fused'):
- fuse_nodes = backward_bfs(node, [], ['Convolution', 'Deconvolution', 'MatMul'])
- is_fused = _fuse_mul(graph, node, fuse_nodes)
-
- fuse_count += is_fused
-
- # Fusion in forward direction
- nodes = graph.pseudo_topological_sort(reverse=True)
- for node in nodes:
- 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.has_and_set('can_be_fused'):
- fuse_nodes = forward_bfs(node, [], ['Convolution', 'Deconvolution', 'MatMul'])
- is_fused = _fuse_mul(graph, node, fuse_nodes, False)
-
- fuse_count += is_fused
-
- log.debug("Fused {} nodes".format(fuse_count))
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_linear_seq.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_linear_seq.py
deleted file mode 100644
index 1e97dbba72c0be..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/fuse_linear_seq.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Mul, Add
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import get_value_in_port, get_tensor_in_port
-from openvino.tools.mo.ops.const import Const
-
-
-def _fuse_linear_sequence(graph: Graph, start_node: Node):
- """
- This function finds the sequence of Mul/Add operations and replaces this sequence with two ops (Mul->Add).
- :param graph:
- :param start_node: The first operation of the sequence
- """
- fnodes = [start_node]
- while True:
- node = fnodes[-1]
- destinations = node.out_port(0).get_destinations()
- if len(destinations) != 1:
- break
- dst_node = destinations[0].node
- if dst_node.soft_get('op') in ['Mul', 'Add'] and get_value_in_port(dst_node) is not None and \
- dst_node.soft_get('can_be_fused') is True:
- fnodes.append(dst_node)
- else:
- break
-
- if len(fnodes) == 1 or (len(fnodes) == 2 and fnodes[0].op == 'Mul' and fnodes[1].op == 'Add'):
- return False
-
- input_shape = get_tensor_in_port(start_node).data.get_shape()
-
- init_dims_cnt = len(input_shape) - 2 if graph.graph['layout'] == 'NCHW' else 1
-
- first_value = get_value_in_port(fnodes[0]).data.get_value()
- if not isinstance(first_value, np.ndarray):
- first_value = mo_array(first_value)
- first_value_type = first_value.dtype
-
- mul = np.ones([1 for x in range(init_dims_cnt)], dtype=first_value_type)
- add = np.zeros([1 for x in range(init_dims_cnt)], dtype=first_value_type)
-
- first_mul_name = None
- first_add_name = None
-
- for node in fnodes:
- const_port_value = get_value_in_port(node).data.get_value()
- if node.op == 'Mul':
- if first_mul_name is None:
- first_mul_name = node.name
- mul = mul * const_port_value
- add = add * const_port_value
- elif node.op == 'Add':
- if first_add_name is None:
- first_add_name = node.name
- add = add + const_port_value
-
- # If mul is scalar we broadcast it to biases shape
- if mul.shape != add.shape and len(mul.shape) == 1 and mul.shape[0] == 1:
- mul = mo_array([mul[0] for x in range(add.shape[0])])
-
- assert (compatible_shapes(get_tensor_in_port(fnodes[0]).data.get_shape(), fnodes[-1].out_port(0).data.get_shape()))
-
- mul_op = Mul(graph, dict(name='{}/Fused_Mul_'.format(first_mul_name or '')))
- add_op = Add(graph, dict(name='{}/Fused_Add_'.format(first_add_name or '')))
-
- in_port = get_tensor_in_port(fnodes[0])
- out_port = fnodes[-1].out_port(0)
-
- """
- Four cases considered below:
- 1. Mul and Add have valid values (mul value != 1 and add value != 0)
- 2. Only Mul has valid values, so we add only Mul node
- 3. Only Add has valid values, so we add only Add node
- 4. When Mul and Add has not valid values we just merge two data nodes
- """
- if any([x != 0 for x in np.nditer(add)]) and any([x != 1 for x in np.nditer(mul)]):
- # Const\ Const\
- # ----->Mul------>Add-->
- mul_const = Const(graph, dict(name="data_mul_", value=mo_array(mul))).create_node()
- add_const = Const(graph, dict(name="data_add_", value=mo_array(add))).create_node()
-
- mul_node = mul_op.create_node()
- add_node = add_op.create_node()
-
- in_port.get_connection().set_destination(mul_node.in_port(0))
- mul_const.out_port(0).connect(mul_node.in_port(1))
-
- mul_node.out_port(0).connect(add_node.in_port(0))
- add_const.out_port(0).connect(add_node.in_port(1))
- out_port.get_connection().set_source(add_node.out_port(0))
- elif any([x != 1 for x in np.nditer(mul)]):
- # Const\
- # ----->Mul-->
- mul_const = Const(graph, dict(name="data_mul_", value=mo_array(mul))).create_node()
- mul_node = mul_op.create_node()
-
- in_port.get_connection().set_destination(mul_node.in_port(0))
- mul_const.out_port(0).connect(mul_node.in_port(1))
- out_port.get_connection().set_source(mul_node.out_port(0))
- elif any([x != 0 for x in np.nditer(add)]):
- # Const\
- # ----->Add-->
- add_const = Const(graph, dict(name="data_add_", value=mo_array(add))).create_node()
- add_node = add_op.create_node()
-
- in_port.get_connection().set_destination(add_node.in_port(0))
- add_const.out_port(0).connect(add_node.in_port(1))
- out_port.get_connection().set_source(add_node.out_port(0))
- else:
- source_node = in_port.get_source()
- in_port.disconnect()
- out_port.get_connection().set_source(source_node)
-
- # Remove fused nodes
- for node in fnodes:
- graph.remove_node(node.id)
-
- log.debug('Fused {} operations'.format(len(fnodes)))
- return True
-
-
-def fuse_mul_add_sequence(graph: Graph):
- """
- This function finds first valid Mul/Add node and pass it to fuse_linear_sequence where full sequence will be found
- """
- while True:
- is_fused = False
- for node in graph.pseudo_topological_sort():
- if node.id in graph:
- if node.soft_get('op') in ['Mul', 'Add'] and get_value_in_port(node) is not None and \
- node.soft_get('can_be_fused') is True:
- is_fused |= _fuse_linear_sequence(graph, node)
- if not is_fused:
- break
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/helpers.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/helpers.py
deleted file mode 100644
index 0d07c31631e72f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/helpers.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from collections import deque
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.graph.port import Port
-
-
-def get_value_id(node: Node):
- assert node.has_valid('op')
- value_id = None
- for port, in_node in node.in_nodes().items():
- if in_node.has_valid('value'):
- if value_id:
- return None
- value_id = port
- return value_id
-
-
-def get_tensor_id(node: Node):
- assert node.has_valid('op')
- tensor_id = None
- for port, in_node in node.in_nodes().items():
- if not in_node.has_valid('value'):
- if tensor_id:
- return None
- tensor_id = port
- return tensor_id
-
-
-def get_tensor_in_port(node) -> Port:
- tensor_ports = []
- for port in node.in_ports().values():
- if port.data.get_value() is None:
- tensor_ports.append(port)
- return None if len(tensor_ports) != 1 else tensor_ports[0]
-
-
-def get_value_in_port(node) -> Port:
- value_ports = []
- for port in node.in_ports().values():
- if port.data.get_value() is not None:
- value_ports.append(port)
- return None if len(value_ports) != 1 else value_ports[0]
-
-
-def common_bfs(start_node: Node, allowed_ops: list, op_name: list, is_backward: bool = True, allowed_all: bool = False,
- attr_to_check='type', follow_multi_consumer_data_nodes=False):
- """
- The purpose of this algorithm is to find layers with 'op_name' located in given direction.
- In case of branching algorithm goes into each branch, but if it can't find layer in one of them it returns
- empty list.
-
- :param start_node: Start node for BFS algorithm
- :param allowed_ops: List of operations that we can jump over
- :param op_name: The list with names of operations for searching
- :param is_backward: The direction of BFS algorithm
- :param allowed_all: Bool flag meaning we can jump over all operations
- :param attr_to_check: the attribute to check when looking if the node is in "op_name" list
- :param follow_multi_consumer_data_nodes: for backward traversal allow to follow data nodes with multiple consumers
- """
- ret = []
- q = deque([start_node])
- used = []
- while len(q) != 0:
- node = q.popleft()
- if node.id in used:
- log.debug("[BFS:ERROR] Graph contains cycle! BFS starts from {} node".format(start_node.id))
- return []
- used.append(node.id)
- in_nodes_size = len(node.in_nodes()) if is_backward else len(node.out_nodes())
- for id in range(in_nodes_size): # in_nodes() can return either list or dict
- pnode = node.in_node(id) if is_backward else node.out_node(id)
- if pnode.has_valid(attr_to_check):
- if pnode[attr_to_check] in op_name:
- if pnode.id not in ret:
- ret.append(pnode.id)
- elif allowed_all or pnode.op in allowed_ops:
- q.append(pnode)
- else:
- return []
- elif pnode.kind == 'data' and pnode.value is None:
- # If we go backward we don't use data node that have more than one consumer
- if not is_backward or (len(pnode.out_nodes()) == 1 or follow_multi_consumer_data_nodes):
- q.append(pnode)
- return [Node(start_node.graph, x) for x in ret]
-
-
-def forward_bfs(start_node: Node, allowed_ops: list, op_name: list, allowed_all: bool = False):
- return common_bfs(start_node, allowed_ops, op_name, False, allowed_all=allowed_all)
-
-
-def backward_bfs(start_node: Node, allowed_ops: list, op_name: list, allowed_all: bool = False):
- return common_bfs(start_node, allowed_ops, op_name, allowed_all=allowed_all)
-
-
-def get_next_operation(node: Node):
- """
- This function returns next op node, so node should be an operation
- """
- assert node.kind == 'op'
-
- out_nodes = node.out_nodes()
- res = []
- for port, out_node in out_nodes.items():
- op_nodes = out_node.out_nodes()
- for op_node in op_nodes:
- if op_node.id not in [n.id for n in res]:
- res.append(op_node)
- return res
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/mark_unfused_nodes.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/mark_unfused_nodes.py
deleted file mode 100644
index 37c015cfaa3ec8..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/mark_unfused_nodes.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import re
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.MarkSubgraphsWithCorrectLayout import MarkSubGraphsWithCorrectLayout
-from openvino.tools.mo.middle.passes.fusing.helpers import get_value_id
-
-
-def _check_lin_op(node: Node, layout: str):
- lin_ops = ['Mul', 'Add']
- if node.soft_get('op') in lin_ops:
- weights_id = get_value_id(node)
- if weights_id is None:
- node.graph.node[node.id]['can_be_fused'] = False
- log.info('[ FUSING ] Node {} wasn\'t marked as fusable (no weights, probably this is element-wise operation'
- ' that is not fusable)'.format(node.id))
- return
-
- node.graph.node[node.id]['can_be_fused'] = True
- log.info('[ FUSING ] Node {} marked as fusable'.format(node.id))
-
-
-def mark_unfused_nodes(graph: Graph, regex_masks: str):
- regex_masks = [] if not regex_masks else regex_masks.split(',')
- nodes = graph.get_op_nodes()
- for node in nodes:
- if node.has_valid('can_be_fused'):
- continue
- disabled = False
- for mask in regex_masks:
- res = re.findall(mask, node.name)
- if res and len(res):
- graph.node[node.id]['can_be_fused'] = False
- log.info('[ FUSING ] Node {} wasn\'t marked as fusable (user decision {})'.format(node.id,mask))
- disabled = True
- if not disabled:
- _check_lin_op(node, graph.graph['layout'])
-
-
-def mark_shape_of_sugraph_as_unfusable(graph: Graph):
- def condition_to_continue(node: Node):
- for port in node.out_ports().values():
- if port.data.get_value() is None:
- return False
- return True
-
- starting_nodes = graph.get_op_nodes(op='ShapeOf')
- shapeof_subgraph_nodes = MarkSubGraphsWithCorrectLayout.bfs(starting_nodes, set(), condition_to_continue)
-
- for node in shapeof_subgraph_nodes:
- node['can_be_fused'] = False
diff --git a/tools/mo/openvino/tools/mo/middle/passes/fusing/resnet_optimization.py b/tools/mo/openvino/tools/mo/middle/passes/fusing/resnet_optimization.py
deleted file mode 100644
index 6ef142dd873adc..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/fusing/resnet_optimization.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import get_next_operation
-from openvino.tools.mo.ops.pooling import Pooling
-
-
-def _clean_fw_tensor_attrs(node: Node):
- attrs = ['fw_tensor_debug_info']
- for attr in attrs:
- if node.has_valid(attr):
- node[attr] = None
-
-
-def _insert_pooling(graph: Graph, first_node: Node, second_node: Node, spatial_dims):
- """
- This function inserts point wise pooling layer between two nodes
- """
- log.debug("STRIDE PROP: Insert pooling between {} and {}".format(first_node.name, second_node.name))
- stride_prop = second_node.stride_prop
- assert len(graph.get_edge_data(first_node.id, second_node.id)) == 1
- eattrs = graph.get_edge_data(first_node.id, second_node.id)[0]
- graph.remove_edge(first_node.id, second_node.id)
-
- pooling = Pooling(graph, dict(name='Pooling_', spatial_dims=spatial_dims, window=mo_array([1, 1, 1, 1]),
- output_spatial_shape=None,
- stride=mo_array(stride_prop), pad_spatial_shape=mo_array([[0, 0], [0, 0]]),
- pad=mo_array([[0, 0], [0, 0], [0, 0], [0, 0]]), pool_method='max',
- is_partial_inferred=False))
- pooling_data = pooling.create_node_with_data([first_node])
-
- _clean_fw_tensor_attrs(pooling_data)
-
- graph.add_edges_from([(pooling_data.id, second_node.id, eattrs)])
-
-
-def _check_next_ops(next_ops: list):
- """
- This function checks list of operation to determine that all ops has same (not 1,1,1,1) stride_prop attr
- """
- stride_props = []
- for op in next_ops:
- if op.has_valid('stride_prop'):
- stride_props.append(mo_array(op.stride_prop))
- else:
- continue
-
- status = not (len(next_ops) != len(stride_props) or (len(stride_props) > 0 and not all(
- np.array_equal(x, stride_props[0]) and not np.array_equal(x, [1, 1, 1, 1]) for x in stride_props)))
- return stride_props, status
-
-
-def _simple_stride_prop(graph: Graph, node: Node, spatial_dims, supported=True):
- """
- This function handles stride propagation for op nodes. If node is in supported ops dict so this is supported operation and we
- can propagate stride directly via this op (stride_prop will be set by using bottom stride_prop), otherwise we can't and
- stride_prop attr will be set as 1,1,1,1
- """
- next_ops = get_next_operation(node)
- stride_props, all_ops_are_valid = _check_next_ops(next_ops)
-
- if not supported or not all_ops_are_valid:
- # We have to insert pooling layers
- for op in next_ops:
- if op.has_valid('stride_prop') and not np.array_equal(op.stride_prop[spatial_dims], mo_array([1, 1])) and \
- (op.has_valid('has_stride') == False or op.soft_get('has_stride') == False):
- _insert_pooling(graph, node.out_node(), op, spatial_dims)
- # If Convolution is valid then set `stride_prop` to Convolution stride
- node['stride_prop'] = mo_array([1, 1, 1, 1])
- return
-
- for op in next_ops:
- if op.soft_get('has_stride') == True:
- op.stride = mo_array([1, 1, 1, 1])
- log.debug("STRIDE PROP: {} {} strides was moved upper via {}".format(op.type, op.name, node.name))
-
- node['stride_prop'] = mo_array(stride_props[0]) if len(stride_props) > 0 else mo_array([1, 1, 1, 1])
- node['is_partial_inferred'] = False
- _clean_fw_tensor_attrs(node.out_node())
-
-
-def _conv_stride_prop(graph: Graph, node: Node, spatial_dims, supported=True):
- """
- This function handles convolution stride propagation. There is two cases: conv->(op) and conv->conv. In first case
- we propagate stride from op, and in second case we also change stride for second conv
- """
- next_ops = get_next_operation(node)
- stride_props, all_ops_are_valid = _check_next_ops(next_ops)
-
- def _check_convolution(node: Node):
- return node.has_valid('kernel_spatial') and np.array_equal(node.kernel_spatial, mo_array([1, 1]))
-
- # Check that all ops are valid and have same values
- if not all_ops_are_valid:
- # We have to insert pooling layers
- for op in next_ops:
- if op.has_valid('stride_prop') and not np.array_equal(op.stride_prop[spatial_dims], mo_array([1, 1])):
- # Insert pooling
- _insert_pooling(graph, node.out_node(), op, spatial_dims)
- elif len(stride_props) > 0:
- node.stride *= stride_props[0]
- log.debug('STRIDE PROP: {} got new strides {}'.format(node.name, node.stride))
- for op in next_ops:
- if op.soft_get('has_stride') == True:
- op.stride = mo_array([1, 1, 1, 1])
- node['is_partial_inferred'] = False
- node['output_spatial_shape'] = False
- _clean_fw_tensor_attrs(node.out_node())
-
- # If Convolution is valid then set `stride_prop` to Convolution stride
- node['stride_prop'] = mo_array(node.stride) if _check_convolution(node) else mo_array([1, 1, 1, 1])
-
-
-supported_ops = {
- 'ReLU': {'stride_prop': _simple_stride_prop, 'attrs': {}},
- 'Maximum': {'stride_prop': _simple_stride_prop, 'attrs': {}},
- 'Mul': {'stride_prop': _simple_stride_prop, 'attrs': {}},
- 'Add': {'stride_prop': _simple_stride_prop, 'attrs': {}},
- 'Convolution': {'stride_prop': _conv_stride_prop, 'attrs': {'has_stride': True}},
-}
-
-
-def _stride_propagation(graph: Graph, spatial_dims):
- """
- This function do stride propagation for all op nodes
- """
- nodes = [node for node in graph.pseudo_topological_sort(reverse=True) if
- node.kind == 'op' and node.soft_get('type') != 'Const']
-
- for node in nodes:
- if node.soft_get('type') in supported_ops:
- op = supported_ops[node.type]
- # Add node attrs
- for key in op['attrs'].keys():
- node[key] = op['attrs'][key]
- op['stride_prop'](graph, node, spatial_dims, True)
- else:
- _simple_stride_prop(graph, node, spatial_dims, False)
-
-
-def stride_optimization(graph: Graph):
- """
- This is main function for stride optimization pass
- """
- layout = graph.graph['layout']
- if layout == 'NCHW':
- spatial_dims = mo_array([2, 3])
- elif layout == 'NHWC':
- spatial_dims = mo_array([1, 2])
- else:
- log.warning('STRIDE PROP: layout {} is not supported'.format(layout))
- return
- _stride_propagation(graph, spatial_dims)
-
- nodes = [node for node in graph.pseudo_topological_sort() if
- node.soft_get('is_partial_inferred') == False]
- for node in nodes:
- node.infer(node)
diff --git a/tools/mo/openvino/tools/mo/middle/passes/infer.py b/tools/mo/openvino/tools/mo/middle/passes/infer.py
deleted file mode 100644
index a3e5ae1dd0c19f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/infer.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from typing import List
-
-import networkx as nx
-
-from openvino.tools.mo.front.common.layout import get_dim_from_layout
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension
-from openvino.tools.mo.graph.graph import Node, Graph, dict_includes
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg, shrink_str_value
-
-
-def log_debug_dict(nodes_per_port: dict, direction_name: str):
- for port, node in nodes_per_port.items():
- value = shrink_str_value(node.soft_get('value'))
- log.debug('{}[{}]: shape = {}, value = {}'.format(direction_name, port, node.soft_get('shape'), value))
-
-
-def control_flow_infer(graph: Graph, node_name: str):
- """
- Executes constant control flow. Propagates nodes executability
- """
- if graph.node[node_name]['kind'] == 'data':
- return
-
- def mark_executability(node_id: str, is_executable: bool):
- if is_executable and not graph.node[node_id]['executable']:
- return
- graph.node[node_id]['executable'] = is_executable
-
- in_edges_with_data = graph.in_edges(node_name, data=True)
- in_df_edges_with_data = [(u, v, attrs) for u, v, attrs in in_edges_with_data
- if 'control_flow_edge' not in attrs or not attrs['control_flow_edge']]
- in_cf_edges_with_data = [(u, v, attrs) for u, v, attrs in in_edges_with_data
- if 'control_flow_edge' in attrs and attrs['control_flow_edge']]
- is_executable_df = all([graph.node[u]['executable'] for u, _, attrs in in_df_edges_with_data]
- if len(in_df_edges_with_data) else [True])
- is_executable_cf = all([graph.node[u]['executable'] for u, _, attrs in in_cf_edges_with_data]
- if len(in_cf_edges_with_data) else [True])
- is_executable = is_executable_df and is_executable_cf
-
- node = Node(graph, node_name)
- if 'cf_infer' in graph.node[node_name] and callable(node.cf_infer):
- node.cf_infer(node, is_executable, mark_executability)
- else:
- for _, out_data in graph.out_edges(node_name):
- mark_executability(out_data, is_executable)
-
-
-def exit_bound_edges(graph: Graph, sources: list, end_node_attrs: dict):
- """
- Finds all descendant nodes for each node from 'sources' that have given attributes from end_node_attrs.
- For each found node, create a tuple with a given element from 'source' and the node.
- """
- result = []
- for node in sources:
- for end_node in nx.descendants(graph, node):
- if dict_includes(big=graph.node[end_node], sub_dict=end_node_attrs):
- result.append((node, end_node, 0, {}))
- return result
-
-
-def partial_infer(graph: Graph, start_node: str = None):
- """
- Tries to execute constant parts of the graph and deduce as much as possible
- information following the data flow, e.g. calculate and propagate shapes and
- constant values. Partially or completely defined values are stored in data
- nodes (kind='data').
- """
- # We have to turn off strict mode due to above we add and remove edeges without attributes that is prohibited
- graph.strict_mode = False
- cycle_nodes = graph.get_nodes_with_attributes(is_cyclic=True)
- cycle_nodes = [Node(graph, node).out_node().id for node in cycle_nodes]
- ebunch_cyclic = list(graph.out_edges(nbunch=cycle_nodes, data=True, keys=True))
- ebunch_reconnected = exit_bound_edges(graph, sources=cycle_nodes, end_node_attrs={'op': 'Exit'})
- graph.remove_edges_from(ebunch_cyclic)
- graph.add_edges_from(ebunch_reconnected)
-
- try:
- nodes = list(nx.topological_sort(graph))
- except:
- raise Error('Graph contains a cycle. Can not proceed. ' + refer_to_faq_msg(97))
-
- graph.remove_edges_from(ebunch_reconnected)
- graph.add_edges_from(ebunch_cyclic)
- graph.strict_mode = True
-
- # Mark all nodes as not inferred yet
- if start_node is not None:
- start_index = nodes.index(start_node)
- nx.set_node_attributes(G=graph.subgraph(nodes[start_index:]), name='is_partial_inferred', values=False)
- else:
- nx.set_node_attributes(G=graph, name='is_partial_inferred', values=False)
-
- nx.set_node_attributes(G=graph, name='executable',
- values={n: True for n in graph.get_nodes_with_attributes(kind='data')})
-
- # first we infer constant sub-graphs so the reverse infer could use constant values sub-graphs. For example,
- # convolution weights may be reshuffled by some operation in the graph and are not directly consumed by the conv
- # node
- infer_nodes(graph, nodes, True)
-
- # we may need to deduce shape for Parameter node(s) if it is not defined
- need_reverse_infer = False
- for parameter in graph.get_op_nodes(op='Parameter'):
- if parameter.soft_get('shape', None) is None:
- need_reverse_infer = True
-
- if need_reverse_infer:
- reverse_infer(graph, nodes)
-
- infer_nodes(graph, nodes, False)
-
- not_fully_inferred = graph.get_nodes_with_attributes(is_not_fully_inferred=True)
- for n in not_fully_inferred:
- node = Node(graph, n)
- if node.has_and_set('infer'):
- node.infer(node)
-
- return graph
-
-
-def infer_nodes(graph: Graph, nodes: List[Node], constant_subgraph_only: bool = False):
- """
- Run "infer" function of the specified nodes.
-
- :param graph: graph with nodes
- :param nodes: list of node ids in the topological order
- :param constant_subgraph_only: flag which specifies whether only inference of constant sub-graphs should be done
- """
- debug_logger = log.getLogger().isEnabledFor(log.DEBUG)
- for n in nodes:
- # Data Flow Infer
- node = Node(graph, n)
- node_name = node.soft_get('name', node.id)
- try:
- if node.has('is_partial_inferred') and not node.is_partial_inferred:
- if node.has('infer') and not node.infer is None:
- # we consider that operation will produce value if all inputs are constants or it is
- # 'ShapeOf' operation
- if constant_subgraph_only:
- in_values = [port.data.get_value() for port in node.in_ports().values()]
- if node.soft_get('op') == 'Parameter' or any(value is None for value in in_values) or \
- (node.soft_get('op') == 'ShapeOf' and node.in_port(0).data.get_shape() is None):
- # if here will be any new ShapeOf type operation, we should update condition above
- continue
-
- if debug_logger:
- log.debug('-' * 20)
- log.debug('Partial infer for {}'.format(node.soft_get('name')))
- log.debug('Op: {}'.format(node.soft_get('op')))
- log.debug('Inputs:')
- log_debug_dict(node.in_nodes(), 'input')
-
- node.infer(node)
- out_nodes = node.out_nodes()
-
- # propagate nchw_layout attributes to data nodes
- if node.has('nchw_layout'):
- for out_node in out_nodes.values():
- out_node['nchw_layout'] = node.nchw_layout
-
- # In debug print current node attributes, input shapes/values and output shape/values
- if debug_logger:
- log.debug('Outputs:')
- log_debug_dict(node.out_nodes(), 'output')
-
- if not constant_subgraph_only:
- not_all_output_shapes = False
-
- for out_port, out_node in out_nodes.items():
- not_all_output_shapes = False
- if not out_node.has_valid('shape'):
- log.error('Shape is not defined for output {} of "{}".'.format(out_port, node_name))
- not_all_output_shapes = True
-
- if not_all_output_shapes:
- raise Error('Not all output shapes were inferred or fully defined for node "{}". ' +
- refer_to_faq_msg(40),
- node_name)
- elif node.kind != 'data':
- raise Error(
- 'There is no registered "infer" function for node "{}" with op = "{}". ' +
- 'Please implement this function in the extensions. ' +
- refer_to_faq_msg(37),
- node_name,
- node.soft_get('op')
- )
- node.is_partial_inferred = True
- except Exception as err:
- log.error('Cannot infer shapes or values for node "{}".'.format(node.soft_get('name')))
- log.error(str(err))
- log.error('')
- log.error('It can happen due to bug in custom shape infer function {}.'.format(node.soft_get('infer')))
- log.error('Or because the node inputs have incorrect values/shapes.')
- log.error('Or because input shapes are incorrect (embedded to the model or passed via --input_shape).')
- debug_messages = '\n'.join(
- ['Layer "' + node_name + '": ' + node_attrs['debug_message'] for node_name, node_attrs in
- graph.nodes(data=True) if 'debug_message' in node_attrs])
- if debug_messages != "":
- log.error('')
- log.error('Other possible failure reasons are listed below:')
- log.error(debug_messages)
- if not debug_logger:
- log.error('Run Model Optimizer with --log_level=DEBUG for more information.')
- else:
- log.debug('Node "{}" attributes: {}'.format(node.soft_get('name'), node.graph.node[node.id]))
- raise Error('Stopped shape/value propagation at "{}" node. '.format(node.soft_get('name')) +
- refer_to_faq_msg(38)) from err
- control_flow_infer(graph, n)
-
-
-def override_batch(graph: Graph, batch: int):
- """
- Overrides batch for nodes with 'op' param set to 'Parameter'
- Parameters
- ----------
- graph: graph to operate on
- batch: user defined integer value to override batch
- """
- if batch is not None:
- in_nodes = graph.get_op_nodes(op='Parameter')
- for node in in_nodes:
- if not node.soft_get('fixed_batch', False):
- name = node.soft_get('name', node.id)
- idx, has_layout = get_dim_from_layout(node, 'N')
- if has_layout:
- if idx is not None:
- node['shape'][idx] = batch
- else:
- log.warning(
- 'Layout for input {} doesn\'t have batch dimension. Skipping this input.'.format(name))
- else:
- validate_batch_in_shape(node['shape'], name)
- node['shape'][0] = batch
-
-
-def validate_batch_in_shape(shape, layer_name: str):
- """
- Raises Error #39 if shape is not valid for setting batch size
- Parameters
- ----------
- shape: current shape of layer under validation
- layer_name: name of layer under validation
- """
- if len(shape) == 0 or (shape[0] is not dynamic_dimension and shape[0] not in (-1, 0, 1)):
- raise Error(('The input layer {} has a shape {} defined in the model. \n\n' +
- 'When you use -b (--batch) option, Model Optimizer applies its value to the first ' +
- 'element of the shape if it is equal to -1, 0 or 1. Otherwise, this is the ambiguous ' +
- 'situation - Model Optimizer can not know in advance whether the layer has the batch ' +
- 'dimension or not.\n\n For example, you want to set batch dimension equals 100 ' +
- 'for the input layer "data" with shape (10,34). Although you can not use --batch, ' +
- 'you should pass --input_shape (100,34) instead of --batch 100. \n\n' +
- 'You can also tell Model Optimizer where batch dimension is located by specifying --layout. \n\n' +
- refer_to_faq_msg(39))
- .format(layer_name, shape))
-
-
-def override_placeholder_shapes(graph: Graph, user_shapes: dict, batch=None):
- """
- This function overrides shapes for nodes with 'op' param set to 'Parameter' with shapes defined by users (only
- for inputs without in/out port specified).
- And override batch if batch was specified and shape for input is not None.
- :param graph: graph to operate on
- :param user_shapes: dictionary, that represents user defined nodes and shapes
- :param batch: user defined integer value to override batch
- """
- if user_shapes is None:
- # DON'T MOVE UPPER!!! WE NEED TO SET BATCH FIRST
- # user did not specify neither shapes nor inputs, keep models values
- return
- placeholders = graph.get_nodes_with_attributes(kind='op', op='Parameter')
- for node_id in placeholders:
- node_attrs = graph.node[node_id]
- shape = None
- if node_id in user_shapes:
- values = user_shapes[node_id]
- for value in values:
- if 'in' not in value and 'out' not in value:
- shape = value['shape'] if value['shape'] is not None else None
- break # we assume only one specified shape for one input
- if shape is not None:
- node_attrs['shape'] = shape
- if batch is not None and node_attrs['shape'] is not None and len(node_attrs['shape']) > 0:
- node_attrs['shape'][0] = batch
-
-
-def type_infer(graph: Graph):
- nodes = list(nx.topological_sort(graph))
- for n in nodes:
- node = Node(graph, n)
- if node.kind == 'op':
- node_name = node.soft_get('name')
- node_type_infer(node)
- log.debug('Type infer for node {}: {}'.format(node_name,
- [port.get_data_type() for port in node.out_ports().values()]))
- """
- Save the precision of input ports in the nodes. It is not possible to get the precision after the port
- re-numbering because the port precision is defined for output port only and for input port it is determined
- with the output port producing data to the input port. When output port id is changed it is not possible to
- determine input port precision.
- """
- for out_port in node.out_ports().values():
- for dest_port in out_port.get_destinations():
- if not dest_port.node.has_valid('_in_port_precision'):
- dest_port.node['_in_port_precision'] = {}
- dest_port.node['_in_port_precision'][dest_port.idx] = out_port.get_data_type()
-
-
-def node_type_infer(node):
- if node.has_valid('type_infer'):
- node.type_infer(node)
- elif node.has_valid('data_type'):
- node.out_port(0).set_data_type(node.data_type)
- else:
- copy_type_infer(node)
-
-
-def copy_type_infer(node):
- for out_port in node.out_ports().values():
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- if len(connected_in_ports) != 0:
- data_type = connected_in_ports[0].get_data_type()
- if data_type is not None:
- out_port.set_data_type(data_type)
- else:
- src_node = connected_in_ports[0].get_connection().get_source().node
- node_type_infer(src_node)
- out_port.set_data_type(connected_in_ports[0].get_data_type())
- else:
- raise Error('No input ports of node {} to determine data type'.format(node.soft_get('name')))
-
-
-def reverse_infer(graph: Graph, nodes: list):
- nodes = reversed(nodes)
- debug_logger = log.getLogger().isEnabledFor(log.DEBUG)
- for n in nodes:
- node = Node(graph, n)
- if node.has_and_set('reverse_infer'):
- log.debug("Executed reverse infer for node '{}'".format(node.soft_get('name', node.id)))
- node.reverse_infer(node)
-
- if debug_logger:
- log.debug('-' * 20)
- log.debug('Reverse infer for {}'.format(node.soft_get('name')))
- log.debug('Op: {}'.format(node.soft_get('op')))
- log.debug('Outputs:')
- log_debug_dict(node.out_nodes(), 'outputs')
-
- log.debug('Inputs:')
- log_debug_dict(node.in_nodes(), 'inputs')
-
- parameters_with_no_shape = []
- for node in graph.get_op_nodes(op='Parameter'):
- if not node.has_valid('shape'):
- parameters_with_no_shape.append(node)
-
- if len(parameters_with_no_shape) == 0:
- return
-
- parameters_names = ''
- for idx, node in enumerate(parameters_with_no_shape):
- parameters_names += "'{}'".format(node.soft_get('name', node.id))
- if idx < len(parameters_with_no_shape) - 1:
- parameters_names += ', '
-
- if len(parameters_with_no_shape) > 0:
- raise Error("Model Optimizer is unable to deduce input shapes for the following Parameter nodes: {}. "
- "Please use cli options --input or --input_shape to set model input shape.".format(parameters_names))
diff --git a/tools/mo/openvino/tools/mo/middle/passes/tensor_names.py b/tools/mo/openvino/tools/mo/middle/passes/tensor_names.py
deleted file mode 100644
index 43297416a67153..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/passes/tensor_names.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from defusedxml import defuse_stdlib
-from defusedxml.minidom import parseString
-import defusedxml.ElementTree as ET
-
-from openvino.tools.mo.graph.graph import Node, Graph
-
-# defuse_stdlib provide patched version of xml.etree.ElementTree which allows to use objects from xml.etree.ElementTree
-# in a safe manner without including unsafe xml.etree.ElementTree
-ET_defused = defuse_stdlib()[ET]
-Element = ET_defused.Element
-SubElement = ET_defused.SubElement
-tostring = ET_defused.tostring
-
-
-def propagate_op_name_to_tensor(graph: Graph):
- for node in graph.nodes():
- node = Node(graph, node)
- if node.kind == 'op' and node.has_valid('name'):
- for out_node, edge in node.out_nodes_edges().values():
- assert out_node.kind == 'data'
- out_node['ie_tensor_name'] = node.name
- out_node['ie_tensor_port'] = edge['out']
- out_node['ie_tensor_id'] = node.node
-
-
-def output_tensor_names_map(graph: Graph, xml_file_name: str):
- mapping = Element('mapping')
- for node in graph:
- node = Node(graph, node)
- if node.has_valid('fw_tensor_debug_info') and node.has_valid('ie_tensor_name'):
- for fw_tensor_debug_info in node.fw_tensor_debug_info:
- # Check that debug info has valid fw attrs
- if not all(attr is not None for attr in fw_tensor_debug_info):
- continue
- map = SubElement(mapping, 'map')
- fw = SubElement(map, 'framework')
- ie = SubElement(map, 'IR')
-
- fw.set('name', fw_tensor_debug_info[0])
- fw.set('out_port_id', str(fw_tensor_debug_info[1]))
-
- if node.has_valid('ie_tensor_name'):
- ie.set('name', node.ie_tensor_name)
- if node.has_valid('ie_tensor_port'):
- ie.set('out_port_id', str(node.ie_tensor_port))
- if node.has_valid('ie_tensor_id'):
- ie.set('id', str(node.ie_tensor_id))
- with open(xml_file_name, 'w') as file:
- file.write(parseString(tostring(mapping)).toprettyxml())
diff --git a/tools/mo/openvino/tools/mo/middle/pattern_match.py b/tools/mo/openvino/tools/mo/middle/pattern_match.py
deleted file mode 100644
index e0fc96c6840fb4..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/pattern_match.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-from networkx.algorithms import isomorphism as ism
-
-from openvino.tools.mo.graph.graph import Node, dict_includes, Graph
-
-
-def inverse_dict(d: dict):
- return {v: k for k, v in d.items()}
-
-
-def for_each_sub_graph(graph: Graph, func: callable):
- """ Run a given function `func` for each sub-graph in a given graph not recursively.
-
- It doesn't search for sub-graphs in found sub-graphs recursively. If the recursion is required,
- a given function `func` should be implemented in a special way to enable fully recursive traversal.
- """
- for node in graph.nodes():
- node = Node(graph, node)
- if node.has_valid('sub_graphs'):
- for sub_graph_name in node.sub_graphs:
- func(node[sub_graph_name])
-
-
-def for_each_sub_graph_recursively(graph: Graph, func: callable):
- """ Run a given function `func` for each sub-graph in a given graph `graph` recursively.
-
- A given function `func` shouldn't contain a recursion for sub-graphs of the second level.
- """
-
- def recursive_helper(sub_graph):
- # user action
- func(sub_graph)
- # recursion
- for_each_sub_graph(sub_graph, recursive_helper)
-
- for_each_sub_graph(graph, recursive_helper)
-
-
-def for_graph_and_each_sub_graph_recursively(graph: Graph, func: callable):
- """ Run a given function `func` for a given graph `graph` and each sub-graph recursively. """
- func(graph)
- for_each_sub_graph_recursively(graph, func)
-
-
-def all_edges_in_nodes(nodes: list, edges: list):
- return all([edge[0] in nodes and edge[1] in nodes for edge in edges])
-
-
-def apply_pattern(graph: Graph, nodes: list, edges: list, action: callable, node_attrs: list = None,
- edge_attrs: list = None):
- """
- Search for all matches of a given subgraph defined by [nodes, edges] in graph,
- then apply action for each such match.
- """
- if not all_edges_in_nodes([node[0] for node in nodes], edges):
- log.warning("Incorrect pattern attributes: not all nodes from edges are in nodes. "
- "Please, mention all nodes you need in pattern in nodes attribute. ")
-
- matches = []
- for match in find_pattern_matches(graph, nodes, edges, node_attrs, edge_attrs):
- matches.append(match)
-
- for match in matches:
- match = inverse_dict(match)
- still_valid = True
- for k in match:
- if not graph.has_node(match[k]):
- # Graph changed significantly
- still_valid = False
- log.warning("The graph has changed significantly during applying pattern:\n"
- "nodes: {}\n"
- "edges: {}\n"
- "node_attrs: {}\n"
- "edge_attrs: {}".format(nodes, edges, node_attrs, edge_attrs))
- break
- match[k] = Node(graph, match[k])
- if still_valid:
- action(graph, match)
-
-
-def check_node_usages_out_of_match(match: dict, node_name_in_match_group: str):
- """
- Checks if node is consumed by nodes out of match
- :param match: dictionary with pattern match
- :param node_name_in_match_group: string
- :return:
- """
- assert node_name_in_match_group in match
- graph = match[node_name_in_match_group].graph
- all_node_ids = [match[name].id for name in match]
- in_out_node_ids = [u for u, _ in graph.in_edges(match[node_name_in_match_group].id)]
- in_out_node_ids.extend([v for _, v in graph.out_edges(match[node_name_in_match_group].id)])
- return all([n in all_node_ids for n in in_out_node_ids])
-
-
-def node_match(data1: dict, data2: dict):
- # We have to skip _in_ports/_out_ports attributes for comparison as they are not comparable
- return dict_includes(data1, data2, skip_attr_names=['_in_ports', '_out_ports'])
-
-
-def edge_match(datasets1, datasets2):
- attrs = list(datasets2[0].keys())
- values1 = set([])
- for data1 in datasets1.values():
- x = tuple(data1.get(attr, None) for attr in attrs)
- values1.add(x)
- values2 = set([])
- for data2 in datasets2.values():
- x = tuple(data2.get(attr, None) for attr in attrs)
- values2.add(x)
- return values1 == values2
-
-
-def build_matcher(graph: Graph, nodes: list, edges: list, node_attrs: list = None,
- edge_attrs: list = None):
- if node_attrs is not None or edge_attrs is not None:
- log.warning('\'edge_attrs\' or `\'node_attrs\'` parameter was passed to function \'find_pattern_matches\', '
- 'but they are not used anymore. Pattern matching proceeds according to \'nodes\' and \'edges\' '
- 'parameters. Please avoid passing \'edge_attrs\' and \'node_attrs\' parameters to any pattern '
- 'matching function like \'find_pattern_matches\', \'apply_pattern\' and \'pattern\' because it '
- 'will be deprecated in the next release.')
-
- subgraph = Graph(name='pattern')
- subgraph.add_nodes_from(nodes)
- subgraph.add_edges_from(edges)
- return ism.MultiDiGraphMatcher(graph, subgraph, node_match, edge_match)
-
-
-def find_pattern_matches(graph: Graph, nodes: list, edges: list, node_attrs: list = None,
- edge_attrs: list = None):
- """
- Find all matches of a given sub-graph defined by [nodes, edges] in graph.
- """
- matcher = build_matcher(graph, nodes, edges, node_attrs, edge_attrs)
- return matcher.subgraph_isomorphisms_iter()
-
-
-def find_isomorphisms(graph: Graph, nodes: list, edges: list):
- ''' Find for isomorphism between a given graph and a pattern specified by a given nodes and edges.
- Applies the same rules as apply_pattern.
- '''
- matcher = build_matcher(graph, nodes, edges)
- result = []
- for match in matcher.isomorphisms_iter():
- match = inverse_dict(match)
- match = {k: Node(graph, match[k]) for k in match.keys()}
- result.append(match)
- return result
-
-
-def check_value(v: np.ndarray, check: callable):
- return v is not None and np.all(np.isreal(v)) and check(v)
diff --git a/tools/mo/openvino/tools/mo/middle/permute_tensor_iterator.py b/tools/mo/openvino/tools/mo/middle/permute_tensor_iterator.py
deleted file mode 100644
index dfc0b3a5294d83..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/permute_tensor_iterator.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.LSTMRNNSequenceToTensorIterator import LSTMToTensorIterator
-from openvino.tools.mo.middle.ONNXRNNSequenceNormalize import ONNXRNNSequenceNormalize
-from openvino.tools.mo.middle.SwapAxesMiddleReplacer import SwapAxisMiddleReplacer
-from openvino.tools.mo.middle.TensorIteratorMerge import TensorIteratorMerge
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import dict_includes, Graph
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.pattern_match import find_isomorphisms
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class TransposeTensorIteratorLSTM(MiddleReplacementPattern):
- """ Fuses Transpose(1,0,2) --> TI --> Transpose(1,0,2) pattern to a single TI with changed axis.
-
- WARNING This transformation is limited to support of very special case of TI but
- code doesn't check all the cases.
- """
-
- enabled = True
-
- def run_after(self):
- return [TensorIteratorMerge, ONNXRNNSequenceNormalize, LSTMToTensorIterator, SwapAxisMiddleReplacer]
-
- def run_before(self):
- return []
-
- def pattern(self):
- return dict(
- nodes=[
- ('input', dict(kind='data')),
- ('direct_permute', dict(kind='op', op='Transpose')),
- ('input_permuted', dict(kind='data')),
- ('init_hidden', dict(kind='data')),
- ('init_cell', dict(kind='data')),
- ('ti', dict(kind='op', op='TensorIterator')),
-
- ('output_permuted', dict(kind='data')),
- ('inverse_permute', dict(op='Transpose')),
- ('output', dict(kind='data')),
- ],
- edges=[
- ('input', 'direct_permute'),
- ('direct_permute', 'input_permuted'),
-
- ('input_permuted', 'ti', {'in': 0}), # affected by permute
- ('init_hidden', 'ti', {'in': 1}),
- ('init_cell', 'ti', {'in': 2}),
- ('ti', 'output_permuted', {'out': 0}), # affected by permute
-
- ('output_permuted', 'inverse_permute'),
- ('inverse_permute', 'output'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
-
- # This transformation works if and only if a body of TI
- # matches the following topology (Squeeze -> LSTMCell -> Unsqueeze)
- nodes = [
- ('squeeze_dim', dict(kind='op', op='Const')),
- ('squeeze_dim_data', dict(kind='data')),
-
- ('unsqueeze_dim', dict(kind='op', op='Const')),
- ('unsqueeze_dim_data', dict(kind='data')),
-
- ('input_unsqueezed', dict(kind='data')),
- ('squeeze', dict(kind='op', op='Squeeze')),
- ('input_squeezed', dict(kind='data')),
- ('input_hidden', dict(kind='data')),
- ('input_cell', dict(kind='data')),
- ('weights', dict(kind='data')),
- ('biases', dict(kind='data')),
-
- ('lstm', dict(kind='op', op='LSTMCell')),
-
- ('output_hidden', dict(kind='data')),
- ('output_cell', dict(kind='data')),
- ('unsqueeze', dict(kind='op', op='Unsqueeze')),
- ('output_unsqueezed', dict(kind='data')),
-
- ('const_w', dict(kind='op', op='Const')),
- ('const_b', dict(kind='op', op='Const')),
-
- ('op_output', dict(kind='op', op='Result')),
- ('op_output_1', dict(kind='op', op='Result')),
- ('op_output_2', dict(kind='op', op='Result')),
-
- ('input_unsqueezed_i', dict(kind='op', op='Parameter')),
- ('input_hidden_i', dict(kind='op', op='Parameter')),
- ('input_cell_i', dict(kind='op', op='Parameter')),
- ]
- edges = [
- ('input_unsqueezed', 'squeeze', {'in': 0}),
- ('squeeze', 'input_squeezed'),
-
- ('squeeze_dim', 'squeeze_dim_data'),
- ('squeeze_dim_data', 'squeeze', {'in': 1}),
-
- ('input_squeezed', 'lstm', {'in': 0}),
- ('input_hidden', 'lstm', {'in': 1}),
- ('input_cell', 'lstm', {'in': 2}),
- ('weights', 'lstm', {'in': 3}),
- ('biases', 'lstm', {'in': 4}),
-
- ('const_w', 'weights'),
- ('const_b', 'biases'),
-
- ('lstm', 'output_hidden', {'out': 0}),
- ('lstm', 'output_cell', {'out': 1}),
-
- ('output_hidden', 'unsqueeze'),
- ('unsqueeze', 'output_unsqueezed'),
-
- ('unsqueeze_dim', 'unsqueeze_dim_data'),
- ('unsqueeze_dim_data', 'unsqueeze', {'in': 1}),
-
- ('output_unsqueezed', 'op_output'),
- ('output_hidden', 'op_output_1'),
- ('output_cell', 'op_output_2'),
-
- ('input_unsqueezed_i', 'input_unsqueezed'),
- ('input_hidden_i', 'input_hidden'),
- ('input_cell_i', 'input_cell'),
- ]
- ti = match['ti']
- isomorphisms = find_isomorphisms(ti.body, nodes, edges)
- if len(list(isomorphisms)) != 1:
- return
- isomorphism = isomorphisms[0]
-
- direct_permute = match['direct_permute']
- inverse_permute = match['inverse_permute']
-
- permute_order = [1, 0, 2]
-
- # Check both perumute orders exactly match expected one - [1, 0, 2]
- direct_order = direct_permute.in_port(1).data.get_value()
- if direct_order is None or not np.array_equal(direct_order, permute_order):
- return
- inverse_order = inverse_permute.in_port(1).data.get_value()
- if inverse_order is None or not np.array_equal(inverse_order, permute_order):
- return
-
- # Check non-ShapeOf output out of direct Transpose is exactly one
- direct_permute_dsts = direct_permute.out_port(0).get_destinations()
- if len([dst for dst in direct_permute_dsts if dst.node.soft_get('type') != 'ShapeOf']) != 1:
- return
- for shape_of_dst in [dst for dst in direct_permute_dsts if dst.node.soft_get('type') == 'ShapeOf']:
- name = shape_of_dst.node.soft_get('name', shape_of_dst.node.id) + '/FusedToTITranspose'
- gather = create_op_with_const_inputs(graph, op=Gather, op_attrs={'name': name},
- port_value_dict={1: int64_array(permute_order), 2: int64_array(0)})
- shape_of_dst.node.out_port(0).get_connection().insert_node(gather)
-
- def find_ports(port_map: list, attrs: dict):
- """ Find all ports in a given port map with specified attributes """
- result = []
- for i, port in enumerate(port_map):
- if dict_includes(port, attrs):
- result.append(i)
- return result
-
- # Check TI has only single partitioned input/output port; all partitioned ports have defined axis
- data_input_port = find_ports(ti.input_port_map, {'axis': lambda attr: attr in [0, 1]})
- data_output_port = find_ports(ti.output_port_map, {'axis': lambda attr: attr in [0, 1]})
- assert len(data_input_port) == 1
- assert len(data_output_port) == 1
- data_input_port = data_input_port[0]
- data_output_port = data_output_port[0]
- # Verify that they are really connected to Transpose layers (guaranteed by port numbers of TI, see the pattern)
- assert ti.in_edge(0)['external_port_id'] == ti.input_port_map[data_input_port]['external_port_id']
- assert ti.out_edge(0)['external_port_id'] == ti.output_port_map[data_output_port]['external_port_id']
-
- # Verify that the TI body have required Reshapes connected to the found ports
- squeeze = isomorphism['squeeze']
- unsqueeze = isomorphism['unsqueeze']
-
- assert len(squeeze.in_node().shape) == 3
- assert len(squeeze.out_node().shape) == 2
- assert len(unsqueeze.in_node().shape) == 2
- assert len(unsqueeze.out_node().shape) == 3
-
- # Remove permutes
- remove_op_node_with_data_node(graph, direct_permute)
- remove_op_node_with_data_node(graph, inverse_permute)
- match['output'].shape = match['output'].shape[permute_order]
-
- # swap 0/1 axis for partitioned ports
- ti.input_port_map[data_input_port]['axis'] = 1 - ti.input_port_map[data_input_port]['axis']
- ti.output_port_map[data_output_port]['axis'] = 1 - ti.output_port_map[data_output_port]['axis']
-
- isomorphism['input_unsqueezed_i'].shape = isomorphism['input_unsqueezed_i'].shape[[1, 0, 2]]
- isomorphism['input_unsqueezed_i'].infer(isomorphism['input_unsqueezed_i'])
- isomorphism['squeeze_dim'].value = ti.input_port_map[data_input_port]['axis']
- isomorphism['squeeze_dim'].infer(isomorphism['squeeze_dim'])
- isomorphism['squeeze']['need_shape_inference'] = True
-
- isomorphism['unsqueeze_dim'].value = ti.output_port_map[data_output_port]['axis']
- isomorphism['unsqueeze_dim'].infer(isomorphism['unsqueeze_dim'])
- isomorphism['unsqueeze'].infer(isomorphism['unsqueeze'])
diff --git a/tools/mo/openvino/tools/mo/middle/preprocessing.py b/tools/mo/openvino/tools/mo/middle/preprocessing.py
deleted file mode 100644
index 95fb6cd5b86fb1..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/preprocessing.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.LeakyReluPattern import LeakyReLUFusion
-from openvino.tools.mo.middle.pass_separator import PostMiddleStart
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.find_inputs import find_inputs
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class CaffeMeanFileProcessing(MiddleReplacementPattern):
- enabled = True
- force_clean_up = True
- graph_condition = [lambda graph: graph.graph['fw'] == 'caffe']
-
- def run_after(self):
- return [LeakyReLUFusion]
-
- def run_before(self):
- return [PostMiddleStart]
-
- def find_and_replace_pattern(self, graph: Graph):
- from openvino.tools.mo.front.caffe import loader
- argv = graph.graph['cmd_params']
- original_shapes = graph.graph['original_shapes']
- caffe_pb2 = graph.graph['caffe_pb2']
- del graph.graph['caffe_pb2']
- input_names = find_inputs(graph)
- graph.graph['input_names'] = input_names
diff --git a/tools/mo/openvino/tools/mo/middle/quantize_dequantize_linear_resolver.py b/tools/mo/openvino/tools/mo/middle/quantize_dequantize_linear_resolver.py
deleted file mode 100644
index 03a0599ea28bfe..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/quantize_dequantize_linear_resolver.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2021 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph, rename_nodes
-from openvino.tools.mo.middle.quantize_linear_resolver import QuantizeLinearResolver
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class QuantizeDequantizeLinearResolver(MiddleReplacementPattern):
- """
- This transformation replaces QuantizeLinear in pair QuantizeLinear/DequantizeLinear with
- constant inputs to FakeQuantize with flag stop_value_propagation=True. This transformation prepare FakeQuantize for
- ConvertQuantizeDequantize in offline transformations.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['layout'] == 'NCHW']
-
- def pattern(self):
- return dict(
- nodes=[('const_input', dict(kind='op', op='Const')),
- ('const_input_d', dict(kind='data')),
- ('quantize', dict(kind='op', op='QuantizeLinear')),
- ('quantize_d', dict(kind='data')),
- ('dequantize', dict(kind='op', op='DequantizeLinear')),
- ],
- edges=[('const_input', 'const_input_d'),
- ('const_input_d', 'quantize', {'in': 0}),
- ('quantize', 'quantize_d'),
- ('quantize_d', 'dequantize', {'in': 0})
- ]
- )
-
- def run_after(self):
- from openvino.tools.mo.middle.quantize_fuses import MarkNodesToFuseUpToFakeQuantize
- return [MarkNodesToFuseUpToFakeQuantize]
-
- def replace_pattern(self, graph: Graph, match: dict):
- dequantize_node = match['dequantize']
- quantize_node = match['quantize']
-
- scale_zerop_is_exist = quantize_node.is_in_port_connected(1) and quantize_node.is_in_port_connected(2) and \
- dequantize_node.is_in_port_connected(1) and dequantize_node.is_in_port_connected(2)
- if not scale_zerop_is_exist:
- return
- q_scale = quantize_node.in_port(1).get_source().node
- q_zerop = quantize_node.in_port(2).get_source().node
- dq_scale = dequantize_node.in_port(1).get_source().node
- dq_zerop = dequantize_node.in_port(2).get_source().node
- scales_and_zerop_is_const = q_scale.soft_get('type') == 'Const' and dq_scale.soft_get('type') == 'Const' and \
- q_zerop.soft_get('type') == 'Const' and dq_zerop.soft_get('type') == 'Const'
- scales_and_zerop_equals = np.array_equal(q_scale.value, dq_scale.value) and \
- np.array_equal(q_zerop.value, dq_zerop.value)
-
- # only constant as for zero_point/scale supported
- # only patterns with same scale/zero_point values for Q and DQ are supported
- if not (scales_and_zerop_is_const or scales_and_zerop_equals):
- return
-
- QuantizeLinearResolver.quantize_to_fakequantize(graph, quantize_node, True)
- quantize_node['isolated'] = True
diff --git a/tools/mo/openvino/tools/mo/middle/quantize_fuses.py b/tools/mo/openvino/tools/mo/middle/quantize_fuses.py
deleted file mode 100644
index f111e664c392c7..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/quantize_fuses.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.BinarizeWeightsM1P1 import BinarizeWeightsM1P1
-from openvino.tools.mo.middle.DeleteControlFlowEdges import DeleteControlFlowEdges
-from openvino.tools.mo.middle.EltwiseChecker import EltwiseChecker
-from openvino.tools.mo.middle.quantize_linear_resolver import QuantizeLinearResolver
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import get_value_in_port
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class MarkNodesToFuseUpToFakeQuantize(MiddleReplacementPattern):
- """
- Marks special nodes that could be pulled through Quantize operation.
- Sets `fuse_up_to_quantize_ports` parameter to list of indexes of input ports of Quantize operation
- where specified node should appear.
-
- """
- enabled = True
-
- def run_after(self):
- return [DeleteControlFlowEdges]
-
- def run_before(self):
- return []
-
- @staticmethod
- def mark_fusable_muls_on_weights(graph):
- for node in graph.get_op_nodes(op='Mul'):
- children = node.out_port(0).get_destinations()
- if len(children) > 1 or children[0].node.soft_get('type') not in ['Convolution', 'Deconvolution', 'MatMul']:
- continue
- value_in_port = get_value_in_port(node)
- if value_in_port is None:
- continue
- value_shape = value_in_port.data.get_shape()
- non_one_axis = np.argwhere(value_shape != 1)
- if non_one_axis.size != 1:
- continue
- non_one_axis = non_one_axis.item(0)
- node['can_be_fused'] = True
- EltwiseChecker().mark_eltwise_node(node, non_one_axis)
-
- def find_and_replace_pattern(self, graph: Graph):
- # to prevent fusing of non per channel lin ops, we run EltwiseChecker to mark nodes with can_be_fused attribute
- EltwiseChecker().find_and_replace_pattern(graph)
- self.mark_fusable_muls_on_weights(graph)
- eltwise_nodes = graph.get_op_nodes(op='Mul', can_be_fused=True) + \
- graph.get_op_nodes(op='Sub', can_be_fused=True) + \
- graph.get_op_nodes(op='Add', can_be_fused=True)
- for elt in eltwise_nodes:
- if elt.in_port(0).data.get_value() is not None or elt.in_port(1).data.get_value() is not None:
- elt['fuse_up_to_quantize_ports'] = [3, 4]
-
- slice = graph.get_op_nodes(op='Slice')
- for sl in slice:
- sl['fuse_up_to_quantize_ports'] = [0]
-
-
-class FakeQuantizeFuse(MiddleReplacementPattern):
- """
- Pulls nodes containing `fuse_up_to_quantize_ports` parameter (node to fuse) through Quantize operation
-
- If `fuse_up_to_quantize_ports` list contains one input port to which node to fuse should be delivered,
- replacer reconnects edges.
-
- If `fuse_up_to_quantize_ports` list contains more than one input port to which node to fuse should be delivered,
- replacer reconnects edges of first port from `fuse_up_to_quantize_ports` list, for other ports
- replacer duplicates node to fuse (duplicate connections of inputs of node to fuse to duplicates of it)
- """
- enabled = True
-
- def run_after(self):
- return [QuantizeLinearResolver]
-
- def run_before(self):
- return [BinarizeWeightsM1P1]
-
- def find_and_replace_pattern(self, graph: Graph):
- 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
- fuse_node = quantize_node.out_port(0).get_destination().node
- quantize_to_mul_in_port_index = quantize_node.out_port(0).get_destination().idx
-
- # connecting the rest of model after mul to quantize, mul node hangs on quantize
- fuse_node.out_port(0).get_connection().set_source(quantize_node.out_port(0))
-
- # mul node is disconnected from the graph
- fuse_node.in_port(quantize_to_mul_in_port_index).disconnect()
-
- first_port_fusion = True
- for in_quantize_port in fuse_node['fuse_up_to_quantize_ports']:
- fuse_node_duplicate = fuse_node
- if not first_port_fusion:
- fuse_node_duplicate = fuse_node.copy_node(
- {'in_ports_count': len(fuse_node.in_ports()),
- 'out_ports_count': len(fuse_node.out_ports())})
-
- quantize_node.in_port(in_quantize_port).get_connection().set_destination(
- fuse_node_duplicate.in_port(quantize_to_mul_in_port_index))
-
- fuse_node_duplicate.out_port(0).connect(quantize_node.in_port(in_quantize_port))
-
- if not first_port_fusion:
- for idx, port in fuse_node.in_ports().items():
- if idx == quantize_to_mul_in_port_index:
- continue
- port.get_source().connect(fuse_node_duplicate.in_port(idx))
- fuse_node_duplicate.infer(fuse_node_duplicate)
-
- first_port_fusion = False
diff --git a/tools/mo/openvino/tools/mo/middle/quantize_linear_resolver.py b/tools/mo/openvino/tools/mo/middle/quantize_linear_resolver.py
deleted file mode 100644
index 5610f09b5db3f8..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/quantize_linear_resolver.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Mul
-from openvino.tools.mo.ops.fakequantize import FakeQuantize
-from openvino.tools.mo.front.common.partial_infer.utils import float_array, int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_with_const_inputs
-from openvino.tools.mo.graph.graph import Graph, rename_nodes, Node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.utils.error import Error
-
-
-class QuantizeLinearResolver(MiddleReplacementPattern):
- """
- Replaces QuantizeLinear with FakeQuantize
- Transformation result depends on the axis value.
- If the axis is not set or x_scale input is scalar or 1D tensor with one element then QuantizeLinear is
- replaced with the sub-graph which can be expressed with the following formula:
- QuantizeLinear -> FakeQuantize(input
- Mul(y_scale, Const(low_value))
- Mul(y_scale, Const(high_value))
- Const(low_value)
- Const(high_value))
- low_value and high_value depend on from y_zero_point type
- In other cases y_scale and y_zero_point can be transform with addition reshape.
- Target shape for y_scale and y_zero_point depend on axis value.
- """
- enabled = True
- graph_condition = [lambda graph: graph.graph['layout'] == 'NCHW']
-
- def run_after(self):
- from openvino.tools.mo.middle.quantize_dequantize_linear_resolver import QuantizeDequantizeLinearResolver
- return [QuantizeDequantizeLinearResolver]
-
- def find_and_replace_pattern(self, graph: Graph):
- for quantize_node in graph.get_op_nodes(op='QuantizeLinear'):
- if quantize_node.has_and_set('isolated'): # node is detached and will be eliminated
- # during the next clean up
- continue
- QuantizeLinearResolver.quantize_to_fakequantize(graph, quantize_node)
-
- @staticmethod
- def quantize_to_fakequantize(graph: Graph, quantize_node: Node, set_stop_value_propagation=False):
- node_name = quantize_node.soft_get('name', quantize_node.id)
- axis = quantize_node.soft_get('axis', None)
- scale_y_shape = quantize_node.in_port(1).data.get_shape()
-
- if quantize_node.is_in_port_connected(2):
- zerop = quantize_node.in_port(2).get_source().node
- else:
- zerop = Const(graph,
- {'value': mo_array(0, dtype=np.uint8), 'name': node_name + '/ZeroPoint'}).create_node()
-
- assert zerop.soft_get('type') == 'Const', 'only constant for zero_point is supported for QuantizeLinear'
- zero_point_type = zerop.value.dtype
- # data type affects range of output values: [-128..127] or [0..255]
- if zero_point_type == np.int8:
- output_low_value = -128.0
- output_high_value = 127.0
- elif zero_point_type == np.uint8:
- output_low_value = 0.0
- output_high_value = 255.0
- else:
- raise Error('Not expected type {} for zero point value in node {}'.format(
- zero_point_type, zerop.soft_get('name')))
-
- fake_quantize = create_op_with_const_inputs(graph, FakeQuantize, {3: float_array(output_low_value),
- 4: float_array(output_high_value)},
- {'levels': 256, 'name': node_name + '/FakeQuantize'})
- if set_stop_value_propagation:
- fake_quantize['stop_compression'] = True
- fake_quantize['stop_value_propagation'] = True
- quantize_node.in_port(0).get_connection().set_destination(fake_quantize.in_port(0))
-
- # Calculate input_low value
- mul_low = create_op_with_const_inputs(graph, Mul, {1: float_array(output_low_value - zerop.value)},
- {'name': node_name + '/Mul/Low'})
- quantize_node.in_port(1).get_connection().set_destination(mul_low.in_port(0))
- mul_low.out_port(0).connect(fake_quantize.in_port(1))
-
- # Calculate input_high value
- mul_high = create_op_with_const_inputs(graph, Mul, {1: float_array(output_high_value - zerop.value)},
- {'name': node_name + '/Mul/High'})
- mul_low.in_port(0).get_connection().add_destination(mul_high.in_port(0))
- mul_high.out_port(0).connect(fake_quantize.in_port(2))
-
- cast = Cast(graph, {'dst_type': zero_point_type, 'name': node_name + '/Cast'}).create_node()
- fake_quantize.out_port(0).connect(cast.in_port(0))
- quantize_node.out_port(0).get_connection().set_source(cast.out_port(0))
- rename_nodes([(quantize_node, node_name + '/TBD'), (cast, node_name)])
-
- assert scale_y_shape is not None, "{0} contains scale(input with port 1) with shape None".\
- format(quantize_node.soft_get('name', quantize_node.id))
- if axis is not None and len(scale_y_shape) > 0 and scale_y_shape[0] > 1:
- input_shape = fake_quantize.in_port(0).data.get_shape()
- target_shape = np.ones(len(input_shape), int)
- target_shape[axis] = input_shape[axis]
- mul_low_reshape = create_op_with_const_inputs(graph, Reshape, {1: int64_array(target_shape)},
- {'name': node_name + '/Reshape/Mul/Low'})
- mul_high_reshape = create_op_with_const_inputs(graph, Reshape, {1: int64_array(target_shape)},
- {'name': node_name + '/Reshape/Mul/high'})
-
- fake_quantize.in_port(1).get_connection().set_destination(mul_low_reshape.in_port(0))
- fake_quantize.in_port(2).get_connection().set_destination(mul_high_reshape.in_port(0))
-
- mul_low_reshape.out_port(0).connect(fake_quantize.in_port(1))
- mul_high_reshape.out_port(0).connect(fake_quantize.in_port(2))
diff --git a/tools/mo/openvino/tools/mo/middle/replacement.py b/tools/mo/openvino/tools/mo/middle/replacement.py
deleted file mode 100644
index e646718fca1bb2..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/replacement.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils import class_registration
-from openvino.tools.mo.utils.replacement_pattern import ReplacementPattern
-
-
-class MiddleReplacementPattern(ReplacementPattern):
- registered_ops = {}
- registered_cls = []
-
- def run_after(self):
- from openvino.tools.mo.middle.pass_separator import MiddleStart
- return [MiddleStart]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.MIDDLE_REPLACER
-
-
-ReplacementPattern.excluded_replacers.append(MiddleReplacementPattern)
diff --git a/tools/mo/openvino/tools/mo/middle/reverse_tensor_iterator.py b/tools/mo/openvino/tools/mo/middle/reverse_tensor_iterator.py
deleted file mode 100644
index b957577bce0033..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/reverse_tensor_iterator.py
+++ /dev/null
@@ -1,134 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.middle.ONNXRNNSequenceNormalize import ONNXRNNSequenceNormalize
-from openvino.tools.mo.middle.permute_tensor_iterator import TransposeTensorIteratorLSTM
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.eliminate import remove_op_node_with_data_node
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-
-
-class ReverseTensorIteratorLSTM(MiddleReplacementPattern):
- """ Fuses Reverse operations around TI: ReverseSequence --> TI --> ReverseSequence.
-
- WARNING This transformation is limited to support of very special case of TI but
- code doesn't check all the cases.
- """
-
- enabled = True
- force_clean_up = True
-
- def run_after(self):
- return [
- ONNXRNNSequenceNormalize,
- TransposeTensorIteratorLSTM,
- ]
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- @staticmethod
- def is_fusable_reverse_sequence(node: Node):
- sequence_lengths = node.in_port(1).data.get_value()
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None
-
- seq_len = input_shape[node.seq_axis]
- if sequence_lengths is not None and is_fully_defined(sequence_lengths) and is_fully_defined(seq_len):
- return np.all(sequence_lengths == seq_len)
- else:
- # check that we take sequence_length from input shape based on ReverseV2ToReverseSequence transformation
- broadcast_node = node.in_port(1).get_source().node
- if broadcast_node.op != 'Broadcast':
- return False
- gather_node = broadcast_node.in_port(0).get_source().node
- if gather_node.op != "Gather" or \
- (np.all(gather_node.in_port(2).data.get_value() != [0]) or
- np.all(gather_node.in_port(1).data.get_value() != [node.seq_axis])):
- return False
- gather_node_2 = broadcast_node.in_port(1).get_source().node
- if gather_node_2.op != "Gather" or \
- (np.all(gather_node_2.in_port(2).data.get_value() != [0]) or
- np.all(gather_node_2.in_port(1).data.get_value() != [node.batch_axis])):
- return False
- shape_node = gather_node.in_port(0).get_source().node
- if shape_node.op != "ShapeOf":
- return False
- if shape_node.in_port(0).get_source().node != node.in_port(0).get_source().node:
- return False
-
- return True
-
- def pattern(self):
- return dict(
- nodes=[
- ('input', dict(kind='data')),
-
- ('direct_seq_len_d', dict(kind='data')),
- ('direct_reverse', dict(op='ReverseSequence')),
- ('input_reversed', dict(kind='data')),
- ('init_hidden', dict(kind='data')),
-
- ('ti', dict(kind='op', op='TensorIterator')),
- ('output_reversed', dict(kind='data')),
-
- ('inverse_seq_len_d', dict(kind='data')),
- ('inverse_reverse', dict(op='ReverseSequence')),
- ('output', dict(kind='data')),
- ],
- edges=[
- ('input', 'direct_reverse', {'in': 0}),
- ('direct_seq_len_d', 'direct_reverse', {'in': 1}),
- ('direct_reverse', 'input_reversed'),
-
- ('input_reversed', 'ti', {'in': 0}),
- ('init_hidden', 'ti', {'in': 1}),
- ('ti', 'output_reversed', {'out': 0}),
-
- ('output_reversed', 'inverse_reverse', {'in': 0}),
- ('inverse_seq_len_d', 'inverse_reverse', {'in': 1}),
- ('inverse_reverse', 'output'),
- ]
- )
-
- def replace_pattern(self, graph: Graph, match: dict):
- ti = match['ti']
- direct_reverse = match['direct_reverse']
- inverse_reverse = match['inverse_reverse']
-
- assert direct_reverse.seq_axis == inverse_reverse.seq_axis
- assert direct_reverse.batch_axis is None and inverse_reverse.batch_axis is None or \
- direct_reverse.batch_axis == inverse_reverse.batch_axis
-
- if not self.is_fusable_reverse_sequence(direct_reverse) or \
- not self.is_fusable_reverse_sequence(inverse_reverse):
- # we can not merge ReverseSequence without equal sequences
- return
-
- # Modify stride in TI
- for port_map in [ti.input_port_map, ti.output_port_map]:
- for port in port_map:
- if 'axis' in port and port['axis'] is not None and 'external_port_id' in port:
- assert port['axis'] == direct_reverse.seq_axis, \
- 'axis == {} != {} == direct_reverse.seq_dim'.format(port['axis'], direct_reverse.seq_axis)
- if 'stride' not in port or port['stride'] is None:
- port['stride'] = 1
- assert port['stride'] in [-1, 1]
- port['stride'] = -port['stride']
- if port['stride'] == -1:
- port['start'] = -1
- port['end'] = 0
- elif port['stride'] == 1:
- port['start'] = 0
- port['end'] = -1
-
- # disconnect subgraph for seq length calculation
- direct_reverse.in_port(1).disconnect()
- inverse_reverse.in_port(1).disconnect()
- # Remove reverses
- remove_op_node_with_data_node(graph, direct_reverse)
- remove_op_node_with_data_node(graph, inverse_reverse)
diff --git a/tools/mo/openvino/tools/mo/middle/sparse_reshape.py b/tools/mo/openvino/tools/mo/middle/sparse_reshape.py
deleted file mode 100644
index ad2fd625f8d10f..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/sparse_reshape.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.eliminate import merge_data_nodes
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.utils.error import Error
-
-
-class SparseReshapeMiddleReplacer(MiddleReplacementPattern):
- """
- Removes SparseReshape operation if the old shape and the output shape are the same.
- """
- enabled = True
-
- def run_before(self):
- from openvino.tools.mo.middle.pass_separator import MiddleFinish
- return [MiddleFinish]
-
- def pattern(self):
- return dict(
- nodes=[
- ('sparse_reshape', dict(op='SparseReshape')),
- ],
- edges=[
- ])
-
- def replace_pattern(self, graph: Graph, match: dict):
- sparse_reshape = match['sparse_reshape']
-
- input_shape_value = sparse_reshape.in_port(1).data.get_value()
- output_shape_value = sparse_reshape.out_port(1).data.get_value()
-
- # establish output shape if value of new shape is given as input
- new_shape_value = sparse_reshape.in_port(2).data.get_value()
- if output_shape_value is None and new_shape_value is not None:
- output_shape_value = new_shape_value
- if np.count_nonzero(output_shape_value == -1) == 1:
- elem = np.prod(input_shape_value) // np.prod(new_shape_value[new_shape_value != -1])
- output_shape_value[output_shape_value == -1] = elem
-
- if input_shape_value is None or output_shape_value is None:
- raise Error("Input shape and output shape values must be defined for node {}".format(sparse_reshape.id))
- if not np.array_equal(input_shape_value, output_shape_value):
- raise Error("Input shape and output shape values must be equal for node {}".format(sparse_reshape.id))
-
- nodes_to_remove = [sparse_reshape.id]
- if sparse_reshape.is_out_port_connected(0):
- sparse_reshape.out_port(0).get_connection().set_source(sparse_reshape.in_port(0).get_source())
- output_data_node = sparse_reshape.out_node(0)
- nodes_to_remove.append(output_data_node.id)
- else:
- input_data_node = sparse_reshape.in_node(0)
- nodes_to_remove.append(input_data_node.id)
-
- if sparse_reshape.is_out_port_connected(1):
- sparse_reshape.out_port(1).get_connection().set_source(sparse_reshape.in_port(1).get_source())
- output_data_node = sparse_reshape.out_node(1)
- nodes_to_remove.append(output_data_node.id)
- else:
- input_data_node = sparse_reshape.in_node(1)
- nodes_to_remove.append(input_data_node.id)
-
- graph.remove_nodes_from(nodes_to_remove)
diff --git a/tools/mo/openvino/tools/mo/middle/split_tdnn_memoryoffset.py b/tools/mo/openvino/tools/mo/middle/split_tdnn_memoryoffset.py
deleted file mode 100644
index f656f51e58d06d..00000000000000
--- a/tools/mo/openvino/tools/mo/middle/split_tdnn_memoryoffset.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-from openvino.tools.mo.ops.result import Result
-
-
-class SplitTdnnMemoryOffset(MiddleReplacementPattern):
- '''
- Splits MemoryOffsets in TDNN blocks into 2 parts. These parts then will be converted to ReadValue and Assign.
- '''
- enabled = True
- run_not_recursively = True
-
- def run_before(self):
- from openvino.tools.mo.middle.ReplaceMemoryOffsetWithSplice import ReplaceMemoryOffsetWithMemoryNodePattern, ReplaceMemoryOffsetNodePattern
- return [ReplaceMemoryOffsetNodePattern, ReplaceMemoryOffsetWithMemoryNodePattern]
-
- def find_and_replace_pattern(self, graph: Graph):
- for offset_node in graph.get_op_nodes(op='MemoryOffset', splitted=False):
- paired_node = MemoryOffset(graph, {'name': offset_node.pair_name, 'splitted': True, 'pair_name': offset_node.id,
- 't': offset_node.t, 'has_default': offset_node.has_default}).create_node()
- offset_node['splitted'] = True
- offset_node.out_port(0).get_connection().set_source(paired_node.out_port(0))
- res_node = Result(graph, {'name': offset_node.id + "_output"}).create_node()
- offset_node.out_port(0).connect(res_node.in_port(0))
-
- # If 'element_size' is previously copied from Parameter of from node with defined dim
- if offset_node.has_valid('element_size'):
- paired_node['element_size'] = offset_node['element_size']
- # Copy shape from previous node. Typically (but not always) for TDNN blocks this is the case
- else:
- paired_node['element_size'] = offset_node.in_port(0).data.get_shape()
diff --git a/tools/mo/openvino/tools/mo/mo.py b/tools/mo/openvino/tools/mo/mo.py
deleted file mode 100755
index f3b8e92ebfdd1f..00000000000000
--- a/tools/mo/openvino/tools/mo/mo.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
- init_mo_telemetry()
- from openvino.tools.mo.subprocess_main import subprocess_main # nosec; pylint: disable=no-name-in-module
- subprocess_main(framework=None)
diff --git a/tools/mo/openvino/tools/mo/mo_caffe.py b/tools/mo/openvino/tools/mo/mo_caffe.py
deleted file mode 100755
index fd05f686f78993..00000000000000
--- a/tools/mo/openvino/tools/mo/mo_caffe.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.subprocess_main import subprocess_main
- from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
- init_mo_telemetry()
- subprocess_main(framework='caffe')
diff --git a/tools/mo/openvino/tools/mo/mo_kaldi.py b/tools/mo/openvino/tools/mo/mo_kaldi.py
deleted file mode 100755
index abdda198dd43ed..00000000000000
--- a/tools/mo/openvino/tools/mo/mo_kaldi.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.subprocess_main import subprocess_main
- from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
- init_mo_telemetry()
- subprocess_main(framework='kaldi')
diff --git a/tools/mo/openvino/tools/mo/mo_onnx.py b/tools/mo/openvino/tools/mo/mo_onnx.py
deleted file mode 100755
index 04c058fc73ef83..00000000000000
--- a/tools/mo/openvino/tools/mo/mo_onnx.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.subprocess_main import subprocess_main
- from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
- init_mo_telemetry()
- subprocess_main(framework='onnx')
diff --git a/tools/mo/openvino/tools/mo/mo_paddle.py b/tools/mo/openvino/tools/mo/mo_paddle.py
deleted file mode 100755
index c6331e202a5ccd..00000000000000
--- a/tools/mo/openvino/tools/mo/mo_paddle.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-if __name__ == "__main__":
- from openvino.tools.mo.subprocess_main import subprocess_main
- from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
- init_mo_telemetry()
- subprocess_main(framework='paddle')
diff --git a/tools/mo/openvino/tools/mo/mo_tf.py b/tools/mo/openvino/tools/mo/mo_tf.py
deleted file mode 100755
index 9037b0930d91ca..00000000000000
--- a/tools/mo/openvino/tools/mo/mo_tf.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-if __name__ == "__main__":
- from openvino.tools.mo.subprocess_main import subprocess_main
- from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
- init_mo_telemetry()
- subprocess_main(framework='tf')
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/__init__.py b/tools/mo/openvino/tools/mo/moc_frontend/__init__.py
deleted file mode 100644
index 923d56d04145b6..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/analysis.py b/tools/mo/openvino/tools/mo/moc_frontend/analysis.py
deleted file mode 100644
index cc4d99ed79425e..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/analysis.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2022 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import json
-from openvino.runtime import PartialShape, Model, Type # pylint: disable=no-name-in-module,import-error
-from openvino.runtime.utils.types import get_dtype
-
-def json_model_analysis_dump(framework_model: Model):
-
- def dump_partial_shape(shape: PartialShape):
- if shape.rank.is_dynamic:
- return 'None'
- return [dim.get_length() if dim.is_static else 0 for dim in shape]
-
- def dump_element_type(ov_type: Type):
- try:
- return str(get_dtype(ov_type))
- except:
- return 'None'
-
- json_dump = {}
- json_dump['inputs'] = {}
- for param in framework_model.get_parameters():
- param_name = param.get_friendly_name()
- json_dump['inputs'][param_name] = {}
- json_dump['inputs'][param_name]['shape'] = dump_partial_shape(param.get_partial_shape())
- json_dump['inputs'][param_name]['data_type'] = dump_element_type(param.get_element_type())
- json_dump['inputs'][param_name]['value'] = 'None' # not supported in 22.1
-
- json_dump['intermediate'] = {}
- #TODO: extend model analysis dump for operations with body graphs (If, Loop, and TensorIterator)
- for op in filter(lambda node: node.type_info.name != "NullNode", framework_model.get_ordered_ops()):
- for out_idx in range(op.get_output_size()):
- output = op.output(out_idx)
- tensor_name = output.get_any_name()
- json_dump['intermediate'][tensor_name] = {}
- json_dump['intermediate'][tensor_name]['shape'] = dump_partial_shape(output.get_partial_shape())
- json_dump['intermediate'][tensor_name]['data_type'] = dump_element_type(output.get_element_type())
- json_dump['intermediate'][tensor_name]['value'] = 'None' # not supported in 22.1
-
- json_model_analysis_print(json_dump)
-
-
-def json_model_analysis_print(json_dump:str):
- print(json.dumps(json_dump))
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/check_config.py b/tools/mo/openvino/tools/mo/moc_frontend/check_config.py
deleted file mode 100644
index 8f9f6d67b7e223..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/check_config.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (C) 2022-2023 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-from pathlib import Path
-
-from openvino.tools.mo.utils.error import Error
-import os
-
-
-def default_path():
- EXT_DIR_NAME = '.'
- return os.path.abspath(os.getcwd().join(EXT_DIR_NAME))
-
-
-def any_extensions_used(argv: argparse.Namespace):
- # Checks that extensions are provided.
- # Allowed types are string containing path to legacy extension directory
- # or path to new extension .so file, or classes inherited from BaseExtension.
- if not hasattr(argv, 'extensions') or argv.extensions is None:
- return False
-
- if isinstance(argv.extensions, list) and len(argv.extensions) > 0:
- has_non_default_path = False
- has_non_str_objects = False
- for ext in argv.extensions:
- if not isinstance(ext, str):
- has_non_str_objects = True
- continue
- if len(ext) == 0 or ext == default_path():
- continue
- has_non_default_path = True
-
- return has_non_default_path or has_non_str_objects
-
- raise Exception("Expected list of extensions, got {}.".format(type(argv.extensions)))
-
-
-def legacy_extensions_used(argv: argparse.Namespace):
- if any_extensions_used(argv):
- extensions = argv.extensions
- legacy_ext_counter = 0
- for extension in extensions:
- if not isinstance(extension, str):
- continue
- if extension == default_path():
- continue
- if not Path(extension).is_file():
- legacy_ext_counter += 1
- if legacy_ext_counter == len(extensions):
- return True # provided only legacy extensions
- elif legacy_ext_counter == 0:
- return False # provided only new extensions
- else:
- raise Error('Using new and legacy extensions in the same time is forbidden')
- return False
-
-
-def new_extensions_used(argv: argparse.Namespace):
- if any_extensions_used(argv):
- extensions = argv.extensions
- if not isinstance(extensions, list):
- extensions = [extensions]
- new_ext_counter = 0
- for extension in extensions:
- if isinstance(extension, str):
- path = Path(extension)
- if path.is_file() and (path.suffix == '.so' or path.suffix == '.dll'):
- new_ext_counter += 1
- else:
- new_ext_counter += 1
- if new_ext_counter == len(extensions):
- return True # provided only new extensions
- elif new_ext_counter == 0:
- return False # provided only legacy extensions
- else:
- raise Error('Using new and legacy extensions in the same time is forbidden')
- return False
-
-
-def get_transformations_config_path(argv: argparse.Namespace) -> Path:
- if hasattr(argv, 'transformations_config') \
- and argv.transformations_config is not None and len(argv.transformations_config):
- if isinstance(argv.transformations_config, str):
- path = Path(argv.transformations_config)
- if path.is_file():
- return path
- return None
-
-
-def legacy_transformations_config_used(argv: argparse.Namespace):
- return get_transformations_config_path(argv) != None
-
-
-def tensorflow_custom_operations_config_update_used(argv: argparse.Namespace):
- return hasattr(argv, 'tensorflow_custom_operations_config_update') and \
- argv.tensorflow_custom_operations_config_update is not None
-
-
-def input_freezig_used(argv):
- return hasattr(argv, 'freeze_placeholder_with_value') and argv.freeze_placeholder_with_value is not None \
- and len(argv.freeze_placeholder_with_value) > 0
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/extractor.py b/tools/mo/openvino/tools/mo/moc_frontend/extractor.py
deleted file mode 100644
index 2dc05a812a9455..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/extractor.py
+++ /dev/null
@@ -1,461 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import re
-from enum import Enum
-
-import numpy as np
-from openvino._pyopenvino import Place, PartialShape # pylint: disable=no-name-in-module,import-error
-
-from openvino.frontend import InputModel # pylint: disable=no-name-in-module,import-error
-from openvino.tools.mo.utils.error import Error
-
-
-def raise_no_node(node_name: str):
- raise Error('No node with name {}'.format(node_name))
-
-
-def raise_node_name_collision(node_name: str, found_nodes: list):
- raise Error('Name collision was found, there are several nodes for mask "{}": {}. '
- 'If your intention was to specify port for node, please instead specify node names connected to '
- 'this port. If your intention was to specify the node name, please add port to the node '
- 'name'.format(node_name, found_nodes))
-
-
-class IOType(Enum):
- Input = 1
- Output = 2
-
-
-def decode_name_with_port(
- input_model: InputModel, node_name: str, framework="", io_type=IOType.Input
-) -> Place or None:
- """
- Decode name with optional port specification w/o traversing all the nodes in the graph
- TODO: in future node_name can specify input/output port groups as well as indices (58562)
- :param input_model: Input Model
- :param node_name: user provided node name
- :return: decoded place in the graph
- """
- found_places = []
- found_place_names = []
-
- def get_place_by_operation_name(input_model, name, framework, io_type):
- node = input_model.get_place_by_operation_name(name)
- if node and framework == "onnx":
- if io_type == IOType.Input:
- return (
- node.get_input_port(input_port_index=0)
- .get_producing_port()
- .get_target_tensor()
- )
- else:
- return node.get_output_port(output_port_index=0).get_target_tensor()
- return node
-
- # find by tensor name
- place = input_model.get_place_by_tensor_name(node_name)
- if place:
- found_place_names.append("Tensor:" + node_name)
- found_places.append(place)
- else:
- # find by operation name
- place = get_place_by_operation_name(input_model, node_name, framework, io_type)
- name = node_name
- if framework == "onnx" and io_type == IOType.Output:
- name = "Tensor:" + name
-
- if place:
- found_place_names.append(name)
- found_places.append(place)
-
- def try_get_node(model, name, framework):
- node = model.get_place_by_operation_name(name)
- if node:
- return node
- if framework == "onnx":
- tensor = model.get_place_by_tensor_name(name)
- if tensor:
- if tensor.is_input() or tensor.is_output():
- return tensor
- return tensor.get_producing_operation()
- return None
-
- def get_port(match, match_starts_with_name, input_model, framework):
- if not match:
- return None
-
- if match_starts_with_name:
- name = match.group(1)
- port_index = match.group(2)
- else:
- name = match.group(2)
- port_index = match.group(1)
-
- node = try_get_node(input_model, name, framework)
- if node:
- # if regular expression has structure :, get node output port.
- # Otherwise get node input port
- if match_starts_with_name:
- return node.get_output_port(output_port_index=int(port_index))
- else:
- return node.get_input_port(input_port_index=int(port_index))
- else:
- return None
-
- regexp_post = r"(.+):(\d+)"
- match = re.search(regexp_post, node_name)
- match_port = get_port(
- match=match,
- match_starts_with_name=True,
- input_model=input_model,
- framework=framework,
- )
-
- if match_port:
- name = match.group(1)
- if framework == "onnx":
- found_place_names.append("Tensor:" + name)
- found_places.append(match_port.get_target_tensor())
- else:
- found_place_names.append(name)
- found_places.append(match_port)
-
- regexp_pre = r"(\d+):(.+)"
- match = re.search(regexp_pre, node_name)
- match_port = get_port(
- match=match,
- match_starts_with_name=False,
- input_model=input_model,
- framework=framework,
- )
-
- if match_port:
- name = match.group(2)
- if framework == "onnx":
- found_place_names.append("Tensor:" + name)
- found_places.append(match_port.get_producing_port().get_target_tensor())
- else:
- found_places.append(match_port)
- found_place_names.append(name)
-
- if len(found_places) == 0:
- raise_no_node(node_name)
-
- # Check that there is no collision, all found places shall point to same data
- if not all([n.is_equal_data(found_places[0]) for n in found_places]):
- raise_node_name_collision(node_name, found_place_names)
-
- # TODO: Add support for input/output group name and port index here (58562)
- # For new frontends logic shall be extended to additionally support input and output group names
- return found_places[0]
-
-
-def fe_input_user_data_repack(
- input_model: InputModel,
- input_user_shapes: [None, list, dict, np.ndarray],
- freeze_placeholder: dict,
- framework: str,
- input_user_data_types=None,
-):
- """
- Restructures user input cutting request. Splits ports out of node names.
- Transforms node names to node ids.
- :param input_model: current input model
- :param input_user_shapes: data structure representing user input cutting request. It may be:
- # None value if user did not provide neither "input" nor "input_shape" keys
- # list instance which contains input layer names with or without ports if user provided
- only "input" key
- # dict instance which contains input layer names with or without ports as keys and shapes as
- values if user provided both "input" and "input_shape"
- # np.ndarray if user provided only "input_shape" key
- :param freeze_placeholder: dictionary with placeholder names as keys and freezing value as values
- :param input_user_data_types: dictionary with input nodes and its data types
- :return: restructured input shapes and freeze placeholder shapes information
- Example of input dictionary:
- _input_shapes =
- {
- 'node_ID':
- [
- {'shape': None, 'in': 0},
- {'shape': None, 'in': 1},
- ],
- 'node_1_ID':
- [
- {'shape': [1, 227, 227, 3], 'port': None, 'data_type': np.int32}
- ],
- 'node_2_ID':
- [
- {'shape': None, 'out': 3}
- ]
- }
- Example of freeze placeholder dictionary:
- _freeze_placeholder =
- {
- 'phase_train' : False
- }
- """
- _input_shapes = []
- _input_names = []
- model_inputs = input_model.get_inputs()
-
- if isinstance(input_user_shapes, list) and len(input_user_shapes) > 1 and isinstance(input_user_shapes[0],
- PartialShape):
- for shape in input_user_shapes:
- assert isinstance(shape, PartialShape), "Got incorrect format of input shapes."
- assert len(model_inputs) == len(input_user_shapes)
- for idx, model_input in enumerate(model_inputs):
- _input_shapes.append({"node": model_input, "shape": input_user_shapes[idx]})
- elif isinstance(input_user_shapes, list) or isinstance(input_user_shapes, dict):
- for input_name in input_user_shapes:
- node = decode_name_with_port(
- input_model, input_name, framework, IOType.Input
- )
- if node is None:
- raise Error(
- "Cannot find location {} in the input model".format(input_name)
- )
- shape = (
- None
- if isinstance(input_user_shapes, list)
- else input_user_shapes[input_name]
- )
- if isinstance(input_user_data_types, dict) and input_user_data_types.get(input_name) is not None:
- data_type = input_user_data_types[input_name]
- _input_shapes.append(
- {
- "node": node,
- "shape": shape,
- "data_type": data_type,
- "input_name": input_name,
- }
- )
- else:
- _input_shapes.append(
- {
- "node": node,
- "shape": shape,
- "input_name": input_name
- }
- )
- _input_names.append(input_name)
- elif isinstance(input_user_shapes, PartialShape):
- # this branch covers the single use of `input_shape` without `input` option
- # but it can be used along with `freeze_placeholder_with_value` option
- # for example, input_shape [3] freeze_placeholder_with_value "is_training->False"
- # means the model has two inputs: one is is_training to be frozen, the other to re-write the shape
- # NOTE: the logic relies on parameters with the single name
- frozen_names = freeze_placeholder.keys()
- assert len(model_inputs) == len(frozen_names) + 1, \
- "Please check the conversion command-line. Total number of model inputs ({} detected) " \
- "must match to a number of input shapes along with frozen inputs ({} in total).".format(
- len(model_inputs),
- len(frozen_names) + 1)
- for node in model_inputs:
- assert len(node.get_names()) > 0, "Original model inputs must have tensor names."
- input_name = node.get_names()[0]
- if input_name not in frozen_names:
- _input_shapes.append(
- {
- "node": node,
- "shape": input_user_shapes,
- "input_name": input_name
- }
- )
- # case when single unnamed input shape and type was specified
- if input_name in input_user_data_types:
- _input_shapes[-1]['data_type'] = input_user_data_types[input_name]
- _input_names.append(input_name)
- break
- else:
- # this case means that we use original inputs of the model
- # and they should not be changed and their properties (shape and type) should not be over-written
- # NOTE: the logic relies on parameters with the single name
- assert input_user_shapes is None
- for node in model_inputs:
- assert len(node.get_names()) > 0, "Original model inputs must have tensor names."
- input_name = node.get_names()[0]
- _input_shapes.append(
- {
- "node": node,
- "input_name": input_name
- }
- )
- # case when types were specified for unnamed inputs
- if input_name in input_user_data_types:
- _input_shapes[-1]['data_type'] = input_user_data_types[input_name]
- # mark-up Place names we already put into the _input_names
- # to avoid duplicates in updates by freeze_placeholder below
- _input_names.append(input_name)
-
- if freeze_placeholder:
- # in case freezing via freeze_placeholder_with_value option, _input_shapes can miss some frozen places
- for input_name in freeze_placeholder:
- if input_name in _input_names or input_name + ":0" in _input_names:
- continue
- node = decode_name_with_port(
- input_model, input_name, framework, IOType.Input
- )
- _input_shapes.append(
- {
- "node": node,
- "input_name": input_name
- }
- )
- return _input_shapes, freeze_placeholder
- return _input_shapes, dict()
-
-
-def fe_output_user_data_repack(input_model: InputModel, outputs: list, framework: str):
- """
-
- :param input_model: Input Model to operate on
- :param outputs: list of node names provided by user
- :return: dictionary with node IDs as keys and list of port dictionaries as values
- Example of outputs dictionary:
- _outputs =
- {
- 'node_ID':
- [
- {'out': 0},
- {'out': 1},
- ],
- 'node_1_ID':
- [
- {'port': None}
- ],
- 'node_2_ID':
- [
- {'in': 3}
- ]
- }
- """
- _outputs = []
- if outputs is not None:
- for output in outputs:
- node = decode_name_with_port(input_model, output, framework, IOType.Output)
- if node is None:
- raise Error("Cannot find location {} in the graph".format(output))
- _outputs.append({"node": node})
- return _outputs
-
-
-def find_first_unused_input(model_inputs: list, freeze_placeholder: dict, param_dict: dict, param_name: str):
- """
- Finds first input in model_inputs, which is not present in freeze_placeholder dictionary or param_dict.
-
- :param model_inputs: list of model inputs
- :param freeze_placeholder: dictionary where key is input name, value is input value for freezing.
- :param param_dict: dictionary where key is input name, value is parameter value (shape or type).
- :param param_name: name of parameter used in exception message.
-
- :return: first input name, which is not present in freeze_placeholder dictionary or param_dict.
- """
- for inp in model_inputs:
- input_names = inp.get_names()
- name_found = False
- for input_name in input_names:
- if input_name in freeze_placeholder or input_name in param_dict:
- name_found = True
- break
- if name_found:
- continue
- return input_names[0]
- raise Error("Could not set {}, as model does not have enough inputs.".format(param_name))
-
-
-def convert_params_lists_to_dicts(input_model,
- input_user_shapes: [list, dict],
- input_user_data_types: [list, dict],
- freeze_placeholder: dict,
- unnamed_freeze_placeholders: list):
- """
- Convert lists of unnamed params to dicts using input names from input_model.
-
- :param input_model: openvino.runtime.InputModel
- :param input_user_shapes: list of input shapes or dictionary where key is input name, value is input shape from user.
- :param input_user_data_types: list of input types or dictionary where key is input name, value is input type from user.
- :param freeze_placeholder: dictionary where key is input name, value is input value from user.
- :param unnamed_freeze_placeholders: list of unnamed input values from user.
-
- :return: (input_user_shapes_dict, input_user_data_types_dict, freeze_placeholder), where
- input_user_shapes_dict - dictionary where key is input name, value is shape from user;
- input_user_data_types_dict - dictionary where key is input name, value is type from user;
- freeze_placeholder - dictionary where key is input name, value is input value from user;
- """
- from openvino.runtime import PartialShape
- model_inputs = input_model.get_inputs()
- input_user_data_types_dict = {}
- input_user_shapes_dict = {}
-
- # input_user_shapes is list only if unnamed inputs were used
- if isinstance(input_user_shapes, list):
-
- # this cycle adds each unnamed shape to dictionary using name from model_inputs
- for idx, shape in enumerate(input_user_shapes):
- assert isinstance(shape, PartialShape), "Got incorrect format of input shapes {}.".format(type(shape))
-
- inp_name = find_first_unused_input(model_inputs, freeze_placeholder, input_user_shapes_dict, "shape")
- input_user_shapes_dict[inp_name] = shape
- else:
- input_user_shapes_dict = input_user_shapes
-
- # input_user_data_types is list only if unnamed inputs were used
- if isinstance(input_user_data_types, list):
- from openvino.runtime import Type
-
- if input_user_shapes_dict is None:
- input_user_shapes_dict = {}
-
- # this cycle adds each unnamed type to dictionary using name from model_inputs
- for idx, node_type in enumerate(input_user_data_types):
- assert isinstance(node_type, (type, np.dtype, Type)), "Got incorrect format of input types. " \
- "Expected numpy type or openvino.runtime.Type, " \
- "got {}.".format(type(node_type))
-
- inp_name = find_first_unused_input(model_inputs, freeze_placeholder, input_user_data_types_dict, "type")
- input_user_data_types_dict[inp_name] = node_type
- # FE postprocessing expects input_user_shapes_dict to always have shapes for corresponding types.
- # If shape is not set it is expected to have None shape in input_user_shapes_dict dictionary.
- if inp_name not in input_user_shapes_dict:
- input_user_shapes_dict[inp_name] = None
- else:
- input_user_data_types_dict = input_user_data_types
-
- # unnamed_freeze_placeholders is always list, it is not empty only if unnamed inputs were used.
- for value in unnamed_freeze_placeholders:
- assert isinstance(value, list), "Got incorrect format of input values. " \
- "Expected list, " \
- "got {}.".format(type(value))
- inp_name = find_first_unused_input(model_inputs, freeze_placeholder, {}, "input value")
- freeze_placeholder[inp_name] = value
-
- return input_user_shapes_dict, input_user_data_types_dict, freeze_placeholder
-
-
-def fe_user_data_repack(
- input_model: InputModel,
- input_user_shapes: [None, list, dict, np.array],
- input_user_data_types: dict,
- outputs: list,
- freeze_placeholder: dict,
- framework: str,
-):
- """
- :param input_model: Input Model to operate on
- :param input_user_shapes: data structure representing user input cutting request
- :param input_user_data_types: dictionary with input nodes and its data types
- :param outputs: list of node names to treat as outputs
- :param freeze_placeholder: dictionary with placeholder names as keys and freezing value as values
- :return: restructured input, output and freeze placeholder dictionaries or None values
- """
- _input_shapes, _freeze_placeholder = fe_input_user_data_repack(
- input_model,
- input_user_shapes,
- freeze_placeholder,
- framework,
- input_user_data_types=input_user_data_types,
- )
- _outputs = fe_output_user_data_repack(input_model, outputs, framework)
-
- return _input_shapes, _outputs, _freeze_placeholder
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/layout_utils.py b/tools/mo/openvino/tools/mo/moc_frontend/layout_utils.py
deleted file mode 100644
index 0dd0e4d820efba..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/layout_utils.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from typing import Callable
-
-from openvino.runtime import PartialShape # pylint: disable=no-name-in-module,import-error
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-def update_layout_to_dict(inputs: list, layout: [list, dict], get_names_func: Callable):
- """
- The function prepares layout values in the dictionary with items of the format:
- { node_name : {'source_layout': 'NHWC', 'target_layout': 'NCHW'} }
- """
- if isinstance(layout, dict):
- if '' in layout:
- input_names = [list(get_names_func(cur_input))[0] for cur_input in inputs]
- if len(input_names) > 1:
- raise Error('Layout without name can be specified for models with only one input, '
- 'but provided model has {} inputs: \'{}\'. '
- 'Please specify explicitly input/output name for "layout" option'
- .format(len(input_names), input_names))
- layout = {
- input_names[0]: {
- 'source_layout': layout[''].get('source_layout'),
- 'target_layout': layout[''].get('target_layout')
- }
- }
- return layout
- if isinstance(layout, list):
- if len(layout) != len(inputs):
- raise Error('Numbers of inputs and layout values do not match. ' + refer_to_faq_msg(61))
- layout_dict = {}
- for idx, cur_input in enumerate(inputs):
- names_list = list(get_names_func(cur_input))
- assert len(names_list) > 0, "No names for input"
- node_name = names_list[0]
- layout_dict.update(
- {
- node_name: layout[idx]
- }
- )
- return layout_dict
- raise Error("Unknown layout type. Expected dict, list. Got {}".format(type(layout)))
-
-
-def get_dimension_index_by_label(input_shape: PartialShape, input_names: list, layout_dict: [dict],
- dimension_label: str, default_dim: int):
- """
- The function returns index of the dimension pointed in the layout
- and a flag indicating if the index is chosen by default.
- For example, the index for 'D' dimension in "NHWDC" layout is 3.
- """
- if input_shape.rank.is_static and input_shape.rank.get_length() == 0:
- # in case a scalar, batch dimension is not defined
- return None, False
-
- # search for the corresponding layout
- for name, layout_value in layout_dict.items():
- if name in input_names:
- layout = layout_value.get('source_layout', None)
- if layout is None:
- return default_dim, True
- from openvino.runtime import Layout # pylint: disable=no-name-in-module,import-error
- layout_parsed = Layout(layout)
- if layout_parsed.has_name(dimension_label):
- return layout_parsed.get_index_by_name(dimension_label), False
- else:
- # if the layout is specified and the required dimension label is not found, the batch is unknown
- return None, False
-
- return default_dim, True
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/moc_emit_ir.py b/tools/mo/openvino/tools/mo/moc_frontend/moc_emit_ir.py
deleted file mode 100644
index 51b9b727c7a04b..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/moc_emit_ir.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-
-from openvino.runtime import Model # pylint: disable=no-name-in-module,import-error
-from openvino.tools.mo.utils.cli_parser import parse_transform
-from openvino.tools.mo.back.preprocessing import apply_preprocessing
-
-
-def moc_emit_ir(ngraph_function: Model, argv: argparse.Namespace):
-
- # Apply preprocessing (mean/scale/reverse_channels/convert_layout/etc)
- apply_preprocessing(ov_function=ngraph_function, argv=argv)
-
- # Apply transformations
- from openvino.tools.mo.back.offline_transformations import apply_user_transformations, \
- apply_moc_legacy_transformations, apply_fused_names_cleanup
-
- from openvino._offline_transformations import apply_moc_transformations # pylint: disable=import-error,no-name-in-module
- apply_moc_transformations(ngraph_function, cf=argv.static_shape, smart_reshape=True)
-
- from openvino._offline_transformations import compress_quantize_weights_transformation # pylint: disable=no-name-in-module,import-error
- compress_quantize_weights_transformation(ngraph_function)
-
- if argv.framework == "onnx":
- # set OldApi map in IR to be executed via OV API 1.x and for parity with legacy MO
- params_with_custom_types = [] if argv.placeholder_data_types is None \
- else list(argv.placeholder_data_types.keys())
- apply_moc_legacy_transformations(ngraph_function, params_with_custom_types)
-
- apply_user_transformations(ngraph_function, parse_transform(argv.transform))
-
- if argv.compress_to_fp16:
- from openvino.tools.mo.back.offline_transformations import compress_model
- compress_model(ngraph_function)
-
- apply_fused_names_cleanup(ngraph_function)
-
- del argv.feManager
- return ngraph_function
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/paddle_frontend_utils.py b/tools/mo/openvino/tools/mo/moc_frontend/paddle_frontend_utils.py
deleted file mode 100644
index def49590632e9c..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/paddle_frontend_utils.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import sys
-import tempfile
-
-
-class paddle_frontend_converter:
- def __init__(self, model, inputs=None, outputs=None):
- self.model = model
- self.inputs = inputs
- self.outputs = outputs
- self.tmp = None
- self.model_name = None
- self.pdmodel = None
- self.pdiparams = None
- self.pdiparams_info = None
- self.is_generated = False
-
- def destroy(self):
- # close tmp file
- if isinstance(self.tmp, tempfile._TemporaryFileWrapper):
- self.tmp.close()
-
- # remove the *.pdmodel
- if os.path.exists(self.pdmodel):
- os.remove(self.pdmodel)
-
- # remove the *.pdiparams
- if os.path.exists(self.pdiparams):
- os.remove(self.pdiparams)
-
- # remove the *.pdiparams.info
- if os.path.exists(self.pdiparams_info):
- os.remove(self.pdiparams_info)
-
- def convert_paddle_to_pdmodel(self):
- '''
- There are three paddle model categories:
- - High Level API: is a wrapper for dynamic or static model, use `self.save` to serialize
- - Dynamic Model: use `paddle.jit.save` to serialize
- - Static Model: use `paddle.static.save_inference_model` to serialize
- '''
- try:
- self.tmp = tempfile.NamedTemporaryFile(delete=True)
- self.model_name = self.tmp.name
- self.pdmodel = "{}.pdmodel".format(self.model_name)
- self.pdiparams = "{}.pdiparams".format(self.model_name)
- self.pdiparams_info = "{}.pdiparams.info".format(self.model_name)
-
- import paddle # pylint: disable=import-error
- if isinstance(self.model, paddle.hapi.model.Model):
- self.model.save(self.model_name, False)
- else:
- if self.inputs is None:
- raise RuntimeError(
- "Saving inference model needs 'inputs' before saving. Please specify 'example_input'"
- )
- if isinstance(self.model, paddle.fluid.dygraph.layers.Layer):
- with paddle.fluid.framework._dygraph_guard(None):
- paddle.jit.save(self.model, self.model_name, input_spec=self.inputs, output_spec=self.outputs)
- elif isinstance(self.model, paddle.fluid.executor.Executor):
- if self.outputs is None:
- raise RuntimeError(
- "Model is static. Saving inference model needs 'outputs' before saving. Please specify 'example_output' for this model"
- )
- paddle.static.save_inference_model(self.model_name, self.inputs, self.outputs, self.model)
- else:
- raise RuntimeError(
- "Conversion just support paddle.hapi.model.Model, paddle.fluid.dygraph.layers.Layer and paddle.fluid.executor.Executor"
- )
-
- if not os.path.exists(self.pdmodel):
- print("Failed generating paddle inference format model")
- sys.exit(1)
-
- self.is_generated = True
- return self.pdmodel
- finally:
- # close tmp file
- if isinstance(self.tmp, tempfile._TemporaryFileWrapper):
- self.tmp.close()
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/pipeline.py b/tools/mo/openvino/tools/mo/moc_frontend/pipeline.py
deleted file mode 100644
index 49ab0770043f5e..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/pipeline.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import logging as log
-import sys
-from copy import copy
-from typing import List
-
-import numpy as np
-import os
-
-from openvino.frontend import FrontEnd, InputModel, NotImplementedFailure, \
- Place # pylint: disable=no-name-in-module,import-error
-from openvino.runtime import PartialShape, Type # pylint: disable=no-name-in-module,import-error
-from openvino.runtime.utils.types import get_element_type, \
- get_numpy_ctype # pylint: disable=no-name-in-module,import-error
-from openvino.tools.mo.moc_frontend.analysis import json_model_analysis_dump
-from openvino.tools.mo.moc_frontend.extractor import fe_user_data_repack, convert_params_lists_to_dicts, fe_output_user_data_repack
-from openvino.tools.mo.moc_frontend.layout_utils import update_layout_to_dict, get_dimension_index_by_label
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.type_utils import np_map_cast
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.middle.passes.infer import validate_batch_in_shape
-
-
-def get_enabled_and_disabled_transforms():
- """
- :return: tuple of lists with force enabled and disabled id of transformations.
- """
- disabled_transforms = os.environ['MO_DISABLED_TRANSFORMS'] if 'MO_DISABLED_TRANSFORMS' in os.environ else ''
- enabled_transforms = os.environ['MO_ENABLED_TRANSFORMS'] if 'MO_ENABLED_TRANSFORMS' in os.environ else ''
-
- assert isinstance(enabled_transforms, str)
- assert isinstance(disabled_transforms, str)
-
- disabled_transforms = disabled_transforms.split(',')
- enabled_transforms = enabled_transforms.split(',')
-
- return enabled_transforms, disabled_transforms
-
-
-def moc_pipeline(argv: argparse.Namespace, moc_front_end: FrontEnd):
- """
- Load input model and convert it to nGraph function
- :param: argv: parsed command line arguments
- :param: moc_front_end: Loaded Frontend for converting input model
- :return: converted nGraph function ready for serialization
- """
- input_checkpoint = getattr(argv, 'input_checkpoint', None)
- share_weights = getattr(argv, 'share_weights', True)
- if argv.input_model and input_checkpoint:
- # frozen format with v1 checkpoints
- input_model = moc_front_end.load([argv.input_model, argv.input_checkpoint], share_weights)
- elif argv.input_model:
- input_model = moc_front_end.load(argv.input_model, share_weights)
- elif argv.saved_model_dir:
- if argv.saved_model_tags:
- input_model = moc_front_end.load([argv.saved_model_dir, argv.saved_model_tags], share_weights)
- else:
- input_model = moc_front_end.load(argv.saved_model_dir, share_weights)
- elif argv.input_meta_graph:
- input_model = moc_front_end.load(argv.input_meta_graph, share_weights)
- if argv.output:
- # Simulate original behavior with freezing model
- # While freezing we do a cutting of model, to keep similar behavior we
- # need to simulate similar behavior with natively supported model
- outputs = fe_output_user_data_repack(input_model, argv.output, moc_front_end.get_name())
- input_model.override_all_outputs([x['node'] for x in outputs])
-
- argv.placeholder_shapes, argv.placeholder_data_types, argv.freeze_placeholder_with_value = convert_params_lists_to_dicts(
- input_model, argv.placeholder_shapes, argv.placeholder_data_types,
- argv.freeze_placeholder_with_value, argv.unnamed_freeze_placeholder_with_value)
-
- user_shapes, outputs, freeze_placeholder = fe_user_data_repack(
- input_model, argv.placeholder_shapes, argv.placeholder_data_types,
- argv.output, argv.freeze_placeholder_with_value, moc_front_end.get_name())
-
- def check_places_are_same(places_original: List[Place], places_new: List[Place]):
- """
- Check if set of new places is same as original or not.
- :param places_original: List[Place] Original model places
- :param places_new: List[Place] New list of places
- :return: True if new list of places is same as original
- """
- return len(places_original) == len(places_new) and len(
- [item for item in places_original if any(
- [item.is_equal(item2['node']) for item2 in places_new])]) == len(places_original)
-
- def add_names_to_tensors(model: InputModel, places: List[Place]):
- """
- Adds additional names to some model input tensors. This helper should be used
- when a model modification is going to happen.
- :param model The input model loaded by a given frontend
- :param places An object containing Places and names that will be used for model modification
- """
- for new_input in places:
- if 'input_name' not in new_input:
- continue
- try:
- model.add_name_for_tensor(new_input['node'], new_input['input_name'])
- except NotImplementedFailure as e:
- # some frontends might not implement this method
- log.warning('Could not add an additional name to a tensor pointed to by \'{}\'. Details: {}'.format(
- new_input['input_name'], str(e)))
-
- enabled_transforms, disabled_transforms = get_enabled_and_disabled_transforms()
- if 'ANALYSIS_JSON_PRINT' in enabled_transforms:
- # NOTE that model analysis is performed before applying user's settings (inputs's shapes etc.)
- framework_model = moc_front_end.decode(input_model)
- json_model_analysis_dump(framework_model)
- # a model is not processed further in json analysis mode
- sys.exit(0)
-
- model_inputs = input_model.get_inputs()
- inputs_equal = True
- if user_shapes:
- inputs_equal = check_places_are_same(model_inputs, user_shapes)
-
- outputs_equal = True
- if outputs:
- outputs_equal = check_places_are_same(input_model.get_outputs(), outputs)
- log.debug('Inputs are same: {}, outputs are same: {}'.format(
- inputs_equal, outputs_equal))
-
- def create_target_input_shapes(new_input_places):
- if isinstance(new_input_places, list) and len(new_input_places) > 1 \
- and isinstance(new_input_places[0], tuple):
- return new_input_places
- new_input_place_names = [x.get_names()[0] for x in new_input_places]
- shapes = [shape for shape in argv.placeholder_shapes.values()]
- return dict(zip(new_input_place_names, shapes))
-
- if not inputs_equal and not outputs_equal:
- log.debug('Using extract subgraph')
- new_input_places = [x['node'] for x in user_shapes]
- new_output_places = [x['node'] for x in outputs]
- add_names_to_tensors(input_model, user_shapes)
- input_model.extract_subgraph(new_input_places, new_output_places)
- # invalidation of existing Place objects could have happened in the operation above
- if user_shapes:
- placeholder_shapes = create_target_input_shapes(new_input_places)
- new_output_places_name = [x.get_names()[0] for x in new_output_places]
-
- user_shapes, outputs, _ = fe_user_data_repack(
- input_model, placeholder_shapes, argv.placeholder_data_types,
- new_output_places_name, argv.freeze_placeholder_with_value, moc_front_end.get_name())
- elif not inputs_equal:
- log.debug('Using override_all_inputs')
- add_names_to_tensors(input_model, user_shapes)
- new_input_places = [x['node'] for x in user_shapes]
- input_model.override_all_inputs(new_input_places)
- # invalidation of existing Place objects could have happened in the operation above
- if user_shapes:
- placeholder_shapes = create_target_input_shapes(new_input_places)
-
- user_shapes, outputs, _ = fe_user_data_repack(
- input_model, placeholder_shapes, argv.placeholder_data_types,
- argv.output, argv.freeze_placeholder_with_value, moc_front_end.get_name())
- elif not outputs_equal:
- log.debug('Using override_all_outputs')
- add_names_to_tensors(input_model, user_shapes)
- new_output_places = [x['node'] for x in outputs]
- input_model.override_all_outputs(new_output_places)
- # invalidation of existing Place objects could have happened in the operation above
- if user_shapes:
- model_inputs = input_model.get_inputs()
-
- if user_shapes:
- for user_shape in user_shapes:
- if user_shape.get('shape') is not None:
- input_model.set_partial_shape(
- user_shape['node'], user_shape['shape'])
- if user_shape.get('data_type') is not None:
- data_type = get_element_type(user_shape['data_type'])
- log.debug('Set data type: {}'.format(data_type))
- input_model.set_element_type(user_shape['node'], data_type)
-
- if freeze_placeholder:
- for name, value in freeze_placeholder.items():
- node = None
- # look for the certain place in user_shapes
- for node_cur in user_shapes:
- if node_cur.get('input_name') == name or node_cur.get('input_name') == name + ":0":
- node = node_cur
- break
- if node is None:
- raise Error("Please check correctness of the command-line. "
- "Place (operation or tensor) with name {} is not found.".format(name))
- place = node.get('node')
-
- if node.get('data_type'):
- dtype = node['data_type']
- ov_type = Type(dtype)
- else:
- # we need to detect type of Placeholder
- try:
- ov_type = input_model.get_element_type(place)
- except NotImplementedFailure:
- raise Error("Please specify type for value freezing {} node explicitly "
- "because the frontend does not support automatic type detection.".format(name))
- # in case of cutting graph (or using custom inputs) and unspecified or dynamic type,
- # the default type is fp32
- if ov_type == Type.undefined or ov_type == Type.dynamic:
- ov_type = Type.f32
- dtype = get_numpy_ctype(ov_type)
-
- input_model.set_element_type(place, ov_type)
- # prepare and cast value to dtype
- if isinstance(value, list):
- casted_list = list()
- for v in mo_array(value):
- casted_list.append(np_map_cast[dtype](v))
- value = mo_array(casted_list, dtype=dtype)
- else:
- value = np_map_cast[dtype](value)
- value = np.array(value, dtype=dtype)
-
- ov_shape = input_model.get_partial_shape(place)
- if node.get('shape'):
- # set user defined shape
- ov_shape = PartialShape(node['shape'])
- input_model.set_partial_shape(place, ov_shape)
- elif ov_shape.is_dynamic:
- # in case of dynamic shape (dynamic rank or dynamic dimension)
- # deduce it based on the value shape and set it
- ov_shape = PartialShape(value.shape)
- input_model.set_partial_shape(place, ov_shape)
-
- input_model.set_tensor_value(place, value)
-
- def shape_to_array(shape: PartialShape):
- return [shape.get_dimension(i) for i in range(shape.rank.get_length())]
-
- # obtain layout for all inputs
- layout_values = {}
- if 'layout_values' in argv and argv.layout_values:
- layout_values = update_layout_to_dict(model_inputs, argv.layout_values,
- lambda input_place: input_place.get_names())
-
- deferred_batch_names = []
- # set batch size for inputs with a static rank
- # for all other inputs, set it after shape deduction is performed during model conversion
- if argv.batch is not None and argv.batch > 0:
- log.debug('Setting batch size to {}'.format(argv.batch))
- frozen_input_names = list(freeze_placeholder.keys()) if freeze_placeholder else []
- for place in model_inputs:
- input_partial_shape = input_model.get_partial_shape(place)
- input_names = place.get_names()
- joined_name = ' '.join(place.get_names())
- assert len(input_names) > 0, "One input place has no names"
-
- # if this input is frozen, there is no need to set the batch
- is_frozen_input = len([name for name in input_names if name in frozen_input_names]) > 0
- if is_frozen_input:
- # skip the frozen input
- continue
-
- if not input_partial_shape.rank.is_static:
- # found input with dynamic rank, so have to repeat the batch setting after the model conversion
- deferred_batch_names += input_names
- continue
-
- batch_dim, is_default_index = get_dimension_index_by_label(input_partial_shape,
- place.get_names(), layout_values, 'N', 0)
- if batch_dim is None:
- # skip because no batch dimension exists in the input
- continue
-
- if is_default_index:
- # if the batch index is chosen by default, we need to ensure that its size equals -1, 0 or 1
- validate_batch_in_shape(shape_to_array(input_partial_shape), joined_name)
-
- assert batch_dim < input_partial_shape.rank.get_length(), \
- "Incorrect layout is specified for {}:" \
- " index of the batch dimension is out of range.".format(input_names[0])
-
- new_partial_shape = copy(input_partial_shape)
- new_partial_shape[batch_dim] = argv.batch
-
- log.debug('Input: {}, Old shape: {}, New shape: {}'.format(
- joined_name, input_partial_shape, new_partial_shape))
- input_model.set_partial_shape(place, new_partial_shape)
-
- ov_model = moc_front_end.convert(input_model)
-
- if argv.batch is not None and argv.batch > 0 and len(deferred_batch_names) > 0:
- # Frontend convert method can include reverse infer functionality that can deduce undefined input shapes
- # so try to repeat batch setting again
- reshape_dict = {}
- log.debug('Deferred batch setting to size {}'.format(argv.batch))
- is_batch_clarified = False
- for model_input in ov_model.inputs:
- input_name = model_input.any_name
- input_partial_shape = model_input.get_partial_shape()
- if input_name in deferred_batch_names and input_partial_shape.rank.is_static:
- # update input shape with the specified batch for input that originally has dynamic rank
- batch_dim, is_default_index = get_dimension_index_by_label(input_partial_shape,
- model_input.get_names(),
- layout_values, 'N', 0)
- if batch_dim is None:
- continue
-
- if is_default_index:
- # if the batch index is chosen by default, we need to ensure that its size equals -1, 0 or 1
- validate_batch_in_shape(shape_to_array(input_partial_shape), input_name)
-
- assert batch_dim < input_partial_shape.rank.get_length(), \
- "Incorrect layout is specified for {}: " \
- "index of the batch dimension is out of range.".format(input_name)
- input_partial_shape[batch_dim] = argv.batch
- is_batch_clarified = True
-
- reshape_dict.update({input_name: input_partial_shape})
-
- if is_batch_clarified:
- # call reshape only if batch dimension for one of the input is clarified
- ov_model.reshape(reshape_dict)
-
- return ov_model
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py b/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py
deleted file mode 100644
index f2f7096f1b7033..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/pytorch_frontend_utils.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import sys
-
-import numpy as np
-# pylint: disable=no-name-in-module,import-error
-from openvino.runtime import Tensor, PartialShape
-
-from openvino.tools.mo.utils.error import Error
-
-
-def get_pytorch_decoder(model, input_shape, example_inputs, args):
- try:
- from openvino.frontend.pytorch.ts_decoder import TorchScriptPythonDecoder
- except Exception as e:
- log.error("PyTorch frontend loading failed")
- raise e
- if 'nncf' in sys.modules:
- is_good_version = True
- try:
- from nncf.torch.nncf_network import NNCFNetwork
-
- if isinstance(model, NNCFNetwork):
- from packaging import version
- if version.parse(sys.modules['nncf'].__version__) < version.parse("2.6"):
- is_good_version = False
- except:
- pass
- if not is_good_version:
- raise RuntimeError(
- "NNCF models produced by nncf<2.6 are not supported directly. Please upgrade nncf or export to ONNX first.")
- inputs = prepare_torch_inputs(example_inputs)
- if not isinstance(model, TorchScriptPythonDecoder):
- decoder = TorchScriptPythonDecoder(model, example_input=inputs, shared_memory=args.get("share_weights", True))
- else:
- decoder = model
- args['input_model'] = decoder
- args["framework"] = "pytorch"
- args["example_input"] = inputs
-
- return args
-
-
-def update_list_or_dict(container, name, idx, value):
- if isinstance(container, dict):
- if name is None:
- name = list(container)[idx]
- container[name] = value
- return
- if idx == len(container):
- container.append(value)
- elif idx > len(container):
- raise Error(f"Wrong {idx}")
- else:
- container[idx] = value
- return
-
-
-def get_value_from_list_or_dict(container, name, idx):
- if isinstance(container, dict):
- if name is None:
- if idx < len(container):
- name = list(container)[idx]
- return None
- return container.get(name)
- if idx < len(container):
- return container[idx]
- return None
-
-
-def extract_input_info_from_example(args, inputs):
- try:
- from openvino.frontend.pytorch.utils import pt_to_ov_type_map # pylint: disable=no-name-in-module,import-error
- except Exception as e:
- log.error("PyTorch frontend loading failed")
- raise e
- example_inputs = args.example_input
- data_types = args.placeholder_data_types or {}
- input_shapes = args.placeholder_shapes or {}
- is_dict_input = isinstance(example_inputs, dict)
- list_inputs = list(example_inputs.values()) if is_dict_input else example_inputs
- input_names = None
- if not isinstance(example_inputs, (list, tuple, dict)):
- list_inputs = [list_inputs]
- if args.input_model._input_is_list:
- list_inputs[0] = list_inputs[0].unsqueeze(0)
- if args.input_model._input_signature is not None and not is_dict_input:
- input_names = args.input_model._input_signature[1:] if args.input_model._input_signature[0] == "self" else args.input_model._input_signature
- if not is_dict_input:
- example_inputs = dict(zip(input_names, list_inputs))
- is_dict_input = True
- elif is_dict_input:
- input_names = list(example_inputs)
- if not data_types and input_names is None:
- data_types = []
- if not input_shapes and input_names is None:
- input_shapes = []
- if inputs:
- for input_id, input_info in enumerate(inputs):
- input_name = input_info.name
- if is_dict_input and input_name in example_inputs:
- example_input = example_inputs[input_name]
- else:
- example_input = list_inputs[input_id]
- if is_dict_input and input_name is None:
- input_name = input_names[input_id]
- dtype = getattr(example_input, "dtype", type(example_input))
- example_dtype = pt_to_ov_type_map.get(str(dtype))
- user_dtype = get_value_from_list_or_dict(data_types, input_name, input_id)
- if user_dtype is not None and example_dtype is not None and example_dtype.to_dtype() != user_dtype:
- raise Error(f"Defined input type {user_dtype} is not equal to provided example_input type {example_dtype.to_dtype()}")
-
- data_rank = getattr(example_input, "ndim", 0)
- user_input_shape = get_value_from_list_or_dict(input_shapes, input_name, input_id)
- if user_input_shape.rank.is_static and user_input_shape.rank.get_length() != data_rank:
- raise Error(
- f"Requested input shape {user_input_shape.rank.get_length()} rank"
- f" is not equal to provided example_input rank {data_rank}")
-
- input_shape = user_input_shape if user_input_shape is not None else PartialShape([-1] * data_rank)
- update_list_or_dict(data_types, input_name, input_id, example_dtype.to_dtype() if example_dtype is not None else None)
- update_list_or_dict(input_shapes, input_name, input_id, input_shape)
- else:
- for input_id, example_input in enumerate(list_inputs):
- dtype = getattr(example_input, "dtype", type(example_input))
- ov_dtype = pt_to_ov_type_map.get(str(dtype))
- data_rank = getattr(example_input, "ndim", 0)
- input_shape = PartialShape([-1] * data_rank)
- input_name = input_names[input_id] if input_names else None
- update_list_or_dict(input_shapes, input_name, input_id, input_shape)
- update_list_or_dict(data_types, input_name, input_id, ov_dtype.to_dtype() if ov_dtype is not None else None)
-
- args.placeholder_data_types = data_types
- args.placeholder_shapes = input_shapes
- if not args.input and input_names:
- args.input_list = input_names
- args.input = ",".join(input_names)
-
-# pylint: disable=no-member
-def to_torch_tensor(tensor):
- import torch # pylint: disable=import-error
- if isinstance(tensor, torch.Tensor):
- return tensor
- if isinstance(tensor, np.ndarray):
- return torch.tensor(tensor)
- if isinstance(tensor, Tensor):
- return torch.tensor(tensor.data)
- if isinstance(tensor, (float, int, bool)):
- return tensor
- if isinstance(tensor, (tuple, list)):
- # TODO: Function to_torch_tensor should be renamed as it handles not only a tensor
- return tuple(to_torch_tensor(x) for x in tensor)
- if isinstance(tensor, dict) and all(isinstance(k, str) for k in tensor.keys()):
- return dict((k, to_torch_tensor(x)) for k, x in tensor.items())
- else:
- raise Error("Unexpected type of example_input. Supported types torch.Tensor, np.array or ov.Tensor. "
- "Got {}".format(type(tensor)))
-
-
-def prepare_torch_inputs(example_inputs):
- import torch
- inputs = None
- if example_inputs is not None:
- inputs = example_inputs
- if isinstance(inputs, list):
- inputs = [to_torch_tensor(x) for x in inputs]
- elif isinstance(inputs, tuple):
- inputs = [to_torch_tensor(x) for x in inputs]
- inputs = tuple(inputs)
- elif isinstance(inputs, dict):
- for name, tensor in inputs.items():
- assert isinstance(name, str), "Expected dictionary where keys are input names of string type and" \
- " values are tensors. Got key of type {}".format(type(name))
- inputs[name] = to_torch_tensor(tensor)
- else:
- inputs = to_torch_tensor(inputs)
- else:
- # No example_input were provided, decoder will use scripting
- return None
- return inputs
diff --git a/tools/mo/openvino/tools/mo/moc_frontend/shape_utils.py b/tools/mo/openvino/tools/mo/moc_frontend/shape_utils.py
deleted file mode 100644
index efe0702499d592..00000000000000
--- a/tools/mo/openvino/tools/mo/moc_frontend/shape_utils.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-from openvino.runtime import PartialShape, Dimension
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.cli_parser import get_placeholder_shapes, split_shapes
-
-
-def get_static_shape(shape: [PartialShape, list, tuple], dynamic_value=None):
- # Current function returns list with static dimensions with following logic.
- # For dynamic dimensions return lower boundaries if they are set, otherwise
- # return upper boundaries if they are set. If dimension is fully dynamic then raise error.
- shape_list = []
- for idx, dim in enumerate(shape):
- if isinstance(dim, int):
- if dim == -1:
- shape_list.append(dynamic_value)
- continue
- shape_list.append(dim)
- elif isinstance(dim, np.int64):
- if dim == np.int64(-1):
- shape_list.append(dynamic_value)
- continue
- shape_list.append(dim)
- elif isinstance(dim, tuple):
- # tuple where (min_length, max_length), the format which uses MO cli parser
- assert len(dim) == 2, "Unknown dimension type {}".format(dim)
- if dim[0] > 0:
- shape_list.append(dim[0])
- elif dim[1] < np.iinfo(np.int64).max:
- shape_list.append(dim[1])
- else:
- shape_list.append(dynamic_value)
- continue
- elif isinstance(dim, Dimension):
- if dim.is_static or dim.get_min_length() > 0:
- shape_list.append(dim.get_min_length())
- elif dim.get_max_length() != -1:
- shape_list.append(dim.get_max_length())
- else:
- shape_list.append(dynamic_value)
- continue
- else:
- raise Error("Unknown dimension type {}".format(dim))
-
- return tuple(shape_list)
-
-
-def get_dynamic_dims(shape: [PartialShape, list, tuple]):
- dynamic_dims = []
- for idx, dim in enumerate(shape):
- if isinstance(dim, int):
- if dim == -1:
- dynamic_dims.append(idx)
- if isinstance(dim, np.int64):
- if dim == np.int64(-1):
- dynamic_dims.append(idx)
- elif isinstance(dim, tuple):
- dynamic_dims.append(idx)
- elif isinstance(dim, Dimension):
- if dim.get_min_length() == 0 and dim.get_max_length() == -1:
- dynamic_dims.append(idx)
-
- return dynamic_dims
-
-
-def parse_input_shapes(argv):
- input_shapes = None
- if 'input_shape' in argv and argv['input_shape'] is not None:
- shapes = argv['input_shape']
- if isinstance(shapes, str):
- shapes = ["[{}]".format(x) for x in split_shapes(shapes)]
- if isinstance(shapes, list) or isinstance(shapes, tuple):
- input_shapes = []
- is_single_shape = False
- for shape in shapes:
- if isinstance(shape, str):
- _, shape_tuple, _ = get_placeholder_shapes(argv_input=None, argv_input_shape=shape)
- input_shapes.append(shape_tuple)
- if is_single_shape:
- raise Error("Incorrect format of shape.")
- elif isinstance(shape, int) or isinstance(shape, np.int64) or isinstance(shape, Dimension):
- is_single_shape = True
- input_shapes.append(shape)
- else:
- input_shapes.append(shape)
- if is_single_shape:
- return [input_shapes]
- else:
- return input_shapes
- elif isinstance(shapes, PartialShape):
- return [shapes]
- else:
- try:
- import torch
- if isinstance(shapes, torch.Size):
- return [shapes]
- except ImportError:
- raise Error("Unknown type of input shape {}.".format(type(shapes)))
-
- return input_shapes
\ No newline at end of file
diff --git a/tools/mo/openvino/tools/mo/ops/BN.py b/tools/mo/openvino/tools/mo/ops/BN.py
deleted file mode 100644
index 450586c543cd44..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/BN.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class BN(Op):
- """
- BN operation comes from caffe and will be replaced by BNToScaleShift FrontReplacer.
- """
- op = 'BN'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 5,
- 'out_ports_count': 1,
- 'infer': None
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/BatchNormInference.py b/tools/mo/openvino/tools/mo/ops/BatchNormInference.py
deleted file mode 100644
index a770ce46b528f7..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/BatchNormInference.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class BatchNormInference(Op):
- """
- BatchNormInference will be replaced by BNToScaleShift FrontReplacer for Caffe or convert_batch_norm
- function for other frameworks
- """
- op = 'batchNormInference'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 5,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }, attrs)
-
- @staticmethod
- def infer(node):
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
diff --git a/tools/mo/openvino/tools/mo/ops/BlockLSTM.py b/tools/mo/openvino/tools/mo/ops/BlockLSTM.py
deleted file mode 100644
index 285d6e49d9721d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/BlockLSTM.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins, dynamic_dimension, shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class BlockLSTM(Op):
- op = 'BlockLSTM'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'infer': self.infer,
- 'type': None,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- """
- MO input edges: | Description:
- -------------------------------------------------
- 0 | x: The sequence input to the LSTM, shape (timelen, batch_size, num_inputs)
- 1 | w: The weight matrix
- 2 | b: The bias vector
- 3 | h_prev: Previous/initial hidden state
- 4 | cs_prev: Value of the initial cell state
-
- MO output edges: | Description:
- 0 | hs: Output data / output hidden states concatenated over the whole time sequence
- 1 | cs: Output cell states concatenated over the whole time sequence
- """
-
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port_idx for port_idx, port in node.in_ports().items() if not port.disconnected()]
- connected_out_ports = [port_idx for port_idx, port in node.out_ports().items() if not port.disconnected()]
- assert len(connected_in_ports) >= 5, "Internal Model Optimizer Error or unsupported BlockLSTM node {}. " \
- "MO expects five inputs for BlockLSTM".format(node_name)
- assert len(connected_out_ports) <= 2, "Internal Model Optimizer Error or unsupported BlockLSTM node {}. " \
- "MO expects at most two outputs for BlockLSTM".format(node_name)
-
- x_shape = node.in_port(0).data.get_shape()
- w_shape = node.in_port(1).data.get_shape()
- b_shape = node.in_port(2).data.get_shape()
-
- time_len = dynamic_dimension
- batch_size = dynamic_dimension
- if len(x_shape) > 2:
- time_len = x_shape[0]
- batch_size = x_shape[1]
-
- hidden_size_output = dynamic_dimension
- if len(b_shape) > 0 and b_shape[0] is not dynamic_dimension:
- hidden_size_output = b_shape[0] // 4
- elif len(w_shape) > 1 and w_shape[1] is not dynamic_dimension:
- hidden_size_output = w_shape[1] // 4
-
- # mark-up inputs for LSTMRNNSequenceToTensorIterator transformation
- mark_input_bins(node)
-
- x_output_shape = shape_array([time_len, batch_size, hidden_size_output])
- if node.is_out_port_connected(0):
- node.out_port(0).data.set_shape(x_output_shape)
-
- # at this point cell states are in aggregated form from all time steps
- # after that the middle transformation BlockLSTMtoLSTMSequence should normalize it to last step cell state
- if node.is_out_port_connected(1):
- node.out_port(1).data.set_shape(x_output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/Cast.py b/tools/mo/openvino/tools/mo/ops/Cast.py
deleted file mode 100644
index 2ea210bffe167e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/Cast.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_precision, convert_blob, \
- np_data_type_to_destination_type, packed_I4, packed_U4
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class Cast(Op):
- op = 'Cast'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': 'Convert',
- 'version': 'opset1',
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- 'type_infer': self.type_infer,
- 'dst_type': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [('destination_type', lambda node: np_data_type_to_destination_type(node.dst_type))]
-
- @staticmethod
- def type_infer(node: Node):
- assert node.has_valid(
- 'dst_type'), 'Destination type of "Cast" operation should be extracted earlier'
- node.out_port(0).set_data_type(node.dst_type)
-
- @staticmethod
- def helper_value_propagation(node_name, value, dst_type):
- new_blob, finite_match_count, zero_match_count = convert_blob(
- value, dst_type)
-
- if finite_match_count:
- log.error("{} elements of {} were clipped to infinity while converting an input blob for node '{}' to {}."
- " ".format(finite_match_count, new_blob.size, node_name, dst_type) + refer_to_faq_msg(76))
- if zero_match_count:
- log.warning("{} elements of {} were clipped to zero while converting an input blob for node '{}' to {}."
- " ".format(zero_match_count, new_blob.size, node_name, dst_type) + refer_to_faq_msg(77))
- return new_blob
-
- @staticmethod
- def custom_type_casting_and_packing(node: Node, value, dst_type):
- """
- Custom types are not supported by numpy but we still need to write it to the .bin file in a compact way.
- To do so we prepare bit representation of int4/uint4 values and store them in a numpy friendly data type.
- We pack int4/uint4 values into uint8 type (two int4/uint4 numbers fit in uint8).
- If the number of elements in the blob is odd we pad them with zero value to be able to fit the bit sequence
- into the uint8 array.
- Example: we need to represent 5 elements of int4 dtype
- we would pad them to 6 element with the last element as zero and we would pack them into 3 uint8 values
- """
- assert dst_type in [packed_U4, packed_I4]
- # TODO: Remove this comment when it's clear that we can fix it easily
- # raise Exception("Packing of u4/i4 data is no longer supported in mo because it is now incompatible with the new "
- # "order of the halfs of a byte that was introduced in OpenVINO runtime recently. Use ovc "
- # "command line tool or openvino.convert_model python function instead.")
-
- minimum_regular_dtype = np.uint8 if dst_type == packed_U4 else np.int8
- # initial casing from the source type to the numpy-friendly type which could absorb all the values of dst_type
- casted_to_regular_type = Cast.helper_value_propagation(
- node.soft_get('name', node.id), value, minimum_regular_dtype)
-
- # packing the values
- data_shape = node.out_port(0).data.get_shape()
- assert data_shape is not None
- data_size = np.prod(data_shape)
-
- num_bits = 4
- assert num_bits < 8 and 8 % num_bits == 0, "Packing algorithm for the data types stored in 1, 2 or 4 bits"
- num_values_fitting_into_uint8 = 8 // num_bits
- pad = (-data_size) % num_values_fitting_into_uint8
-
- flattened = casted_to_regular_type.flatten()
- padded = np.concatenate((flattened, np.zeros([pad], dtype=minimum_regular_dtype)))
- assert np.prod(padded.shape) % num_values_fitting_into_uint8 == 0
-
- bit_order_little = (padded[:, None] & (
- 1 << np.arange(num_bits)) > 0).astype(np.uint8)
- bit_order_big_flattened = bit_order_little.flatten()
- # u1 still has reversed bit order:
- packed = np.packbits(bit_order_big_flattened,
- bitorder='little' if num_bits > 1 else 'big')
-
- node.out_node(0)['force_shape'] = data_shape.copy()
- node.out_node(0)['force_type'] = np_data_type_to_precision(dst_type)
- node.out_port(0).data.set_value(packed)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- dst_type = node.soft_get('dst_type', None)
-
- assert dst_type is not None, \
- 'Destination type of "Cast" operation should be extracted earlier, but it`s not for node: ' + node_name
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None
- node.out_port(0).data.set_shape(input_shape)
-
- value = node.in_port(0).data.get_value()
- if value is None or node.has_and_set('stop_value_propagation'):
- return
-
- if dst_type in [packed_U4, packed_I4]: # custom types conversion
- Cast.custom_type_casting_and_packing(node, value, dst_type)
- else:
- node.out_port(0).data.set_value(
- Cast.helper_value_propagation(node_name, value, dst_type))
diff --git a/tools/mo/openvino/tools/mo/ops/ClipByValueTF.py b/tools/mo/openvino/tools/mo/ops/ClipByValueTF.py
deleted file mode 100644
index c983cb54bb23bd..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ClipByValueTF.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ClibByValueTF(Op):
- """
- The ClipByValue from TF which will be replaced with a front transformation.
- """
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': 'ClipByValueTF',
- 'out_ports_count': 1,
- 'in_ports_count': 3,
- 'infer': None
- }
- super().__init__(graph, mandatory_props, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/Complex.py b/tools/mo/openvino/tools/mo/ops/Complex.py
deleted file mode 100644
index ec4c293ba8e076..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/Complex.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Complex(Op):
- op = 'Complex'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': Complex.infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
-
- @staticmethod
- def infer(node: Node):
- real_shape = node.in_port(0).data.get_shape()
- imag_shape = node.in_port(1).data.get_shape()
- if real_shape is None or imag_shape is None:
- return
-
- assert np.array_equal(real_shape, imag_shape), \
- "Shapes of real and imaginary parts must be the same. Got: {} as real part shape " \
- "and {} as imaginary part shape for Node {} with op {}." \
- "".format(real_shape, imag_shape, node.soft_get("name", node.id), node.op)
-
- output_shape = np.ma.append(real_shape, 2)
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/ConvertLike.py b/tools/mo/openvino/tools/mo/ops/ConvertLike.py
deleted file mode 100644
index 93b35e4d89d47d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ConvertLike.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ConvertLike(Op):
- op = 'ConvertLike'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'infer': copy_shape_infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- 'type_infer': self.type_infer,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def type_infer(node: Node):
- assert node.is_in_port_connected(1), 'The second input is not connected for a node {}.' \
- ''.format(node.soft_get('name'), node.id)
- node.out_port(0).set_data_type(node.in_port(1).get_data_type())
diff --git a/tools/mo/openvino/tools/mo/ops/DetectionOutput.py b/tools/mo/openvino/tools/mo/ops/DetectionOutput.py
deleted file mode 100644
index afe00f8126d643..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/DetectionOutput.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, compatible_dims, \
- undefined_shape_of_rank, set_input_shapes
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class DetectionOutput(Op):
- op = 'DetectionOutput'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset8',
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'input_width': 1,
- 'input_height': 1,
- 'normalized': True,
- 'share_location': True,
- 'clip_after_nms': False,
- 'clip_before_nms': False,
- 'decrease_label_id': False,
- 'variance_encoded_in_target': False,
- 'type_infer': self.type_infer,
- }, attrs)
-
- def supported_attrs(self):
- supported_attrs = [
- 'background_label_id',
- ('clip_after_nms', lambda node: bool_to_str(node, 'clip_after_nms')),
- ('clip_before_nms', lambda node: bool_to_str(node, 'clip_before_nms')),
- 'code_type',
- 'confidence_threshold',
- ('decrease_label_id', lambda node: bool_to_str(node, 'decrease_label_id')),
- 'input_height',
- 'input_width',
- 'keep_top_k',
- 'nms_threshold',
- ('normalized', lambda node: bool_to_str(node, 'normalized')),
- ('share_location', lambda node: bool_to_str(node, 'share_location')),
- 'top_k',
- ('variance_encoded_in_target', lambda node: bool_to_str(node, 'variance_encoded_in_target')),
- 'objectness_score',
- ]
- opset = self.get_opset()
- if opset == 'opset1':
- supported_attrs += ['num_classes']
- return supported_attrs
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(np.float32)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- loc_shape = node.in_port(0).data.get_shape()
- conf_shape = node.in_port(1).data.get_shape()
- prior_boxes_shape = node.in_port(2).data.get_shape()
-
- if loc_shape is None or conf_shape is None or prior_boxes_shape is None:
- raise Error('Shapes for the Detection Output node "{}" are not defined'.format(node_name))
-
- prior_size = 4
- if node.has('normalized') and not node.normalized:
- prior_size = 5
-
- if is_fully_defined(prior_boxes_shape[-1]) and prior_boxes_shape[-1] % prior_size != 0:
- raise Error('Amount of confidences "{}" is not divisible by {} for node "{}"'
- ''.format(prior_boxes_shape[-1], prior_size, node_name))
-
- num_priors = prior_boxes_shape[-1] // prior_size
- if not node.has_valid('keep_top_k') or node.keep_top_k == -1:
- node['keep_top_k'] = num_priors
-
- num_classes = conf_shape[-1] // num_priors
- num_loc_classes = num_classes
- if node.has_and_set('share_location') and node.share_location:
- num_loc_classes = 1
-
- if not compatible_dims(num_priors * num_loc_classes * 4, loc_shape[-1]):
- raise Error('Locations and prior boxes shapes mismatch: "{}" vs "{}" for node "{}"'
- ''.format(loc_shape, prior_boxes_shape, node_name))
-
- if not node.variance_encoded_in_target and not compatible_dims(prior_boxes_shape[-2], 2):
- raise Error('The "-2" dimension of the prior boxes must be 2 but it is "{}" for node "{}".'
- ''.format(prior_boxes_shape[-2], node_name))
-
- if is_fully_defined(conf_shape[-1]) and is_fully_defined(num_priors) and conf_shape[-1] % num_priors != 0:
- raise Error('Amount of confidences "{}" is not divisible by amount of priors "{}" for node "{}".'
- ''.format(conf_shape[-1], num_priors, node_name))
-
- node.out_port(0).data.set_shape([1, 1, conf_shape[0] * node.keep_top_k, 7])
-
- # the line below is needed for the TF framework so the MO will not change the layout
- node.graph.node[node.out_node(0).id]['nchw_layout'] = True
-
- @staticmethod
- def reverse_infer(node):
- num_in_ports = len(node.in_ports())
- assert num_in_ports in [3, 6], 'incorrect number of input ports for DetectionOutput node {}'.format(node.soft_get('name', node.id))
- if num_in_ports == 3:
- set_input_shapes(node,
- undefined_shape_of_rank(2),
- undefined_shape_of_rank(2),
- undefined_shape_of_rank(3))
- elif num_in_ports == 6:
- set_input_shapes(node,
- undefined_shape_of_rank(2),
- undefined_shape_of_rank(2),
- undefined_shape_of_rank(3),
- undefined_shape_of_rank(2),
- undefined_shape_of_rank(2))
diff --git a/tools/mo/openvino/tools/mo/ops/Enter.py b/tools/mo/openvino/tools/mo/ops/Enter.py
deleted file mode 100644
index e53a9dedba8531..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/Enter.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Enter(Op):
- op = "Enter"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 1,
- 'infer': Enter.enter_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def enter_infer(node: Node):
- output_shape = node.in_port(0).data.get_shape()
- output_value = node.in_port(0).data.get_value()
-
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = shape_array(output_shape)
- node.graph.node[out_node]['value'] = None if output_value is None else output_value.copy()
diff --git a/tools/mo/openvino/tools/mo/ops/Exit.py b/tools/mo/openvino/tools/mo/ops/Exit.py
deleted file mode 100644
index b6b8f749c4a1b3..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/Exit.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Exit(Op):
- op = "Exit"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'infer': Exit.exit_infer,
- 'in_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def exit_infer(node: Node):
- output_shape = node.in_port(0).data.get_shape()
- output_value = node.in_port(0).data.get_value()
-
- for port in node.out_ports():
- if not node.out_port(port).disconnected():
- node.out_port(port).data.set_shape(output_shape)
- if output_value is not None:
- node.out_port(port).data.set_value(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/ExtractImagePatches.py b/tools/mo/openvino/tools/mo/ops/ExtractImagePatches.py
deleted file mode 100644
index 71d434d5fbbd59..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ExtractImagePatches.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import shape_for_layout, get_batch_dim, get_features_dim
-from openvino.tools.mo.front.common.partial_infer.utils import tf_window_op_pad_infer, shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ExtractImagePatches(Op):
- op = "ExtractImagePatches"
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'spatial_dims' in attrs, \
- 'ExtractImagePatches operation should have `spatial_dims` parameter set during creation'
-
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset3',
- 'infer': self.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return [
- ('sizes', lambda node: ','.join(map(str, node['sizes'][node.spatial_dims]))),
- ('strides', lambda node: ','.join(map(str, node['strides'][node.spatial_dims]))),
- ('rates', lambda node: ','.join(map(str, node['rates'][node.spatial_dims]))),
- 'auto_pad',
- ]
-
- @staticmethod
- def infer(node: Node):
- assert [port.idx for port in node.in_ports().values() if not port.disconnected()] == [0], \
- 'Wrong input nodes number for node {} with type ExtractImagePatches'.format(node.soft_get('name', node.id))
- input_shape = node.in_port(0).data.get_shape()
- name = node.soft_get('name', node.id)
- assert input_shape is not None, 'Input shape is not set for node {} with type ExtractImagePatches'.format(name)
-
- assert len(input_shape) == 4, 'ExtractImagePatches operation supports only 4D tensors'
-
- layout = node.graph.graph['layout']
- N = input_shape[get_batch_dim(layout, 4)]
- C = input_shape[get_features_dim(layout, 4)]
-
- size_spatial = shape_array(node.sizes)[node.spatial_dims]
-
- input_spatial_shape = input_shape[node.spatial_dims]
- stride_spatial_shape = node.strides[node.spatial_dims]
-
- size_extent = node.rates[node.spatial_dims] * (size_spatial - 1) + 1
-
- pad_spatial_shape, output_spatial_shape = tf_window_op_pad_infer(input_spatial_shape,
- size_extent,
- stride_spatial_shape,
- node.auto_pad,
- False)
-
- out_shape = shape_for_layout(layout,
- batch=N,
- features=C * np.prod(size_spatial),
- height=output_spatial_shape[0],
- width=output_spatial_shape[1])
-
- node.out_port(0).data.set_shape(out_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/GRU.py b/tools/mo/openvino/tools/mo/ops/GRU.py
deleted file mode 100644
index a031aa755ded79..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/GRU.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.RNN import rnn_infer, RNN
-from openvino.tools.mo.ops.op import Op
-
-
-class GRU(Op):
- op = 'GRU'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': 'RNNSequence', # should be never emitted to IR; for debugging purposes
- 'op': __class__.op,
- 'blobs_wrb': False,
- 'has_num_directions': False,
- 'direction': 'forward',
- 'infer': __class__.infer,
- 'reverse_infer': RNN.reverse_infer,
- 'multiplier': 3,
- 'multilayers': False,
- 'gate_order': mo_array([0, 1, 2]), # TODO: change it later
- 'normalized': False,
-
- 'activation_alpha': None,
- 'activation_beta': None,
- 'activations': None,
- 'clip': None,
- 'linear_before_reset': None,
- 'in_ports_count': 6,
- 'out_ports_count': 2,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def supported_attrs():
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'axis',
-
- 'activation_alpha',
- 'activation_beta',
- 'activations',
- 'clip',
- 'linear_before_reset',
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'axis',
-
- ('activations', lambda node: ','.join(node['activations']) if node.has_and_set('activations') else None),
- ('activations_alpha', lambda node: ','.join(map(str, node['activations_alpha']))
- if node.has_and_set('activations_alpha') else None),
- ('activations_beta', lambda node: ','.join(map(str, node['activations_beta']))
- if node.has_and_set('activations_beta') else None),
- 'clip',
- 'linear_before_reset',
- ]
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) >= 3 # X, W and R
- assert len(node.in_nodes()) <= 5
- assert len(node.out_nodes()) <= 2
-
- rnn_infer(node, [1])
diff --git a/tools/mo/openvino/tools/mo/ops/GRUBlockCell.py b/tools/mo/openvino/tools/mo/ops/GRUBlockCell.py
deleted file mode 100644
index a93449c2e1375f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/GRUBlockCell.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class GRUBlockCell(Op):
- op = 'GRUBlockCell'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': None,
- 'in_ports_count': 6,
- 'out_ports_count': 4,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/GRUCell.py b/tools/mo/openvino/tools/mo/ops/GRUCell.py
deleted file mode 100644
index 17a9459a353f1d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/GRUCell.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class GRUCell(Op):
- """ A single GRU cell (without a loop).
-
- 2 inputs:
- - [0, required] input data (2D),
- - [1, required] initial hidden state (2D),
-
- 2 blobs:
- - [2, required] cell FC weights
- - [3, required] cell FC biases
-
- 1 outputs:
- - [required] output data / resulting hidden state (2D)
- """
- op = 'GRUCell'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': __class__.op,
- 'op': __class__.op,
- 'infer': __class__.infer,
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- 'version': 'opset3',
- 'wr_input_id': 2,
- 'gates_count': 3,
- 'linear_before_reset': False,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'activations',
- 'activation_alpha',
- 'activation_beta',
- 'clip',
- 'linear_before_reset',
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- ('activations', lambda node: ','.join(node['activations']) if node.has_and_set('activations') else None),
- ('activations_alpha', lambda node: ','.join(map(str, node['activations_alpha']))
- if node.has_and_set('activations_alpha') else None),
- ('activations_beta', lambda node: ','.join(map(str, node['activations_beta']))
- if node.has_and_set('activations_beta') else None),
- 'clip',
- ('linear_before_reset', lambda node: bool_to_str(node, 'linear_before_reset')),
- ]
-
- @staticmethod
- def infer(node: Node):
- assert len(node.out_nodes()) in [1, 2]
-
- hidden_shape = node.in_port(1).data.get_shape().copy()
-
- mark_input_bins(node, start_port=2)
- node.out_port(0).data.set_shape(hidden_shape)
-
- hidden_size = hidden_shape[1]
- if node.has_valid('hidden_size'):
- if node.hidden_size != hidden_size:
- raise Error("Input shape {} for hidden size doesn't match pre-defined hidden_size in node {}".format(
- node.in_node(1).shape, node.soft_get('name')))
- else:
- node['hidden_size'] = hidden_size
diff --git a/tools/mo/openvino/tools/mo/ops/GatherTree.py b/tools/mo/openvino/tools/mo/ops/GatherTree.py
deleted file mode 100644
index f4a932f31cec6d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/GatherTree.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class GatherTree(Op):
- op = 'GatherTree'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
- 'infer': copy_shape_infer,
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
diff --git a/tools/mo/openvino/tools/mo/ops/If.py b/tools/mo/openvino/tools/mo/ops/If.py
deleted file mode 100644
index 510db285de3b11..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/If.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, is_fully_defined, dynamic_dimension_value, unmask_shape
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.op import Op
-
-
-class If(Op):
- """
- If operation is an operation which has an input with condition which defines what sub-graph "then" or "else" to be
- executed.
- """
- op = 'If'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- base_attrs = {
- 'type': self.op,
- 'op': self.op,
- 'then_graph': None, # an Graph object with a "then" body sub-graph (condition is True)
- 'else_graph': None, # an Graph object with a "else" body sub-graph (condition is False)
- 'sub_graphs': ['then_graph', 'else_graph'], # built-in attribute with all sub-graphs
- 'version': 'opset8',
- 'infer': self.infer,
- 'type_infer': self.type_infer,
- }
- base_attrs.update(attrs)
- super().__init__(graph, base_attrs, attrs)
-
- def port_map_attrs(self):
- return [
- 'external_port_id',
- 'internal_layer_id'
- ]
-
- @staticmethod
- def connect_body_input(if_node: Node, condition: bool, if_input_port_idx: int, body_parameter: Node):
- """
- Update the specified body parameter and connect it with If input
-
- :param if_node: the If node
- :param condition: the boolean defining a condition (then/else) graph to add connect the body
- :param if_input_port_idx: the input port index to connect
- :param body_parameter: the body parameter node to connect
- :return: None
- """
- assert if_node.soft_get('op') == 'If'
- assert body_parameter.soft_get('op') == 'Parameter'
- sub_graph = if_node.then_graph if condition else if_node.else_graph
- assert body_parameter.id in sub_graph
- body_parameter['input_id'] = if_input_port_idx
-
- @staticmethod
- def connect_body_output(if_node: Node, condition: bool, if_output_port_idx: int, internal_result: Node):
- """
- Update the specified output port and connect it with If output
-
- :param if_node: the If node
- :param condition: the boolean defining a condition (then/else) graph to add connect the body
- :param if_output_port_idx: the output port index to connect
- :param internal_result: the body Result node to connect
- :return: None
- """
- assert if_node.soft_get('op') == 'If'
- assert internal_result.soft_get('op') == 'Result'
- sub_graph = if_node.then_graph if condition else if_node.else_graph
- assert internal_result.id in sub_graph
- internal_result['output_id'] = if_output_port_idx
-
- @staticmethod
- def update_body_parameters_type(if_node: Node, condition: bool):
- """
- Update the data type for If body Parameter nodes based on data type of the outer graph nodes producing data
- for them.
-
- :param if_node: The If node
- :param condition: the boolean defining a condition (then/else) graph
- :return: None
- """
- assert if_node.soft_get('type') == 'If'
-
- subgraph = if_node.then_graph if condition else if_node.else_graph
- for node in subgraph.get_op_nodes():
- if node.has('input_id'):
- assert node.soft_get('type') == 'Parameter'
- input_port_id = node['input_id']
- input_type = if_node.in_port(input_port_id).get_data_type()
- node.data_type = input_type
- log.debug('Updated data type for the body node with name "{}" with value {}'
- .format(node.name, node.data_type))
-
- @staticmethod
- def update_body_parameters_shape(if_node: Node, condition: bool):
- """
- Update shape for If body parameters.
-
- :param if_node: The If node
- :param condition: the boolean defining a condition (then/else) graph to add connect the body
- :return: None
- """
- subgraph = if_node.then_graph if condition else if_node.else_graph
- for node in subgraph.get_op_nodes():
- if node.has('input_id'):
- assert node.soft_get('type') == 'Parameter'
- input_port_id = node['input_id']
- input_shape = if_node.in_port(input_port_id).data.get_shape()
- if node.soft_get('shape', None) is None:
- node['shape'] = None
- node.shape = input_shape.copy()
- log.debug('Updated shape for the body node with name "{}" with value {}'
- .format(node.soft_get('name', node.soft_get('id')), node.shape))
-
- @staticmethod
- def results_mapping_and_finding_fake_outputs(output_nodes_in_subgraph, branch_name, outputs_mapping):
- """
- This method checked result nodes in subgraph and set map between output from If operation and internal subgraph
- result. Also This method return True if internal graph has fake results.
-
- :param output_nodes_in_subgraph: Result node with attribute 'output_id'
- :param branch_name: name of subgraph
- :param outputs_mapping: map between If operation output ID and subgraph results
-
- :return: True if all results of subgraph are empty tensors
- """
- graph_contain_fake_outputs = True
-
- for output_node in output_nodes_in_subgraph:
- assert output_node.soft_get('type') == 'Result'
- port_id = output_node['output_id']
- assert port_id in outputs_mapping.keys(), 'Incorrect mapping then_graph outputs with {0} outputs! ' \
- 'Can\'t find port with ID {1} in If operation.' \
- .format(output_node.name, port_id)
- outputs_mapping[port_id][branch_name] = output_node
- out_node_shape = output_node.in_port(0).data.get_shape()
- graph_contain_fake_outputs = graph_contain_fake_outputs and np.any(unmask_shape(out_node_shape) == 0)
- return graph_contain_fake_outputs
-
- @staticmethod
- def update_if_output_ports_shape(if_node: Node):
- """
- Update shape and values for If output ports.
-
- :param if_node: The If node to update output ports and shapes
- :return: None
- """
- node_name = if_node.soft_get('name', if_node.id)
-
- then_outputs = [node for node in if_node.then_graph.get_op_nodes() if node.has('output_id')]
- else_outputs = [node for node in if_node.else_graph.get_op_nodes() if node.has('output_id')]
- outputs_mapping = {}
- outputs_number = len(if_node.out_ports())
-
- if outputs_number == 0 and len(if_node.out_ports(control_flow=True)) != 0:
- # Some models have if with control flow outputs.
- # These shape inference for such ifs
- # TODO: need to rethink and redo support for control flow edges in if operation
- for node in if_node.out_nodes(control_flow=True).values():
- node.shape = int64_array([])
- return
-
- for port_id in if_node.out_ports().keys():
- outputs_mapping[port_id] = {}
-
- # variables then_contains_fake_outputs/else_contains_fake_outputs contains True value
- # if all outputs from then_body/else_body have shape [0]. It means then_body/else_body does not return data
- # and further shape_inference for this branch is not possible.
- # TODO: exclude support fake_outputs from this code when we will support shape_inference with empty tensors
-
- then_contains_fake_outputs = \
- If.results_mapping_and_finding_fake_outputs(then_outputs, 'then_graph', outputs_mapping)
- else_contains_fake_outputs = \
- If.results_mapping_and_finding_fake_outputs(else_outputs, 'else_graph', outputs_mapping)
-
- # use_then_shape is True when else_body or when both bodies do not return data. If use_then_shape is True If's
- # outputs will have the same shapes as then_body results
- use_then_shape = else_contains_fake_outputs or not then_contains_fake_outputs
-
- cond_value = if_node.in_port(0).data.get_value()
-
- for port_id in outputs_mapping:
- then_else_nodes = outputs_mapping[port_id]
- assert 'then_graph' in then_else_nodes.keys(), 'then_graph does not connect with If.out_port[{0}] ' \
- 'in {1} node!'.format(port_id, node_name)
- assert 'else_graph' in then_else_nodes.keys(), 'else_graph does not connect with If.out_port[{0}] ' \
- 'in {1} node!'.format(port_id, node_name)
-
- then_shape = then_else_nodes['then_graph'].in_port(0).data.get_shape()
- then_value = then_else_nodes['then_graph'].in_port(0).data.get_value()
- else_shape = then_else_nodes['else_graph'].in_port(0).data.get_shape()
- else_value = then_else_nodes['else_graph'].in_port(0).data.get_value()
-
- if is_fully_defined(cond_value):
- if cond_value.item() is True:
- if then_value is not None:
- if_node.out_port(port_id).data.set_value(then_value)
- else:
- if_node.out_port(port_id).data.set_shape(then_shape)
- else:
- if else_value is not None:
- if_node.out_port(port_id).data.set_value(else_value)
- else:
- if_node.out_port(port_id).data.set_shape(else_shape)
- else:
- if then_contains_fake_outputs ^ else_contains_fake_outputs:
- # if exactly one of the outputs is fake then use another one
- if_node.out_port(port_id).data.set_shape(then_shape if use_then_shape else else_shape)
- else:
- # find "intersection" which is equal to the dimension value if corresponding dimensions are equal
- # and dynamic otherwise
- assert len(then_shape) == len(else_shape), 'Ranks of "then" and "else" output tensors are ' \
- 'different for node {} for port {}'.format(node_name,
- port_id)
- output_shape = [d1 if is_fully_defined(d1) and is_fully_defined(d2) and d1 == d2 else
- dynamic_dimension_value for d1, d2 in zip(then_shape, else_shape)]
- if_node.out_port(port_id).data.set_shape(output_shape)
-
-
- @staticmethod
- def update_if_output_ports_type(if_node: Node):
- """
- Update types for If output ports.
-
- :param if_node: The If node to update output ports and types
- :return: None
- """
- then_outputs = [node for node in if_node.then_graph.get_op_nodes() if node.has('output_id')]
- else_outputs = [node for node in if_node.else_graph.get_op_nodes() if node.has('output_id')]
- outputs_mapping = {}
- outputs_number = len(if_node.out_ports())
- assert outputs_number == len(then_outputs), 'Incorrect number outputs in then_graph of If with ' \
- 'name {0}! then_graph must has {1} outputs' \
- .format(if_node.name, outputs_number)
- assert outputs_number == len(else_outputs), 'Incorrect number outputs in else_graph of If with ' \
- 'name {0}! else_graph must has {1} outputs' \
- .format(if_node.name, outputs_number)
- for port_id in if_node.out_ports().keys():
- outputs_mapping[port_id] = {}
- port_ids = outputs_mapping.keys()
- for then_output_node in then_outputs:
- assert then_output_node.soft_get('type') == 'Result'
- port_id = then_output_node['output_id']
- assert port_id in port_ids, 'Incorrect mapping then_graph outputs with {0} outputs! ' \
- 'Can\'t find port with ID {1} in If operation.' \
- .format(then_output_node.name, port_id)
- outputs_mapping[port_id]['then_graph'] = then_output_node
-
- for else_output_node in else_outputs:
- assert else_output_node.soft_get('type') == 'Result'
- port_id = else_output_node['output_id']
- assert port_id in port_ids, 'Incorrect mapping then_graph outputs with {0} outputs! ' \
- 'Can\'t find port with ID {1} in If operation.' \
- .format(else_output_node.name, port_id)
- outputs_mapping[port_id]['else_graph'] = else_output_node
-
- for port_id in outputs_mapping:
- then_else_nodes = outputs_mapping[port_id]
- assert 'then_graph' in then_else_nodes.keys(), 'then_graph does not connect with If.out_port[{0}] ' \
- 'in {1} node!'.format(port_id, if_node.name)
- assert 'else_graph' in then_else_nodes.keys(), 'else_graph does not connect with If.out_port[{0}] ' \
- 'in {1} node!'.format(port_id, if_node.name)
- then_type = then_else_nodes['then_graph'].in_port(0).get_data_type()
- else_type = then_else_nodes['else_graph'].in_port(0).get_data_type()
- assert then_type == else_type, 'Cannot get type for if.out_port[{0}]! ' \
- 'Types in then_graph and else_graph are not equal!'.format(port_id)
- if_node.out_port(port_id).set_data_type(then_type)
-
- @staticmethod
- def re_numerate_internal_id_and_get_if_id(if_node):
- """
- This method is called before IR generation. This method sets internal_layer_id.
-
- :param if_node: The If node where is necessary to set internal_layer_id in bodies.
- :return: if_node
- """
- then_graph_nodes = if_node.then_graph.nodes()
- for node in if_node.then_graph.get_op_nodes():
- then_graph_nodes[node.id]['internal_layer_id'] = node.id
- else_graph_nodes = if_node.else_graph.nodes()
- for node in if_node.else_graph.get_op_nodes():
- else_graph_nodes[node.id]['internal_layer_id'] = node.id
- return if_node.node
-
- def substitute_ie_attrs(self, new_attrs: dict):
- """
- Replace standard list of attribute in layer/data by attributes
- delivered by backend_attrs
- """
-
- port_map_attrs = self.port_map_attrs()
- new_attrs.update({
- 'IE': [(
- 'layer',
- [('id', lambda node: self.re_numerate_internal_id_and_get_if_id(node)), 'name', 'type', 'version'],
- [
- '@ports',
- ('then_port_map', [], [
- ('@list', lambda node: self.generate_port_map(node, True, 'in'),
- ('input', port_map_attrs, [])),
- ('@list', lambda node: self.generate_port_map(node, True, 'out'),
- ('output', port_map_attrs, [])),
- ]),
- ('else_port_map', [], [
- ('@list', lambda node: self.generate_port_map(node, False, 'in'),
- ('input', port_map_attrs, [])),
- ('@list', lambda node: self.generate_port_map(node, False, 'out'),
- ('output', port_map_attrs, [])),
- ]),
- ('then_body', [], [('@network', 'then_graph')]),
- ('else_body', [], [('@network', 'else_graph')]),
- ])]
- })
-
- @staticmethod
- def generate_port_map(if_node: Node, condition: bool, dir: str):
- """
- Extract port_map attributes from if_node and its subgraphs attributes.
-
- :param if_node: The If node
- :param condition: the boolean defining a condition (then/else) graph
- :param dir: the str value defining type (for inputs or for putputs) of port_map
- :return: port_map -> list of dictionaries with to values(external_port_id or internal_layer_id)
- """
- port_map = []
- subgraph = if_node.then_graph if condition else if_node.else_graph
- name_of_connection = 'input_id' if dir == 'in' else 'output_id'
-
- for internal_node in subgraph.get_op_nodes():
- if internal_node.has(name_of_connection):
- port_map.append({'external_port_id': internal_node[name_of_connection],
- 'internal_layer_id': internal_node['internal_layer_id']})
-
- return port_map
-
- @staticmethod
- def infer(if_node: Node):
- If.update_body_parameters_shape(if_node, True)
- If.update_body_parameters_shape(if_node, False)
- partial_infer(if_node.then_graph)
- partial_infer(if_node.else_graph)
- If.update_if_output_ports_shape(if_node)
-
- @staticmethod
- def type_infer(if_node: Node):
- from openvino.tools.mo.middle.passes.infer import type_infer
- If.update_body_parameters_type(if_node, True)
- If.update_body_parameters_type(if_node, False)
- type_infer(if_node.then_graph)
- type_infer(if_node.else_graph)
- If.update_if_output_ports_type(if_node)
diff --git a/tools/mo/openvino/tools/mo/ops/LSTM.py b/tools/mo/openvino/tools/mo/ops/LSTM.py
deleted file mode 100644
index a135ceda832545..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/LSTM.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.RNN import rnn_infer, RNN
-from openvino.tools.mo.ops.op import Op
-
-
-class LSTM(Op):
- op = 'LSTM'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': 'RNNSequence', # should be never emitted to IR; for debugging purposes
- 'op': self.op,
- 'blobs_wrb': False, # input blobs have three separate components W, R and B like in ONNX/LSTM
- 'has_num_directions': False, # if True, output shape has 4 dimensions; 3D otherwise
- 'direction': 'forward',
- 'infer': self.infer,
- 'reverse_infer': RNN.reverse_infer,
- 'multiplier': 4,
- 'gate_order': None,
- 'normalized': False,
- 'multilayers': False,
- 'format': None, # format type of input blobs for different frameworks (onnx, tf),
-
- 'activation_alpha': None,
- 'activation_beta': None,
- 'activations': None,
- 'clip': None,
- 'input_forget': None,
- 'in_ports_count': 7,
- 'out_ports_count': 3,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def supported_attrs():
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'axis',
-
- 'activation_alpha',
- 'activation_beta',
- 'activations',
- 'clip',
- # 'input_forget', # Not supported yet
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'axis',
-
- ('activations', lambda node: ','.join(node['activations']) if node.has_and_set('activations') else None),
- ('activations_alpha', lambda node: ','.join(map(str, node['activations_alpha']))
- if node.has_and_set('activations_alpha') else None),
- ('activations_beta', lambda node: ','.join(map(str, node['activations_beta']))
- if node.has_and_set('activations_beta') else None),
- 'clip',
- # 'input_forget', # Not supported yet
- ]
-
- @staticmethod
- def infer(node: Node):
- # there are limitations coming from ONNX LSTM definition and normalization rules
- assert len(node.in_nodes()) >= 3 # X, W and R
- assert len(node.in_nodes()) <= 7
- assert len(node.out_nodes()) <= 3
-
- rnn_infer(node, [1, 2])
diff --git a/tools/mo/openvino/tools/mo/ops/LookupTableInsert.py b/tools/mo/openvino/tools/mo/ops/LookupTableInsert.py
deleted file mode 100644
index fc7f41e7661216..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/LookupTableInsert.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class LookupTableInsert(Op):
- """
- This operation has only output control flow edges and no output data edges in some models.
- And for these cases implementation of the shape inference is needed since the shape inference is executed
- before control flow edges resolving. This operation has non-tensor output so the output shape is empty.
- """
- enabled = False
- op = 'LookupTableInsert'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 3, \
- "Incorrect number of inputs for {} node".format(node_name)
-
- # check shapes of input tensors
- keys_shape = node.in_port(1).data.get_shape()
- values_shape = node.in_port(2).data.get_shape()
- assert np.array_equal(keys_shape, values_shape), \
- 'Shapes of tensors with keys and values must be equal for {} node'.format(node_name)
-
- # set output shape that must be empty
- # since output is not a tensor
- node.out_port(0).data.set_shape([])
diff --git a/tools/mo/openvino/tools/mo/ops/MatMul.py b/tools/mo/openvino/tools/mo/ops/MatMul.py
deleted file mode 100644
index 43c2c297afb169..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/MatMul.py
+++ /dev/null
@@ -1,247 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import assign_dims_to_weights, compatible_dims, compatible_shapes, \
- shape_array, is_fully_defined, shape_delete, shape_insert
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.type_utils import override_data_type_of_constant
-
-
-class MatMul(Op):
- """
- Operation is specified at docs/ops/matrix/MatMul_1.md
- """
- op = 'MatMul'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'transpose_a': False,
- 'transpose_b': False,
- 'infer': self.infer,
- 'type_infer': self.type_infer,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- ('transpose_a', lambda node: bool_to_str(node, 'transpose_a')),
- ('transpose_b', lambda node: bool_to_str(node, 'transpose_b')),
- ]
-
- @staticmethod
- def shape_alignment(node: Node):
- """
- Specification of MatMul operation allows inputs to be aligned together before matrix multiplication.
- Current method raises an error if input shapes are not valid at any step of alignment process
- :return: aligned copies of both input shapes
- """
- node_name = node.soft_get('name', str(node.id))
- input_shapes = [node.in_port(i).data.get_shape() for i in range(2)]
- transpose_a = node.has_and_set('transpose_a')
- transpose_b = node.has_and_set('transpose_b')
-
- transformed_shapes = []
- for i, shape in enumerate(input_shapes):
- input_shape = shape.copy()
- # prerequisites check
- assert input_shape is not None, "MatMul has shape=`None` for {} input of `{}` node".format(i, node_name)
- assert input_shape.ndim == 1, "MatMul doesn't support scalar inputs. {} input of `{}` node has shape {}" \
- "".format(i, node_name, input_shape)
- assert input_shape.size >= 1, "MatMul doesn't support inputs with rank lower than 1. {} input of `{}` " \
- "node has shape {}".format(i, node_name, input_shape)
- rank = input_shape.size
- # shape alignment
- if rank != 1 and ((i == 0 and transpose_a) or (i == 1 and transpose_b)):
- input_shape[-2], input_shape[-1] = input_shape[-1], input_shape[-2]
- if rank == 1:
- input_shape = shape_insert(input_shape, int(i == 1), 1)
-
- max_shape_length = max(input_shapes[0].size, input_shapes[1].size)
- input_shape = shape_insert(input_shape, 0, [1] * (max_shape_length - input_shape.size))
- transformed_shapes.append(input_shape)
-
- A_shape = shape_array(transformed_shapes[0])
- B_shape = shape_array(transformed_shapes[1])
-
- assert A_shape.size == B_shape.size, \
- "Shapes were not aligned by length for MatMul `{}`. Shapes: `{}`".format(node_name, transformed_shapes)
-
- # batch broadcasting
- batch_len = A_shape.size - 2
- for i in range(batch_len):
- if A_shape[i] != B_shape[i]:
- if A_shape[i] == 1:
- A_shape[i] = B_shape[i]
- if B_shape[i] == 1:
- B_shape[i] = A_shape[i]
-
- assert compatible_shapes(A_shape[:-2], B_shape[:-2]), \
- "MatMul input shapes are incorrect. BATCH_DIMs are not equal. Node: {}. Aligned shapes: {}" \
- "".format(node_name, transformed_shapes)
-
- return A_shape, B_shape
-
- @staticmethod
- def value_propagation(node: Node):
- """
- This function performs a value propagation for MatMul layer.
- :param node: MatMul layer
- :return: None
- """
- a_value = node.in_port(0).get_source().data.get_value()
- b_value = node.in_port(1).get_source().data.get_value()
- if is_fully_defined(a_value) and is_fully_defined(b_value):
- if node.transpose_a:
- a_value = transpose(a_value)
- if node.transpose_b:
- b_value = transpose(b_value)
- # np.matmul does not work correctly with masked arrays, so need explicitly convert inputs to regular arrays
- if isinstance(a_value, np.ma.masked_array):
- a_value = a_value.filled()
- if isinstance(b_value, np.ma.masked_array):
- b_value = b_value.filled()
- node.out_port(0).data.set_value(np.matmul(a_value, b_value))
-
- @staticmethod
- def infer(node: Node):
- """
- Performs shape inference of MatMul node as operation doc-string says
- Raises on any shape inconsistency
- """
- name = node.soft_get('name', str(node.id))
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) == 2 and 0 in connected_in_ports and 1 in connected_in_ports, \
- "MatMul should have 2 connected input ports, but it doesn't for node: `{}`. Ports: {}" \
- "".format(name, connected_in_ports)
-
- log.debug('MatMul `{}` input shapes: {}'.format(name, [node.in_port(i).data.get_shape() for i in range(2)]))
- A_shape, B_shape = MatMul.shape_alignment(node)
- log.debug('MatMul `{}` aligned input shapes: {}'.format(name, [A_shape, B_shape]))
-
- assert compatible_dims(A_shape[-1], B_shape[-2]), \
- "MatMul input shapes are incorrect. COL_INDEX_DIMs are not equal. Node: {}. Shapes: {}" \
- "".format(name, [A_shape, B_shape])
-
- output_shape = np.ma.concatenate((A_shape[:-1], B_shape[-1:]))
-
- if node.in_port(0).data.get_shape().size == 1:
- assert compatible_dims(output_shape[-2], 1)
- output_shape = shape_delete(output_shape, -2)
- if node.in_port(1).data.get_shape().size == 1:
- assert compatible_dims(output_shape[-1], 1)
- output_shape = shape_delete(output_shape, -1)
-
- node.out_port(0).data.set_shape(output_shape)
-
- in_ch = 0 if not node.transpose_b else 1
- out_ch = 1 if not node.transpose_b else 0
- assign_dims_to_weights(node.in_node(1), None, in_ch, out_ch, node.in_port(1).data.get_shape().size)
- MatMul.value_propagation(node)
-
- @staticmethod
- def type_infer(node):
- override_data_type_of_constant(node)
- node.out_port(0).set_data_type(node.in_port(0).get_data_type())
-
-
-def transpose(value):
- num_of_dims = value.ndim
- if num_of_dims == 1:
- return value
- else:
- return np.transpose(value, [*range(0, num_of_dims - 2), num_of_dims - 1, num_of_dims - 2])
-
-
-# MatMul-like operation from frameworks
-class GemmONNX(Op):
- """
- Represents Gemm operation from ONNX
-
- Missing `type` and `infer` attributes on purpose - node should be decomposed on front phase
- and should never be inferred or translated to IR as is
- """
- op = 'Gemm'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'transpose_a': False,
- 'transpose_b': False,
- 'alpha': 1,
- 'beta': 1,
- 'broadcast_c': True,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
-
-class FullyConnected(Op):
- # TODO: remove `infer`, `type` and supported_attrs after op removal from IR Spec
- op = 'FullyConnected'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return [
- 'out-size',
- ]
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) >= 2 and 0 in connected_in_ports and 1 in connected_in_ports, \
- 'FullyConnected should have 2 connected input ports, but it doesn\'t for node: `{}`. Ports: {}' \
- ''.format(name, connected_in_ports)
-
- assert node.has_valid('out-size')
- input_shape = node.in_port(0).data.get_shape()
- weights_shape = node.in_port(1).data.get_shape()
- assert input_shape is not None and weights_shape is not None, \
- 'Incorrect FullyConnected input shapes. Node: {}. Shapes: {}'.format(name, [input_shape, weights_shape])
- assert weights_shape.size == 2
- out_size = node.soft_get('out-size')
- assert compatible_dims(weights_shape[0], out_size), \
- 'weights_shape={}, out-size={}'.format(weights_shape, out_size)
-
- if 2 in connected_in_ports:
- bias_value = node.in_port(2).data.get_value()
- bias_shape = node.in_port(2).data.get_shape()
- assert bias_shape is not None, 'Shape was not inferred for biases of FullyConnected {}'.format(name)
- assert bias_value is not None, 'Value was not inferred for biases of FullyConnected {}'.format(name)
- assert compatible_shapes(bias_shape, [out_size]) or compatible_shapes(bias_shape, [1, out_size]), \
- 'Incorrect FullyConnected bias shape `{}` for node {}. `out-size`={}'.format(bias_shape, node, out_size)
-
- node.out_port(0).data.set_shape([*input_shape[:-1], out_size])
-
-
-# MatMul-like operations for IR V6
-class Gemm(MatMul):
- """
- Represents GEMM operation that is acceptable to appear in v6 IRs
- Inherits MatMul semantic to be re-inferred in back phase and to be successfully translated to IR (v6)
- """
- op = 'GEMM'
- enabled = False
diff --git a/tools/mo/openvino/tools/mo/ops/NextIteration.py b/tools/mo/openvino/tools/mo/ops/NextIteration.py
deleted file mode 100644
index 64ff627c702108..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/NextIteration.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class NextIteration(Op):
- op = "NextIteration"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'in_ports_count': 1,
- 'infer': NextIteration.enter_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def enter_infer(node: Node):
- output_shape = node.in_node(0).shape
- output_value = node.in_node(0).value
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = mo_array(output_shape)
- node.graph.node[out_node]['value'] = None if output_value is None else mo_array(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/ONNXResize10.py b/tools/mo/openvino/tools/mo/ops/ONNXResize10.py
deleted file mode 100644
index f9d98e668387fc..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ONNXResize10.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ONNXResize10(Op):
- op = 'ONNXResize10'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/ONNXResize11.py b/tools/mo/openvino/tools/mo/ops/ONNXResize11.py
deleted file mode 100644
index 3990dd867fc851..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ONNXResize11.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ONNXResize11Op(Op):
- op = 'ONNXResize11'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'out_ports_count': 1,
- 'infer': ONNXResize11Op.onnx_resize_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'coordinate_transformation_mode',
- 'cube_coeff',
- 'exclude_outside',
- 'extrapolation_value',
- 'mode',
- 'nearest_mode'
- ]
-
- @staticmethod
- def onnx_resize_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- if input_shape is None:
- return
-
- assert (node.is_in_port_connected(0) and (node.is_in_port_connected(2) or node.is_in_port_connected(3))), \
- "One of the scales or sizes inputs must be connected to Node {} with op {}." \
- "".format(node.soft_get("name", node.id), node.op)
-
- assert node.coordinate_transformation_mode != 'tf_crop_and_resize', \
- 'Mode tf_crop_and_resize is not supported for op {} with name {}'.format(node.op,
- node.soft_get("name", node.id))
-
- if not node.is_in_port_connected(3):
- # i.e. input 'sizes' is not given
- input2_value = node.in_port(2).data.get_value()
- assert input2_value is not None, \
- "Node {} with op {} has no value in input port 2".format(node.soft_get('name', node.id), node.op)
- scale = mo_array(input2_value)
- output_shape = np.floor(input_shape * scale + 1.0e-6).astype(np.int64)
- else:
- # i.e. input 'sizes' is given
- sizes = node.in_port(3).data.get_value()
- assert sizes is not None, \
- "Node {} with op {} has no value in input port 3".format(node.soft_get("name", node.id), node.op)
- output_shape = input_shape.copy()
- spatial_dimension_indices = range(2, len(input_shape))
- output_shape[spatial_dimension_indices] = sizes[2:]
-
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/RNN.py b/tools/mo/openvino/tools/mo/ops/RNN.py
deleted file mode 100644
index ea73368cc1fa10..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/RNN.py
+++ /dev/null
@@ -1,242 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins, shape_insert, dynamic_dimension, \
- shape_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph, add_opoutput, Error
-from openvino.tools.mo.ops.op import Op
-
-
-class RNN(Op):
- op = 'RNN'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': 'RNNSequence', # should be never emitted to IR; for debugging purposes
- 'op': self.op,
- 'blobs_wrb': False,
- 'has_num_directions': False,
- 'direction': 'forward',
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'multiplier': 1,
- 'gate_order': mo_array([0]), # Only one gate in this cell
- 'normalized': False,
-
- 'activation_alpha': None,
- 'activation_beta': None,
- 'activations': None,
- 'clip': None,
- 'in_ports_count': 6,
- 'out_ports_count': 2,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def supported_attrs():
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'axis',
-
- # Additional attributes
- 'activation_alpha',
- 'activation_beta',
- 'activations',
- 'clip',
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'axis',
-
- # Additional attributes
- 'activation_alpha',
- 'activation_beta',
- ('activations', lambda node: ','.join(node.activations) if node.activations is not None else None),
- 'clip',
- ]
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) >= 3 # X, W and R
- assert len(node.in_nodes()) <= 5
- assert len(node.out_nodes()) <= 2
-
- rnn_infer(node, [1])
-
- @staticmethod
- def reverse_infer(node: Node):
- if node.in_port(0).data.get_shape() is not None:
- return
-
- input_size = get_rnn_input_size(node)
- batch_size, seq_len = get_rnn_batch_size_and_seq_len(node)
- # ONNX has the same input layout
- input_shape = shape_array([seq_len, batch_size, input_size])
- if node.format == 'tf':
- input_shape = shape_array([batch_size, seq_len, input_size])
-
- node.in_port(0).data.set_shape(input_shape)
-
-
-def rnn_infer(node: Node, out_ports=None):
- """
- General infer function for RNN, GRU, LSTM layers.
- Assume that 0-port input of node is input data for recurrent layer and node have attrs:
- hidden_size,
- """
- if out_ports is None:
- out_ports = []
-
- # 1. Necessary checks (from ONNX specification)
- assert node.batch_dim <= 1
- assert node.sequence_dim <= 1
- assert node.batch_dim != node.sequence_dim
- assert node.direction in ['forward', 'reverse', 'bidirectional']
-
- if node.blobs_wrb:
- mark_input_bins(node, ['W', 'R', 'B'])
- else:
- mark_input_bins(node)
-
- # 2. Output shape calculations
- input_shape = node.in_node(0).shape
- assert len(input_shape) == 3
-
- # Reshape input nodes
- for port in [2, 3]:
- if port in node.in_nodes() and len(node.in_node(port).in_nodes()) > 0 and \
- 'zero_shapes' in node.in_node(port).in_node():
- for i in node.in_node(port).in_node().zero_shapes:
- if node.in_node(port).shape[i] != input_shape[i]:
- node.in_node(port).value = np.repeat(node.in_node(port).value, input_shape[i], axis=i)
- node.in_node(port).shape[i] = input_shape[i]
-
- out_shape = [input_shape[node.sequence_dim], input_shape[node.batch_dim], node.hidden_size]
-
- if node.batch_dim == 0:
- out_shape = [input_shape[node.batch_dim], input_shape[node.sequence_dim], node.hidden_size]
-
- num_directions = 2 if node.direction in ['bidirectional'] else 1
- if node.has_num_directions:
- # ONNX-like, insert extra dimension to output shape for num_directions
- out_shape = shape_insert(out_shape, 1, np.int64(num_directions))
-
- # 0 output is required creating it if doesn't exist
- if 0 not in node.out_nodes():
- data_node = Op._create_data_node(
- node.graph,
- name=node.node + '/ExtraOutput/{}'.format(0),
- attrs={'executable': True}
- )
- if 0 not in node.out_ports():
- node.add_output_port(0)
- node.graph.add_edge(node.id, data_node.id, key=0, out=0)
- add_opoutput(node.graph, data_node.id, 0, False)
- node.out_port(0).data.set_shape(out_shape)
-
- # 3. Extra outputs for hidden/cell states shape calculations (optional)
- state_size = [input_shape[node.batch_dim], node.hidden_size]
- if node.has_num_directions:
- state_size = shape_insert(state_size, 0, num_directions)
-
- if node.multilayers:
- # For multilayer case state sizes from every layer will be concatenated by last axis
- num_layers = node.num_layers
- state_size[-1] *= num_layers
-
- for i in out_ports:
- # If node hasn't consumers for hidden/cells state -> create them
- if i not in node.out_nodes():
- data_node = Op._create_data_node(
- node.graph,
- name=node.node + '/ExtraOutput/' + str(i),
- attrs={'executable': True}
- )
- if i not in node.out_ports():
- node.add_output_port(i)
- node.graph.add_edge(node.id, data_node.id, key=0, out=i)
- add_opoutput(node.graph, data_node.id, 0, False)
- else:
- data_node = node.out_node(i)
- data_node.shape = shape_array(state_size)
-
-
-def get_rnn_batch_size_and_seq_len(node: Node):
- """
- Gets batch_size and sequence_length from RNN constant inputs
- and output shapes retrieved during reverse_infer
-
- :param node:
- :return:
- """
- node_name = node.soft_get('name', node.id)
- out_shape = node.out_port(0).data.get_shape()
- batch_size = dynamic_dimension
- seq_len = dynamic_dimension
- in_port_with_initial_states = 3 # initial hidden size values is framework dependent
-
- if out_shape is not None:
- # note that op is not in opset state but in the state of the original framework
- if node.batch_dim == 1:
- seq_len = out_shape[0]
-
- if node.format == 'onnx':
- assert len(out_shape) == 4, 'incorrect out_shape rank for node {}'.format(node_name)
- # even for ONNX in extractor 'batch_dim': 1 (front/onnx/lstm_ext.py:26) despite the fact that
- # out_shape = [seq_len, num_directions, batch_size, hidden_size]
- batch_size = out_shape[2]
- in_port_with_initial_states = 5
- elif node.format == 'tf':
- log.error('reverse infer for TensorFlow RNN operation {} is not implemented yet'.format(node_name),
- extra={'is_warning': True})
- else:
- raise Error('Incorrect framework name')
- elif node.batch_dim == 0:
- # out_shape = [batch_size, num_directions, seq_len, hidden_size]
- batch_size = out_shape[0]
- seq_len = out_shape[2]
- in_port_with_initial_states = 3
- else:
- raise Error('incorrect batch_dim for node {}'.format(node_name))
-
- if batch_size is dynamic_dimension:
- if node.is_in_port_connected(in_port_with_initial_states):
- initial_hidden_state_size = node.in_port(in_port_with_initial_states).data.get_shape()
- if initial_hidden_state_size is not None:
- batch_size = initial_hidden_state_size[1]
-
- if seq_len is dynamic_dimension and node.format == 'onnx':
- # ONNX can store seq_len in optional input
- if node.is_in_port_connected(4):
- seq_len_val = node.in_port(4).data.get_value()
- if seq_len_val is not None:
- seq_len = seq_len.item()
-
- return [batch_size, seq_len]
-
-
-def get_rnn_input_size(node: Node):
- node_name = node.soft_get('name', node.id)
- assert node.is_in_port_connected(1), 'weights input is not connected'
-
- if node.format == 'onnx':
- # ONNX weights on input 1 contain only W part, R, and B are connected separately
- # weights_shape = `[num_directions, 4 * hidden_size, input_size]`
- weights_size = node.in_port(1).data.get_shape()
- assert len(weights_size) == 3, 'incorrect weights ranks for ONNX {} node {}'.format(node.op, node_name)
- input_size = weights_size[2]
- return input_size
- elif node.format == 'tf':
- log.error('reverse infer for TensorFlow RNN operation {} is not implemented yet'.format(node_name),
- extra={'is_warning': True})
- else:
- raise Error('Incorrect framework name')
diff --git a/tools/mo/openvino/tools/mo/ops/RNNCell.py b/tools/mo/openvino/tools/mo/ops/RNNCell.py
deleted file mode 100644
index 0f48644eb4039e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/RNNCell.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class RNNCell(Op):
- """ A single RNN cell (without a loop).
-
- 2 inputs:
- - [0, required] input data (2D),
- - [1, required] initial hidden state (2D),
-
- 2 blobs:
- - [2, required] cell FC weights
- - [3, required] cell FC biases
-
- 1 outputs:
- - [required] output data / resulting hidden state (2D)
- """
- op = 'RNNCell'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'infer': self.infer,
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- 'version': 'opset3',
- 'wr_input_id': 2,
- 'gates_count': 1
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'activations',
- 'activation_alpha',
- 'activation_beta',
- 'clip',
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- ('activations', lambda node: ','.join(node.activations) if node.activations is not None else None),
- 'activation_alpha',
- 'activation_beta',
- 'clip',
- ]
-
- @staticmethod
- def infer(node: Node):
- assert len(node.out_nodes()) in [1, 2]
-
- hidden_shape = node.in_node(1).shape.copy()
-
- mark_input_bins(node, start_port=2)
- node.out_node(0).shape = hidden_shape
-
- hidden_size = hidden_shape[1]
- if node.has_valid('hidden_size'):
- if node.hidden_size != hidden_size:
- raise Error("Input shape {} for hidden size doesn't match pre-defined hidden_size in node {}".format(
- node.in_node(1).shape, node.soft_get('name')))
- else:
- node['hidden_size'] = hidden_size
diff --git a/tools/mo/openvino/tools/mo/ops/ReduceOps.py b/tools/mo/openvino/tools/mo/ops/ReduceOps.py
deleted file mode 100644
index 569d50fce953ac..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ReduceOps.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, is_fully_defined
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-
-reduce_map = {
- 'ReduceSum': np.sum,
- 'ReduceProd': np.prod,
- 'ReduceL1': lambda x, axis, keepdims: np.sum(a=np.absolute(x), axis=axis, keepdims=keepdims),
- 'ReduceL2': lambda x, axis, keepdims: np.sqrt(np.sum(a=np.square(x), axis=axis, keepdims=keepdims)),
- 'ReduceMax': np.max,
- 'ReduceMin': np.min,
- 'ReduceMean': np.mean,
- 'ReduceAnd': np.all,
- 'ReduceLogicalAnd': np.all,
- 'ReduceLogicalOr': np.any,
-}
-
-
-def reduce_helper(func: callable, x: np.array, axis: tuple, keepdims: bool):
- """
- Performs the reduction of input data tensor "x" over axis "axis" with function "func" and optionally removes reduced
- dimensions (if "keepdims" is False). If the input tensor has dynamic values, all elements of the result tensor
- are changed to be dynamic.
-
- :param func: numpy reduce function
- :param x: the data to perform reduction on
- :param axis: the axis for reduction
- :param keepdims: flag specifying whether keep reduce dimensions or not
- :return: the result tensor
- """
- result = func(x, axis=axis, keepdims=keepdims)
- # we need to handle this case specially to avoid problems with deepcopy method with MaskedConstant converted to
- # masked_array - see issue https://github.com/numpy/numpy/issues/21022
- if isinstance(result, np.ma.core.MaskedConstant):
- return np.ma.masked_array(data=-1, mask=True, dtype=result.dtype)
- if is_fully_defined(x):
- return result
- else:
- return np.ma.masked_array(result, mask=np.ones(result.shape, dtype=bool))
-
-
-def reduce_infer(node: Node):
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 2, \
- "{} node `{}` should have 2 input ports, where 0-input is data input and 1-input represent " \
- "`reduction_indices`".format(node.op, node.id)
-
- in_data = node.in_port(0).data
- in_shape = in_data.get_shape()
- axis = node.in_port(1).data.get_value()
-
- # If the axis is None then reduce over all the dimensions of the input tensor
- if axis.size == 1 and axis.item() is None:
- axis = int64_array(list(range(len(in_shape))))
- node.in_port(1).data.set_value(axis)
-
- assert in_shape is not None, "Can not infer {} node `{}`: shape of 0-input unknown".format(node.op, node.id)
-
- axis = axis.copy()
- if axis.size == 1:
- axis = int64_array([axis.item()])
-
- in_value = in_data.get_value()
-
- if in_value is not None:
- value = reduce_helper(reduce_map[node.op], in_value.copy(), axis=tuple(axis), keepdims=node.keep_dims)
- node.out_port(0).data.set_value(value)
- else:
- used_dims = np.zeros(len(in_shape), dtype=bool)
- output_shape = in_shape.copy()
-
- for dim in axis:
- used_dims[dim] = True
- output_shape[dim] = 1
-
- # In case if keep dims == False, we should remove all 1 dims that was used in reduction
- if not node.keep_dims:
- output_shape = output_shape[np.invert(used_dims)]
-
- node.out_port(0).data.set_shape(output_shape)
-
- # if the operation changes the rank of the output tensor then it is necessary to insert Permute if the input is 4D
- # or 5D
- if not node.keep_dims:
- node['reinterp_shape'] = True
-
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
-
-
-class ReduceOp(Op):
- enabled = False
- op = None
- op_type = None
- version = 'opset1'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op_type,
- 'version': self.version,
- 'infer': reduce_infer,
- 'keep_dims': 0,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'force_precision_in_ports': {
- 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'])
-
- def supported_attrs(self):
- return [
- ('keep_dims', lambda node: bool_to_str(node, 'keep_dims')),
- ]
-
-
-class ReduceSum(ReduceOp):
- enabled = True
- op = 'ReduceSum'
- op_type = 'ReduceSum'
-
-
-class ReduceProd(ReduceOp):
- op = 'ReduceProd'
- op_type = 'ReduceProd'
- enabled = True
-
-
-class ReduceMin(ReduceOp):
- op = 'ReduceMin'
- op_type = 'ReduceMin'
- enabled = True
-
-
-class ReduceMax(ReduceOp):
- op = 'ReduceMax'
- op_type = 'ReduceMax'
- enabled = True
-
-
-class ReduceMean(ReduceOp):
- op = 'ReduceMean'
- op_type = 'ReduceMean'
- enabled = True
-
-
-class ReduceL1(ReduceOp):
- op = 'ReduceL1'
- op_type = 'ReduceL1'
- version = 'opset4'
-
-
-class ReduceL2(ReduceOp):
- op = 'ReduceL2'
- op_type = 'ReduceL2'
- version = 'opset4'
-
-
-class ReduceAnd(ReduceOp):
- op = 'ReduceAnd'
- op_type = 'ReduceLogicalAnd'
- enabled = True
-
-
-class ReduceLogicalAnd(ReduceOp):
- op = 'ReduceLogicalAnd'
- op_type = 'ReduceLogicalAnd'
- enabled = True
-
-
-class ReduceLogicalOr(ReduceOp):
- op = 'ReduceLogicalOr'
- op_type = 'ReduceLogicalOr'
- enabled = True
diff --git a/tools/mo/openvino/tools/mo/ops/Reverse.py b/tools/mo/openvino/tools/mo/ops/Reverse.py
deleted file mode 100644
index 9b4af1157b451f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/Reverse.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Reverse(Op):
- op = 'Reverse'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'axis': None,
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node):
- input_shape = node.in_port(0).data.get_shape()
- input_value = node.in_port(0).data.get_value()
- assert input_shape is not None
- if not node.has_valid('axis'):
- assert 1 in node.in_nodes()
- assert node.in_node(1).has_valid('value')
- assert node.in_node(1).value.size == 1
-
- node['axis'] = node.in_node(1).value.item()
- node.in_port(1).disconnect()
-
- assert node.has_valid('axis')
-
- assert len(node.out_nodes()) == 1
- if input_value is not None:
- node.out_port(0).data.set_value(np.flip(input_value, node.axis))
- else:
- node.out_port(0).data.set_shape(input_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/TFFFT.py b/tools/mo/openvino/tools/mo/ops/TFFFT.py
deleted file mode 100644
index d0f10aa5c0b038..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TFFFT.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TFFFT(Op):
- """
- This operation is intended to read TF operations FFT, FFT2D, FFT3D, IFFT, IFFT2D, IFFT3D, RFFT, RFFT2D, RFFT3D,
- IRFFT, IRFFT2D, IRFFT3D. The operation TFFFT has two attributes: an integer attribute num_of_dimensions and
- a string attribute fft_kind.
-
- If an operation is used to read FFT, FFT2D, or FFT3D, then the attribute 'fft_kind' is 'DFT'.
- If an operation is used to read IFFT, IFFT2D, or IFFT3D, then the attribute 'fft_kind' is 'IDFT'.
- If an operation is used to read RFFT, RFFT2D, or RFFT3D, then the attribute 'fft_kind' is 'RDFT'.
- If an operation is used to read IRFFT, IRFFT2D, or IRFFT3D, then the attribute 'fft_kind' is 'IRDFT'.
-
- The attribute 'num_of_dimensions' is equal to number of transformed axes, i.e. 1 for FFT, IFFT, RFFT, and IRFFT;
- 2 for FFT2D, IFFT2D, RFFT2D, and IRFFT2D; 3 for FFT3D, IFFT3D, RFFT3D, and IRFFT3D.
-
- The transformation TFFFTToDFT converts the operation TFFFT into MO operation according to the following rules:
- 1) FFT, FFT2D, FFT3D are converted into DFT;
- 2) IFFT, IFFT2D, IFFT3D are converted into IDFT;
- 3) RFFT, RFFT2D, RFFT3D are converted into RDFT;
- 4) IRFFT, IRFFT2D, IRFFT3D are converted into IRDFT.
- """
- op = 'TFFFT'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'out_ports_count': 1,
- 'in_ports_count': 1,
- }
- assert 'fft_kind' in attrs, 'Attribute fft_kind is not given for the operation TFFFT.'
- assert 'num_of_dimensions' in attrs, 'Attribute num_of_dimensions is not given for the operation TFFFT.'
- super().__init__(graph, mandatory_props, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/TFResize.py b/tools/mo/openvino/tools/mo/ops/TFResize.py
deleted file mode 100644
index 7fa4ab4600d6fd..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TFResize.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TFResize(Op):
- op = 'TFResize'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'out_ports_count': 1,
- 'in_ports_count': 2,
- 'infer': TFResize.tf_resize_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def tf_resize_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- if input_shape is None:
- return
-
- attrs_msg = "If half_pixel_centers attribute of the node {} with op {} is True, " \
- "the attribute align_corners must be False"
- node_name = node.soft_get('name', node.id)
- assert not node.half_pixel_centers or (node.half_pixel_centers and not node.align_corners), \
- attrs_msg.format(node_name, node.op)
-
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 2, \
- "Node {} with op {} number of inputs must be equal to 2.".format(node_name, node.op)
-
- new_sizes_value = node.in_port(1).data.get_value()
- assert new_sizes_value is not None, "Node {} with op {} has no value in input port 1".format(node_name, node.op)
-
- input_rank = len(input_shape)
- assert input_rank == 4, \
- "Resized input data of the node {} with op {} must be 4D tensor".format(node_name, node.op)
-
- len_msg = "Op {} with name {} supports only resize with respect to height and width dimension simultaneously"
- assert len(new_sizes_value) == 2, len_msg.format(node_name, node.op)
-
- output_shape = input_shape.copy()
-
- output_shape[1] = new_sizes_value[0]
- output_shape[2] = new_sizes_value[1]
-
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/TensorArray.py b/tools/mo/openvino/tools/mo/ops/TensorArray.py
deleted file mode 100644
index c0d5c531dbf758..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorArray.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TensorArray(Op):
- op = "TensorArrayV3"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': TensorArray.array_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def array_infer(node: Node):
- size = node.in_node(0)
- assert size.value is not None
-
- # 0 port: handle
- if 0 in node.out_nodes().keys():
- if node.has_valid('element_shape'):
- element_shape = node['element_shape']
- else:
- element_shape = None
-
- out_node = node.out_node(0).id
- output_value = node.out_node(0).id
- node.graph.node[out_node]['value'] = mo_array(output_value)
-
- output_shape = node.graph.node[out_node]['value'].shape
- node.graph.node[out_node]['shape'] = shape_array(output_shape)
-
- node.graph.node[out_node]['element_shape'] = shape_array(element_shape)
- node.graph.node[out_node]['size'] = size.value
- # 1 port flow
- if 1 in node.out_nodes().keys():
- output_value = None
-
- out_node = node.out_node(1).id
- node.graph.node[out_node]['value'] = None if output_value is None else mo_array(output_value)
- node.graph.node[out_node]['shape'] = shape_array(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/TensorArrayGather.py b/tools/mo/openvino/tools/mo/ops/TensorArrayGather.py
deleted file mode 100644
index b62960d694f785..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorArrayGather.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.utils import symm_match_shapes
-
-
-class TensorArrayGather(Op):
- op = "TensorArrayGatherV3"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': TensorArrayGather.array_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def array_infer(node: Node):
- assert len(node.in_nodes()) == 3
-
- handle = node.in_node(0)
-
- ta_node = Node(node.graph, str(handle.value))
-
- if ta_node.has_valid('element_shape') and ta_node.element_shape is not None and len(ta_node.element_shape) > 0:
- assert symm_match_shapes(ta_node['element_shape'], node.element_shape)
- else:
- ta_node['element_shape'] = node.element_shape
- data_shape = ta_node['element_shape']
-
- assert ta_node.has_valid('size')
- size = ta_node['size']
-
- output_shape = [size] + [data_shape[i] for i in range(len(data_shape))]
-
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = shape_array(output_shape)
- node.graph.node[out_node]['value'] = None
diff --git a/tools/mo/openvino/tools/mo/ops/TensorArrayRead.py b/tools/mo/openvino/tools/mo/ops/TensorArrayRead.py
deleted file mode 100644
index 3275c2921252f7..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorArrayRead.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TensorArrayReader(Op):
- op = "TensorArrayReadV3"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': TensorArrayReader.array_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def array_infer(node: Node):
- assert len(node.in_nodes()) == 3
-
- handle = node.in_node(0)
-
- ta_node = Node(node.graph, str(handle.value))
- assert ta_node.has_valid('element_shape')
-
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = shape_array(ta_node['element_shape'])
- node.graph.node[out_node]['value'] = None
diff --git a/tools/mo/openvino/tools/mo/ops/TensorArrayScatter.py b/tools/mo/openvino/tools/mo/ops/TensorArrayScatter.py
deleted file mode 100644
index 0294f5bee38a47..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorArrayScatter.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.utils import match_shapes
-
-
-class TensorArrayScatter(Op):
- op = "TensorArrayScatterV3"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': TensorArrayScatter.array_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def array_infer(node: Node):
- handle = node.in_node(0)
- value = node.in_node(2)
- flow_in = node.in_node(3)
-
- ta_node = Node(node.graph, str(handle.value))
- if ta_node.has_valid('element_shape') and len(ta_node.element_shape) > 0:
- assert match_shapes(ta_node['element_shape'], value.shape[1:]), \
- 'Shapes are not compatible: {} and {}'.format(ta_node['element_shape'], value.shape[1:])
- else:
- ta_node['element_shape'] = value.shape[1:]
-
- # Assign element_shape anyway, because the original element_shape can contain -1
- ta_node['element_shape'] = value.shape[1:]
-
- output_value = flow_in.value
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = shape_array(flow_in.shape)
- node.graph.node[out_node]['value'] = None if output_value is None else mo_array(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/TensorArraySize.py b/tools/mo/openvino/tools/mo/ops/TensorArraySize.py
deleted file mode 100644
index d0322999f0c9ac..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorArraySize.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TensorArraySize(Op):
- op = "TensorArraySizeV3"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': TensorArraySize.array_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def array_infer(node: Node):
- assert len(node.in_nodes()) == 2
-
- handle = node.in_node(0)
-
- ta_node = Node(node.graph, str(handle.value))
- assert ta_node.has_valid('size')
-
- output_value = mo_array(ta_node['size'])
-
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = shape_array(output_value.shape)
- node.graph.node[out_node]['value'] = output_value.copy()
diff --git a/tools/mo/openvino/tools/mo/ops/TensorArrayWrite.py b/tools/mo/openvino/tools/mo/ops/TensorArrayWrite.py
deleted file mode 100644
index 516412572c04ff..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorArrayWrite.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.utils import match_shapes
-
-
-class TensorArrayWriter(Op):
- op = "TensorArrayWriteV3"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': TensorArrayWriter.array_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def array_infer(node: Node):
- assert len(node.in_nodes()) == 4
-
- handle = node.in_node(0)
- index = node.in_node(1)
- value = node.in_node(2)
- flow_in = node.in_node(3)
-
- value_shape = value.shape
-
- ta_node = Node(node.graph, str(handle.value))
- if ta_node.has_valid('element_shape') and len(ta_node.element_shape) > 0:
- assert match_shapes(ta_node['element_shape'], value.shape), \
- 'Shapes are not compatible: {} and {}'.format(ta_node['element_shape'], value.shape)
- ta_node['element_shape'] = value_shape
-
- output_value = flow_in.value
-
- for _, out_node in node.graph.out_edges(node.id):
- node.graph.node[out_node]['shape'] = shape_array(flow_in.shape)
- node.graph.node[out_node]['value'] = None if output_value is None else output_value.copy()
diff --git a/tools/mo/openvino/tools/mo/ops/TensorIterator_ops.py b/tools/mo/openvino/tools/mo/ops/TensorIterator_ops.py
deleted file mode 100644
index 786419f178eb02..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/TensorIterator_ops.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-# TODO: check all supported attributes in this file
-class TensorIteratorInput(Op):
- op = "TensorIteratorInput"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'axis': None,
- 'start': None,
- 'end': None,
- 'stride': None,
- 'part_size': None,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': TensorIteratorInput.input_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['external_port_id', 'internal_layer_id', 'internal_port_id', 'axis', 'start', 'stride', 'part_size']
-
- @staticmethod
- def input_infer(node: Node):
- pass
-
-
-class TensorIteratorOutput(Op):
- op = "TensorIteratorOutput"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'axis': None,
- 'start': None,
- 'end': None,
- 'stride': None,
- 'part_size': None,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': TensorIteratorOutput.input_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['external_port_id', 'internal_layer_id', 'internal_port_id', 'axis', 'start', 'stride', 'part_size']
-
- @staticmethod
- def input_infer(node: Node):
- pass
-
-
-class TensorIteratorCondition(Op):
- op = "TensorIteratorCondition"
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'in_ports_count': 2,
- 'out_ports_count': 2,
- 'infer': TensorIteratorCondition.input_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def input_infer(node: Node):
- pass
-
-
-class TensorIteratorBackEdge(Op):
- op = 'TensorIteratorBackEdge'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': TensorIteratorBackEdge.input_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def input_infer(node: Node):
- pass
diff --git a/tools/mo/openvino/tools/mo/ops/__init__.py b/tools/mo/openvino/tools/mo/ops/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/ops/activation.py b/tools/mo/openvino/tools/mo/ops/activation.py
deleted file mode 100644
index 586f5307a3d65a..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/activation.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Activation(Op):
- op = 'Activation'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': __class__.op,
- 'op': __class__.op,
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['operation']
-
- def backend_attrs(self):
- return [('type', 'operation'), 'alpha'] # operation --> type
diff --git a/tools/mo/openvino/tools/mo/ops/activation_ops.py b/tools/mo/openvino/tools/mo/ops/activation_ops.py
deleted file mode 100644
index 133e02b744b68d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/activation_ops.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.clamp import AttributedClamp
-from openvino.tools.mo.ops.op import Op
-
-activation_ops = ['Sigmoid', 'Tanh', 'ReLU6', 'Exp', 'Elu', 'LogicalNot', 'Floor', 'Ceiling']
-
-
-class Activation(Op):
- enabled = False
- operation = None
- op = None
- version = 'opset1'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'operation': self.operation,
- 'version': self.version,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @classmethod
- def infer(cls, node: Node):
- return eltwise_infer(node, node.operation)
-
-
-class Sigmoid(Activation):
- op = 'Sigmoid'
- operation = staticmethod(lambda x: 1 / (1 + np.ma.exp(-x)))
-
-
-class Sin(Activation):
- op = 'Sin'
- operation = staticmethod(lambda x: np.ma.sin(x))
-
-
-class Sinh(Activation):
- op = 'Sinh'
- operation = staticmethod(lambda x: np.ma.sinh(x))
-
-
-class Asin(Activation):
- op = 'Asin'
- operation = staticmethod(lambda x: np.ma.arcsin(x))
-
-
-class Asinh(Activation):
- op = 'Asinh'
- version = 'opset4'
- operation = staticmethod(lambda x: np.arcsinh(x))
-
-
-class Cos(Activation):
- op = 'Cos'
- operation = staticmethod(lambda x: np.ma.cos(x))
-
-
-class Cosh(Activation):
- op = 'Cosh'
- operation = staticmethod(lambda x: np.ma.cosh(x))
-
-
-class Acos(Activation):
- op = 'Acos'
- operation = staticmethod(lambda x: np.ma.arccos(x))
-
-
-class Acosh(Activation):
- op = 'Acosh'
- version = 'opset4'
- operation = staticmethod(lambda x: np.ma.arccosh(x))
-
-
-class Tan(Activation):
- op = 'Tan'
- operation = staticmethod(lambda x: np.ma.tan(x))
-
-
-class Tanh(Activation):
- op = 'Tanh'
- operation = staticmethod(lambda x: np.ma.tanh(x))
-
-
-class Atan(Activation):
- op = 'Atan'
- operation = staticmethod(lambda x: np.ma.arctan(x))
-
-
-class Atanh(Activation):
- op = 'Atanh'
- version = 'opset4'
- operation = staticmethod(lambda x: np.ma.arctanh(x))
-
-
-class ReLU6(AttributedClamp):
- def __init__(self, graph: Graph, attrs: dict):
- relu6_attrs = {'min': 0, 'max': 6}
- relu6_attrs.update(attrs)
- super().__init__(graph, relu6_attrs)
-
-
-class Exp(Activation):
- op = 'Exp'
- operation = staticmethod(lambda x: np.ma.exp(x))
-
-
-class ReLU(Activation):
- op = 'ReLU'
- operation = staticmethod(lambda x: np.ma.maximum(0, x))
-
-
-class Erf(Activation):
- op = 'Erf'
- operation = None
-
-
-class Floor(Activation):
- op = 'Floor'
- operation = staticmethod(lambda x: x if np.issubdtype(x.dtype, np.integer) else np.ma.floor(x))
-
-
-class Ceiling(Activation):
- op = 'Ceiling'
- operation = staticmethod(lambda x: np.ma.ceil(x))
-
-
-class Abs(Activation):
- op = 'Abs'
- operation = staticmethod(lambda x: np.ma.abs(x))
-
-
-class Sign(Activation):
- op = 'Sign'
- operation = staticmethod(lambda x: np.sign(x))
-
-
-class Elu(Activation):
- op = 'Elu'
-
- def __init__(self, graph: Graph, attrs):
- elu_attrs = {'alpha': 1.0}
- elu_attrs.update(attrs)
- super().__init__(graph, elu_attrs)
-
- @staticmethod
- def elu(values: np.ndarray, alpha: float):
- values = values.astype(float)
- for index, x in np.ndenumerate(values):
- if x < 0:
- values[index] = alpha * (np.ma.exp(x) - 1)
- return values
-
- @classmethod
- def infer(cls, node: Node):
- return eltwise_infer(node, lambda x, alpha: Elu.elu(x, alpha), alpha=node.alpha)
-
- def backend_attrs(self):
- return ['alpha']
-
-
-class ThresholdedRelu(Activation):
- # The operation will be decomposed to primitive operations
- op = 'ThresholdedRelu'
-
- def __init__(self, graph: Graph, attrs):
- trelu_attrs = {'alpha': 1.0, 'type': None}
- trelu_attrs.update(attrs)
- super().__init__(graph, trelu_attrs)
-
- @staticmethod
- def thresholded_relu(values: np.ndarray, alpha: float):
- values = values.astype(float)
- for index, x in np.ndenumerate(values):
- values[index] = values[index] * (x > alpha)
- return values
-
- @classmethod
- def infer(cls, node: Node):
- return eltwise_infer(node, lambda x, alpha: ThresholdedRelu.thresholded_relu(x, alpha), alpha=node.alpha)
-
-
-class LeakyReLU(Op):
- op = 'LeakyReLU'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'infer': self.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def leaky_relu(values: np.ndarray, negative_slope: float):
- for index, x in np.ndenumerate(values):
- if x < 0:
- values[index] = negative_slope * x
- return values
-
- @staticmethod
- def infer(node: Node):
- return eltwise_infer(node, lambda x, negative_slope: LeakyReLU.leaky_relu(x, negative_slope),
- negative_slope=node.negative_slope)
-
- def supported_attrs(self):
- return ['negative_slope']
-
-
-class LogicalNot(Activation):
- op = 'LogicalNot'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- not_attrs = {'type_infer': self.type_infer}
- not_attrs.update(attrs)
- super().__init__(graph, not_attrs)
-
- operation = staticmethod(lambda x: np.ma.logical_not(x))
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(bool)
-
-
-class Log(Activation):
- op = 'Log'
- operation = staticmethod(lambda x: np.ma.log(x))
-
-
-class SoftPlus(Activation):
- op = 'SoftPlus'
- version = 'opset4'
- operation = staticmethod(lambda x: np.ma.log(np.ma.exp(x) + 1.0))
-
-
-class Mish(Activation):
- op = 'Mish'
- version = 'opset4'
- operation = staticmethod(lambda x: x * np.ma.tanh(np.ma.log(np.ma.exp(x) + 1.0)))
-
-
-class HSwish(Activation):
- op = 'HSwish'
- version = 'opset4'
- operation = staticmethod(lambda x: x * np.ma.minimum(np.ma.maximum(x + 3.0, 0.0), 6.0) / 6.0)
-
-
-class HSigmoid(Activation):
- op = 'HSigmoid'
- version = 'opset5'
- operation = staticmethod(lambda x: np.ma.minimum(np.ma.maximum(x + 3.0, 0.0), 6.0) / 6.0)
-
-
-class Swish(Op):
- op = 'Swish'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset4',
-
- 'infer': self.infer,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
-
- beta = 1.0
- if node.is_in_port_connected(1):
- beta = node.in_port(1).data.get_value()
- if beta is not None:
- assert beta.ndim == 0, 'The "beta" value for node {} must be a scalar'.format(node_name)
- beta = beta.item()
-
- input_value = node.in_port(0).data.get_value()
- if input_value is not None and beta is not None:
- node.out_port(0).data.set_value(input_value / (1.0 + np.exp(-input_value * beta)))
-
-
-class SoftSign(Activation):
- op = "SoftSign"
- version = "opset9"
- operation = staticmethod(lambda x: x / (np.ma.abs(x) + 1))
diff --git a/tools/mo/openvino/tools/mo/ops/adaptive_avg_pooling.py b/tools/mo/openvino/tools/mo/ops/adaptive_avg_pooling.py
deleted file mode 100644
index ceead9e5edf07e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/adaptive_avg_pooling.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.pooling import Pooling
-
-
-class AdaptiveAvgPooling(Op):
- '''
- Non-reshape-able op.
- '''
- enabled = False
- op = 'AdaptiveAvgPooling'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': __class__.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @classmethod
- def infer(cls, node: Node):
- input_shape = node.in_node(0).shape
- input_h = input_shape[2]
- input_w = input_shape[3]
- output_h = node.output_size[0]
- output_w = node.output_size[1]
-
- stride_h = input_h // output_h
- stride_w = input_w // output_w
- kernel_h = input_h - (output_h - 1) * stride_h
- kernel_w = input_w - (output_w - 1) * stride_w
-
- data = {
- 'window': int64_array([1, 1, kernel_h, kernel_w]),
- 'stride': int64_array([1, 1, stride_h, stride_w]),
- 'pad': int64_array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'pad_spatial_shape': int64_array([[0, 0], [0, 0]]),
- 'pool_method': 'avg',
- 'exclude_pad': False,
- 'output_spatial_shape': None,
- 'spatial_dims': None,
- 'channel_dims': int64_array([1]),
- 'batch_dims': int64_array([0]),
- 'layout': 'NCHW',
- 'rounding_type': 'floor',
- 'pooling_convention': 'valid'
- }
-
- # update the attributes of the node
- Pooling.update_node_stat(node, data)
- Pooling.infer(node)
diff --git a/tools/mo/openvino/tools/mo/ops/argmax.py b/tools/mo/openvino/tools/mo/ops/argmax.py
deleted file mode 100644
index 6bb00b0109334f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/argmax.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-def arg_ops_infer(node: Node):
- shape = node.in_port(0).data.get_shape()
- node_name = node.soft_get('name', node.id)
- assert shape is not None, "Input shape for the node {} is None".format(node_name)
-
- # there are two inputs in TensorFlow. The second input is the axis for ArgMax
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- if len(connected_in_ports) == 2:
- axis = node.in_port(1).data.get_value()
- if axis is None:
- log.debug('The second argument to {} is None'.format(node.soft_get('name', node.id)))
- return
- node.axis = axis
- # remove the unnecessary input
- node.in_port(1).disconnect()
-
- num_top_axes = shape.size
- if num_top_axes < 3:
- num_top_axes = 3
-
- out_shape = np.ones(num_top_axes, dtype=np.int64)
-
- if node.has_valid('axis'):
- axis = get_canonical_axis_index(shape, node.axis)
- node.axis = axis
- out_shape = shape.copy()
- out_shape[axis] = node.top_k
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
- else:
- out_shape[0] = shape[0]
- out_shape[2] = node.top_k
- if node.has_and_set('out_max_val'):
- out_shape[1] = 2
-
- node.out_port(0).data.set_shape(out_shape)
-
-
-class ArgMaxOp(Op):
- op = 'ArgMax'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': arg_ops_infer,
- 'output_type': np.int64,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'out_max_val',
- 'top_k',
- 'axis',
- ]
diff --git a/tools/mo/openvino/tools/mo/ops/argmin.py b/tools/mo/openvino/tools/mo/ops/argmin.py
deleted file mode 100644
index 448856e73f82d0..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/argmin.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.argmax import arg_ops_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ArgMinOp(Op):
- op = 'ArgMin'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'infer': arg_ops_infer,
- 'output_type': np.int64,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'top_k',
- 'axis',
- ]
diff --git a/tools/mo/openvino/tools/mo/ops/assert_op.py b/tools/mo/openvino/tools/mo/ops/assert_op.py
deleted file mode 100644
index 7725918dc3fe5d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/assert_op.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Assert(Op):
- op = 'Assert'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'infer': Assert.assert_infer,
- 'cf_infer': Assert.assert_control_flow_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def assert_infer(node: Node):
- assert_value = node.in_node(0).value
- node.out_node().value = assert_value.copy()
- node.out_node().shape = []
-
- @staticmethod
- def assert_control_flow_infer(node: Node, is_executable: bool, mark_executability: callable):
- """
- Infers control flow through assert operation node. It marks output data nodes executability according to
- executability of current node and assert data value
- :param node: Node instance to infer control flow through
- :param is_executable: if current node is executable
- :param mark_executability: function to mark executability of node
- """
- graph = node.graph
- assert_value = node.out_node().value
- for n in [v for _, v in graph.out_edges(node.id)]:
- mark_executability(n, assert_value and is_executable)
-
diff --git a/tools/mo/openvino/tools/mo/ops/assign.py b/tools/mo/openvino/tools/mo/ops/assign.py
deleted file mode 100644
index 3ab82769a27409..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/assign.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class Assign(Op):
- op = 'Assign'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset6',
- 'infer': self.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return ['variable_id']
-
- @staticmethod
- def infer(node: Node):
- assert node.has_valid('variable_id'), \
- "There is no required attribute variable_id in Assign op with name " + node.id
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
diff --git a/tools/mo/openvino/tools/mo/ops/aten.py b/tools/mo/openvino/tools/mo/ops/aten.py
deleted file mode 100644
index 9fbefaa8f96142..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/aten.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ATen(Op):
- op = 'ATen'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
-
- 'infer': None,
- }, attrs)
-
- def supported_attrs(self):
- return ['mode', 'operator']
diff --git a/tools/mo/openvino/tools/mo/ops/axpy.py b/tools/mo/openvino/tools/mo/ops/axpy.py
deleted file mode 100644
index 0ff157c16b2ef2..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/axpy.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class AxpyOp(Op):
- """
- Empty Op for Axpy layer. It will be replaced by AxpyToSSandAdd FrontReplacer
- """
- op = 'Axpy'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': __class__.op,
- 'infer': None
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/binarization.py b/tools/mo/openvino/tools/mo/ops/binarization.py
deleted file mode 100644
index 9187756cf46dd5..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/binarization.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Binarization(Op):
- op = 'Binarization'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'infer': None,
- 'dst_type': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/box_nms.py b/tools/mo/openvino/tools/mo/ops/box_nms.py
deleted file mode 100644
index 7484d4809cd2cb..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/box_nms.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class BoxNms(Op):
- """
- It is assumed that there is no equivalent of this op in IE.
- """
- op = '_contrib_box_nms'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'coord_start': 2,
- 'force_suppress': False,
- 'id_index': 0,
- 'overlap_thresh': 0.45,
- 'score_index': 1,
- 'topk': 400,
- 'valid_thresh': 0.01,
- 'infer': self.infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'coord_start',
- 'force_suppress',
- 'id_index',
- 'overlap_thresh',
- 'score_index',
- 'topk',
- 'valid_thresh',
- ]
-
- @staticmethod
- def infer(node: Node):
- raise Error(
- "Operation _contrib_box_nms not not supported. " +
- "For gluoncv ssd topologies use cmd parameter: '--enable_ssd_gluoncv' " +
- refer_to_faq_msg(102))
diff --git a/tools/mo/openvino/tools/mo/ops/broadcast.py b/tools/mo/openvino/tools/mo/ops/broadcast.py
deleted file mode 100644
index 5bc1b89d4a9008..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/broadcast.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, shape_array, undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.broadcasting import bi_directional_shape_broadcasting, uni_directional_shape_broadcasting, \
- uni_directional_broadcasting, bi_directional_broadcasting, explicit_broadcasting, explicit_shape_broadcasting
-from openvino.tools.mo.utils.error import Error
-
-
-class Broadcast(Op):
- """ Broadcast tensor to a given shape with optional axis parameter
-
- Inputs:
- [0] - tensor to be broadcasted
- [1] - shape to be broadcast to
- [2] - optional axes_mapping tensor
- """
-
- op = 'Broadcast'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset3',
- 'mode': 'numpy',
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'force_precision_in_ports':
- {1: 'int64',
- 2: 'int64',
- },
- 'infer': self.infer,
- }, attrs)
-
- def supported_attrs(self):
- return ['mode']
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
-
- input_shape = node.in_port(0).data.get_shape()
- input_value = node.in_port(0).data.get_value()
- target_shape_shape = node.in_port(1).data.get_shape()
- target_shape = node.in_port(1).data.get_value()
- assert node.has_and_set('mode'), 'Broadcasting mode is not defined for node "{}"'.format(node_name)
-
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'output:0', 'shape')
-
- # Dynamic target shape is possible to infer only if shape of target shape is static
- if target_shape is None:
- assert len(target_shape_shape) == 1, 'Shape of target_shape must be [1] for node "{}"'.format(node_name)
- assert is_fully_defined(target_shape_shape), 'Output shape is not defined for node "{}"'.format(node_name)
- new_shape = undefined_shape_of_rank(target_shape_shape.item(0))
- node.out_port(0).data.set_shape(new_shape)
- if node.mode == 'explicit':
- assert node.is_in_port_connected(
- 2), 'Axes mapping must be specified for Broadcast(mode="explicit"). Node: `{}`'.format(node_name)
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'output:0', 'axis')
- return
-
- if input_value is not None and not node.has_and_set('stop_value_propagation') and \
- is_fully_defined(target_shape):
- if node.mode == 'numpy':
- node.out_port(0).data.set_value(uni_directional_broadcasting(input_value, target_shape))
- elif node.mode == 'bidirectional':
- node.out_port(0).data.set_value(bi_directional_broadcasting(input_value, target_shape))
- elif node.mode == 'explicit':
- axes_mapping = node.in_port(2).data.get_value()
- assert axes_mapping is not None, 'Broadcast(mode="explicit") with dynamic axes_mapping input ' \
- 'is not supported. Node: `{}`'.format(node_name)
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'output:0', 'axis')
- axes_mapping = node.in_port(2).data.get_value()
- node.out_port(0).data.set_value(explicit_broadcasting(input_value, target_shape, axes_mapping))
- else:
- raise Error('The node "{}" has unsupported mode "{}"'.format(node_name, node.mode))
- else:
- if node.mode == 'numpy':
- node.out_port(0).data.set_shape(uni_directional_shape_broadcasting(input_shape, target_shape))
- elif node.mode == 'bidirectional':
- node.out_port(0).data.set_shape(bi_directional_shape_broadcasting(input_shape, target_shape))
- elif node.mode == 'explicit':
- axes_mapping = node.in_port(2).data.get_value()
- assert axes_mapping is not None, 'Broadcast(mode="explicit") with dynamic axes_mapping input ' \
- 'is not supported. Node: `{}`'.format(node_name)
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'output:0', 'axis')
- axes_mapping = node.in_port(2).data.get_value()
- new_shape, _ = explicit_shape_broadcasting(input_shape, target_shape, axes_mapping)
- node.out_port(0).data.set_shape(new_shape)
- else:
- raise Error('The node "{}" has unsupported mode "{}"'.format(node_name, node.mode))
diff --git a/tools/mo/openvino/tools/mo/ops/bucketize.py b/tools/mo/openvino/tools/mo/ops/bucketize.py
deleted file mode 100644
index f7ddc506f64489..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/bucketize.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-
-
-class Bucketize(Op):
- op = 'Bucketize'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'kind': 'op',
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset3',
-
- 'type_infer': self.type_infer,
- 'infer': self.infer,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == "extension":
- return [('with_right_bound', lambda node: bool_to_str(node, 'with_right_bound'))]
- else:
- return [
- ('with_right_bound', lambda node: bool_to_str(node, 'with_right_bound')),
- ('output_type', lambda node: np_data_type_to_destination_type(node.output_type)),
- ]
-
- @staticmethod
- def type_infer(node):
- # the output is always integer since the layer outputs a bucket index
- if node.get_opset() == "extension":
- node.out_port(0).set_data_type(np.int32)
- else:
- assert node.output_type in [np.int64, np.int32], \
- 'Bucketize `output_type` attribute must be int32 or int64, `{}` found' \
- ''.format(np.dtype(node.output_type).name)
- node.out_port(0).set_data_type(node.output_type)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- assert node.with_right_bound is not None, \
- "Attribute \"with_right_bound\" is not defined"
- assert len(node.in_nodes()) == 2, \
- "Incorrect number of inputs for {} node".format(node.id)
- if node.get_opset() != "extension":
- assert node.has_valid('output_type'), \
- '`output_type` attribute is not set for Bucketize node `{}`'.format(node_name)
- assert node.output_type in [np.int64, np.int32], \
- 'Bucketize `output_type` attribute must be int32 or int64, `{}` found'.format(np.dtype(node.output_type).name)
-
- output_shape = node.in_port(0).data.get_shape()
- node.out_port(0).data.set_shape(output_shape)
-
- input_value = node.in_port(0).data.get_value()
- buckets_value = node.in_port(1).data.get_value()
-
- # compute if all input is constant
- if input_value is not None and buckets_value is not None:
- node.out_port(0).data.set_value(mo_array(np.digitize(input_value, buckets_value, right=node.with_right_bound), dtype=node.output_type))
diff --git a/tools/mo/openvino/tools/mo/ops/clamp.py b/tools/mo/openvino/tools/mo/ops/clamp.py
deleted file mode 100644
index 56d9a5b348ff06..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/clamp.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class AttributedClamp(Op):
- op = 'AttributedClamp'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': 'Clamp',
- 'op': self.op,
- 'version': 'opset1',
- 'infer': self.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return [
- 'max',
- 'min'
- ]
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
-
- assert len(connected_in_ports) == 1 and connected_in_ports[0].idx == 0, \
- 'AttributedClamp should have only one input, but it has {}'.format(len(connected_in_ports))
- assert node.has_valid('max') and node.has_valid('min'), \
- 'Mandatory attributes `max` and `min` were not set for AttributedClamp node: `{}`'.format(name)
- assert node.max >= node.min, \
- 'AttributedClamp max=={} is less than min=={} for node `{}`'.format(node.max, node.min, name)
-
- if node.in_port(0).data.get_value() is not None:
- node.out_port(0).data.set_value(np.clip(node.in_port(0).data.get_value(), node['min'], node['max']))
- else:
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
-
-
-class Clamp(Op):
- op = 'Clamp'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
- min_input_connected = node.has_port('in', 1) and not node.in_port(1).disconnected()
- max_input_connected = node.has_port('in', 2) and not node.in_port(2).disconnected()
-
- input_value = node.in_port(0).data.get_value()
- min_value = node.in_port(1).data.get_value() if min_input_connected else np.finfo(np.float32).min
- max_value = node.in_port(2).data.get_value() if max_input_connected else np.finfo(np.float32).max
-
- if input_value is not None and min_value is not None and max_value is not None:
- assert np.all(max_value >= min_value), \
- 'Clamp max_value=={} is less than min_value=={} for node `{}`'.format(max_value, min_value, name)
- node.out_port(0).data.set_value(np.clip(node.in_port(0).data.get_value(), min_value, max_value))
- else:
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
diff --git a/tools/mo/openvino/tools/mo/ops/concat.py b/tools/mo/openvino/tools/mo/ops/concat.py
deleted file mode 100644
index 9a561b4af77e6f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/concat.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.op import Op
-
-
-class Concat(Op):
- op = 'Concat'
- enabled = True
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'axis': 1,
- 'infer': concat_infer,
- 'reverse_infer': self.reverse_infer,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['axis']
-
- @staticmethod
- def reverse_infer(node: Node):
- assert hasattr(node, 'axis')
- out_shape = node.out_port(0).data.get_shape()
-
- if out_shape is None:
- return
-
- out_shape[node.axis] = dynamic_dimension
-
- for in_port in node.in_ports().values():
- in_shape = in_port.data.get_shape()
- if in_shape is None:
- in_port.data.set_shape(out_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/const.py b/tools/mo/openvino/tools/mo/ops/const.py
deleted file mode 100644
index 8c6e3cb1380018..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/const.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, int64_array
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np, np_data_type_to_destination_type, \
- precision_to_destination_type
-from openvino.tools.mo.ops.op import Op
-
-
-class Const(Op):
- """
- Operation producing constant value stored in the attribute 'value' of shape 'shape'.
- """
- op = 'Const'
-
- def __init__(self, graph, attrs: dict = None):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'infer': self.infer,
- 'value': None,
- 'shape': None,
- 'data_type': None,
- 'out_ports_count': 1,
- 'type_infer': self.type_infer,
- }, attrs)
- if not isinstance(self.attrs['value'], np.ndarray):
- self.attrs['value'] = mo_array(self.attrs['value'])
-
- self.attrs['shape'] = int64_array(self.attrs['value'].shape)
- if 'force_shape' in self.attrs and self.attrs['force_shape'] is not None:
- self.attrs['shape'] = int64_array(self.attrs['force_shape'])
-
- self.attrs['data_type'] = self.attrs['value'].dtype
- if 'force_type' in self.attrs and self.attrs['force_type'] is not None:
- self.attrs['data_type'] = data_type_str_to_np(self.attrs['force_type'])
-
- def supported_attrs(self):
- return [
- 'offset',
- 'size',
- ('shape', lambda node: ','.join([str(i) for i in node.shape])),
- ('element_type', lambda node: precision_to_destination_type(node.force_type)
- if node.has_valid('force_type') else np_data_type_to_destination_type(node.value.dtype)),
- ]
-
- @staticmethod
- def type_infer(node):
- node.out_port(0).set_data_type(node.value.dtype, override=True)
- if node.has_valid('force_type'):
- node.out_port(0).set_data_type(node.data_type, override=True)
-
- @staticmethod
- def infer(node):
- # no broadcast, copy as-is (tensor or scalar) or apply broadcast depending on value and shape
- output_value = node.value if isinstance(node.value, np.ndarray) or len(node.shape) == 0 \
- else np.full(node.shape, node.value)
-
- node.out_port(0).data.set_value(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/constant_fill.py b/tools/mo/openvino/tools/mo/ops/constant_fill.py
deleted file mode 100644
index 294e1d8bfd7c35..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/constant_fill.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ConstantFill(Op):
- """ Constant blob generation by broadcasting specified value to a given shape.
-
- It is assumed that there is no equivalent of this op in IE,
- so it is usually relevant to constant folding.
- """
- op = 'ConstantFill'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'input_as_shape': 1,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': self.infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'input_as_shape',
- 'fill_value'
- ]
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) == 1
- assert node.fill_value is not None
- assert node.input_as_shape
-
- shape = node.in_port(0).data.get_value()
- assert shape is not None
-
- if is_fully_defined(shape):
- node.out_port(0).data.set_value(np.full(shape, node.fill_value, np.float32))
- else:
- node.out_port(0).data.set_shape(shape)
diff --git a/tools/mo/openvino/tools/mo/ops/constant_of_shape.py b/tools/mo/openvino/tools/mo/ops/constant_of_shape.py
deleted file mode 100644
index 76ced6f78fcb53..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/constant_of_shape.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ConstantOfShape(Op):
- """ Create a tensor of the shape specified in the first input with all values equal to attribute 'value'.
- The operation is converted to Broadcast operation
- """
-
- op = 'ConstantOfShape'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'kind': 'op',
- 'type': None,
- 'op': __class__.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'fill_value': 0,
- 'infer': None,
- }, attrs)
-
- def supported_attrs(self):
- return ['fill_value']
diff --git a/tools/mo/openvino/tools/mo/ops/convolution.py b/tools/mo/openvino/tools/mo/ops/convolution.py
deleted file mode 100644
index 6a75ad1d45b39f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/convolution.py
+++ /dev/null
@@ -1,310 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mark_input_bins, assign_dims_to_weights, \
- tf_window_op_pad_infer, dynamic_dimension_value, shape_array, is_fully_defined, undefined_shape_of_rank
-from openvino.tools.mo.front.onnx.extractors.utils import get_backend_pad
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.pipeline.common import convert_const_node_value_type
-from openvino.tools.mo.utils.error import Error
-
-
-class Convolution(Op):
- op = 'Convolution'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'type_infer': self.type_infer,
- 'multiplication_transparent': True,
- 'multiplication_transparent_ports': [(0, 0), (1, 0)],
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- def pad_attribute_helper(node: Node, pad_type: str='begin'):
- assert pad_type in ['begin', 'end']
- if not node.has_valid('pad'):
- return None
- pad = get_backend_pad(node.pad, node.spatial_dims, 0 if pad_type == 'begin' else 1)
- if node.has_valid('auto_pad') and node.auto_pad != 'explicit':
- pad = [0 for _ in pad]
- return ','.join(map(str, pad))
-
- return [
- ('auto_pad', lambda node: node.auto_pad if node.has_valid('auto_pad') else 'explicit'),
- ('strides', lambda node: ','.join(map(str, node['stride'][node.spatial_dims]))),
- ('dilations', lambda node: ','.join(map(str, node['dilation'][node.spatial_dims]))),
- ('pads_begin', lambda node: pad_attribute_helper(node, 'begin')),
- ('pads_end', lambda node: pad_attribute_helper(node, 'end')),
-
- # for Backpropdata operations only - according to spec
- ('output_padding', lambda node: ','.join(map(str, node.output_padding[node.spatial_dims])) \
- if node.has_valid('output_padding') and node.type in
- ('GroupConvolutionBackpropData', 'ConvolutionBackpropData') else None),
-
- # for BinaryConvolution only
- 'pad_value',
- 'mode',
- ]
-
- @staticmethod
- def calc_convolution(input_spatial_shape, stride_spatial_shape, pad_spatial_shape, kernel_extent):
- """
- Calculates output shape for Convolution.
- Verified to be applicable for both Caffe and ONNX.
- """
- spatial_val_wo_stride = input_spatial_shape + pad_spatial_shape - kernel_extent
-
- if np.any(spatial_val_wo_stride < 0):
- raise Error("Data after padding has dimension less than window size. " +
- "Possible reason of error is incorrectly specified model input shape(s).")
-
- return spatial_val_wo_stride / stride_spatial_shape + 1
-
- @staticmethod
- def calc_deconvolution(node, input_spatial_shape, pad_spatial_shape, kernel_extent):
- """
- Calculates output shape for Deconvolution.
- Verified to be applicable for both Caffe and ONNX with explicitly defined pads.
- If pads are not specified for ONNX operator, this function is not applicable.
- """
- return node.stride[node.spatial_dims] * (input_spatial_shape - 1) + kernel_extent - pad_spatial_shape
-
- @staticmethod
- def infer(node: Node):
- """
- Infers shape of convolution node as it is done in ONNX.
- It is very similar to one that Caffe does, but slightly different.
- We made a complete fork of this function because they are supposed to be
- supported differently by different people.
- Args:
- node: graph convolution node
- """
- input_shape = node.in_port(0).data.get_shape()
- if input_shape is None:
- raise Error('Input data shape is None for node {}'.format(node.soft_get('name', node.id)))
-
- # bias_term cannot be deduced earlier for frameworks that represent
- # convolution weights/biases as regular inputs; so the number of inputs
- # is being checked here and restore correct value for bias_term to
- # have the rest of the code unchanged. It will be used after we merge
- # several infer functions for convolution in different FWs to a single one.
- if not node.has_valid('bias_term'):
- node['bias_term'] = len(node.in_nodes()) == 3
-
- weights_index = node.weights_index if node.has_valid('weights_index') else 1
- # Reshape weights kernel to original shape
- # In case of Caffe framework, values for weights have no structured shape like OIHW
- # so we have to reshape weights to normal shape
- # For this case, Convolution node should have attribute reshape_kernel = True
- if node.has_valid('reshape_kernel') and node.reshape_kernel:
- if not (node.has_valid('output') and node.has_valid('channel_dims') and node.has_valid(
- 'group') and node.has_valid('kernel_spatial')):
- log.error('Cannot reshape kernel due to not all required attrs was set to {} node'.format(node.id))
- return
-
- # since item() unmasks values, result should be masked back
- num_in_channels = shape_array(input_shape[node.channel_dims].item())
-
- # layout for Convolution weights is OIHW
- kernel_shape = shape_array([node.output, num_in_channels / node.group,
- *[node.kernel_spatial[i] for i in range(len(node.kernel_spatial))]])
- if node.type == 'Deconvolution': # layout for Deconvolution weights is IOHW
- kernel_shape[[0, 1]] = kernel_shape[[1, 0]]
-
- if is_fully_defined(kernel_shape) and np.prod(kernel_shape) != np.prod(node.in_node(weights_index).value.shape):
- log.error("Size of weights {} does not match kernel shape: {}\n"
- "".format(np.prod(node.in_node(weights_index).value.shape), kernel_shape) +
- " Possible reason is wrong channel number in input shape\n")
- raise Error("Cannot reshape weights to kernel shape")
-
- if not is_fully_defined(kernel_shape):
- num_undefined = np.count_nonzero(kernel_shape.mask is True) # pylint: disable=no-member
- if num_undefined > 1:
- raise Error('Too many undefined dimensions of the kernel shape for node {}. Use --input_shape '
- 'command line parameter to specify model input shapes'.format(node.soft_get('name',
- node.id)))
- kernel_size = np.prod(node.in_node(weights_index).value.shape)
- # calculate undefined dimension using fully defined shape of the weights input and known kernel_shape
- # dimensions
- kernel_shape[np.where(kernel_shape == np.ma.masked)[0][0]] = kernel_size // np.prod(kernel_shape)
-
- node.in_node(weights_index).shape = shape_array(kernel_shape)
- node.in_node(weights_index).value = np.reshape(node.in_node(weights_index).value, kernel_shape)
- node.reshape_kernel = False
-
- # Pass weights shape to node attribute kernel_shape
- kernel_shape = node.in_node(weights_index).shape
- node['kernel_shape'] = kernel_shape
- # Calculate kernel_spatial_idx and spatial_dims if it is not specified
- # It is necessary for ONNX dut to convolution can be 1D/2D/3D
- if not node.has_valid('kernel_spatial_idx'):
- node['kernel_spatial_idx'] = np.delete([x for x in range(len(kernel_shape))],
- (node.input_feature_channel, node.output_feature_channel))
-
- if not node.has_valid('spatial_dims'):
- node['spatial_dims'] = np.delete([x for x in range(len(input_shape))],
- (node.channel_dims[0], node.batch_dims[0]))
-
- node['kernel_spatial'] = kernel_shape[node.kernel_spatial_idx]
-
- if not node.has_valid('output'):
- # restore the number of output feature maps from the second argument that is weights
- if node.type in ['Convolution', 'Deconvolution', 'DeformableConvolution', 'BinaryConvolution']:
- node['output'] = kernel_shape[node.output_feature_channel]
- else:
- raise Error(
- 'Convolution infer function was called for a node {} with unsupported type {}',
- node.soft_get('name'),
- node.type
- )
-
- # Set default values for dilation, strides and pads if not set
- if not node.has_valid('dilation'):
- node['dilation'] = np.full([len(input_shape)], 1, dtype=np.int64)
- if not node.has_valid('stride'):
- node['stride'] = np.full([len(input_shape)], 1, dtype=np.int64)
- if not node.has_valid('pad'):
- node['pad'] = int64_array([[0, 0]] * len(input_shape))
- node['pad_spatial_shape'] = node.pad[node.spatial_dims]
-
- if not node.has_valid('output_padding'):
- node['output_padding'] = np.full([len(input_shape)], 0, dtype=np.int64)
-
- if node.has_valid('output_padding') and len(input_shape) > len(node['output_padding']):
- output_padding = np.zeros(len(input_shape), dtype=np.int64)
- for i in range(len(node['output_padding'])):
- output_padding[i] = node['output_padding'][i]
- node['output_padding'] = output_padding
-
- input_spatial_shape = input_shape[node.spatial_dims]
- stride_spatial_shape = node.stride[node.spatial_dims]
-
- kernel_extent = node.dilation[node.spatial_dims] * (node.kernel_spatial - 1) + 1
- # TensorFlow always has auto_pad attribute that can be either valid or same_upper
- # In ONNX auto_pad attribute is deprecated but appears in some models (could be valid, same_upper or same_lower)
- # Caffe do not use auto_pad attribute
- if node.has_valid('auto_pad') and node.auto_pad != 'explicit' and not node.has_valid('output_spatial_shape'):
- node['pad_spatial_shape'], node['output_spatial_shape'] = tf_window_op_pad_infer(input_spatial_shape,
- kernel_extent,
- stride_spatial_shape,
- node.auto_pad,
- node.type == 'Deconvolution')
-
- pad = np.zeros((len(input_shape), 2), dtype=np.int64)
- pad[node.spatial_dims] = node.pad_spatial_shape
- node.pad = pad
- else:
- pad_spatial_shape = np.add.reduce(node.pad_spatial_shape, axis=1)
- if node.type in ('Convolution', 'BinaryConvolution'):
- float_spatial = Convolution.calc_convolution(input_spatial_shape, stride_spatial_shape,
- pad_spatial_shape,
- kernel_extent)
- node['output_spatial_shape'] = shape_array(float_spatial)
- elif node.type == 'Deconvolution':
- # In case of given output_spatial_shape we calculate pads spatial
- if node.has_valid('output_spatial_shape'):
- if node.has_valid('get_pad'):
- node['pad'] = node.get_pad(node, input_shape, kernel_shape)
- else:
- log.debug('Can\'t calculate paddings due to missing lambda get_pad in {} node'.format(node.id))
- return
- else:
- output_padding = node.output_padding[node.spatial_dims] if node.has_valid('output_padding') else None
- if output_padding is not None and any(output_padding):
- pad_spatial_shape -= output_padding
- for dim in range(len(pad_spatial_shape)):
- node.pad_spatial_shape[dim][1] -= pad_spatial_shape[dim]
-
- float_spatial = Convolution.calc_deconvolution(node, input_spatial_shape, pad_spatial_shape,
- kernel_extent)
- node['output_spatial_shape'] = shape_array(float_spatial)
- elif node.type == 'DeformableConvolution':
- # get the output spatial shape from the second input with offsets
- node['output_spatial_shape'] = int64_array([node.in_node(1).shape[2:4]])
- else:
- assert 'Unsupported layer type "{}"'.format(node.type)
-
- # For cases when group attribute wasn't set in extractor we should specify get_group attribute
- # this attribute should store lambda node: ... (check tf convolution extractor)
- if node.has_valid('get_group'):
- node['group'] = node.get_group(node)
- output_shape = shape_array([dynamic_dimension_value for _ in range(len(input_shape))])
- output_shape[node.batch_dims] = input_shape[node.batch_dims] # pylint: disable=unsupported-assignment-operation
- output_shape[node.spatial_dims] = node.output_spatial_shape # pylint: disable=unsupported-assignment-operation
-
- # For cases when output attribute wasn't set in extractor we should specify get_output_feature_dim attribute
- # this attribute should store lambda node: ... (check tf convolution extractor)
- if node.has_valid('get_output_feature_dim'):
- node['output'] = node.get_output_feature_dim(node)
- output_shape[node.channel_dims] = node.output # pylint: disable=unsupported-assignment-operation
- node['output_shape'] = output_shape
-
- node.out_port(0).data.set_shape(output_shape)
-
- # bin attribute is used for pre-processing, but it will be deleted in BlobNormalizer transformation
- # and the blobs (weights, biases) will be represented as inputs to the node
- mark_input_bins(node, start_port=1 if node.type != 'DeformableConvolution' else 2)
- assign_dims_to_weights(node.in_node(weights_index), node.kernel_spatial_idx, node.input_feature_channel,
- node.output_feature_channel, len(kernel_shape))
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('pad', 'input:0'),
- ('stride', 'input:0'),
- ('dilation', 'input:0'),
- ('output_shape', 'input:0'),
- ('batch_dims', 'input:0'),
- ('channel_dims', 'input:0'),
- ('spatial_dims', 'input:0'),
-
- ('kernel_shape', 'input:{}'.format(weights_index)),
- ('kernel_spatial_idx', 'input:{}'.format(weights_index)),
- ('input_feature_channel', 'input:{}'.format(weights_index)),
- ('output_feature_channel', 'input:{}'.format(weights_index)),
- ])
-
- # is needed to permute Conv weights from the original TF [H, W, C_IN, C_OUT] into OV [C_OUT, C_IN, H, W]
- # but for other nodes in weights subgraph permutations must turned off
- # by marking with MarkSubGraphsWithCorrectLayout even if graph layout is NCHW.
- PermuteAttrs.set_permutation(node.in_node(weights_index), node, node.soft_get('get_weights_permute', None))
- PermuteInputs().set_input_permutation(
- node.in_node(weights_index), node, 'input:{}'.format(weights_index), 'transpose')
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- if input_shape is None:
- shape = None
- # TODO FIXME this is ugly solution based on various attributes which may not be set in some cases
- for attr in ['dilation', 'stride', 'pad']:
- if node.has_valid(attr):
- shape = undefined_shape_of_rank(len(node.soft_get(attr)))
- break
- if shape is not None:
- node.in_port(0).data.set_shape(shape)
-
- @staticmethod
- def type_infer(node):
- in_type_0 = node.in_port(0).get_data_type()
- in_type_1 = node.in_port(1).get_data_type()
- in_node_1 = node.in_port(1).get_source().node
- # in case of input values data type mismatch we try to change the type of the constant to match the type of
- # input at index 0.
- if in_type_1 in [np.float16, np.float32, np.float64] and in_type_0 != in_type_1 and in_node_1.op == 'Const':
- in_node_1 = node.in_port(1).get_source().node
- log.error("Changing Const node '{}' data type from {} to {} for Convolution operation".format(
- in_node_1.soft_get('name', in_node_1.id), in_type_1, in_type_0),
- extra={'is_warning': True})
- convert_const_node_value_type(in_node_1, in_type_0)
- node.out_port(0).set_data_type(node.in_port(0).get_data_type())
diff --git a/tools/mo/openvino/tools/mo/ops/copyop.py b/tools/mo/openvino/tools/mo/ops/copyop.py
deleted file mode 100644
index bdf1322826c43f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/copyop.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class CopyOp(Op):
- """
- Empty Op for Copy layer. It will be replaced by FrontReplacer
- """
- op = 'copy'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': __class__.op,
- 'infer': None
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/crop.py b/tools/mo/openvino/tools/mo/ops/crop.py
deleted file mode 100644
index 2344da7d4f12d4..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/crop.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.utils.error import Error
-
-
-class Crop(Op):
- op = 'Crop'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': self.infer,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return [
- ('axis', lambda node: None if not node.has_valid('axis') else ','.join(map(str, node.axis))),
- ('offset', lambda node: None if not node.has_valid('offset') else ','.join(map(str, node.offset))),
-
- ('dim', lambda node: None if not node.has_valid('dim') else ','.join(map(str, node.dim))),
-
- ('crop_begin', lambda node: None if not node.has_valid('crop_begin') else ','.join(map(str,
- node.crop_begin))),
- ('crop_end', lambda node: None if not node.has_valid('crop_end') else ','.join(map(str, node.crop_end))),
- ]
-
- @staticmethod
- def infer(node: Node):
- """
- Crops the shape of the output blob according to input ones be specified params.
- Detailed Crop description can be found in IR Catalog specification.
- In short: crop layer can be represented in three ways:
- 1. Two inputs, where the shape of the second input is crop dim (axis and offset attrs)
- 2. One input and dim, axis and offset attributes.
- 3. Ont input and axis, crop_begin and crop_end attributes
- """
-
- input_count = len(node.in_nodes())
-
- if input_count == 2:
- Crop._two_inputs_infer(node)
- elif input_count == 1:
- Crop._one_input_infer(node)
- else:
- log.error('Wrong number of input tensors ({}) in {}'.format(input_count, node.name))
- return
-
- @staticmethod
- def _one_input_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- node_name = node.soft_get('name', node.id)
- if input_shape is None:
- raise Error('input_shape is none for {} node'.format(node_name))
-
- if not node.has_valid('axis'):
- raise Error('axis attribute is missing for {} node. should be set in crop extractor'.format(node_name))
-
- output_shape = input_shape.copy()
- if node.has_valid('dim'):
- if len(node.dim) != len(node.axis):
- raise Error('Number of axis "{}" should match number of dim "{}" for node "{}"'
- ''.format(node.axis, node.dim, node_name))
- output_shape[node.axis] = node.dim
- elif node.has_valid('crop_begin') and node.has_valid('crop_end'):
- if len(node.crop_begin) != len(node.axis) or len(node.crop_end) != len(node.axis):
- raise Error('number of crop_begin({})/crop_end({}) should match number of axis "{}" for node "{}"'
- ''.format(node.crop_begin, node.crop_end, node.axis, node_name))
- if type(node.axis) in [list, tuple]:
- for i in range(len(node.axis)):
- output_shape[node.axis[i]] = output_shape[node.axis[i]] - node.crop_begin[i] - node.crop_end[i]
- else:
- output_shape[node.axis] = output_shape[node.axis] - node.crop_begin - node.crop_end
- else:
- raise Error('Crop node {} should have either dim or crop_begin and crop_end attributes'.format(node_name))
-
- node.out_port(0).data.set_shape(output_shape)
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
- @staticmethod
- def _two_inputs_infer(node: Node):
- N = len(node.in_nodes())
- node_name = node.soft_get('name', node.id)
-
- shapes = [node.in_port(i).data.get_shape() for i in range(N)]
- if any(s is None for s in shapes):
- raise Error('Not all input shapes were defined for {} node'.format(node_name))
-
- if not node.has_valid('axis'):
- raise Error('axis attribute is missing for {} node. should be set in crop extractor'.format(node_name))
-
- if not node.has_valid('offset'):
- raise Error('offset attribute is missing for {} node. should be set in crop extractor'.format(node_name))
-
- input_shape = shapes[0].copy()
- start_axis = get_canonical_axis_index(input_shape, node.axis)
- node.axis = start_axis
-
- reference_shape = shapes[1].copy()
- if node.has_valid('axes'):
- # The axes parameter contain shape indexes for second input and show which shape indexes we need to use for
- # dim attribute.
- input_dim = node.axes
- node.in_port(1).disconnect()
- else:
- input_dim = list(range(0, input_shape.size))
-
- # set new shape to current shape
- new_shape = input_shape.copy()
- ir_axis = []
- ir_offset = []
- dim = []
-
- for i in input_dim:
- if i < start_axis:
- new_shape[i] = input_shape[i]
- continue
-
- crop_offset = 0
- if len(node.offset) == 1:
- crop_offset = node.offset[0]
- elif len(node.offset) > 1:
- crop_offset = node.offset[i - start_axis]
-
- if input_shape[i] - crop_offset < reference_shape[i]:
- raise Error('The crop for dimension is out of bounds in node {}'.format(node_name))
-
- dim.append(reference_shape[i])
- ir_axis.append(i)
- ir_offset.append(crop_offset)
- new_shape[i] = reference_shape[i]
-
- node.axis = ir_axis
- node.offset = ir_offset
- node['dim'] = dim
- node.out_port(0).data.set_shape(new_shape)
-
- if node.in_node(0).has_valid('value') and \
- not getattr(node.graph.graph['cmd_params'], 'enable_ssd_gluoncv', False):
- out_value = np.copy(node.in_node(0).value)
-
- slice_indexes = []
- for s in out_value.shape:
- slice_indexes.append(slice(0, s))
-
- for axis in input_dim:
- slice_indexes[axis] = slice(0, new_shape[axis])
- out_value = out_value[tuple(slice_indexes)]
- node.out_port(0).data.set_value(out_value)
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
diff --git a/tools/mo/openvino/tools/mo/ops/ctc_greedy_decoder.py b/tools/mo/openvino/tools/mo/ops/ctc_greedy_decoder.py
deleted file mode 100644
index 6966628aef3a68..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ctc_greedy_decoder.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, compatible_dims
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class CTCGreedyDecoderOp(Op):
- op = 'CTCGreedyDecoder'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
- 'reinterp_shape': True,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
-
- 'ctc_merge_repeated': True
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- ('ctc_merge_repeated', lambda node: bool_to_str(node, 'ctc_merge_repeated'))
- ]
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 2, \
- "Incorrect number of inputs for {} node".format(node_name)
-
- logits_shape = node.in_port(0).data.get_shape()
- sequence_mask_shape = node.in_port(1).data.get_shape()
-
- # check shapes of input tensors
- assert len(logits_shape) == 3, \
- 'Incorrect rank of logits for {} node'.format(node_name)
- assert len(sequence_mask_shape) == 2, \
- 'Incorrect rank of sequence length tensor for {} node'.format(node_name)
- assert compatible_dims(logits_shape[1], sequence_mask_shape[1]), \
- 'Batch dimensions of input tensors must be the same for {} node'.format(node_name)
- assert compatible_dims(logits_shape[0], sequence_mask_shape[0]), \
- 'Time dimensions of input tensors must be the same for {} node'.format(node_name)
-
- batch_size = logits_shape[1]
- time_size = logits_shape[0]
- node.out_port(0).data.set_shape([batch_size, time_size, 1, 1])
diff --git a/tools/mo/openvino/tools/mo/ops/ctc_greedy_decoder_seq_len.py b/tools/mo/openvino/tools/mo/ops/ctc_greedy_decoder_seq_len.py
deleted file mode 100644
index 1d65597a905b1c..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ctc_greedy_decoder_seq_len.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, compatible_dims
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class CTCGreedyDecoderSeqLenOp(Op):
- op = 'CTCGreedyDecoderSeqLen'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset6',
-
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'in_ports_count': 3,
- 'out_ports_count': 2,
-
- 'merge_repeated': True,
- 'classes_index_type': np.int32,
- 'sequence_length_type': np.int32
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == 'opset6':
- return [('classes_index_type', lambda node: np_data_type_to_destination_type(node.classes_index_type)),
- ('sequence_length_type', lambda node: np_data_type_to_destination_type(node.sequence_length_type)),
- ('merge_repeated', lambda node: bool_to_str(node, 'merge_repeated'))]
- else:
- raise Error('Unknown opset version "{}"'.format(version))
-
- @staticmethod
- def type_infer(node):
- opset = node.get_opset()
- if opset == 'opset6':
- node.out_port(0).set_data_type(node.classes_index_type)
- node.out_port(1).set_data_type(node.sequence_length_type)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) in [2, 3], \
- "Incorrect number of inputs for {} node".format(node_name)
-
- logits_shape = node.in_port(0).data.get_shape()
- sequence_len_shape = node.in_port(1).data.get_shape()
- if len(node.in_nodes()) == 3:
- blank_index_shape = node.in_port(2).data.get_shape()
- assert len(blank_index_shape) == 1, \
- 'Incorrect rank of blank_index for {} node'.format(node_name)
-
- # check shapes of input tensors
- assert len(logits_shape) == 3, \
- 'Incorrect rank of logits for {} node'.format(node_name)
-
- assert len(sequence_len_shape) == 1, \
- 'Incorrect rank of sequence length tensor for {} node'.format(node_name)
- assert compatible_dims(logits_shape[0], sequence_len_shape[0]), \
- 'Batch dimensions of input tensors must be the same for {} node'.format(node_name)
-
- batch_size = logits_shape[0]
- time_size = logits_shape[1]
- if node.is_out_port_connected(0):
- node.out_port(0).data.set_shape([batch_size, time_size])
- if node.is_out_port_connected(1):
- node.out_port(1).data.set_shape([batch_size])
diff --git a/tools/mo/openvino/tools/mo/ops/ctc_loss.py b/tools/mo/openvino/tools/mo/ops/ctc_loss.py
deleted file mode 100644
index 2066be6afbe8eb..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/ctc_loss.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, compatible_dims
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class CTCLoss(Op):
- op = 'CTCLoss'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset4',
-
- 'type_infer': self.type_infer,
- 'infer': self.infer,
-
- 'in_ports_count': 5,
- 'out_ports_count': 1,
-
- 'preprocess_collapse_repeated': False,
- 'ctc_merge_repeated': True,
- 'unique': False
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [('preprocess_collapse_repeated', lambda node: bool_to_str(node, 'preprocess_collapse_repeated')),
- ('ctc_merge_repeated', lambda node: bool_to_str(node, 'ctc_merge_repeated')),
- ('unique', lambda node: bool_to_str(node, 'unique'))]
-
- @staticmethod
- def type_infer(node):
- logits_type = node.in_port(0).get_data_type()
- logit_length_type = node.in_port(1).get_data_type()
- labels_type = node.in_port(2).get_data_type()
- label_length_type = node.in_port(3).get_data_type()
- blank_index_type = labels_type
- if not node.in_port(4).disconnected():
- blank_index_type = node.in_port(4).get_data_type()
-
- assert logit_length_type == label_length_type and logit_length_type in [np.int64, np.int32], \
- 'Inputs with logits and labels lengths for node {} must be the same and int32 or int64, {} and {} found'.format(
- node.soft_get('name'), logit_length_type, label_length_type)
- assert labels_type == blank_index_type and labels_type in [np.int64, np.int32], \
- 'Inputs with labels and blank index for node {} must be the same and int32 or int64, {} and {} found'.format(
- node.soft_get('name'), labels_type, blank_index_type)
-
- node.out_port(0).set_data_type(logits_type)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) in [4, 5], \
- "Incorrect number of inputs for {} node".format(node_name)
-
- logits_shape = node.in_port(0).data.get_shape()
- logit_length_shape = node.in_port(1).data.get_shape()
- labels_shape = node.in_port(2).data.get_shape()
- label_length_shape = node.in_port(3).data.get_shape()
- blank_index_shape = int64_array([])
- if len(node.in_nodes()) == 5:
- blank_index_shape = node.in_port(4).data.get_shape()
-
- # check shapes of input tensors
- assert len(logits_shape) == 3 and len(logit_length_shape) == 1 and len(labels_shape) == 2\
- and len(label_length_shape) == 1 and len(blank_index_shape) == 0, \
- 'Incorrect rank of some input tensor for {} node'.format(node_name)
- assert compatible_dims(logits_shape[0], logit_length_shape[0]) and \
- compatible_dims(logits_shape[0], labels_shape[0]) and \
- compatible_dims(logits_shape[0], label_length_shape[0]), \
- 'Batch dimensions of input tensors must be the same for {} node'.format(node_name)
- assert compatible_dims(logits_shape[1], labels_shape[1]), \
- 'Time dimensions of input tensors must be the same for {} node'.format(node_name)
-
- batch_size = logits_shape[0]
- node.out_port(0).data.set_shape([batch_size])
diff --git a/tools/mo/openvino/tools/mo/ops/cumsum.py b/tools/mo/openvino/tools/mo/ops/cumsum.py
deleted file mode 100644
index 0cd72270a6153e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/cumsum.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-def cumsum(a, axis=None, exclusive=False, reverse=False):
- if reverse:
- a = np.flip(a, axis)
- res = np.cumsum(a, axis=axis)
- if exclusive:
- res -= a
- if reverse:
- res = np.flip(res, axis)
- return res
-
-
-class CumSum(Op):
- enabled = False
- op = 'CumSum'
- version = 'opset3'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': self.version,
-
- 'infer': self.infer,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return [('exclusive', lambda node: bool_to_str(node, 'exclusive')),
- ('reverse', lambda node: bool_to_str(node, 'reverse'))]
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, 'Input shape is None for node "{}"'.format(node_name)
- if not node.in_port(1).disconnected():
- assert len(node.in_port(1).data.get_shape()) == 0, 'Axis is not scalar for node: {}'.format(node_name)
-
- node.out_port(0).data.set_shape(input_shape.copy())
-
- input_value = node.in_port(0).data.get_value()
- if input_value is not None:
- axis = None if node.in_port(1).disconnected() else node.in_port(1).data.get_value()
- reverse = node.reverse if node.has_valid('reverse') else False
- exclusive = node.exclusive if node.has_valid('exclusive') else False
- node.out_port(0).data.set_value(cumsum(input_value, axis=axis, reverse=reverse, exclusive=exclusive))
diff --git a/tools/mo/openvino/tools/mo/ops/deconvolution.py b/tools/mo/openvino/tools/mo/ops/deconvolution.py
deleted file mode 100644
index 5dc917ec993e7d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/deconvolution.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins, assign_dims_to_weights, tf_window_op_pad_infer, \
- shape_array, compatible_shapes
-from openvino.tools.mo.front.onnx.extractors.utils import get_backend_pad
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-class Deconvolution(Op):
- op = 'Deconvolution'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return [
- ('dilations', lambda node: ','.join(map(str, node['dilation'][node.spatial_dims]))),
- ('strides', lambda node: ','.join(map(str, node['stride'][node.spatial_dims]))),
- ('pads_begin',
- lambda node: ','.join(map(str, get_backend_pad(node.pad, node.spatial_dims, 0))) if node.has_valid(
- 'pad') else None),
- ('pads_end',
- lambda node: ','.join(map(str, get_backend_pad(node.pad, node.spatial_dims, 1))) if node.has_valid(
- 'pad') else None),
- 'auto_pad',
- ]
-
- @staticmethod
- def infer(node: Node):
- """
- Deconvolution has an input argument that explicitly determines output shape, so in contrast
- to the forward Conv2d we shouldn't infer output shape. We just use this output shape as
- an input shape and pass it to our utilities that computes numeric values for padding.
- They also deliver output shape that is interpreted here as input shape for convolution.
- We need to check that the real input shape and shape inferred by those utility functions match.
- """
- output_shape = shape_array(node.in_node(2).value)
- output_shape[0] = node.in_port(0).data.get_shape()[0]
- kernel_shape = node.in_port(1).data.get_shape()
- node['kernel_shape'] = kernel_shape
- if output_shape is None or kernel_shape is None or node.spatial_dims is None or node.stride is None:
- return
-
- if not node.has_valid('kernel_spatial_idx'):
- node['kernel_spatial_idx'] = np.delete([x for x in range(len(kernel_shape))],
- (node.input_feature_channel, node.output_feature_channel))
-
- if not node.has_valid('dilation'):
- node['dilation'] = np.full([len(output_shape)], 1, dtype=np.int64)
-
- if node.has_valid('get_group'):
- node['group'] = node.get_group(node)
-
- spatial_dims = node.spatial_dims
- output_spatial = shape_array(output_shape[spatial_dims])
- stride_spatial = shape_array(node.stride[spatial_dims])
- node['kernel_spatial'] = shape_array(kernel_shape[node.kernel_spatial_idx])
- node.pad_spatial_shape, input_spatial_for_check = tf_window_op_pad_infer(
- output_spatial, node.kernel_spatial, stride_spatial, node.auto_pad)
-
- assert compatible_shapes(input_spatial_for_check, node.in_node(0).shape[spatial_dims])
-
- pad = np.zeros((len(output_shape), 2), dtype=np.int64)
- pad[spatial_dims] = node.pad_spatial_shape
- node.pad = pad
-
- node.output = output_shape[node.channel_dims][0]
- node.output_shape = output_shape
- node.out_port(0).data.set_shape(output_shape)
-
- mark_input_bins(node, ['weights'], 1)
- assign_dims_to_weights(node.in_node(1), node.kernel_spatial_idx, node.input_feature_channel,
- node.output_feature_channel, len(kernel_shape))
-
- # OK, now we are sure this is a supported Deconvolution layer
- node.type = 'Deconvolution'
- node.op = 'Deconv2D'
-
- # Add permute_attrs
- PermuteAttrs.create_permute_attrs(node, attrs=[('pad', 'input:0'),
- ('stride', 'input:0'),
- ('output_shape', 'input:0'),
- ('batch_dims', 'input:0'),
- ('channel_dims', 'input:0'),
- ('spatial_dims', 'input:0'),
-
- ('kernel_shape', 'input:1'),
- ('kernel_spatial_idx', 'input:1'),
- ('input_feature_channel', 'input:1'),
- ('output_feature_channel', 'input:1'),
- ])
-
- # is needed to permute Deconv weights from the original TF [H, W, C_OUT, C_IN] into OV [C_IN, C_OUT, H, W]
- # but for other nodes in weights subgraph permutations must turned off
- # by marking with MarkSubGraphsWithCorrectLayout even if graph layout is NCHW.
- PermuteAttrs.set_permutation(node.in_node(1), node, node.soft_get('get_weights_permute', None))
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:1', 'transpose')
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'shape')
-
- node['force_precision_in_ports'] = {2: 'int64'}
diff --git a/tools/mo/openvino/tools/mo/ops/deformable_convolution.py b/tools/mo/openvino/tools/mo/ops/deformable_convolution.py
deleted file mode 100644
index 5a7fe12ceb8faf..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/deformable_convolution.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.op import Op
-
-
-class DeformableConvolution(Op):
- op = 'DeformableConvolution'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': __class__.op,
- 'op': __class__.op,
- 'version': 'opset8',
- 'infer': Convolution.infer,
- 'group': 1,
- 'deformable_group': 1,
- 'multiplication_transparent': True,
- 'multiplication_transparent_ports': [(0, 0), (2, 0)],
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'bilinear_interpolation_pad': False,
- }, attrs)
-
- def backend_attrs(self):
- # the same attributes as in a regular convolution and additional attributes 'deformable_group', 'group'
- # and 'bilinear_interpolation_pad'
- attrs = Convolution(self.graph, {}).backend_attrs() + ['deformable_group', 'group']
- if self.get_opset() == 'opset8':
- attrs.append('bilinear_interpolation_pad')
- return attrs
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape_1 = node.in_port(0).data.get_shape()
- input_shape_2 = node.in_port(1).data.get_shape()
- if input_shape_1 is None:
- node.in_port(0).data.set_shape(undefined_shape_of_rank(4))
- if input_shape_2 is None:
- node.in_port(1).data.set_shape(undefined_shape_of_rank(4))
diff --git a/tools/mo/openvino/tools/mo/ops/depth_to_space.py b/tools/mo/openvino/tools/mo/ops/depth_to_space.py
deleted file mode 100644
index 741c7373927f6b..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/depth_to_space.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import shape_for_layout, get_height_dim, get_batch_dim, get_features_dim, get_width_dim
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class DepthToSpaceOp(Op):
- op = 'DepthToSpace'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'mode': 'blocks_first',
-
- 'infer': self.infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['mode', 'block_size']
-
- @staticmethod
- def infer(node: Node):
- in_shape = node.in_port(0).data.get_shape()
- if in_shape.size != 4:
- raise Error('TensorFlow DepthToSpace operation is supported for 4D \'NHWC\' input layout only. '
- 'Current input shape is \'{}\''.format(in_shape))
-
- layout = node.graph.graph['layout']
-
- N = in_shape[get_batch_dim(layout, 4)]
- H = in_shape[get_height_dim(layout, 4)]
- W = in_shape[get_width_dim(layout, 4)]
- C = in_shape[get_features_dim(layout, 4)]
-
- block_size = node['block_size']
- if C is not dynamic_dimension and C % (block_size ** 2):
- raise Error('Feature dimensions of input tensor of DepthToSpace operation have to be divisible by square '
- 'of DepthToSpace \'block_size\' parameter. Input tensor shape = {}. Feature dimension = {}. '
- 'block_size = {}'.format(in_shape, C, block_size))
-
- out_shape = shape_for_layout(layout,
- batch=N,
- features=C // (block_size * block_size),
- height=H * block_size,
- width=W * block_size)
-
- if is_fully_defined(in_shape) and is_fully_defined(out_shape) and np.prod(in_shape) != np.prod(out_shape):
- raise Error('Number of input elements "{}" is not equal to number of output elements "" for node "{}"'
- ''.format(in_shape, out_shape, node.soft_get('name', node.id)))
- node.out_port(0).data.set_shape(out_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/dequantize_linear.py b/tools/mo/openvino/tools/mo/ops/dequantize_linear.py
deleted file mode 100644
index b2ae98107ab865..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/dequantize_linear.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class DequantizeLinear(Op):
- op = 'DequantizeLinear'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'axis': None,
- 'version': None,
- 'infer': copy_shape_infer,
- 'out_ports_count': 1,
- 'in_ports_count': 3,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['axis']
diff --git a/tools/mo/openvino/tools/mo/ops/detection_output_onnx.py b/tools/mo/openvino/tools/mo/ops/detection_output_onnx.py
deleted file mode 100644
index f4ab98497f6403..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/detection_output_onnx.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, set_input_shapes
-from openvino.tools.mo.ops.op import Op
-
-
-class ExperimentalDetectronDetectionOutput(Op):
- op = 'ExperimentalDetectronDetectionOutput'
- enabled = True
-
- def __init__(self, graph, attrs):
- mandatory_props = dict(
- type=self.op,
- op=self.op,
- version='opset6',
- infer=self.infer,
- reverse_infer=self.reverse_infer,
- type_infer=self.type_infer,
- in_ports_count=4,
- out_ports_count=3,
- )
-
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [
- ('class_agnostic_box_regression', lambda node: str(bool(node['class_agnostic_box_regression'])).lower()),
- 'max_detections_per_image',
- 'nms_threshold',
- 'num_classes',
- 'post_nms_count',
- 'score_threshold',
- 'max_delta_log_wh',
- ('deltas_weights', lambda node: ','.join(map(str, node['deltas_weights'])))]
-
- @staticmethod
- def infer(node):
- rois_num = node.max_detections_per_image
- # boxes
- node.out_port(0).data.set_shape([rois_num, 4])
- # classes, scores, batch indices
- # We use range(1, 1 + max(node.out_ports().keys())) instead of range(1, 3), because there are incorrectly
- # generated models where ExperimentalDetectronDetectionOutput has 4 outputs.
- for port_ind in range(1, 1 + max(node.out_ports().keys())):
- if not node.out_port(port_ind).disconnected():
- node.out_port(port_ind).data.set_shape([rois_num])
-
- @staticmethod
- def type_infer(node):
- in_data_type = node.in_port(0).get_data_type()
- node.out_port(0).set_data_type(in_data_type)
- node.out_port(1).set_data_type(np.int32) # the second output contains class indices
- node.out_port(2).set_data_type(in_data_type)
- if node.is_out_port_connected(3):
- node.out_port(3).set_data_type(np.int32) # the fourth output contains batch indices
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node,
- shape_array([dynamic_dimension_value, 4]),
- shape_array([dynamic_dimension_value, node['num_classes'] * 4]),
- shape_array([dynamic_dimension_value, node['num_classes']]),
- shape_array([1, 3]))
diff --git a/tools/mo/openvino/tools/mo/ops/dft.py b/tools/mo/openvino/tools/mo/ops/dft.py
deleted file mode 100644
index 5ca6e2eb9326a7..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/dft.py
+++ /dev/null
@@ -1,276 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class FFTBase(Op):
- enabled = False
- op = None
- version = 'opset7'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'out_ports_count': 1,
- 'in_ports_count': 3,
- 'version': self.version,
- 'infer': self.infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def infer(self, node: Node):
- node_name = node.soft_get(node.name, node.id)
- assert len([p for p in node.in_ports().values() if not p.disconnected()]) in [2, 3], \
- '(I)DFT node {} must have 2 or 3 inputs'.format(node_name)
-
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None, 'The input data shape of (I)DFT node {} must not be None'.format(node_name)
- assert src_shape[-1] == 2, \
- 'The last dimension of input shape of (I)DFT node {} should be equal to 2'.format(node_name)
-
- input_rank = len(src_shape)
- assert input_rank >= 2, 'The input rank of (I)DFT node {} should be greater or equal to 2'.format(node_name)
-
- axes = FFTBase.get_axes(node)
- assert input_rank >= len(axes) + 1, \
- 'The input rank must be greater than number of (I)DFT node {} axes'.format(node_name)
- axes = FFTBase.canonicalize_axes(axes, input_rank)
- assert (input_rank - 1) not in axes, '(I)DFT node {} axes cannot contain the last axis'.format(node_name)
- assert len(set(axes)) == len(axes), '(I)DFT node {} axes must be unique.'.format(node_name)
-
- output_shape = src_shape.copy()
- if node.is_in_port_connected(2):
- signal_size = FFTBase.get_signal_size(node)
- signal_size = FFTBase.canonicalize_signal_size(signal_size, axes, src_shape)
- output_shape[axes] = signal_size
-
- node.out_port(0).data.set_shape(output_shape)
-
- @staticmethod
- def canonicalize_axes(axes, input_rank):
- """
- FFT operation supports for negative axes to transform. More precisely, according to the FFT operation
- specification, axes should be integers from -(r - 1) to (r - 2) inclusively, where r = rank(data).
- A negative axis 'a' is interpreted as an axis 'r - 1 + a'. The reason is the following: real input
- tensor of the shape [n_0, ..., n_{r - 1}, 2] is interpreted as a complex tensor with the shape
- [n_0, ..., n_{r - 1}]. Hence, we need to 'canonicalize' axes using the formula 'r - 1 + a'.
-
- :param axes: axes to canonicalize
- :param input_rank: input tensor rank
- :return: canonicalized axes
- """
- result = axes.copy()
- for i, axis in enumerate(axes):
- if axis < 0:
- result[i] = axis + input_rank - 1
- return result
-
- @staticmethod
- def canonicalize_signal_size(signal_size, axes, input_shape):
- result = signal_size.copy()
- for i, axis in enumerate(axes):
- size = signal_size[i]
- if size == -1:
- result[i] = input_shape[axis]
- return result
-
- @staticmethod
- def get_axes(node: Node):
- axes = node.in_port(1).get_source().data.get_value()
- node_name = node.soft_get('name', node.id)
- assert axes is not None, 'The input with axes is not constant for node {}'.format(node_name)
- return int64_array(axes)
-
- @staticmethod
- def get_signal_size(node: Node):
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None
- input_rank = len(src_shape)
- if node.is_in_port_connected(2):
- signal_size = node.in_port(2).get_source().data.get_value()
- else:
- axes = FFTBase.get_axes(node)
- signal_size = [src_shape[: input_rank - 1][a] for a in axes]
-
- node_name = node.soft_get('name', node.id)
- assert signal_size is not None, 'The input with signal_size is not constant for node {}'.format(node_name)
-
- return int64_array(signal_size)
-
-
-class DFT(FFTBase):
- op = 'DFT'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- }
- mandatory_props.update(attrs)
- super().__init__(graph, mandatory_props)
-
-
-class IDFT(FFTBase):
- op = 'IDFT'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- }
- mandatory_props.update(attrs)
- super().__init__(graph, mandatory_props)
-
-
-class RDFT(Op):
- op = 'RDFT'
- enabled = False
- version = 'opset9'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'out_ports_count': 1,
- 'in_ports_count': 3,
- 'version': self.version,
- 'infer': self.infer,
- 'type': self.op,
- 'op': self.op,
- }
- mandatory_props.update(attrs)
- super().__init__(graph, mandatory_props)
-
- def infer(self, node: Node):
- node_name = node.soft_get(node.name, node.id)
- assert len([p for p in node.in_ports().values() if not p.disconnected()]) in [2, 3], \
- 'RDFT node {} must have 2 or 3 inputs'.format(node_name)
-
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None, 'The input data shape of RDFT node {} must not be None'.format(node_name)
-
- input_rank = len(src_shape)
- assert input_rank >= 1, 'The input rank of RDFT node {} should be greater or equal to 1'.format(node_name)
-
- axes = RDFT.get_axes(node)
- assert input_rank >= len(axes), \
- 'The input rank must be greater than or equal to number of RDFT node {} axes'.format(node_name)
- axes = RDFT.canonicalize_axes(axes, input_rank)
- assert len(set(axes)) == len(axes), 'RDFT node {} axes must be unique.'.format(node_name)
-
- output_shape = src_shape.copy()
- if node.is_in_port_connected(2):
- signal_size = RDFT.get_signal_size(node)
- signal_size = RDFT.canonicalize_signal_size(signal_size, axes, src_shape)
- output_shape[axes] = signal_size
- output_shape[axes[-1]] = output_shape[axes[-1]] // 2 + 1
- output_shape = np.ma.append(output_shape, 2)
-
- node.out_port(0).data.set_shape(output_shape)
-
- @staticmethod
- def canonicalize_axes(axes, input_rank):
- """
- RDFT operation supports for negative axes to transform. More precisely, according to the RDFT operation
- specification, axes should be integers from -r to (r - 1) inclusively, where r = rank(data). A negative
- axis 'a' is interpreted as an axis 'r + a'. Hence, we need to 'canonicalize' axes using the formula 'r + a'.
-
- :param axes: axes to canonicalize
- :param input_rank: input tensor rank
- :return: canonicalized axes
- """
- result = axes.copy()
- for i, axis in enumerate(axes):
- if axis < 0:
- result[i] = axis + input_rank
- return result
-
- @staticmethod
- def canonicalize_signal_size(signal_size, axes, input_shape):
- result = signal_size.copy()
- for i, axis in enumerate(axes):
- size = signal_size[i]
- if size == -1:
- result[i] = input_shape[axis]
- return result
-
- @staticmethod
- def get_axes(node: Node):
- axes = node.in_port(1).get_source().data.get_value()
- node_name = node.soft_get('name', node.id)
- assert axes is not None, 'The input with axes is not constant for node {}'.format(node_name)
- return int64_array(axes)
-
- @staticmethod
- def get_signal_size(node: Node):
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None
- input_rank = len(src_shape)
- if node.is_in_port_connected(2):
- signal_size = node.in_port(2).get_source().data.get_value()
- else:
- axes = RDFT.get_axes(node)
- signal_size = [src_shape[: input_rank][a] for a in axes]
-
- node_name = node.soft_get('name', node.id)
- assert signal_size is not None, 'The input with signal_size is not constant for node {}'.format(node_name)
-
- return int64_array(signal_size)
-
-
-class IRDFT(FFTBase):
- enabled = False
- op = 'IRDFT'
- version = 'opset9'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'out_ports_count': 1,
- 'in_ports_count': 3,
- 'version': self.version,
- 'infer': self.infer,
- 'type': self.op,
- 'op': self.op,
- }
- mandatory_props.update(attrs)
- super().__init__(graph, mandatory_props)
-
- def infer(self, node: Node):
- node_name = node.soft_get(node.name, node.id)
- assert len([p for p in node.in_ports().values() if not p.disconnected()]) in [2, 3], \
- 'IRDFT node {} must have 2 or 3 inputs'.format(node_name)
-
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None, 'The input data shape of IRDFT node {} must not be None'.format(node_name)
- assert src_shape[-1] == 2, \
- 'The last dimension of input shape of IRDFT node {} should be equal to 2'.format(node_name)
-
- input_rank = len(src_shape)
- assert input_rank >= 2, 'The input rank of IRDFT node {} should be greater or equal to 2'.format(node_name)
-
- axes = FFTBase.get_axes(node)
- assert input_rank >= len(axes) + 1, \
- 'The input rank must be greater than number of IRDFT node {} axes'.format(node_name)
- axes = FFTBase.canonicalize_axes(axes, input_rank)
- assert (input_rank - 1) not in axes, 'IRDFT node {} axes cannot contain the last axis'.format(node_name)
- assert len(set(axes)) == len(axes), 'IRDFT node {} axes must be unique.'.format(node_name)
-
- output_shape = src_shape.copy()
- input_rank = len(output_shape)
- output_shape = output_shape[0: input_rank - 1]
- if node.is_in_port_connected(2):
- signal_size = FFTBase.get_signal_size(node)
- for i, axis in enumerate(axes):
- if signal_size[i] != -1:
- output_shape[axis] = signal_size[i]
- if signal_size[-1] == -1:
- output_shape[axes[-1]] = 2 * (src_shape[axes[-1]] - 1)
- else:
- output_shape[axes[-1]] = 2 * (src_shape[axes[-1]] - 1)
-
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/dropoutmask.py b/tools/mo/openvino/tools/mo/ops/dropoutmask.py
deleted file mode 100644
index e6062d62ae3e45..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/dropoutmask.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class DropoutMask(Op):
- """
- Operation for dropout proportion, it will be replaced by broadcast constant on front stage
- """
- op = 'dropoutmaskcomponent'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'dropout_proportion': None,
- 'type': None, # type is None because this operation should not appear in IR
- 'infer': None,
- 'in_ports_count': 0,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/einsum.py b/tools/mo/openvino/tools/mo/ops/einsum.py
deleted file mode 100644
index ef3c58d5286367..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/einsum.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import re
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.broadcasting import bi_directional_shape_broadcasting
-
-
-class Einsum(Op):
- op = 'Einsum'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset7',
- 'infer': self.infer,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return ['equation']
-
- @staticmethod
- def is_label_elsewhere(input_subscripts: list, label_to_check: str, excluded_subscript_inds: list) -> bool:
- """
- Check if the given label is met in input subscripts excluding ones specified by a list of indices
- excluded_subscript_inds
-
- :param input_subscripts: input subscripts among which to check if the label is met
- :param label_to_check: a label to check
- :param excluded_subscript_inds: indices of input subscripts to be excluded for this check
- :return: True - met, False - otherwise
- """
- for ind, input_subscript in enumerate(input_subscripts):
- if ind not in excluded_subscript_inds and label_to_check in input_subscript:
- return True
- return False
-
- @staticmethod
- def parse_equation(node_name: str, equation: str) -> (list, str):
- """
- Parse Einsum equation and check that its format is correct to make sure that
- all input subscripts consists of only alphabetic letters or alphabetic letters with one ellipsis.
- In case of implicit mode the method recovers the right-hand part.
-
- :param node_name: Einsum node name for which to parse an equation
- :param equation: Equation to be parsed and checked
- :return: A tuple of a list of input subscripts and output subscript
- """
- # normalize equation by removing white-spaces
- equation = equation.strip()
-
- # split equation into the left and right hands
- splitted_equation = equation.split('->')
- assert len(splitted_equation) <= 2, "Einsum node {} has `equation` of incorrect format".format(node_name)
-
- # split left-hand side of the equation and check a format of input subscripts
- input_subscripts = splitted_equation[0]
- input_subscripts_list = input_subscripts.split(',')
-
- # prepare pattern to check a format of subscripts
- subscript_pattern = re.compile("^[a-zA-Z]*(\\.\\.\\.){0,1}[a-zA-Z]*$")
- ellipsis_pattern = re.compile("\\.\\.\\.")
-
- is_ellipsis_met = False
- for input_subscript in input_subscripts_list:
- assert re.match(subscript_pattern, input_subscript) is not None, \
- "Einsum node {} has `equation` with incorrect input subscript: {}".format(node_name, input_subscript)
- is_ellipsis_met = is_ellipsis_met or re.search(ellipsis_pattern, input_subscript)
-
- if len(splitted_equation) == 2:
- output_subscript = splitted_equation[1]
- assert re.match(subscript_pattern, output_subscript), \
- "Einsum node {} has `equation` with incorrect output subscript: {}".format(node_name, output_subscript)
- # if ellipsis is met, the output subscript must contain it as well
- if is_ellipsis_met:
- assert re.search(ellipsis_pattern, output_subscript), \
- "The output subscript of Einsum node {} must contain ellipsis".format(node_name)
- elif len(splitted_equation) == 1:
- # recover output subscript in case implicit mode
- output_subscript = ""
- for ind, input_subscript in enumerate(input_subscripts_list):
- labels = Einsum.extract_subscript_labels(node_name, input_subscript)
- for label in labels:
- if Einsum.is_label_elsewhere(input_subscripts_list, label, [ind]) is False:
- output_subscript += label
- output_subscript = ''.join(sorted(list(set(output_subscript) - {'.'})))
- if is_ellipsis_met:
- output_subscript = "..." + output_subscript
- else:
- assert False, "Einsum node {} equation has incorrect format. " \
- "It must be in either explicit or implicit mode.".format(node_name)
-
- return input_subscripts_list, output_subscript
-
- @staticmethod
- def normalize_equation(node_name: str, equation: str) -> str:
- """
- Recover explicit mode of equation.
-
- :param node_name: Einsum node name for which to recover explicit mode
- :param equation: Einsum equation to recover explicit mode
- :return: Recovered equation in explicit mode
- """
- input_subscripts_list, output_subscript = Einsum.parse_equation(node_name, equation)
- return ','.join(input_subscripts_list) + "->" + output_subscript
-
- @staticmethod
- def extract_subscript_labels(node_name: str, subscript: str) -> list:
- """
- Extract labels for given subscript. Each label can be either alphabetic letter or ellipsis
-
- :param node_name: Einsum node name
- :param subscript: Given subscript
- :return: A list of labels
- """
- labels = []
- len_subscript = len(subscript)
- label_ind = 0
- while label_ind < len_subscript:
- if subscript[label_ind].isalpha():
- labels.append(subscript[label_ind])
- label_ind += 1
- elif len_subscript - label_ind > 2 and subscript[label_ind:label_ind + 3] == "...":
- labels.append("...")
- label_ind += 3
- else:
- assert False, "Einsum node {} has `equation` with incorrect subscript: {}".format(node_name, subscript)
- return labels
-
- @staticmethod
- def adjust_equation_with_NCHW_layout(node_name: str, equation: str, input_ranks: list, output_rank: int,
- input_correct_layout_mask: list, output_correct_layout_mask: bool) -> (
- str, list, bool):
- """
- In order to satisfy NCHW layout, subscripts for tensors with rank greater than three must be adjusted by moving labels
- of the last dimension to the second position in the subscript. There is an exception for such tensors when
- the label is ellipsis and it covers multiple tail dimensions. The method returns equation with adjusted subscripts
- to NCHW layout along with a boolean mask to indicate which subscripts are adjusted.
-
- :param node_name: Einsum node name for which equation is adjusted
- :param equation: Equation to be adjusted
- :param input_ranks: a list of input ranks
- :param output_rank: output rank
- :return: adjusted equation, boolean mask for inputs, and boolean flag if output subscript is adjusted
- """
- is_inputs_adjusted = []
- input_subscripts, output_subscript = Einsum.parse_equation(node_name, equation)
- num_inputs = len(input_ranks)
- assert len(input_subscripts) == num_inputs, "The number of inputs must match a number " \
- "of input subscripts"
- assert len(input_correct_layout_mask) == num_inputs, "The number of inputs must match a number " \
- "elements in input_correct_layout_mask list"
-
- # permute labels in input subscripts and mark inputs for which inference in NCHW layout is acceptable
- # in case ellipsis covering multiple dimensions in the end, the permutation is impossible
- # so the corresponding input must be in the original format (NHWC)
- permuted_input_subscripts = []
- for input_ind in range(num_inputs):
- input_subscript = input_subscripts[input_ind]
- input_rank = input_ranks[input_ind]
- labels = Einsum.extract_subscript_labels(node_name, input_subscript)
- num_broadcasted_dims = input_rank - len(labels) + 1
- if input_correct_layout_mask[input_ind]:
- is_inputs_adjusted.append(True)
- elif input_rank > 3 and (labels[-1] != "..." or labels[-1] == "..." and num_broadcasted_dims == 1):
- is_inputs_adjusted.append(True)
- labels.insert(1, labels[-1])
- del labels[-1]
- else:
- is_inputs_adjusted.append(False)
- permuted_input_subscript = ''.join(labels)
- permuted_input_subscripts.append(permuted_input_subscript)
-
- # perform the same procedure for the output subscript as for the inputs subscripts
- labels = Einsum.extract_subscript_labels(node_name, output_subscript)
- num_broadcasted_dims = output_rank - len(labels) + 1
- if output_correct_layout_mask:
- is_output_adjusted = True
- elif output_rank > 3 and (labels[-1] != "..." or labels[-1] == "..." and num_broadcasted_dims == 1):
- is_output_adjusted = True
- labels.insert(1, labels[-1])
- del labels[-1]
- else:
- is_output_adjusted = False
- permuted_output_subscript = ''.join(labels)
-
- # concatenate the left and right hands of the resulted equation
- left_hand = ','.join(permuted_input_subscripts)
- right_hand = permuted_output_subscript
- permuted_equation = left_hand + "->" + right_hand
- return permuted_equation, is_inputs_adjusted, is_output_adjusted
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- num_inputs = len(connected_in_ports)
- assert node.has_valid('equation'), "Einsum node {} must contain `equation` attribute".format(node_name)
- equation = node.equation
-
- # parse the equation and extract input and output subscripts
- input_subscripts, output_subscript = Einsum.parse_equation(node_name, equation)
-
- # check that each operand has the corresponding input subscript
- assert len(input_subscripts) == num_inputs, "The number of input operands of Einsum node {} " \
- "must match the number of input subscripts " \
- "in `equation`".format(node_name)
-
- # check compatibility of dimension sizes with the same label and generate a dictionary of shapes for labels
- label_to_shape = {}
- for input_ind in range(num_inputs):
- input_shape = node.in_port(input_ind).data.get_shape()
- input_subscript = input_subscripts[input_ind]
- labels = Einsum.extract_subscript_labels(node_name, input_subscript)
- num_dims = len(input_shape)
- num_labels = len(labels)
- num_broadcasted_dims = num_dims - num_labels + 1
- dim_ind = 0
- label_ind = 0
- while label_ind < num_labels and dim_ind < num_dims:
- label = labels[label_ind]
- if label == "...":
- sub_shape = input_shape[dim_ind:dim_ind + num_broadcasted_dims]
- if label in label_to_shape.keys():
- common_shape = bi_directional_shape_broadcasting(sub_shape, label_to_shape[label])
- assert common_shape is not None, "The dimensions labeled of ellipsis must be broadcastable " \
- "for Einsum node {}".format(node_name)
- label_to_shape[label] = common_shape
- else:
- label_to_shape[label] = sub_shape
- dim_ind += num_broadcasted_dims
- else:
- dim_size = input_shape[dim_ind]
- sub_shape = shape_array([dim_size])
- assert label not in label_to_shape.keys() or np.array_equal(label_to_shape[label], sub_shape), \
- "Sizes of dimensions with the same label of Einsum node {} " \
- "must be compatible".format(node_name)
- label_to_shape[label] = sub_shape
- dim_ind += 1
- label_ind += 1
-
- # generate output shape based on the output subscript
- output_shape = shape_array([])
- labels = Einsum.extract_subscript_labels(node_name, output_subscript)
- for label in labels:
- assert label in label_to_shape.keys(), "The label in the output subscript must appear" \
- " in input subscripts in equation {} " \
- "of Einsum node {}".format(equation, node_name)
- output_shape = np.ma.concatenate((output_shape, label_to_shape[label]))
-
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/elementwise.py b/tools/mo/openvino/tools/mo/ops/elementwise.py
deleted file mode 100644
index 0c9a6f8249a5ae..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/elementwise.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer, bias_add_infer, eltwise_reverse_infer
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array, reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.infer import copy_type_infer
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.type_utils import override_data_type_of_constant
-
-
-class Elementwise(Op):
- enabled = False
- operation = None
- op = None
- op_type = None
- version = 'opset1'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op_type,
- 'version': self.version,
- 'infer': lambda node: eltwise_infer(node, self.operation),
- 'reverse_infer': eltwise_reverse_infer,
- 'type_infer': self.type_infer,
- 'can_be_bias': True,
- 'can_be_fused': True,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'is_eltwise': True,
- 'stop_value_propagation': False,
- 'auto_broadcast': 'numpy'
- }, attrs)
-
- @staticmethod
- def type_infer(node):
- override_data_type_of_constant(node)
- node.out_port(0).set_data_type(node.in_port(0).get_data_type())
-
- def backend_attrs(self):
- return ['auto_broadcast']
-
-
-class UnaryElementwise(Elementwise):
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {**{
- 'in_ports_count': 1,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }, **attrs})
-
- @staticmethod
- def type_infer(node):
- copy_type_infer(node)
-
- def backend_attrs(self):
- return []
-
-
-class Add(Elementwise):
- op = 'Add'
- op_type = 'Add'
- operation = staticmethod(lambda a, b: a + b)
-
-
-class BiasAdd(Add):
- op_type = 'BiasAdd'
-
- def __init__(self, graph: Graph, attrs: dict):
- attrs.update({'infer': lambda node: bias_add_infer(node, self.operation)})
- super().__init__(graph, attrs)
-
-
-class Sub(Elementwise):
- op = 'Sub'
- op_type = 'Subtract'
- operation = staticmethod(lambda a, b: a - b)
-
-
-class Mul(Elementwise):
- op = 'Mul'
- op_type = 'Multiply'
- operation = staticmethod(lambda a, b: a * b)
-
-
-def both_types_are_integer(a, b):
- return np.issubdtype(a.dtype, np.integer) and np.issubdtype(b.dtype, np.integer)
-
-
-class Div(Elementwise):
- op = 'Div'
- op_type = 'Divide'
- operation = staticmethod(lambda a, b: a // b if both_types_are_integer(a, b) else a / b)
-
-
-class SquaredDifference(Elementwise):
- op = 'SquaredDifference'
- op_type = 'SquaredDifference'
- operation = staticmethod(lambda a, b: (a - b) * (a - b))
-
-
-class Pow(Elementwise):
- op = 'Pow'
- op_type = 'Power'
-
- @staticmethod
- def operation(a, b):
- if np.any(b < 0) and np.issubdtype(a.dtype, np.signedinteger):
- return float32_array(a.astype(np.float32) ** b)
- return a ** b
-
-
-class LogicalElementwise(Elementwise):
- @staticmethod
- def type_infer(node):
- override_data_type_of_constant(node)
- node.out_port(0).set_data_type(bool)
-
-
-class Greater(LogicalElementwise):
- op = 'Greater'
- op_type = 'Greater'
- operation = staticmethod(lambda a, b: np.ma.greater(a, b))
-
-
-class GreaterEqual(LogicalElementwise):
- op = 'GreaterEqual'
- op_type = 'GreaterEqual'
- operation = staticmethod(lambda a, b: np.ma.greater_equal(a, b))
-
-
-class Less(LogicalElementwise):
- op = 'Less'
- op_type = 'Less'
- operation = staticmethod(lambda a, b: np.ma.less(a, b))
-
-
-class LessEqual(LogicalElementwise):
- op = 'LessEqual'
- op_type = 'LessEqual'
- operation = staticmethod(lambda a, b: np.ma.less_equal(a, b))
-
-
-class Equal(LogicalElementwise):
- op = 'Equal'
- op_type = 'Equal'
- operation = staticmethod(lambda a, b: np.ma.equal(a, b))
-
-
-class NotEqual(LogicalElementwise):
- op = 'NotEqual'
- op_type = 'NotEqual'
- operation = staticmethod(lambda a, b: np.ma.not_equal(a, b))
-
-
-class Maximum(Elementwise):
- op = 'Maximum'
- op_type = 'Maximum'
- operation = staticmethod(lambda a, b: np.ma.maximum(a, b))
-
-
-class Minimum(Elementwise):
- op = 'Minimum'
- op_type = 'Minimum'
- operation = staticmethod(lambda a, b: np.ma.minimum(a, b))
-
-
-class Round(UnaryElementwise):
- op = 'Round'
- op_type = 'Round'
- version = 'opset5'
-
- def __init__(self, graph: Graph, attrs):
- round_attrs = {'mode': 'half_to_even',
- 'infer': self.infer
- }
- round_attrs.update(attrs)
- super().__init__(graph, round_attrs)
-
- def backend_attrs(self):
- return ['mode']
-
- @classmethod
- def infer(cls, node: Node):
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
-
- a = node.in_port(0).data.get_value()
- if a is not None:
- assert node.soft_get('mode') in ['half_to_even', 'half_away_from_zero'], \
- 'Round node {} has unsupported "mode" attribute value: {}'.format(node.soft_get('name', node.id),
- node.soft_get('mode'))
- if node.mode == 'half_away_from_zero':
- mask = (a >= 0)
- out = np.ma.empty_like(a)
- out[mask] = np.ma.floor(a[mask] + 0.5)
- out[~mask] = np.ma.ceil(a[~mask] - 0.5)
- else:
- out = np.ma.round(a)
- node.out_port(0).data.set_value(out)
-
-
-class LogicalOr(LogicalElementwise):
- op = 'LogicalOr'
- op_type = 'LogicalOr'
- operation = staticmethod(lambda a, b: np.ma.logical_or(a, b))
-
-
-class LogicalXor(Elementwise):
- op = 'LogicalXor'
- op_type = 'LogicalXor'
- operation = staticmethod(lambda a, b: np.ma.logical_xor(a, b))
-
-
-class LogicalAnd(LogicalElementwise):
- op = 'LogicalAnd'
- op_type = 'LogicalAnd'
- operation = staticmethod(lambda a, b: np.ma.logical_and(a, b))
-
-
-class FloorMod(Elementwise):
- op = 'FloorMod'
- op_type = 'FloorMod'
- operation = staticmethod(lambda a, b: np.ma.fmod(a, b))
-
-
-class Mod(Elementwise):
- op = 'Mod'
- op_type = 'Mod'
- operation = staticmethod(lambda a, b: np.ma.mod(a, b))
-
-
-class Negative(UnaryElementwise):
- op = 'Negative'
- op_type = 'Negative'
- operation = staticmethod(lambda a: -a)
-
-
-class Sqrt(UnaryElementwise):
- op = 'Sqrt'
- op_type = 'Sqrt'
-
- @staticmethod
- def operation(a):
- if np.issubdtype(a.dtype, np.signedinteger):
- return float32_array(a.astype(np.float32) ** 0.5)
- return a ** 0.5
-
-
-class BitwiseAnd(Elementwise):
- op = 'BitwiseAnd'
- op_type = 'BitwiseAnd'
- version = 'opset13'
-
-
-class BitwiseOr(Elementwise):
- op = 'BitwiseOr'
- op_type = 'BitwiseOr'
- version = 'opset13'
-
-
-class BitwiseXor(Elementwise):
- op = 'BitwiseXor'
- op_type = 'BitwiseXor'
- version = 'opset13'
-
-
-class BitwiseNot(UnaryElementwise):
- op = 'BitwiseNot'
- op_type = 'BitwiseNot'
- version = 'opset13'
diff --git a/tools/mo/openvino/tools/mo/ops/eltwise.py b/tools/mo/openvino/tools/mo/ops/eltwise.py
deleted file mode 100644
index da7852bf5de0ba..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/eltwise.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Eltwise(Op):
- op = 'Eltwise'
-
- def __init__(self, graph: Graph, attrs: dict):
- operations = {
- 'sum': ('Add', lambda a, b: a + b),
- 'mul': ('Mul', lambda a, b: a * b),
- 'max': ('Max', lambda a, b: np.ma.maximum(a, b)),
- 'pow': ('Pow', lambda a, b: np.ma.power(a, b)),
- 'less': ('Less', lambda a, b: np.ma.less(a, b)),
- 'less_equal': ('LessEqual', lambda a, b: np.ma.less_equal(a, b)),
- 'greater': ('Greater', lambda a, b: np.ma.greater(a, b)),
- 'greater_equal': ('GreaterEqual', lambda a, b: np.ma.greater_equal(a, b)),
- 'equal': ('Equal', lambda a, b: np.ma.equal(a, b)),
- 'floor_mod': ('FloorMod', lambda a, b: np.ma.fmod(a, b)),
- 'not_equal': ('NotEqual', lambda a, b: np.ma.not_equal(a, b)),
- 'logical_or': ('LogicalOr', lambda a, b: bool(a) or bool(b)),
- 'logical_and': ('LogicalAnd', lambda a, b: bool(a) and bool(b)),
- 'logical_xor': ('LogicalXor', lambda a, b: bool(a) ^ bool(b)),
- 'log': ('Log', lambda x: np.ma.log(x)),
- }
-
- super().__init__(graph, {
- 'type': self.op,
- 'op': operations[attrs['operation']][0],
- 'infer': lambda node: eltwise_infer(node, operations[node.operation][1]),
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['operation']
diff --git a/tools/mo/openvino/tools/mo/ops/eltwise_n.py b/tools/mo/openvino/tools/mo/ops/eltwise_n.py
deleted file mode 100644
index d7679ae5980779..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/eltwise_n.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class EltwiseN(Op):
- """
- The elementwise operation that has more than 2 inputs. This operation is replaced in a front phase with a number of
- simple elementwise operations with 2 inputs. Refer to EltwiseNFrontReplacer for a list of supported operations.
- """
- op = 'EltwiseN'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None, # type is None because this operation should not appear in IR
- 'infer': None,
- 'out_ports_count': 1,
- }, attrs)
- if 'operation' not in self.attrs:
- raise Error('"operation" attribute is not set for operation "{}".'.format(self.op))
-
-
-class EltwiseNMul(EltwiseN):
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {'operation': 'mul'})
-
-
-class EltwiseNMin(EltwiseN):
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {'operation': 'min'})
-
-
-class EltwiseNMax(EltwiseN):
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {'operation': 'max'})
-
-
-class EltwiseNAdd(EltwiseN):
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {'operation': 'sum'})
diff --git a/tools/mo/openvino/tools/mo/ops/eltwise_ninputs_in_1.py b/tools/mo/openvino/tools/mo/ops/eltwise_ninputs_in_1.py
deleted file mode 100644
index f3176b2442038c..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/eltwise_ninputs_in_1.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class EltwiseNin1(Op):
- """
- The elementwise operation that has all inputs in 1 input. This operation is replaced in a front phase with
- a number of simple elementwise operations with 2 inputs.
- """
- op = 'EltwiseNin1'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': __class__.op,
- 'type': None, # type is None because this operation should not appear in IR
- 'infer': None,
- 'out_ports_count': 1,
- }, attrs)
- if 'operation' not in self.attrs:
- raise Error('"operation" attribute is not set for operation "{}".'.format(__class__.op))
diff --git a/tools/mo/openvino/tools/mo/ops/embedding_bag.py b/tools/mo/openvino/tools/mo/ops/embedding_bag.py
deleted file mode 100644
index d32d35804e37ab..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/embedding_bag.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class EmbeddingBagBase(Op):
- enabled = False
-
- op = op_type = None
- version = None
- in_ports_count = None
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op_type,
- 'version': self.version,
-
- 'infer': self.infer,
-
- 'in_ports_count': self.in_ports_count,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- raise NotImplementedError('Please use specialized EmbeddingBag operation class, EmbeddingBagBase is base class')
-
-
-class EmbeddingBagOffsetsSum(EmbeddingBagBase):
- op = op_type = 'EmbeddingBagOffsetsSum'
- version = 'opset3'
- in_ports_count = 5
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) >= 3 and all(p in connected_in_ports for p in [0, 1, 2]), \
- "EmbeddingBagOffsetsSum should have at least 3 connected input port, but it doesn't " \
- "for node: `{}`. Ports: {}".format(name, connected_in_ports)
-
- weights_shape = node.in_port(0).data.get_shape()
- assert len(weights_shape) >= 2, \
- "EmbeddingBagOffsetsSum should have at least 2D weights for node: `{}`".format(name)
- offsets_shape = node.in_port(2).data.get_shape()
- assert offsets_shape is not None and len(offsets_shape) == 1, \
- "Rank of the offsets in EmbeddingBagOffsetsSum should be equal to 1 for node: `{}`".format(name)
-
- node.out_port(0).data.set_shape(np.ma.concatenate((offsets_shape[:1], weights_shape[1:])))
-
-
-class EmbeddingBagPackedSum(EmbeddingBagBase):
- op = op_type = 'EmbeddingBagPackedSum'
- version = 'opset3'
- in_ports_count = 3
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) >= 2 and all(p in connected_in_ports for p in [0, 1]), \
- "EmbeddingBagPackedSum should have at least 2 connected input port, but it doesn't for node: `{}`. " \
- "Ports: {}".format(name, connected_in_ports)
-
- weights_shape = node.in_port(0).data.get_shape()
- assert len(weights_shape) >= 2, \
- "EmbeddingBagPackedSum should have at least 2D weights for node: `{}`".format(name)
- input_shape = node.in_port(1).data.get_shape()
-
- node.out_port(0).data.set_shape(np.ma.concatenate((input_shape[:1], weights_shape[1:])))
-
-
-class EmbeddingSegmentsSum(EmbeddingBagBase):
- op = op_type = 'EmbeddingSegmentsSum'
- version = 'opset3'
- in_ports_count = 6
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) >= 4 and all(p in connected_in_ports for p in [0, 1, 2, 3]), \
- "{} should have at least 4 connected input port, but it doesn't for node: `{}`. " \
- "Ports: {}".format(node.op, name, connected_in_ports)
-
- weights_shape = node.in_port(0).data.get_shape()
- assert len(weights_shape) >= 2, \
- "{} should have at least 2D weights for node: `{}`".format(node.op, name)
- indices_shape = node.in_port(1).data.get_shape()
- segment_ids = node.in_port(2).data.get_shape()
- assert len(indices_shape) == 1 and len(segment_ids) == 1 and indices_shape == segment_ids, \
- "Both indices and segment_ids should have the same shape for node: `{}`".format(name)
- num_segments = node.in_port(3).data.get_value()
- assert num_segments is not None, "{} should have a constant num_segments provided, but it " \
- "doesn't for node: `{}`.".format(node.op, name)
- output_shape = np.ma.concatenate(([num_segments], weights_shape[1:]))
- node.out_port(0).data.set_shape(output_shape)
-
-
-class EmbeddingSegmentsMean(Op):
- """
- Internal Operation.
-
- In order not to overload transformations (EmbeddingSegmentsOperationSingleFeatureFusing,
- EmbeddingSegmentsOperationMultipleFeaturesFusing) with additional sub-graph computing mean value of embedding
- vectors, we introduce internal operation EmbeddingSegmentsMean. After these transformations, this operation
- is decomposed into EmbeddingSegmentSum with appropriate computation of mean value for embedding vectors collected
- for each object in a batch.
- """
- op = "EmbeddingSegmentsMean"
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 6,
- 'out_ports_count': 1,
- # it must have the same shape infer function as EmbeddingSegmentsSum
- 'infer': EmbeddingSegmentsSum.infer
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/expand_dims.py b/tools/mo/openvino/tools/mo/ops/expand_dims.py
deleted file mode 100644
index 5a2412174bd3fc..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/expand_dims.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, is_fully_defined, shape_insert
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class ExpandDims(Op):
- """
- The ExpandDims layer adds dimensions with shape 1 to the specified positions. The positions is a layer attribute,
- not a separate input.
- """
- op = 'ExpandDims'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'reinterp_shape': True,
- 'infer': self.infer,
- 'expand_axis': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- input_shape = node.in_port(0).data.get_shape()
- input_value = node.in_port(0).data.get_value()
- if input_shape is None:
- raise Error('Input shape for node "{}" is None'.format(node_name))
-
- assert len(node.in_nodes()) == 1, 'Wrong number of inputs to the layer {}'.format(node_name)
-
- if not node.has_valid('expand_axis'):
- raise Error('ExpandDims axis is not defined for node {}'.format(node_name))
-
- expand_axes = node.expand_axis
- if expand_axes is None:
- raise Error('The "expand_axis" attribute is None for node "{}"'.format(node_name))
-
- if isinstance(expand_axes, int):
- expand_axes = int64_array([expand_axes])
- elif expand_axes.ndim == 0:
- expand_axes = expand_axes.reshape([1])
-
- # expand_axis is a position where the new axis is placed so expand_dims works for negative axis in a different
- # way not as insert operation
- for expand_axis in expand_axes:
- if expand_axis < 0:
- expand_axis += len(input_shape) + 1
-
- expand_axes = sorted(expand_axes)
- output_shape = input_shape.copy()
- for expand_axis in expand_axes:
- output_shape = shape_insert(output_shape, expand_axis, 1)
-
- if input_value is not None and is_fully_defined(output_shape):
- node.out_port(0).data.set_value(input_value.reshape(output_shape))
- else:
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/eye.py b/tools/mo/openvino/tools/mo/ops/eye.py
deleted file mode 100644
index 73e52da5ea0d6f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/eye.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, shape_array
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined
-
-
-class Eye(Op):
- """
- Eye operation that generates shift matrix or a batch of matrices.
- """
- op = 'Eye'
- enabled = False
- in_ports_count = 4
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset9',
- 'infer': self.infer,
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- 'type_infer': self.type_infer,
- 'output_type': np.float32,
- }, attrs)
-
- def backend_attrs(self):
- return [('output_type', lambda node: np_data_type_to_destination_type(node.output_type))]
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(node['output_type'])
-
- @staticmethod
- def infer(node: Node):
- assert node.has_valid('output_type')
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) >= 3 and all(p in connected_in_ports for p in [0, 1, 2]), \
- "Eye should have at least 3 connected input port." \
- "Got ports: `{}`.".format(connected_in_ports)
-
- num_rows_port = 0
- num_columns_port = 1
- diagonal_index_port = 2
- batch_shape_port = 3
-
- num_rows_shape = node.in_port(num_rows_port).data.get_shape()
- assert len(num_rows_shape) <= 1, \
- '"num_rows" should be 1D tensor or scalar. Got: '.format(len(num_rows_shape))
- num_rows = node.in_port(num_rows_port).data.get_value()
- if num_rows is None:
- num_rows = dynamic_dimension
- else:
- num_rows = np.array(num_rows).item()
-
- num_columns_shape = node.in_port(num_columns_port).data.get_shape()
- assert len(num_columns_shape) <= 1, \
- '"num_columns" should be 1D tensor or scalar. Got: '.format(len(num_columns_shape))
- num_columns = node.in_port(num_columns_port).data.get_value()
- if num_columns is None:
- num_columns = dynamic_dimension
- else:
- num_columns = np.array(num_columns).item()
-
- diagonal_index_shape = node.in_port(diagonal_index_port).data.get_shape()
- assert len(diagonal_index_shape) <= 1, \
- '"diagonal_index" should be 1D tensor or scalar. Got: '.format(len(diagonal_index_shape))
- diagonal_index = node.in_port(diagonal_index_port).data.get_value()
-
- if batch_shape_port in connected_in_ports:
- batch_shape_shape = node.in_port(batch_shape_port).data.get_shape()
- assert len(batch_shape_shape) == 1, \
- '"batch_shape" should be 1D tensor. Got: '.format(len(batch_shape_shape))
- batch_shape = node.in_port(batch_shape_port).data.get_value()
- if batch_shape is None:
- batch_shape = [dynamic_dimension] * batch_shape_shape[0]
- else:
- batch_shape = []
-
- output_shape = [*batch_shape, num_rows, num_columns]
- node.out_port(0).data.set_shape(output_shape)
-
- if is_fully_defined(output_shape) and diagonal_index is not None:
- tile_shape = [*batch_shape, 1, 1]
- one_matrix = np.eye(num_rows, M=num_columns, k=np.array(diagonal_index).item(), dtype=node.output_type)
- output_value = np.tile(one_matrix, tile_shape)
- node.out_port(0).data.set_value(shape_array(output_value))
-
-
-class TFEye(Op):
- """ Eye operation that that generates shift matrix or a batch of matrices.
- Eye operation from TensorFlow has three inputs: row number, column number and batch shape
- """
- op = 'TFEye'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': None,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'output_type': np.float32,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/fake_output.py b/tools/mo/openvino/tools/mo/ops/fake_output.py
deleted file mode 100644
index 3bac58daf58614..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/fake_output.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer, copy_value
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class FakeOutput(Op):
- """
- This op is needed only to store the output name, it will be transformed into opset op and is doing nothing
- """
- op = 'FakeOutput'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
- 'version': None,
-
- 'infer': lambda n: copy_shape_infer(n, copy_value),
-
- 'type_infer': None,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/fakequantize.py b/tools/mo/openvino/tools/mo/ops/fakequantize.py
deleted file mode 100644
index 1c21fb7c57b543..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/fakequantize.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-def broadcastable(broadcast_from, broadcast_to):
- """Check if shape broadcast_from can be broadcasted to broadcast_to"""
- broadcast_to = int64_array(broadcast_to)
- broadcast_from = int64_array(broadcast_from)
- if broadcast_from.size > broadcast_to.size:
- return False
- broadcast_from = np.concatenate(
- (int64_array([1] * (broadcast_to.size - broadcast_from.size)), broadcast_from))
- return np.all(np.logical_or(broadcast_from == 1, broadcast_from == broadcast_to))
-
-
-def round_half_up(n):
- return np.floor(n + 0.5)
-
-
-class FakeQuantize(Op):
- op = 'FakeQuantize'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'levels': None,
- 'is_eltwise': True,
- 'infer': self.infer,
- 'in_ports_count': 5,
- 'out_ports_count': 1,
- 'auto_broadcast': 'numpy'
- }
- super().__init__(graph, mandatory_props, attrs)
- if self.attrs['levels'] is None:
- raise Error("FakeQuantize operation has no levels parameter")
-
- def supported_attrs(self):
- return [
- 'levels',
- 'auto_broadcast'
- ]
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) == 5
- assert len(node.out_nodes()) == 1
- inputs = [node.in_node(i) for i in range(5)]
- x, input_low, input_high, output_low, output_high = inputs
- assert x.has_valid('shape')
- # TODO Check all inputs[1..4] shapes are broadcastable to inputs[0] shape
- assert all([broadcastable(inputs[i].shape, inputs[0].shape) for i in range(1, 5)]), \
- "Not all shapes from FakeQuantize inputs can be broadcasted to input[0] for node {}".format(
- node.soft_get('name'))
- node.out_node().shape = x.shape.copy()
-
- if all([node.in_node(i).has_valid('value') for i in range(5)]):
- x, input_low, input_high, output_low, output_high = \
- [float32_array(np.broadcast_to(node.value, x.value.shape)) for node in inputs]
-
- assert node.has_valid('levels')
- assert isinstance(node.levels, int)
-
- underflow_mask = x <= input_low
- overflow_mask = x > input_high
- # pylint: disable=assignment-from-no-return
- middle_mask = np.logical_not(np.logical_or(underflow_mask, overflow_mask))
-
- def middle_part(x, input_low, input_high, output_low, output_high):
- return round_half_up((x - input_low) / (input_high - input_low) * (node.levels - 1)) / \
- (node.levels - 1) * (output_high - output_low) + output_low
-
- output = np.zeros_like(x)
- # pylint: disable=unsupported-assignment-operation
- output[middle_mask] = middle_part(
- x[middle_mask],
- input_low[middle_mask],
- input_high[middle_mask],
- output_low[middle_mask],
- output_high[middle_mask],
- )
-
- # pylint: disable=unsupported-assignment-operation
- output[overflow_mask] = output_high[overflow_mask]
- # pylint: disable=unsupported-assignment-operation
- output[underflow_mask] = output_low[underflow_mask]
-
- if not node.has_and_set('stop_value_propagation'):
- node.out_node().value = output
diff --git a/tools/mo/openvino/tools/mo/ops/fill.py b/tools/mo/openvino/tools/mo/ops/fill.py
deleted file mode 100644
index 8cb27f5eeeceeb..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/fill.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.op import Op
-
-
-class Fill(Op):
- """
- The Fill layer tiles the second input tensor (0D constant) to the shape specified in the first input.
-
- This operation is converted to Broadcast layer.
- """
- op = 'Fill'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': __class__.op,
- 'infer': None,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/flatten.py b/tools/mo/openvino/tools/mo/ops/flatten.py
deleted file mode 100644
index 7c2541876f120f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/flatten.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Flatten(Op):
- op = 'Flatten'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': __class__.op,
- 'type': None,
-
- 'axis': None,
- 'end_axis': np.int64(-1),
- 'infer': None,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
-
-class FlattenONNX(Op):
- op = 'FlattenONNX'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': __class__.op,
- 'type': None,
-
- 'axis': None,
- 'infer': None,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/gather.py b/tools/mo/openvino/tools/mo/ops/gather.py
deleted file mode 100644
index 2a899de53ce726..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/gather.py
+++ /dev/null
@@ -1,201 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, int64_array, is_fully_defined, shape_array, \
- dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.utils.error import Error
-
-
-class Gather(Op):
- op = 'Gather'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset8',
- 'batch_dims': 0,
- 'reinterp_shape': True,
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'force_precision_in_ports': {1: 'int32', 2: 'int64'},
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- assert 'axis' not in self.attrs, \
- 'Use AttributedGather operation instead of Gather to create it with `axis` as a parameter'
-
- def backend_attrs(self):
- version = self.get_opset()
- if version in ['opset7', 'opset8']:
- return ['batch_dims']
- elif version == 'opset1':
- return []
- else:
- raise Error('Unsupported operation opset version "{}"'.format(version))
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) == 3 and 0 in connected_in_ports and 1 in connected_in_ports and \
- 2 in connected_in_ports, "Gather should have 3 connected input port, but it doesn't for " \
- "node: `{}`. Ports: {}".format(name, connected_in_ports)
-
- data_shape = node.in_port(0).data.get_shape()
- assert data_shape is not None
- indices_shape = node.in_port(1).data.get_shape()
- assert indices_shape is not None
- axis = node.in_port(2).data.get_value()
-
- # axis of Gather could be accepted as both scalar and 1D tensor
- if isinstance(axis, np.ndarray):
- axis = axis.item()
- assert axis is not None, 'axis input is undefined'
-
- assert -len(data_shape) <= axis < len(data_shape), \
- 'axis must be within interval [-data_rank, data_rank). Instead got axis = {}, data_rank = {} '.\
- format(axis, len(data_shape))
-
- batch_dims = node.batch_dims
- assert -len(indices_shape) <= batch_dims <= len(indices_shape), \
- 'batch_dims must be within interval [-indices_rank, indices_rank]. Instead got batch_dims = {}, ' \
- 'indices_rank = {} '.format(batch_dims, len(indices_shape))
-
- # normalize to positive values
- axis = axis + len(data_shape) if axis < 0 else axis
- batch_dims = batch_dims + len(indices_shape) if batch_dims < 0 else batch_dims
-
- assert np.ma.allequal(data_shape[:batch_dims], indices_shape[:batch_dims]), \
- 'data and indices inputs must have equal first dimensions until batch_dims'
-
- assert batch_dims <= axis, \
- 'normalized batch_dims must be <= axis. Instead got batch_dims = {}, axis = {}'.format(axis, batch_dims)
-
- # we import PermuteInputs locally because it uses Gather inside and we have recursive imports
- from openvino.tools.mo.graph.perm_inputs import PermuteInputs
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'axis')
-
- batch_dims_range = indices_shape[:batch_dims]
- out_shape = np.concatenate((data_shape[:axis], indices_shape[batch_dims:], data_shape[axis + 1:]))
-
- data_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- if data_value is not None and indices_value is not None and is_fully_defined(indices_value):
- indices_value = int64_array(indices_value)
- if batch_dims == 0:
- node.out_port(0).data.set_value(np.ma.take(data_value, indices_value, axis))
- else:
- out_value = np.empty(out_shape)
- for batch_idx in np.ndindex(tuple(batch_dims_range)):
- out_value[batch_idx] = np.ma.take(data_value[batch_idx], indices_value[batch_idx],
- axis - batch_dims)
- node.out_port(0).data.set_value(out_value)
- else:
- node.out_port(0).data.set_shape(out_shape)
-
- @staticmethod
- def reverse_infer(node: Node):
- out_shape = node.out_port(0).data.get_shape()
- data_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- batch_dims = node.batch_dims
- batch_dims = batch_dims + len(indices_shape) if batch_dims < 0 else batch_dims
-
- axis = node.in_port(2).data.get_value()
- # axis of Gather could be accepted as both scalar and 1D tensor
- if isinstance(axis, np.ndarray):
- axis = axis.item()
- assert axis is not None, 'axis input is undefined'
-
- # we can deduce data or indices partial shapes from output shape calculation formula
- # out_shape = Concat(data_shape[:axis], indices_shape[batch_dims:batch_dims + indices_rank], data_shape[axis + 1:])
-
- # data partial shape is unknown
- if out_shape is not None and data_shape is None and indices_shape is not None:
- out_rank = len(out_shape)
- indices_rank = len(indices_shape)
-
- deduced_data_shape = out_shape.tolist(dynamic_dimension_value)
- for i in range(indices_rank):
- deduced_data_shape.pop(axis)
- deduced_data_shape.insert(axis, dynamic_dimension_value)
- node.in_port(0).data.set_shape(shape_array(deduced_data_shape))
-
- # indices partial shape is unknown
- if out_shape is not None and indices_shape is None and data_shape is not None:
- out_rank = len(out_shape)
- data_rank = len(data_shape)
- indices_rank = out_rank + 1 - data_rank + batch_dims
-
- indices_shape = out_shape[axis:axis + indices_rank]
- node.in_port(1).data.set_shape(indices_shape)
-
-
-class AttributedGather(Op):
- op = 'AttributedGather'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': 'Gather',
-
- 'axis': 0,
- 'reinterp_shape': True,
- 'infer': self.infer,
- # reverse_infer is not needed since is replaced by Gather on the front (AttributedGatherNormalizer)
-
- 'force_precision_in_ports': {1: 'int32'},
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return [
- 'axis',
- ]
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) == 2 and 0 in connected_in_ports and 1 in connected_in_ports, \
- "AttributedGather should have 2 connected input port, but it doesn't for node: `{}`. Ports: {}" \
- "".format(name, connected_in_ports)
-
- axis = node.soft_get('axis', None)
- assert axis is not None
-
- data_shape = node.in_port(0).data.get_shape()
- assert data_shape is not None
- indices_shape = node.in_port(1).data.get_shape()
- assert indices_shape is not None
-
- # Convert negative axis
- axis = get_canonical_axis_index(data_shape, axis)
- node.axis = axis
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
- data_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- if data_value is not None and indices_value is not None:
- node.out_port(0).data.set_value(mo_array(np.take(data_value, indices_value, axis), dtype=data_value.dtype))
- return
-
- shape = np.concatenate((data_shape[:axis], indices_shape))
- if axis < len(data_shape) - 1:
- shape = np.concatenate((shape, data_shape[axis + 1:]))
-
- node.out_port(0).data.set_shape(int64_array(shape))
diff --git a/tools/mo/openvino/tools/mo/ops/gatherelements.py b/tools/mo/openvino/tools/mo/ops/gatherelements.py
deleted file mode 100644
index 8f026223b1411e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/gatherelements.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.utils.error import Error
-
-
-class GatherElements(Op):
- op = 'GatherElements'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset6',
- 'infer': self.infer,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'axis': 0,
- }, attrs)
-
- def backend_attrs(self):
- return ['axis']
-
- @staticmethod
- def infer(node: Node):
- data_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- axis = node.axis
- data_rank = len(data_shape)
-
- assert data_rank >= 1, 'data_rank must be >= 1'
- assert data_rank == len(indices_shape), 'data and indices inputs for node {} must be of the ' \
- 'same rank. Instead got {} and {}'. \
- format(node.name, data_rank, len(indices_shape))
- assert -data_rank <= axis < data_rank, 'axis for node {0} must be within interval ' \
- '[-{1}, {1} - 1]. Instead got: axis={2}'. \
- format(node.name, data_rank, axis)
- if axis < 0:
- axis += data_rank
- out_shape = indices_shape.copy()
- for idx, (data_sz, ind_sz) in enumerate(zip(data_shape, indices_shape)):
- out_shape[idx] = ind_sz if ind_sz is not dynamic_dimension or idx == axis else data_sz
- if idx != axis and data_sz != ind_sz:
- raise Error('Sizes along axis {} for node {} do not match. data and indices must have '
- 'equal size along all axes except for axis {}'.format(idx, node.name, axis))
-
- data = node.in_port(0).data.get_value()
- indices = node.in_port(1).data.get_value()
-
- if data is not None and indices is not None:
- out_value = np.empty(indices_shape, dtype=data.dtype)
- for idx in np.ndindex(*indices_shape):
- data_idx = list(idx)
- data_idx[node.axis] = indices[idx]
- out_value[idx] = data[tuple(data_idx)]
- node.out_port(0).data.set_value(out_value)
- else:
- node.out_port(0).data.set_shape(out_shape)
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
diff --git a/tools/mo/openvino/tools/mo/ops/gathernd.py b/tools/mo/openvino/tools/mo/ops/gathernd.py
deleted file mode 100644
index 02b900688f8c06..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/gathernd.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, is_fully_defined, dynamic_dimension_value, \
- compatible_dims
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class GatherND(Op):
- op = 'GatherND'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset8',
- 'infer': self.infer,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'batch_dims': 0
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return ['batch_dims']
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 2, \
- "Incorrect number of inputs for {} node".format(node_name)
-
- data_shape = node.in_port(0).data.get_shape()
- data_value = node.in_port(0).data.get_value()
- indices_shape = node.in_port(1).data.get_shape()
- indices_value = node.in_port(1).data.get_value()
-
- assert node.has_valid('batch_dims'), "Node {} must contain `batch_dims` attribute".format(node_name)
- batch_dims = node.batch_dims
-
- # check that a number of batch dimensions is less than both ranks of data and indices tensors
- assert batch_dims < len(data_shape), "Number of batch dimensions must be less than a rank of data"
- assert batch_dims < len(indices_shape), "Number of batch dimensions must be less than a rank of indices"
-
- # check that batch dimensions of data and indices are the same
- for batch_dim in range(batch_dims):
- assert compatible_dims(data_shape[batch_dim], indices_shape[batch_dim]), \
- "The dimension {} for data and indices tensors must be the same".format(batch_dim)
-
- # check ranks of input tensors
- assert len(data_shape) > 0, "Data must not be a scalar"
- assert len(indices_shape) > 0, "Indices must not be a scalar"
- assert (batch_dims + indices_shape[-1]) <= len(data_shape), \
- "Length of a tuple with indices must not exceed a rank of data tensor excluding batch dimensions"
- assert node['version'] in ['opset5', 'opset8'], 'Unsupported version of GatherND operation: {}, operation ' \
- 'name : {}'.format(node['version'], node.soft_get('name'))
-
- # compute output shape
- batch = []
- if batch_dims > 0:
- if node['version'] == 'opset5': # Support old version of gatherND shape inference
- if is_fully_defined(data_shape[:batch_dims]):
- batch = [np.prod(data_shape[:batch_dims]).tolist()]
- else:
- batch = [dynamic_dimension_value]
- elif node['version'] == 'opset8':
- for dim in range(batch_dims):
- assert compatible_dims(indices_shape[dim], data_shape[dim]),\
- "Batch dimensions in data.shape and indices.shape must be compatible"
- if is_fully_defined(indices_shape[:batch_dims]):
- batch = indices_shape[:batch_dims].tolist()
- elif is_fully_defined(data_shape[:batch_dims]):
- batch = data_shape[:batch_dims].tolist()
- else:
- for ind in range(batch_dims):
- if indices_shape[ind] != dynamic_dimension_value:
- batch.append(indices_shape[ind])
- elif data_shape[ind] != dynamic_dimension_value:
- batch.append(data_shape[ind])
- else:
- batch.append(dynamic_dimension_value)
-
- slice_shape = list(data_shape[(batch_dims + indices_shape[-1]):])
-
- output_shape = batch + list(indices_shape)[batch_dims:-1] + slice_shape
- node.out_port(0).data.set_shape(output_shape)
-
- # compute output value if all input indices are defined
- if is_fully_defined(indices_value) and data_value is not None:
- batch_dims_size = 1
-
- for i in range(batch_dims):
- batch_dims_size *= indices_shape[i]
-
- output_data = []
-
- reshaped_indices = indices_value.reshape(batch_dims_size, -1, indices_shape[-1])
-
- reshaped_data = data_value.reshape((batch_dims_size,) + tuple((data_shape[batch_dims:])))
-
- for batch_dim in range(reshaped_indices.shape[0]):
- for outer_dim in range(reshaped_indices.shape[1]):
- gather_index = tuple(reshaped_indices[batch_dim][outer_dim])
- output_data.append(reshaped_data[(batch_dim,) + gather_index])
- output_value = np.asarray(output_data, dtype=data_value.dtype).reshape(output_shape)
- node.out_port(0).data.set_value(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/gelu.py b/tools/mo/openvino/tools/mo/ops/gelu.py
deleted file mode 100644
index 8b6be1b9e4c6aa..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/gelu.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class GeLUOP(Op):
- op = 'Gelu'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'version': 'opset7',
- 'infer': copy_shape_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- if self.get_opset() == 'opset7':
- return ['approximation_mode']
- else:
- return []
diff --git a/tools/mo/openvino/tools/mo/ops/grn.py b/tools/mo/openvino/tools/mo/ops/grn.py
deleted file mode 100644
index 3b36e7c2c1c08f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/grn.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class GRNOp(Op):
- op = 'GRN'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': __class__.op,
- 'op': __class__.op,
- 'version': 'opset1',
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': copy_shape_infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'bias'
- ]
diff --git a/tools/mo/openvino/tools/mo/ops/group_norm.py b/tools/mo/openvino/tools/mo/ops/group_norm.py
deleted file mode 100644
index 647ea518e911e0..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/group_norm.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class GroupNorm(Op):
- op = 'GroupNorm'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': __class__.op,
- 'infer': copy_shape_infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
-
-class GroupNormalization(Op):
- op = 'GroupNormalization'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'infer': copy_shape_infer,
- 'version': 'opset12',
-
- 'num_groups': None,
- 'epsilon': None,
-
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return ['num_groups', 'epsilon']
diff --git a/tools/mo/openvino/tools/mo/ops/hard_sigmoid.py b/tools/mo/openvino/tools/mo/ops/hard_sigmoid.py
deleted file mode 100644
index 1f0eeb971ace0a..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/hard_sigmoid.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class HardSigmoid(Op):
- op = 'HardSigmoid'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- input_node = node.in_node(0)
- data_value = node.in_port(0).data.get_value()
- alpha_value = node.in_port(1).data.get_value()
- beta_value = node.in_port(2).data.get_value()
- if data_value is not None and alpha_value is not None and beta_value is not None:
- node.out_port(0).data.set_value(np.clip(data_value * alpha_value + beta_value, 0, 1))
- return
-
- node.out_port(0).data.set_shape(input_node.shape.copy())
diff --git a/tools/mo/openvino/tools/mo/ops/identity.py b/tools/mo/openvino/tools/mo/ops/identity.py
deleted file mode 100644
index 0861a0dda5c2bf..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/identity.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Identity(Op):
- op = 'Identity'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
-
- 'identity': True,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node):
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
- if node.in_port(0).data.get_value() is not None:
- node.out_port(0).data.set_value(node.in_port(0).data.get_value())
-
-
-class IdentityN(Op):
- op = 'IdentityN'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/instance_normalization.py b/tools/mo/openvino/tools/mo/ops/instance_normalization.py
deleted file mode 100644
index 500ddf8d9e34cb..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/instance_normalization.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class InstanceNormalization(Op):
- ''' InstanceNormalization like it is defined in ONNX
-
- y = scale * (x - mean) / sqrt(variance + epsilon) + B
-
- where x is input(0), scale is input(1) and B is input(2)
- '''
- op = 'InstanceNormalization'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': __class__.op,
- 'epsilon': None,
- #'infer' - is not needed, this op should be replaced by a front replacer
- }, attrs)
-
- def supported_attrs(self):
- return ['epsilon']
diff --git a/tools/mo/openvino/tools/mo/ops/interp.py b/tools/mo/openvino/tools/mo/ops/interp.py
deleted file mode 100644
index 8cd31cd56960e2..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/interp.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import inspect
-import logging as log
-
-from openvino.tools.mo.ops.resize_factor_utils import factor_update
-from openvino.tools.mo.front.common.layout import get_batch_dim, get_features_dim, get_height_dim, get_width_dim, shape_for_layout
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class InterpOp(Op):
- op = 'Interp'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': __class__.op,
- 'op': __class__.op,
- 'factor': None,
- 'align_corners': 1,
- 'parse_2nd_input': 'value',
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': None
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'height',
- 'width',
- 'zoom_factor',
- 'shrink_factor',
- 'factor', # float factor required by OV shape inference
- 'pad_beg',
- 'pad_end',
- 'align_corners'
- ]
-
- @staticmethod
- def interp_infer(node: Node):
- layout = node.graph.graph['layout']
- assert len(layout) == 4
- if len(node.in_nodes()) == 2:
- src_shape = node.in_node(0).shape
- dst_shape = node.in_node(1).shape
-
- # in Caffe can be 2 inputs too, but shape should be got from shape of the second input
- if node.parse_2nd_input == 'shape':
- dst_shape = [dst_shape[get_height_dim(layout, 4)], dst_shape[get_width_dim(layout, 4)]]
- else:
- # it is TF case
- dst_shape = node.in_node(1).value
-
- if src_shape is None or dst_shape is None or len(src_shape) != 4 or len(dst_shape) != 2:
- log.error(
- 'Node {} with op {} cannot be converted to Resample layer because there is no enough info about '
- 'src/dst shapes: src_shape = {}, dst_shape = {}'.format(node.name, node.op, src_shape, dst_shape))
- node.type = None # prevent translation to a valid OV layer
- return
- in_height = src_shape[get_height_dim(layout, 4)]
- in_width = src_shape[get_width_dim(layout, 4)]
- out_height = dst_shape[0]
- out_width = dst_shape[1]
-
- node.factor = factor_update(
- node.factor,
- [float(out_height) / in_height, float(out_width) / in_width],
- [in_height, in_width],
- [out_height, out_width],
- node.soft_get('name')
- )
-
- if node.factor is None:
- node['width'] = out_width
- node['height'] = out_height
-
- node.out_node().shape = shape_for_layout(layout,
- batch=src_shape[get_batch_dim(layout, 4)],
- features=src_shape[get_features_dim(layout, 4)],
- height=out_height,
- width=out_width)
- node.graph.remove_edge(node.in_node(1).id, node.id)
- else:
- outn = node.out_node(0)
-
- in_shape = node.in_node(0)
- num_ = in_shape.shape[get_batch_dim(layout, 4)]
- channels_ = in_shape.shape[get_features_dim(layout, 4)]
- height_in_ = in_shape.shape[get_height_dim(layout, 4)]
- width_in_ = in_shape.shape[get_width_dim(layout, 4)]
-
- height_out_ = height_in_ + node.pad_beg + node.pad_end
- width_out_ = width_in_ + node.pad_beg + node.pad_end
-
- if node.shrink_factor != 1 and node.zoom_factor == 1:
- shrink_factor = node.shrink_factor
- if shrink_factor < 1:
- log.error('Shrink factor should be positive in node {}'.format(node.id))
- return None
- height_out_ = (height_out_ - 1) / shrink_factor + 1
- width_out_ = (width_out_ - 1) / shrink_factor + 1
- elif node.shrink_factor == 1 and node.zoom_factor != 1:
- zoom_factor = node.zoom_factor
- if zoom_factor < 1:
- log.error('Zoom factor should be positive in node {}'.format(node.id))
- return None
-
- node['debug_message'] = 'Interp layer shape inference function may be wrong, please, try to update ' \
- 'layer shape inference function in the file (openvino/tools/mo/ops/interp.op at the ' \
- 'line {}).'.format(inspect.currentframe().f_lineno) + refer_to_faq_msg(100)
- # Reshape methods can be different in some cases
- # Commented out section represents reshape that used in deeplab-caffe
- # Uncomment the following lines, if your model was trained with deeplab-caffe
- # or have the same reshape method
- # height_out_ = height_out_ + (height_out_ - 1) * (zoom_factor - 1)
- # width_out_ = width_out_ + (width_out_ - 1) * (zoom_factor - 1)
-
- # Comment out the following lines if you use the reshape method from previous section
- height_out_ = height_out_ * zoom_factor
- width_out_ = width_out_ * zoom_factor
- elif node.width != 0 and node.height != 0:
- height_out_ = node.height
- width_out_ = node.width
- elif node.shrink_factor != 1 and node.zoom_factor != 1:
- shrink_factor = node.shrink_factor
- zoom_factor = node.zoom_factor
- if shrink_factor < 1:
- log.error('Shrink factor should be positive in node {}'.format(node.id))
- return None
- if zoom_factor < 1:
- log.error('Zoom factor should be positive in node {}'.format(node.id))
- return None
- height_out_ = (height_out_ - 1) / shrink_factor + 1
- width_out_ = (width_out_ - 1) / shrink_factor + 1
- height_out_ = height_out_ + (height_out_ - 1) * (zoom_factor - 1)
- width_out_ = width_out_ + (width_out_ - 1) * (zoom_factor - 1)
-
- outn.shape = shape_for_layout(layout,
- batch=num_,
- features=channels_,
- height=height_out_,
- width=width_out_)
diff --git a/tools/mo/openvino/tools/mo/ops/interpolate.py b/tools/mo/openvino/tools/mo/ops/interpolate.py
deleted file mode 100644
index 6bd38456d94203..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/interpolate.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import math
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension, dynamic_dimension_value
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-def infer_for_opsetX(node: Node, opset: str):
- if opset == "opset4":
- scales_port = 2
- axes_port = 3
- min_inputs_num = 3
- elif opset == "opset11":
- scales_port = 1
- axes_port = 2
- min_inputs_num = 2
- else:
- raise "Unknown opset: {}".format(opset)
- assert len([p for p in node.in_ports().values() if not p.disconnected()]) in [min_inputs_num, min_inputs_num + 1], \
- "Interpolate node {} must have at least {} inputs".format(node.soft_get(node.name, node.id), axes_port)
- assert node.has_valid('mode')
- assert node.has_valid('shape_calculation_mode')
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None
-
- input_rank = len(src_shape)
-
- pads_begin = correct_pad(node.soft_get('pads_begin', [0]), input_rank)
- pads_end = correct_pad(node.soft_get('pads_end', [0]), input_rank)
- node['pads_begin'] = pads_begin
- node['pads_end'] = pads_end
-
- if len(node.in_ports()) == axes_port:
- axes = list(range(0, input_rank))
- else:
- axes = node.in_port(axes_port).get_source().data.get_value()
- assert axes is not None, \
- "Interpolate node with name {} has None as 'axes' input".format(node.soft_get('name', node.id))
-
- axes = int64_array(axes)
- output_shape = src_shape + pads_begin + pads_end
- if node.shape_calculation_mode == 'sizes':
- dst_shape = node.in_port(1).data.get_value()
- assert dst_shape is not None
- if node.get_opset() != "opset11":
- correct_scales_using_dst_shape(node, dst_shape, src_shape, axes)
- for i, axis in enumerate(axes):
- output_shape[axis] = dst_shape[i]
- else:
- scales = node.in_port(scales_port).data.get_value()
- assert scales is not None
- for i, axis in enumerate(axes):
- if output_shape[axis] is not dynamic_dimension and scales[i] is not dynamic_dimension:
- output_shape[axis] = math.floor(scales[i] * output_shape[axis] + 1.0e-5)
- else:
- output_shape[axis] = dynamic_dimension_value
-
- if node.is_in_port_connected(axes_port):
- PermuteInputs().set_input_permutation(node.in_node(axes_port), node, 'input:0', 'axis')
-
- node.out_port(0).data.set_shape(output_shape)
-
-
-def infer_for_opset1(node: Node):
- assert len([p for p in node.in_ports().values() if not p.disconnected()]) == 2
- assert node.has_valid('mode')
- assert node.has_valid('axes')
-
- src_shape = node.in_port(0).data.get_shape()
-
- assert src_shape is not None
- dst_shape = node.in_port(1).data.get_value()
- assert dst_shape is not None
-
- output_shape = src_shape.copy()
- for ind, axis in enumerate(node.axes):
- output_shape[axis] = dst_shape[ind]
-
- node.out_port(0).data.set_shape(output_shape)
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('axes', 'input:0')])
-
-
-def pad_attribute_to_str(node: Node, attr: str):
- return ','.join(map(str, node[attr])) if node.has_valid(attr) else None
-
-
-def correct_pad(pad, rank):
- pad_len = len(pad)
- if pad_len < rank:
- return np.pad(pad, (0, rank - pad_len), 'constant').astype(np.int64)
- elif pad_len > rank:
- return int64_array(pad[: rank])
- else:
- return int64_array(pad)
-
-
-def correct_scales_using_dst_shape(node, dst_shape, src_shape, axes):
- scales_value = node.in_port(2).data.get_value()
- if scales_value is None or len(scales_value) != len(dst_shape):
- corrected_scales = np.zeros(len(dst_shape), dtype=np.float32)
- for i, axis in enumerate(list(axes)):
- corrected_scales[i] = dst_shape[i] / src_shape[axis]
- node.in_port(2).data.set_value(corrected_scales)
-
-
-class Interpolate(Op):
- op = 'Interpolate'
- enabled = False
- infers = {
- 'opset1': infer_for_opset1,
- 'opset4': lambda node: infer_for_opsetX(node, "opset4"),
- 'opset11': lambda node: infer_for_opsetX(node, "opset11")
- }
-
- def __init__(self, graph: Graph, attrs: dict):
- self.attributes_for_opsets = {
- 'opset1': [
- ('axes', lambda node: ','.join(map(str, node.axes))),
- ('antialias', lambda node: bool_to_str(node, 'antialias')),
- ('align_corners', lambda node: bool_to_str(node, 'align_corners')),
- 'mode', 'pads_begin', 'pads_end',
- ],
- 'opset4': [
- 'mode', 'nearest_mode', 'cube_coeff', 'coordinate_transformation_mode',
- 'shape_calculation_mode',
- ('antialias', lambda node: bool_to_str(node, 'antialias')),
- ('pads_begin', lambda node: pad_attribute_to_str(node, 'pads_begin')),
- ('pads_end', lambda node: pad_attribute_to_str(node, 'pads_end')),
- ]
- }
- # attributes for opset11 are same as for opset4
- self.attributes_for_opsets['opset11'] = self.attributes_for_opsets['opset4']
-
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'axes': None,
- 'mode': None,
- 'align_corners': 0,
- 'antialias': 0,
- 'pads_begin': 0,
- 'pads_end': 0,
-
- 'infer': self.infer,
- 'force_precision_in_ports': {1: 'int64'},
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
- if self.attrs['version'] == 'opset11' and self.attrs['shape_calculation_mode'] != 'sizes':
- del self.attrs['force_precision_in_ports']
-
- def supported_attrs(self):
- opset = self.get_opset()
- key = opset if opset in self.attributes_for_opsets else 'opset1'
- return self.attributes_for_opsets[key]
-
- def infer(self, node: Node):
- opset = self.get_opset()
- key = opset if opset in self.infers else 'opset1'
- self.infers[key](node)
-
- @staticmethod
- def get_axes(node: Node) -> np.ndarray:
- opset = node.get_opset()
- if opset == 'opset1':
- interp_axes = node.soft_get('axes', None)
- return interp_axes if interp_axes is None else int64_array(interp_axes)
-
- src_shape = node.in_port(0).data.get_shape()
- assert src_shape is not None
- input_rank = len(src_shape)
-
- if len(node.in_ports()) == 3:
- axes = list(range(0, input_rank))
- else:
- axes = node.in_port(3).get_source().data.get_value()
- return int64_array(axes)
diff --git a/tools/mo/openvino/tools/mo/ops/layer_norm.py b/tools/mo/openvino/tools/mo/ops/layer_norm.py
deleted file mode 100644
index 02feb1b6399691..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/layer_norm.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class LayerNorm(Op):
- """
- MXNet operation which normalizes the channels of the input tensor by mean and variance, and applies a scale gamma
- and offset beta. Operation computes output with the same shape as input as following formula:
-
- out = ((data - mean(data, axis)) / sqrt(var(data, axis) + eps)) * gamma + beta
-
- inputs:
- data - input data
- gamma - gamma array
- beta - beta array
-
- attributes:
- axis - axis to perform layer normalization
- eps - epsilon parameter to prevent division by zero
- output_mean_var - output the mean and std calculated along the given axis. Default value is False. Non default value
- is not supported
- """
-
- op = 'LayerNorm'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
- 'axis': -1,
- 'epsilon': 0.001,
- 'output_mean_var': False,
- 'infer': copy_shape_infer,
- 'in_ports_count': 3 if attrs.get('output_mean_var') is True else 1,
- 'out_ports_count': 3,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/log_softmax.py b/tools/mo/openvino/tools/mo/ops/log_softmax.py
deleted file mode 100644
index 1f1e4491fb5d05..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/log_softmax.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-class LogSoftmax(Op):
- op = 'LogSoftmax'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset5',
- 'infer': self.infer,
- 'axis': 1,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['axis']
-
- @staticmethod
- def infer(node: Node):
- assert len([port for port in node.in_ports().values() if not port.disconnected()]) == 1,\
- 'LogSoftmax node with id {} have more than one port connected'.format(node.id)
- if node.axis < 0:
- node.axis = len(node.in_port(0).data.get_shape()) + node.axis
- assert 0 <= node.axis < len(node.in_port(0).data.get_shape()),\
- 'LogSoftmax node with id {} has wrong axis attribute'.format(node.id)
- copy_shape_infer(node)
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
-
-class LogSoftmaxONNX(Op):
- op = 'LogSoftmaxONNX'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'infer': None,
- 'kind': 'op',
- 'axis': 1,
- 'type': None, # the operation will be replaced with a
- # Reshape(LogSoftmax(FlattenONNX(x, axis), 1), x.shape) sub-graph
- 'op': self.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/loop.py b/tools/mo/openvino/tools/mo/ops/loop.py
deleted file mode 100644
index 6c6cd297b87f2a..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/loop.py
+++ /dev/null
@@ -1,548 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.ops.tensor_iterator import TensorIterator
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, is_fully_defined, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.fusing.helpers import common_bfs
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.const import Const
-
-
-class Loop(TensorIterator):
- """
- Loop layer that iterates over tensors and execute embedded sub-graph. The main difference from the TensorIterator is
- that Loop operation performs explicit slicing of data using special input called "current_iteration". Also the Loop
- has special input determining the execution condition and special output producing execution condition for the next
- iteration.
- """
- op = 'Loop'
-
- def __init__(self, graph: Graph, attrs: dict):
- base_attrs = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset5',
- 'input_port_map': [], # a list of dicts with such attrs as external_port_id, etc.
- 'output_port_map': [], # a list of dicts with such attrs as external_port_id, etc.
- 'back_edges': [], # a list of dicts with such attrs as from_layer, from_port, etc.
- 'body': None, # an Graph object with a body sub-graph
- 'sub_graphs': ['body'], # built-in attribute with all sub-graphs
- 'infer': self.infer,
- 'type_infer': self.type_infer,
- }
- base_attrs.update(attrs)
- super().__init__(graph, base_attrs)
-
- def port_map_attrs(self):
- return super().port_map_attrs() + ['purpose']
-
- @staticmethod
- def generate_port_map(node: Node, src_port_map, dir: str):
- result_list = []
- for record in src_port_map:
- # do not update ids for not-connected output which is used in the Loop operation only
- if record['external_port_id'] != -1:
- if dir == 'out': # increase the output port id by the number of input ports
- # update the port id for proper generation of a "ports" section
- record['external_port_id'] += len(node.in_ports())
- record['internal_layer_id'] = TensorIterator.find_internal_layer_id(node.body, record['internal_layer_id'])
- result_list.append(record)
- return result_list
-
- @staticmethod
- def get_body_node_by_internal_id(loop_node: Node, internal_id: int):
- suitable_nodes = loop_node.body.get_op_nodes(internal_layer_id=internal_id)
- assert len(suitable_nodes) <= 1, \
- 'Expected 0 or 1 node with `internal_layer_id`={}, {} found'.format(internal_id, len(suitable_nodes))
- return suitable_nodes[0] if len(suitable_nodes) == 1 else None
-
- @staticmethod
- def get_external_nodes_by_internal_id(loop_node: Node, internal_layer_id: int) -> list:
- """
- Get a list of nodes from the main graph that are connected with a node with internal_layer_id
- from the body graph
-
- :param loop_node: The Loop node
- :param internal_layer_id: Internal layer ID of the node in the body graph
- :return: A list of external nodes (from the main graph) that are connected with a node with
- internal_layer_id from the body graph
- """
- for map_item in loop_node.input_port_map:
- if map_item['internal_layer_id'] == internal_layer_id \
- and loop_node.is_in_port_connected(map_item['external_port_id']):
- return [loop_node.in_port(map_item['external_port_id']).get_source().node]
- for map_item in loop_node.output_port_map:
- if map_item['internal_layer_id'] == internal_layer_id \
- and loop_node.is_out_port_connected(map_item['external_port_id']):
- return [dest.node for dest in loop_node.out_port(map_item['external_port_id']).get_destinations()]
- return []
-
- @staticmethod
- def updated_body_parameters_shape(loop_node: Node):
- """
- Update shape for Loop body parameters.
- The input shape of the "current_iteration" number input is handled separately because it is not connected with
- the Loop operation.
-
- :param loop_node: The Loop node
- :return: None
- """
- for record in loop_node.input_port_map:
- body_node = Loop.get_body_node_by_internal_id(loop_node, record['internal_layer_id'])
- # the Parameter may be removed because it was not used in the body, for example, the current iteration
- # number input
- if body_node is not None:
- assert body_node.soft_get('type') == 'Parameter'
-
- input_shape = shape_array([]) # this is a current iteration number input shape
- loop_port_idx = record['external_port_id']
- if loop_port_idx != -1:
- input_shape = loop_node.in_port(loop_port_idx).get_connection().get_source().data.get_shape()
- slice_axis = record['axis']
- body_node.shape = input_shape.copy()
- if slice_axis is not None:
- body_node.shape[slice_axis] = 1
- log.debug('Updated shape for the body node with internal_id "{}" with value {}'
- ''.format(record['internal_layer_id'], body_node.shape))
-
- @staticmethod
- def updated_loop_output_ports_shape_and_value(loop_node: Node):
- """
- Update shape and values for Loop output ports. If the number of iterations is dynamic then the corresponding
- dimension for the scan outputs (having "axis" attribute) are set to 1 because MO cannot generate IR with
- undefined dimensions.
-
- :param loop_node: The Loop node
- :return: None
- """
- loop_name = loop_node.soft_get('name', loop_node.id)
- for record in loop_node.output_port_map:
- body_node = Loop.get_body_node_by_internal_id(loop_node, record['internal_layer_id'])
- assert body_node is not None
- assert body_node.soft_get('type') == 'Result'
-
- loop_port_idx = record['external_port_id']
- if loop_port_idx != -1: # the id = -1 for execution condition output which is not connected anywhere
- output_value = body_node.in_port(0).data.get_value()
- output_shape = body_node.in_port(0).data.get_shape().copy()
- concat_axis = record['axis']
- if concat_axis is not None:
- assert output_shape[concat_axis] == 1, 'Dimension for concatenation is not equal to 1 for scan ' \
- 'output for Loop node "{}" for loop output port "{}"'.\
- format(loop_name, loop_port_idx)
- output_shape[concat_axis] = Loop.iterations_count(loop_node)
- # MO does not support evaluation of Loop scan outputs with const values
- if concat_axis is None and output_value is not None:
- loop_node.out_port(loop_port_idx).data.set_value(output_value)
- else:
- loop_node.out_port(loop_port_idx).data.set_shape(output_shape)
-
- @staticmethod
- def iterations_count(loop_node: Node):
- """
- Try to determine the number of loop iterations. If we detect that the number is dynamic then return None.
-
- :param loop_node: Loop operation node
- :return: number of iterations or dynamic_dimensions if the number depends on runtime values.
- """
- assert loop_node.soft_get('type') == 'Loop'
-
- if loop_node.is_in_port_connected(1):
- execution_condition = loop_node.in_port(1).data.get_value()
- if not is_fully_defined(execution_condition): # dynamic execution condition
- return dynamic_dimension_value
- execution_condition = execution_condition.item()
- if not execution_condition: # 0 iterations
- return 0
- num_iterations = loop_node.in_port(0).data.get_value()
- if not is_fully_defined(num_iterations):
- return dynamic_dimension_value
- if num_iterations is not None:
- num_iterations = num_iterations.item(0)
- # in some ONNX models the num_iterations input is equal to max(int64) meaning dynamic number of iterations
- if num_iterations < 0 or num_iterations == np.iinfo(np.int64).max:
- return dynamic_dimension_value
- return num_iterations
-
- @staticmethod
- def update_body_parameters_type(loop_node: Node):
- """
- Update the data type for Loop body Parameter nodes based on data type of the outer graph nodes producing data
- for them.
-
- :param loop_node: The Loop node
- :return: None
- """
- assert loop_node.soft_get('type') == 'Loop'
- for record in loop_node.input_port_map:
- body_node = Loop.get_body_node_by_internal_id(loop_node, record['internal_layer_id'])
- # the Parameter may be removed because it was not used in the body, for example, the current iteration
- # number input
- if body_node is not None:
- assert body_node.soft_get('type') == 'Parameter'
-
- loop_port_idx = record['external_port_id']
- if loop_port_idx != -1:
- input_type = loop_node.in_port(loop_port_idx).get_data_type()
- else: # this is a current iteration number input node which is not connected to the Loop node
- assert record['purpose'] == 'current_iteration'
- input_type = np.int64
-
- body_node.data_type = input_type
- log.debug('Updated data type for the body node with internal_id "{}" with value {}'
- ''.format(record['internal_layer_id'], body_node.data_type))
-
- @staticmethod
- def update_loop_output_ports_type(loop_node: Node):
- """
- Update the data type for Loop output ports.
-
- :param loop_node: The Loop node
- :return: None
- """
- assert loop_node.soft_get('type') == 'Loop'
- for record in loop_node.output_port_map:
- body_node = Loop.get_body_node_by_internal_id(loop_node, record['internal_layer_id'])
- assert body_node is not None
- assert body_node.soft_get('type') == 'Result'
-
- loop_port_idx = record['external_port_id']
- if loop_port_idx != -1: # the id = -1 for execution condition output which is not connected anywhere
- output_type = body_node.in_port(0).get_data_type()
- loop_node.out_port(loop_port_idx).set_data_type(output_type)
-
- @staticmethod
- def mark_current_iteration_parameter_node(loop_node: Node, body_parameter_node: Node):
- assert body_parameter_node.id in loop_node.body
- assert body_parameter_node.soft_get('op') == 'Parameter'
- assert body_parameter_node.has_valid('internal_layer_id')
- assert len(loop_node.body.get_op_nodes(purpose='current_iteration')) == 0
-
- loop_node.input_port_map.append({'axis': None, 'stride': None, 'part_size': None, 'start': None, 'end': None,
- 'external_port_id': -1, 'purpose': 'current_iteration',
- 'internal_layer_id': body_parameter_node['internal_layer_id']})
-
- @staticmethod
- def mark_execution_condition_result_node(loop_node: Node, body_result_node: Node):
- assert body_result_node.id in loop_node.body
- assert body_result_node.soft_get('op') == 'Result'
- assert body_result_node.has_valid('internal_layer_id')
- assert len(loop_node.body.get_op_nodes(purpose='execution_condition')) == 0
-
- loop_node.output_port_map.append({'axis': None, 'stride': None, 'part_size': None, 'start': None, 'end': None,
- 'external_port_id': -1, 'purpose': 'execution_condition',
- 'internal_layer_id': body_result_node['internal_layer_id']})
-
- @staticmethod
- def external_port_id_to_body_node(loop_node: Node, external_port_id: int, port_map: dict):
- """
- Return the body Node connected to the Loop port with number "external_port_id".
-
- :param loop_node: the Loop node
- :param external_port_id: the Loop node port idx
- :param port_map: the port_map value to look for external_port_id
- :return: the corresponding body Node
- """
- assert loop_node.soft_get('type') == 'Loop'
- body_graph = loop_node.body
- result_nodes = []
- for record in port_map:
- if record['external_port_id'] == external_port_id:
- result_nodes.extend(body_graph.get_op_nodes(internal_layer_id=record['internal_layer_id']))
- assert len(result_nodes) == 1, 'There should be just one body node for external port "{}", but there "{}"' \
- ''.format(external_port_id, len(result_nodes))
- return result_nodes[0]
-
- @staticmethod
- def connect_body_input(loop_node: Node, loop_input_port_idx: int, body_parameter: Node,
- axis: [int, None] = None, start: [int, None] = None, end: [int, None] = None,
- stride: [int, None] = None, part_size: [int, None] = None):
- """
- Update the input port map to connect the input port with the specified body parameter
-
- :param loop_node: the Loop node
- :param loop_input_port_idx: the input port index to connect
- :param body_parameter: the body parameter node to connect
- :param axis: dimension for input slicing
- :param start: start value of dimension from which to start slicing
- :param end: end value of dimension when to finish slicing
- :param stride: a step value for slicing
- :param part_size: a partial size for slicing, i.e. slicing [start; start + part_size)
- :return: None
- """
- assert loop_node.soft_get('op') == 'Loop'
- assert body_parameter.soft_get('op') == 'Parameter'
- assert body_parameter.id in loop_node.body
-
- loop_node.input_port_map.append({'axis': axis, 'stride': stride, 'part_size': part_size, 'start': start,
- 'end': end, 'external_port_id': loop_input_port_idx,
- 'internal_layer_id': body_parameter['internal_layer_id']})
-
- @staticmethod
- def connect_body_output(loop_node: Node, loop_output_port_idx: int, internal_result: Node, axis: [int, None] = None,
- start: [int, None] = None, end: [int, None] = None, stride: [int, None] = None,
- part_size: [int, None] = None):
- """
- Update the output port map to connect the body Result node with the specified output port
-
- :param loop_node: the Loop node
- :param loop_output_port_idx: the output port index to connect
- :param internal_result: the body Result node to connect
- :param axis: dimension for output concatenation
- :param start: start value of dimension from which to start concatenation
- :param end: end value of dimension when to finish concatenation
- :param stride: a step value for concatenation
- :param part_size: a partial size for concatenation, i.e. concatenation [start; start + part_size)
- :return: None
- """
- assert loop_node.soft_get('op') == 'Loop'
- assert internal_result.soft_get('op') == 'Result'
- assert internal_result.id in loop_node.body
-
- loop_node.output_port_map.append({'axis': axis, 'stride': stride, 'part_size': part_size, 'start': start,
- 'end': end, 'external_port_id': loop_output_port_idx,
- 'internal_layer_id': internal_result['internal_layer_id']})
-
- @staticmethod
- def add_back_edge(loop_node: Node, internal_parameter: Node, internal_result: Node):
- assert internal_parameter.id in loop_node.body
- assert internal_parameter.soft_get('op') == 'Parameter'
- assert internal_result.id in loop_node.body
- assert internal_result.soft_get('op') == 'Result'
-
- loop_node.back_edges.append({'from_layer': internal_result['internal_layer_id'],
- 'to_layer': internal_parameter['internal_layer_id'],
- 'from_port': 0,
- 'to_port': 0})
-
- @staticmethod
- def parameter_unchanged_after_iteration(loop_node: Node, body_parameter: Node):
- """
- Checks if the body Parameter node is connected to some body Result and the data provided to Result is not
- changed between iterations. The data is considered unchanged if:
- 1. There is no back edge for this Parameter OR
- 2. There is a back edge from some Result to Parameter and there are only Identity ops in between or
- Parameter is connected to Result directly.
-
- :param loop_node: the Loop node to check
- :param body_parameter: the body Parameter node
- :return: the result of the check
- """
- assert body_parameter.id in loop_node.body
- assert body_parameter.soft_get('op') == 'Parameter'
- if not any([attr['to_layer'] == body_parameter.soft_get('internal_layer_id') for attr in loop_node.back_edges]):
- return True
-
- for back_edge_attrs in loop_node.back_edges:
- if back_edge_attrs['to_layer'] == body_parameter.soft_get('internal_layer_id'):
- result_internal_id = back_edge_attrs['from_layer']
- result_nodes = loop_node.body.get_op_nodes(internal_layer_id=result_internal_id)
- assert len(result_nodes) == 1, 'There should be exactly one node with id {}, but there are {}' \
- ''.format(result_internal_id, len(result_nodes))
- result_node = result_nodes[0]
- # check that the Result node consumes data from Parameter node directly or through Identity operations
- parameters = common_bfs(result_node, ['Identity'], ['Parameter'], is_backward=True, attr_to_check='op',
- follow_multi_consumer_data_nodes=True)
- if any([node.soft_get('internal_layer_id') == body_parameter.internal_layer_id for node in parameters]):
- return True
- return False
-
- @staticmethod
- def pull_constant_inputs_into_body(loop_node: Node):
- for port_idx, in_port in reversed(loop_node.in_ports().items()):
- if port_idx > 1 and not in_port.disconnected() and in_port.get_source().node.soft_get('type') == 'Const':
- body_parameter = Loop.external_port_id_to_body_node(loop_node, port_idx, loop_node.input_port_map)
- # if there is a back edge into a body Parameter then we cannot replace it with a Const if the value
- # is updated during each iteration. So we need to check that the tensor is passed to the next iteration
- # unchanged
- if not Loop.parameter_unchanged_after_iteration(loop_node, body_parameter):
- continue
-
- original_const_node = in_port.get_source().node
- new_const_node = Const(loop_node.body, original_const_node.attrs()).create_node()
-
- body_parameter.out_port(0).get_connection().set_source(new_const_node.out_port(0))
- loop_node.body.remove_nodes_from([body_parameter.id])
- loop_node.delete_input_port(port_idx)
-
- @staticmethod
- def update_port_map_value(port_map: dict, attr: str, original_value: int, new_value: int):
- matched = 0
- for record in port_map:
- if record[attr] == original_value:
- record[attr] = new_value
- matched += 1
- assert matched == 1, 'More than one record in the portmap for attr "{}" with original value "{}"' \
- ''.format(attr, original_value)
-
- @staticmethod
- def update_port_map_value_ext(port_map: dict, layer_id_attr: str, layer_id_value: int,
- updated_attr: str, new_attr_value: int):
- """
- Updates a value of requested attribute for a certain layer id in a port map
- :param port_map: a map of external ports to internal layer ids
- :param layer_id_attr: layer id attribute for which to update attribute
- :param layer_id_value: layer id value for which to update attribute
- :param updated_attr: a name of attribute which to update
- :param new_attr_value: new value of attribute
- """
- matched = 0
- for record in port_map:
- if record.get(layer_id_attr) == layer_id_value:
- record[updated_attr] = new_attr_value
- matched += 1
- assert matched == 1, 'More than one record in the portmap for attr "{}" with original value "{}"' \
- ''.format(layer_id_attr, layer_id_value)
-
- @staticmethod
- def back_edge_exists(back_edges_map: dict, from_layer: int, to_layer: int):
- """
- Checks if a back edge exists in the back_edges_map connecting specific nodes
- :param back_edges_map: a map where to search for specified back edge
- :param from_layer: id of Result node that belongs a back edge
- :param to_layer: id of Parameter node that belongs a back edge
- :return: True or False
- """
- for back_edge in back_edges_map:
- if back_edge['from_layer'] == from_layer and back_edge['to_layer'] == to_layer:
- return True
- return False
-
- @staticmethod
- def inter_edge_exists(port_map: dict, external_port_id: int, internal_layer_id: int):
- """
- Check if inter-graph edge (i.e. an edge between the main graph and body graph) exists
- :param port_map: a port map where to search for inter-graph edge
- :param external_port_id: port index from/to which edge goes
- :param internal_layer_id: layer id from/to which edge goes
- :return: True or False
- """
- for i_port in port_map:
- if i_port['external_port_id'] == external_port_id and \
- i_port['internal_layer_id'] == internal_layer_id:
- return True
- return False
-
- @staticmethod
- def re_numerate_input_ports(loop_node: Node):
- """
- Update input ports ids to be consecutive from 0 to num_input_ports - 1 and update the port_map values of the
- Loop node.
-
- :param loop_node: the Loop node
- :return: None
- """
- def re_number_input_port(loop_node: Node, old_port_id: int, new_port_id: int):
- loop_node.add_input_port(new_port_id, skip_if_exist=True)
- loop_node.in_port(old_port_id).get_connection().set_destination(loop_node.in_port(new_port_id))
- Loop.update_port_map_value(loop_node.input_port_map, 'external_port_id', old_port_id, new_port_id)
-
- if len(loop_node.in_ports()) > 0:
- max_port_id = sorted(loop_node.in_ports().keys())[-1]
- new_port_id = 0
- for port_id in range(max_port_id + 1):
- if loop_node.is_in_port_connected(port_id):
- if port_id != new_port_id:
- re_number_input_port(loop_node, port_id, new_port_id)
- new_port_id += 1
-
- for port_idx_to_remove in reversed(range(new_port_id, max_port_id + 1)):
- if port_idx_to_remove in loop_node.in_ports().keys():
- loop_node.delete_input_port(port_idx_to_remove)
-
- @staticmethod
- def re_numerate_output_ports(loop_node: Node):
- """
- Update output ports ids to be consecutive from 0 to num_output_ports - 1 and update the port_map values of the
- Loop node.
-
- :param loop_node: the Loop node
- :return: None
- """
- assert loop_node.soft_get('type') == 'Loop'
-
- def re_number_output_port(loop_node: Node, old_port_id: int, new_port_id: int):
- loop_node.add_output_port(new_port_id, skip_if_exist=True)
- loop_node.out_port(old_port_id).get_connection().set_source(loop_node.out_port(new_port_id))
- Loop.update_port_map_value(loop_node.output_port_map, 'external_port_id', old_port_id, new_port_id)
-
- if len(loop_node.out_ports()) > 0:
- max_port_id = sorted(loop_node.out_ports().keys())[-1]
- new_port_id = 0
- for port_id in range(max_port_id + 1):
- if port_id in loop_node.out_ports():
- if port_id != new_port_id:
- re_number_output_port(loop_node, port_id, new_port_id)
- new_port_id += 1
-
- for port_idx_to_remove in reversed(range(new_port_id, max_port_id + 1)):
- if port_idx_to_remove in loop_node.out_ports().keys():
- loop_node.delete_output_port(port_idx_to_remove)
-
- @staticmethod
- def remove_unused_ops_from_port_map(loop_node: Node, port_map: dict, port_map_attr: str, dir: [None, str] = None):
- """
- Find unused operations in the Loop body referenced in the port_map and removes Loop ports connected to it.
- Loop input port with index 0 and 1 are mandatory so cannot be removed.
- Output ports of the Loop may not be connected so check for that case also and remove such an ops from the
- port_map. The only exception is the "execution_condition" output which is a mandatory.
-
- :param loop_node: the Loop node to update
- :param port_map: the port_map (input, output or back edges)
- :param port_map_attr: the port_map attribute containing the `internal_layer_id`
- :param dir: the direction of the port_map meaning 'in' or 'out' port of the Loop
- :return:
- """
- record_ids_to_remove = []
- for record_id, record in enumerate(port_map):
- if len(loop_node.body.get_op_nodes(internal_layer_id=record[port_map_attr])) == 0 or \
- (dir == 'out' and record.get('purpose', "") != 'execution_condition' and
- record['external_port_id'] not in loop_node.out_ports()):
- record_ids_to_remove.append(record_id)
- for record_id_to_remove in reversed(record_ids_to_remove):
- if dir in ['in', 'out']:
- port_to_remove = port_map[record_id_to_remove]['external_port_id']
- if port_to_remove != -1:
- if dir == 'in':
- # input port 0 and 1 are mandatory for the Loop node
- if port_to_remove not in [0, 1] and port_to_remove in loop_node.in_ports().keys():
- loop_node.delete_input_port(port_to_remove)
- elif dir == 'out' and port_to_remove in loop_node.out_ports():
- loop_node.delete_output_port(port_to_remove)
- del port_map[record_id_to_remove]
-
- @staticmethod
- def normalize_input_output_ports(loop_node: Node):
- """
- Remove inputs, outputs, back edges from the port map which are not used in the body and were removed by a
- graph clean up, for example, in case of not used current_iteration body Parameter. Then renumber input/output
- ports.
-
- :param loop_node: the Loop node to normalize
- :return: None
- """
- Loop.remove_unused_ops_from_port_map(loop_node, loop_node.input_port_map, 'internal_layer_id', 'in')
- Loop.remove_unused_ops_from_port_map(loop_node, loop_node.output_port_map, 'internal_layer_id', 'out')
- Loop.remove_unused_ops_from_port_map(loop_node, loop_node.back_edges, 'to_layer')
-
- # remove not connected input/output ports
- Loop.re_numerate_input_ports(loop_node)
- Loop.re_numerate_output_ports(loop_node)
-
- @staticmethod
- def infer(loop_node: Node):
- Loop.updated_body_parameters_shape(loop_node)
- partial_infer(loop_node.body)
- Loop.updated_loop_output_ports_shape_and_value(loop_node)
-
- @staticmethod
- def type_infer(loop_node: Node):
- from openvino.tools.mo.middle.passes.infer import type_infer
- Loop.update_body_parameters_type(loop_node)
- type_infer(loop_node.body)
- Loop.update_loop_output_ports_type(loop_node)
diff --git a/tools/mo/openvino/tools/mo/ops/lrn.py b/tools/mo/openvino/tools/mo/ops/lrn.py
deleted file mode 100644
index f7c0337e510474..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/lrn.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class LRN(Op):
- op = 'LRN'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'alpha' in attrs, 'LRN operation should have `alpha` parameter set while creation'
- assert 'beta' in attrs, 'LRN operation should have `beta` parameter set while creation'
- assert 'bias' in attrs, 'LRN operation should have `bias` parameter set while creation'
- assert 'size' in attrs, 'LRN operation should have `size` parameter set while creation'
- assert 'region' not in attrs, \
- 'LRN operation should not have `region` parameter set while creation, please use AttributedLRN operation ' \
- 'instead or keep using LRN operation with region expressed as second `axis`-input'
-
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['alpha', 'beta', 'bias', 'size']
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
-
- connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_inputs) == 2 and 0 in connected_inputs and 1 in connected_inputs, \
- 'LRN should have 2 connected input ports, but it doesn`t for node: `{}`. Ports: {}' \
- ''.format(name, connected_inputs)
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, 'Input shape is unknown for node {}'.format(name)
- node.out_port(0).data.set_shape(input_shape)
-
-
-class AttributedLRN(Op):
- op = 'AttributedLRN'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'alpha' in attrs, 'AttributedLRN operation should have `alpha` parameter set while creation'
- assert 'beta' in attrs, 'AttributedLRN operation should have `beta` parameter set while creation'
- assert 'local_size' in attrs, 'AttributedLRN operation should have `local_size` parameter set while creation'
-
- super().__init__(graph, {
- 'op': self.op,
- 'type': 'Norm',
- 'version': 'opset1',
-
- 'bias': 1,
- 'region': 'across',
- 'infer': self.infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- assert 'region' in self.attrs, 'AttributedLRN operation should have `region` parameter set while creation'
- assert self.attrs['region'] in ['across', 'same'], \
- 'AttributedLRN operation should have `region` parameter set to `across` or `same`, but it is `{}`' \
- ''.format(self.attrs['region'])
-
- def supported_attrs(self):
- return [
- 'alpha',
- 'beta',
- ('local-size', lambda node: node.local_size),
- 'region' # deprecated in V10 attribute, but it is kept for V6 compatibility
- ]
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
-
- connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_inputs) == 1 and 0 in connected_inputs, \
- 'AttributedLRN should have 1 connected input port, but it doesn`t for node: `{}`. Ports: {}' \
- ''.format(name, connected_inputs)
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, 'Input shape is unknown for node {}'.format(name)
- node.out_port(0).data.set_shape(input_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/lstm_cell.py b/tools/mo/openvino/tools/mo/ops/lstm_cell.py
deleted file mode 100644
index 0de05611d0644b..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/lstm_cell.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins, compatible_dims
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class LSTMCell(Op):
- ''' A single LSTM cell (without a loop).
-
- 3 inputs:
- - [0, required] input data (2D),
- - [1, required] initial hidden state (2D),
- - [2, required] initial cell state (2D),
-
- 2 blobs:
- - [3, required] LSTM FC weights
- - [4, required] LSTM FC biases
-
- 2 outputs:
- - [required] output data / resulting hidden state (2D)
- - [required] resulting cell state (2D)
- '''
- op = 'LSTMCell'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset4',
- 'infer': self.infer,
- 'in_ports_count': 5,
- 'out_ports_count': 2,
- 'wr_input_id': 3,
- 'gates_count': 4
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'activations',
- 'activation_alpha',
- 'activation_beta',
- 'clip',
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- ('activations', lambda node: ','.join(node['activations']) if node.has_and_set('activations') else None),
- ('activations_alpha', lambda node: ','.join(map(str, node['activations_alpha']))
- if node.has_and_set('activations_alpha') else None),
- ('activations_beta', lambda node: ','.join(map(str, node['activations_beta']))
- if node.has_and_set('activations_beta') else None),
- 'clip',
- ]
-
- @staticmethod
- def infer(node: Node):
- if node.has_and_set('extra_inputs'):
- assert len(node.in_nodes()) == 8
- else:
- assert len(node.in_nodes()) == 5
- assert len(node.out_nodes()) in [1, 2]
-
- hidden_shape = node.in_node(1).shape.copy()
- cell_shape = node.in_node(2).shape.copy()
-
- mark_input_bins(node, start_port=3)
- node.out_node(0).shape = hidden_shape
- if len(node.out_nodes()) == 2:
- node.out_node(1).shape = cell_shape
-
- hidden_size = hidden_shape[1]
-
- if node.has_valid('hidden_size'):
- if node.hidden_size != hidden_size:
- raise Error("Input shape {} for hidden size doesn't match pre-defined hidden_size in node {}".format(
- node.in_node(1).shape, node.soft_get('name')))
- else:
- node['hidden_size'] = hidden_size
-
- assert cell_shape[1] == hidden_size
-
- input_shape = node.in_node(0).shape
- assert input_shape is not None
- assert compatible_dims(hidden_shape[0], cell_shape[0]) and \
- compatible_dims(cell_shape[0], input_shape[0]), 'States are not broadcast-able by batch for node {}' \
- ''.format(node.soft_get('name', node.id))
diff --git a/tools/mo/openvino/tools/mo/ops/lstm_sequence.py b/tools/mo/openvino/tools/mo/ops/lstm_sequence.py
deleted file mode 100644
index 8db2e629c9af92..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/lstm_sequence.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins, shape_array, shape_insert
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node, add_opoutput, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class LSTMSequence(Op):
- """ Implements a layer that incorporates LSTM cell in a loop like it is specified in ONNX
-
- It is assumed that there is no equivalent of this op in IE,
- so it is considered as intermediate operation that will be translated differently.
- We define type for this operation to enable debuggin at OV side.
-
- There are several flavors of this op depending on how it was created and in which framework.
- There are several attributes that specifies the LSTM flavor:
- - ONNX/LSTM gives this op in non-normalized form and will require normalization
- as a separate transformation (see LSTMSequenceNormalize middle transformation);
- in this case blobs_wrb=True. Normalized weights/biases for MatMul is used when
- blobs_wrb=True.
- - ONNX/LSTM defines output shape as 4D: [seq_length, num_directions, batch_size,
- hidden_size], where num_directions = 1 is supported only. In this case
- has_num_directions=True. Otherwise, output is 3D and doesn't contain num_directions.
- - Depending on the original framework, `format` attrtibutes is specified accordingly.
- Its value controls which normalize transformations are called.
- """
- op = 'LSTMSequence'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None, # should be never emitted to IR; for debugging purposes
- 'op': self.op,
- 'blobs_wrb': False,
- 'has_num_directions': False,
- 'direction': 'forward',
- 'num_layers': 1,
- 'infer': self.infer,
- 'blob_bidirectional_split': lambda node: (
- LSTMSequence.split_helper(node, 0, 'forward'),
- LSTMSequence.split_helper(node, 1, 'reverse')
- )
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'hidden_size', # number of the elements in hidden cell size
- 'direction', # one of 'forward', 'reverse', or 'bidirectional'
- 'batch_dim', # batch dimension index in input/output shape
- 'sequence_dim', # sequence dimension index in input shape
- 'blobs_wrb', # input blobs have three separate components W, R and B like in ONNX/LSTM
- 'has_num_directions', # if True, output shape has 4 dimensions; 3D otherwise
- 'format', # format type of input blobs for different frameworks (onnx, tf)
- ]
-
- def backend_attrs(self):
- return [
- 'hidden_size',
- ('activations', lambda node: ','.join(node['activations']) if node.has_and_set('activations') else None),
- ('activations_alpha', lambda node: ','.join(map(str, node['activations_alpha']))
- if node.has_and_set('activations_alpha') else None),
- ('activations_beta', lambda node: ','.join(map(str, node['activations_beta']))
- if node.has_and_set('activations_beta') else None),
- 'clip',
- 'direction',
- ]
-
- @staticmethod
- def split_helper(node, index: int, direction: str):
- return Op._create_data_node(
- node.graph,
- name=node.name + '/SplittedBiLSTM/{}/'.format(direction),
- attrs={'value': node.value[index], 'shape': int64_array(node.value[index].shape)}
- )
-
- @staticmethod
- def infer(node: Node):
- # there are limitations coming from ONNX LSTM definition and normalization rules
- assert len(node.in_nodes()) >= 3 # X, W and R
- assert len(node.in_nodes()) <= 7
- assert len(node.out_nodes()) <= 3
- assert node.batch_dim <= 1
- assert node.sequence_dim <= 1
- assert node.batch_dim != node.sequence_dim
-
- assert node.direction in ['forward', 'reverse', 'bidirectional']
-
- if node.blobs_wrb:
- mark_input_bins(node, ['W', 'R', 'B'])
- else:
- mark_input_bins(node)
- input_shape = node.in_node(0).shape
- assert len(input_shape) == 3
-
- for port in [2, 3]:
- if port in node.in_nodes() and len(node.in_node(port).in_nodes()) > 0 and \
- 'zero_shapes' in node.in_node(port).in_node():
- for i in node.in_node(port).in_node().zero_shapes:
- if node.in_node(port).shape[i] != input_shape[i]:
- node.in_node(port).value = np.repeat(node.in_node(port).value, input_shape[i], axis=i)
- node.in_node(port).shape[i] = input_shape[i]
-
- out_shape = shape_array([input_shape[node.sequence_dim], input_shape[node.batch_dim], node.hidden_size])
- assert not node.has_num_directions or node.sequence_dim == 0, \
- 'If has_num_directions == True, then node.sequence_dim should be equal 0, but it is {}'.format(
- node.sequence_dim)
- num_directions = 2 if node.direction in ['bidirectional'] else 1
- num_layers = node.num_layers
- if node.has_num_directions:
- # insert extra dimension to output shape for num_directions
- out_shape = shape_insert(out_shape, 1, np.int64(num_directions))
- node.out_node(0).shape = out_shape
- # extra outputs for hidden/cell states
- state_size = shape_array([input_shape[1], node.hidden_size])
- if node.has_num_directions:
- state_size = shape_insert(state_size, 0, num_directions * num_layers)
- for i in [1,2]:
- if i not in node.out_nodes():
- data_node = Op._create_data_node(
- node.graph,
- name=node.node+'/ExtraOutput/' + str(i),
- attrs={'executable': True}
- )
- node.graph.add_edge(node.id, data_node.id, key=0, out=i)
- add_opoutput(node.graph, data_node.id, 0, False)
- else:
- data_node = node.out_node(i)
- data_node.shape = state_size.copy()
diff --git a/tools/mo/openvino/tools/mo/ops/lstmnonlinearity.py b/tools/mo/openvino/tools/mo/ops/lstmnonlinearity.py
deleted file mode 100644
index cff8da3a98c1df..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/lstmnonlinearity.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class LstmNonLinearity(Op):
- """
- """
- op = 'LstmNonLinearity'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': __class__.op,
- 'use_dropout': False,
- 'type': None, # type is None because this operation should not appear in IR
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/memory.py b/tools/mo/openvino/tools/mo/ops/memory.py
deleted file mode 100644
index 5c337eaf588245..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/memory.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-class Memory(Op):
- op = 'Memory'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': 'Memory',
- 'op': 'Memory',
- 'id': None,
- 'size': None,
- 'index': None,
- 'infer': Memory.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'type_infer': __class__.type_infer,
- }, attrs)
-
- def supported_attrs(self):
- return ['id', 'size', 'index']
-
- @staticmethod
- def infer(node: Node):
- if len(node.in_nodes()) > 0:
- # In case this is a memory node with input,
- # It should not have output
- # However in order not to break MO pipeline,
- # we just set the same shape to the output
- # node that will be removed later in pipeline
- copy_shape_infer(node)
- return
- elif node.has_valid('shape'):
- # For Memories, that has not input infer shapes is very difficult
- # But often we can know shape in extracting attributes
- # And we can set the attribute 'shape' in extracting
- batch = 1
- for out_node in node.out_nodes().values():
- out_node.shape = shape_array([batch, *node.shape[:]])
- return
- else:
- raise Error('Model Optimizer is unable to calculate output shape of Memory node {}. ' +
- refer_to_faq_msg(88),
- node.id)
-
- @staticmethod
- def type_infer(node: Node):
- if node.has_valid('dst_type'):
- node.out_port(0).set_data_type(node.dst_type)
- else:
- node.out_port(0).set_data_type(data_type_str_to_np(node.graph.graph['cmd_params'].data_type))
diff --git a/tools/mo/openvino/tools/mo/ops/memoryoffset.py b/tools/mo/openvino/tools/mo/ops/memoryoffset.py
deleted file mode 100644
index 0e59385b47640e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/memoryoffset.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class MemoryOffset(Op):
- op = 'MemoryOffset'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': 'MemoryOffset',
- 'type': None,
- 'pair_name': None,
- 'splitted': False,
- 'has_default': False,
- 'infer': self.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- if node.has_valid('element_size'):
- # element_size should be set by Kaldi loader or MemoryOffsetAdjustment or SplitRecurrentMemoryOffset
- node.out_port(0).data.set_shape(node.element_size)
- else:
- # for TDNN blocks
- copy_shape_infer(node)
diff --git a/tools/mo/openvino/tools/mo/ops/merge.py b/tools/mo/openvino/tools/mo/ops/merge.py
deleted file mode 100644
index f98a5d12cd51b1..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/merge.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes, shape_array, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Merge(Op):
- op = 'Merge'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'infer': self.merge_infer,
- 'cf_infer': self.control_flow_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def merge_infer(node: Node):
- # we infer only through executable input nodes
- inferred_nodes = [n for n in node.in_nodes().values() if n['is_partial_inferred']]
- assert len(inferred_nodes) != 0
- tensor = inferred_nodes[0]
-
- if len(inferred_nodes) < len(node.in_nodes()):
- node['is_not_fully_inferred'] = True
- else:
- node['is_not_fully_inferred'] = False
- assert np.all(compatible_shapes(node.shape, inferred_nodes[0].shape) for node in inferred_nodes)
-
- inferred_and_executable = [n for n in node.in_nodes().values() if n['is_partial_inferred'] and
- 'executable' in n and n['executable']]
- if len(inferred_and_executable) > 0:
- tensor = inferred_and_executable[0]
-
- if all([tensor.has_valid('value') and n.has_valid('value') and strict_compare_tensors(tensor.value,
- n.value)
- for n in inferred_and_executable]):
- node.out_node().value = tensor.value.copy()
- else:
- node.out_node().value = None
-
- # do not use set_shape(tensor.shape) here because input port shape may be different from the calculated output
- # shape and `set_shape` will raise an error that shape has changed
- node.out_node(0).shape = shape_array(tensor.shape)
-
- @staticmethod
- def control_flow_infer(node: Node, is_executable: bool, mark_executability: callable):
- in_data_nodes = node.in_nodes(control_flow=True)
- out_data_nodes = node.out_nodes(control_flow=True)
-
- is_executable = any([d.has_and_set('executable') for i, d in in_data_nodes.items()]
- if len(in_data_nodes) else [False])
-
- for i, d in out_data_nodes.items():
- mark_executability(d.id, is_executable)
-
diff --git a/tools/mo/openvino/tools/mo/ops/multinomial.py b/tools/mo/openvino/tools/mo/ops/multinomial.py
deleted file mode 100644
index 0bf3c7c3385fc2..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/multinomial.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Graph, Node
-
-from openvino.tools.mo.ops.op import Op
-
-
-class Multinomial(Op):
- op = 'Multinomial'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset13',
- 'infer': self.infer,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'type_infer': self.type_infer,
- 'with_replacement': False,
- 'log_probs': False,
- 'global_seed': 0,
- 'op_seed': 0,
- 'convert_type': np.int64,
- }, attrs)
-
- def backend_attrs(self):
- return ['convert_type',
- ('with_replacement', lambda node: bool_to_str(
- node, 'with_replacement')),
- ('log_probs', lambda node: bool_to_str(node, 'log_probs')),
- 'global_seed',
- 'op_seed']
-
- def supported_attrs(self):
- return ['convert_type',
- 'with_replacement',
- 'log_probs',
- 'global_seed',
- 'op_seed']
-
- @staticmethod
- def type_infer(node: Node):
- assert node.has_valid('convert_type')
- if node['convert_type'] == 'i32':
- node.out_port(0).set_data_type(np.int32)
- else:
- node.out_port(0).set_data_type(np.int64)
-
- @staticmethod
- def infer(node: Node):
-
- input_shape = node.in_node(0).shape
- output_shape = []
- if input_shape is not None and input_shape.size == 2:
- output_shape.append(input_shape[0])
-
- num_samples = node.in_port(1).data.get_value()
- if num_samples is not None:
- output_shape.append(np.array(num_samples).item())
- else:
- output_shape.append(dynamic_dimension_value)
- node.out_port(0).data.set_shape(shape_array(output_shape))
diff --git a/tools/mo/openvino/tools/mo/ops/mvn.py b/tools/mo/openvino/tools/mo/ops/mvn.py
deleted file mode 100644
index fa6f010e75a48a..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/mvn.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class MVN(Op):
- op = 'MVN'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'kind': 'op',
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset6',
- 'eps': None,
- 'normalize_variance': None,
- 'eps_mode': None,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }, attrs)
-
- def supported_attrs(self):
- return ['eps', 'eps_mode', 'normalize_variance']
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == 'opset2':
- return ['eps',
- ('across_channels', lambda node: bool_to_str(node, 'across_channels')),
- ('normalize_variance', lambda node: bool_to_str(node, 'normalize_variance'))]
- elif version == 'opset6':
- return ['eps', 'eps_mode', ('normalize_variance', lambda node: bool_to_str(node, 'normalize_variance'))]
- else:
- raise Error('Unsupported MVN opset version "{}"'.format(version))
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- assert node.eps is not None, 'MVN required attribute `eps` unspecified for node {}'.format(name)
- assert node.normalize_variance is not None, \
- 'MVN required attribute `normalize_variance` unspecified for node {}'.format(name)
-
- if node.version == 'opset6':
- assert node.eps_mode is not None, 'MVN required attribute `eps_mode` unspecified for node {}'.format(name)
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
-
- copy_shape_infer(node)
-
-
-class MVNOnnx(Op):
- op = 'MVNOnnx'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'kind': 'op',
- 'type': None,
- 'op': self.op,
- 'version': None,
- 'eps': None,
- 'eps_mode': None,
- 'normalize_variance': None,
- 'axes': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': None
- }, attrs)
-
-
-class MVNCaffe(Op):
- op = 'MVNCaffe'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'kind': 'op',
- 'type': None,
- 'op': self.op,
- 'version': None,
- 'eps': 1e-9,
- 'normalize_variance': None,
- 'across_channels': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': None
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/mxfft.py b/tools/mo/openvino/tools/mo/ops/mxfft.py
deleted file mode 100644
index fa37ebc63c9b5e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/mxfft.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class MXFFT(Op):
- """
- This operation is intended to read MxNet operations FFT and IFFT.
- The operation MXFFT has one attribute: a boolean attribute is_inverse.
-
- If an operation to read is FFT, then the attribute 'is_inverse' is False, and True otherwise.
-
- The transformation MXFFTToDFT converts the operation MXFFT into MO DFT (if the attribute 'is_inverse'
- is False), or into MO IDFT (otherwise).
- """
- op = 'MXFFT'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'out_ports_count': 1,
- 'in_ports_count': 1,
- 'infer': self.infer
- }
- assert 'is_inverse' in attrs, 'Attribute is_inverse is not given for the operation MXFFT.'
- super().__init__(graph, mandatory_props, attrs)
-
- def infer(self, node: Node):
- node_name = node.soft_get('name', node.id)
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, 'Input shape of MXFFT node {} must not be None'.format(node_name)
- is_inverse = node.soft_get('is_inverse', False)
- output_shape = input_shape.copy()
- if is_inverse:
- output_shape[-1] = output_shape[-1] // 2
- else:
- output_shape[-1] = output_shape[-1] * 2
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/mxrepeat.py b/tools/mo/openvino/tools/mo/ops/mxrepeat.py
deleted file mode 100644
index 004b282abd39a1..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/mxrepeat.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class MXRepeat(Op):
- op = 'MXRepeat'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'axis' in attrs, 'MXRepeat operation should have `axis` parameter set during creation'
- assert 'repeats' in attrs, 'MXRepeat operation should have `repeats` parameter set during creation'
-
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
-
- # operation should be resolved on the front phase, partial inference is not needed
- 'infer': None,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/nms_rotated.py b/tools/mo/openvino/tools/mo/ops/nms_rotated.py
deleted file mode 100644
index 0385de8a9cd66e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/nms_rotated.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class NMSRotated(Op):
- op = 'NMSRotated'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset13',
-
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'sort_result_descending': True,
- 'output_type': np.int64,
- 'clockwise': True,
-
- 'in_ports_count': 5,
- 'out_ports_count': 3,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [('sort_result_descending', lambda node: bool_to_str(node, 'sort_result_descending')),
- 'output_type',
- ('clockwise', lambda node: bool_to_str(node, 'clockwise'))]
-
- def supported_attrs(self):
- return [
- 'sort_result_descending',
- 'output_type',
- 'clockwise',
- ]
-
- @staticmethod
- def infer(node: Node):
- num_of_inputs = len(node.in_ports())
- opset = node.get_opset()
- required_num_inputs = 5
- input_msg_fmt = 'NMSRotated node {} from {} must have {} inputs'
- node_name = node.soft_get('name', node.id)
- inputs_msg = input_msg_fmt.format(
- node_name, opset, required_num_inputs)
- assert num_of_inputs == required_num_inputs, inputs_msg
-
- node.out_port(0).data.set_shape(
- shape_array([dynamic_dimension_value, 3]))
- num_of_outputs = len(
- [port for port in node.out_ports().values() if not port.disconnected()])
- if num_of_outputs >= 2 and node.has_port('out', 1):
- node.out_port(1).data.set_shape(
- shape_array([dynamic_dimension_value, 3]))
- if num_of_outputs >= 3 and node.has_port('out', 2):
- node.out_port(2).data.set_shape(shape_array([1]))
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(1).set_data_type(np.float32)
- if node.has_valid('output_type') and node['output_type'].lower() == 'i32':
- node.out_port(0).set_data_type(np.int32)
- node.out_port(2).set_data_type(np.int32)
- else:
- node.out_port(0).set_data_type(np.int64)
- node.out_port(2).set_data_type(np.int64)
diff --git a/tools/mo/openvino/tools/mo/ops/non_max_suppression.py b/tools/mo/openvino/tools/mo/ops/non_max_suppression.py
deleted file mode 100644
index 1faa431b709359..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/non_max_suppression.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, shape_array, dynamic_dimension_value, \
- set_input_shapes, undefined_shape_of_rank
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class NonMaxSuppression(Op):
- op = 'NonMaxSuppression'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset9',
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'output_type': np.int64,
- 'box_encoding': 'corner',
- 'in_ports_count': 5,
- 'sort_result_descending': 1,
- 'force_precision_in_ports': {
- 2: 'int64'},
- 'type_infer': self.type_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
- version = self.get_opset()
- if version in ['opset1', 'opset3', 'opset4']:
- self.attrs['out_ports_count'] = 1
- elif version in ['opset5', 'opset9']:
- self.attrs['out_ports_count'] = 3
- else:
- raise Error('Unsupported operation opset version "{}"'.format(version))
-
- def backend_attrs(self):
- version = self.get_opset()
- if version in ['opset3', 'opset4', 'opset5', 'opset9']:
- return [('sort_result_descending', lambda node: bool_to_str(node, 'sort_result_descending')),
- 'box_encoding',
- ('output_type', lambda node: np_data_type_to_destination_type(node.output_type))]
- elif version == 'opset1':
- return [('sort_result_descending', lambda node: bool_to_str(node, 'sort_result_descending')),
- 'box_encoding']
- else:
- raise Error('Unsupported operation opset version "{}"'.format(version))
-
- @staticmethod
- def infer(node: Node):
- num_of_inputs = len(node.in_ports())
- opset = node.get_opset()
- max_num_of_inputs = 6 if opset in ['opset5', 'opset9'] else 5
- input_msg_fmt = 'NonMaxSuppression node {} from {} must have from 2 to {} inputs'
- node_name = node.soft_get('name', node.id)
- inputs_msg = input_msg_fmt.format(node_name, opset, max_num_of_inputs)
- assert 2 <= num_of_inputs <= max_num_of_inputs, inputs_msg
-
- boxes_shape = node.in_port(0).data.get_shape()
- assert boxes_shape is not None, 'The shape of tensor with boxes is not defined'
- scores_shape = node.in_port(1).data.get_shape()
- assert scores_shape is not None, 'The shape of tensor with scores is not defined'
- assert len(boxes_shape) == 3, 'Length of tensors with boxes must be equal to 3'
- assert len(scores_shape) == 3, 'Length of tensors with scores must be equal to 3'
-
- # According to the specification of the operation NonMaxSuppression,
- # the input 'max_output_boxes_per_class' (port 2) is optional, with default value 0.
- if num_of_inputs >= 3:
- max_output_boxes_per_class = node.in_port(2).data.get_value()
- else:
- max_output_boxes_per_class = 0
-
- if not max_output_boxes_per_class:
- log.info('Set default "max_output_boxes_per_class" for node {} to number of boxes'.format(node.name))
- max_output_boxes_per_class = boxes_shape[1]
-
- # convert the np.array value to a scalar to avoid issue with ragged numpy array generation in the shape
- # calculation formulas below
- if isinstance(max_output_boxes_per_class, np.ndarray):
- max_output_boxes_per_class = max_output_boxes_per_class.item()
-
- num_classes = scores_shape[1]
- num_input_boxes = boxes_shape[1]
- assert scores_shape[2] is dynamic_dimension or scores_shape[2] == num_input_boxes or scores_shape[2] is None \
- or num_input_boxes is None, 'Number of boxes mismatch for operation {}'.format(node_name)
-
- if node.get_opset() in ['opset4', 'opset5', 'opset9']:
- max_number_of_boxes = min(num_input_boxes, max_output_boxes_per_class) * boxes_shape[0] * num_classes
- else:
- max_number_of_boxes = min(num_input_boxes, boxes_shape[0] * max_output_boxes_per_class * num_classes)
- node.out_port(0).data.set_shape(shape_array([max_number_of_boxes, 3]))
-
- if opset in ['opset5', 'opset9']:
- node.out_port(0).data.set_shape(shape_array([dynamic_dimension_value, 3]))
- num_of_outputs = len([port for port in node.out_ports().values() if not port.disconnected()])
- if num_of_outputs >= 2 and node.has_port('out', 1):
- node.out_port(1).data.set_shape(shape_array([dynamic_dimension_value, 3]))
- if num_of_outputs >= 3 and node.has_port('out', 2):
- node.out_port(2).data.set_shape(shape_array([1]))
-
- @staticmethod
- def type_infer(node):
- opset = node.get_opset()
- if opset in ['opset5', 'opset9']:
- node.out_port(0).set_data_type(node.output_type)
- if node.has_port('out', 1):
- node.out_port(1).set_data_type(np.float32)
- if node.has_port('out', 2):
- node.out_port(2).set_data_type(np.int64)
- elif opset in ['opset3', 'opset4']:
- node.out_port(0).set_data_type(node.output_type)
- else:
- node.out_port(0).set_data_type(np.int64)
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node, undefined_shape_of_rank(3), undefined_shape_of_rank(3))
diff --git a/tools/mo/openvino/tools/mo/ops/non_zero.py b/tools/mo/openvino/tools/mo/ops/non_zero.py
deleted file mode 100644
index da8f6bd031b07b..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/non_zero.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, dynamic_dimension_value
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-
-
-class NonZero(Op):
- op = 'NonZero'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'output_type' in attrs, 'NonZero has mandatory `output_type` attribute'
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset3',
-
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [
- ('output_type', lambda node: np_data_type_to_destination_type(node.output_type)),
- ]
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, 'The input shape for node "{}" is None'.format(node_name)
- assert node.has_valid('output_type'), \
- '`output_type` attribute is not set for NonZero node `{}`'.format(node_name)
- assert node.output_type in [np.int64, np.int32], \
- 'NonZero `output_type` attribute must be int32 or int64, `{}` found'.format(np.dtype(node.output_type).name)
-
- input_value = node.in_port(0).data.get_value()
- if is_fully_defined(input_value):
- node.out_port(0).data.set_value(mo_array(np.nonzero(input_value), dtype=node.output_type))
- else:
- if is_fully_defined(input_shape):
- # output shape of NonZero is still static (upper bound)
- node.out_port(0).data.set_shape([len(input_shape), np.prod(input_shape)])
- else:
- node.out_port(0).data.set_shape([len(input_shape), dynamic_dimension_value])
-
- @staticmethod
- def type_infer(node):
- assert node.output_type in [np.int64, np.int32], \
- 'NonZero `output_type` attribute must be int32 or int64, `{}` found'.format(np.dtype(node.output_type).name)
- node.out_port(0).set_data_type(node.output_type)
diff --git a/tools/mo/openvino/tools/mo/ops/normalize.py b/tools/mo/openvino/tools/mo/ops/normalize.py
deleted file mode 100644
index 4bcaa82e9f1784..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/normalize.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class NormalizeOp(Op):
- op = 'Normalize'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'eps': None,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer
- }, attrs)
-
- if 'across_spatial' in self.attrs and isinstance(self.attrs['across_spatial'], str):
- self.attrs['across_spatial'] = int(self.attrs['across_spatial'])
-
- if 'channel_shared' in self.attrs and isinstance(self.attrs['channel_shared'], str):
- self.attrs['channel_shared'] = int(self.attrs['channel_shared'])
-
- self.attrs['across_spatial'] = bool(self.attrs['across_spatial'])
- self.attrs['channel_shared'] = bool(self.attrs['channel_shared'])
-
- def supported_attrs(self):
- return ['eps', 'eps_mode',
- ('across_spatial',
- lambda node: bool(node.across_spatial) if node.has_valid('across_spatial') else None),
- ('channel_shared',
- lambda node: bool(node.channel_shared) if node.has_valid('channel_shared') else None),
- ]
-
- @staticmethod
- def infer(node: Node):
- mark_input_bins(node)
- copy_shape_infer(node)
diff --git a/tools/mo/openvino/tools/mo/ops/normalize_l2.py b/tools/mo/openvino/tools/mo/ops/normalize_l2.py
deleted file mode 100644
index 56c263b5913bc2..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/normalize_l2.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-
-
-class NormalizeL2Op(Op):
- op = 'NormalizeL2'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'eps': None,
- 'p': None,
- 'eps_mode': None,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }, attrs)
-
- def supported_attrs(self):
- return ['eps', 'eps_mode']
-
- @staticmethod
- def infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- if input_shape is None:
- return
-
- input_value = node.in_port(0).data.get_value()
- axes = node.in_port(1).data.get_value()
- if input_value is not None and axes is not None:
- norm_value = np.linalg.norm(input_value, node.p, axes, keepdims=True)
- if node.eps_mode == 'add':
- norm_value = norm_value + node.eps
- elif node.eps_mode == 'max':
- norm_value = np.max(norm_value, node.eps)
- else:
- assert False, 'Unsupported "eps_mode" = {}'.format(node.eps_mode)
- node.out_port(0).data.set_value(input_value / norm_value)
- else:
- node.out_port(0).data.set_shape(input_shape)
-
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
diff --git a/tools/mo/openvino/tools/mo/ops/one_hot.py b/tools/mo/openvino/tools/mo/ops/one_hot.py
deleted file mode 100644
index 03317f0822168c..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/one_hot.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_insert
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class OneHot(Op):
- op = 'OneHot'
- enabled = False # we have to extract for `axis` attribute
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'axis': -1,
- 'infer': self.infer,
- 'out_ports_count': 1,
- 'in_ports_count': 4,
- 'data_type': None,
- 'force_precision_in_ports': {1: 'int64'},
- 'type_infer': self.type_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['axis']
-
- @staticmethod
- def infer(node: Node):
- indices_shape = node.in_port(0).data.get_shape()
- assert indices_shape is not None
- dim = indices_shape.size
-
- assert_msg = "OneHot `{0}` ({1} input port value) should be scalar: node: `{2}`, {0} value: `{3}`"
- 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)
-
- assert node.has_valid('axis')
- axis = node['axis']
- assert -1 <= axis <= dim
-
- # If axis == -1 we need to insert new depth dimension in the end of indices_shape shape
- axis = dim if axis == -1 else axis
-
- if dim == 0:
- # scalar indices case
- output_shape = [depth]
- else: # dim >= 1
- # vector/matrix indices case
- output_shape = shape_insert(indices_shape, axis, depth)
-
- node.out_port(0).data.set_shape(output_shape)
-
- indices = node.in_port(0).data.get_value()
- depth = node.in_port(1).data.get_value()
- on_value = node.in_port(2).data.get_value()
- off_value = node.in_port(3).data.get_value()
-
- if indices is not None and depth is not None and on_value is not None and off_value is not None:
- onehot_value = np.full(output_shape, off_value)
-
- for idx in np.ndindex(tuple(indices_shape)):
- if axis == 0:
- hot_idx = indices[idx], *idx
- elif (axis > 0) and (axis < len(output_shape) - 1):
- hot_idx = *idx[:axis], indices[idx], *idx[axis:]
- elif axis == len(output_shape) - 1:
- hot_idx = *idx, indices[idx]
-
- if -depth <= indices[idx] < depth:
- onehot_value[hot_idx] = on_value # pylint: disable=possibly-used-before-assignment
-
- node.out_port(0).data.set_value(onehot_value)
-
- # This operation should be inferred in original layout
- node['reinterp_shape'] = True
- node['NCHW'] = True
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(node.in_port(2).get_data_type())
diff --git a/tools/mo/openvino/tools/mo/ops/op.py b/tools/mo/openvino/tools/mo/ops/op.py
deleted file mode 100644
index 9ed180c1e4852a..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/op.py
+++ /dev/null
@@ -1,478 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import copy
-import logging as log
-from collections import namedtuple
-
-import networkx as nx
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, strict_compare_tensors
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import add_attrs_props, update_ie_fields
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils import class_registration
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.runtime_info import RTInfo
-
-
-class Op(object):
- registered_ops = {}
- registered_cls = []
- # Add the derived class to excluded_classes if one should not be registered in registered_ops
- excluded_classes = []
-
- def __init__(self, graph: Graph, attrs1: dict = None, attrs2: dict = None):
- self.graph = graph
- try:
- self.ir_version = graph.graph['ir_version']
- except:
- self.ir_version = None
-
- self.attrs = {
- 'kind': 'op',
- 'rt_info': RTInfo()
- }
- self.default_backend_attrs = []
- if attrs1 is not None:
- self.attrs.update(attrs1)
- if attrs2 is not None:
- self.attrs.update(attrs2)
-
- def add_node(self, attrs: dict = None):
- new_attrs = {}
- new_attrs.update(self.attrs)
- if attrs is not None:
- new_attrs.update(attrs)
- id_prefix = new_attrs['name'] if 'name' in new_attrs else ''
- id = self.graph.unique_id(id_prefix)
- new_attrs['name'] = id
- new_attrs = add_attrs_props(new_attrs)
- update_ie_fields(new_attrs, self.ir_version)
- self.substitute_ie_attrs(new_attrs)
- self.graph.add_node(id, **new_attrs)
-
- node = Node(self.graph, id)
- return node
-
- def substitute_ie_attrs(self, new_attrs: dict):
- """
- Replace standard list of attribute in layer/data by attributes
- delivered by backend_attrs
- """
- backend_attrs_mapping = {
- None: self.backend_attrs,
- 10: self.backend_attrs,
- 11: self.backend_attrs,
- }
-
- if self.ir_version not in backend_attrs_mapping.keys():
- raise Error("Unrecognized IR version was specified: {}".format(self.ir_version))
-
- new_attrs.update({
- 'IE': [(
- 'layer',
- [('id', lambda node: node.node), 'name', 'type', 'version'],
- [
- ('data', backend_attrs_mapping[self.ir_version]() + self.default_backend_attrs, []),
- '@runtime_info',
- '@ports',
- '@consts'])]
- })
-
- @staticmethod
- def extract_port(node_port):
- if isinstance(node_port, tuple):
- node = node_port[0]
- port = node_port[1]
- else:
- node = node_port
- port = 0
- # 'data' nodes do not have 'out' edge attribute but always has one output
- out_ids = [attr['out'] for _, __, attr in node.graph.out_edges(node.id, data=True) if 'out' in attr]
- if len(set(out_ids)) > 1 and not isinstance(node_port, tuple):
- raise Error('Node {} has more than one outputs. Provide output port explicitly. '.format(node.name))
- return node, port
-
- def create_node_on_port(self, node: Node, out_port: int, attrs: dict = None, edge_attrs: dict = None):
- """
- Removes an edge, that is connected to nodes out_port. Creates new_node with attrs attributes and
- connects it to node by edge that stores the same information as cutted edge.
- :param node: Input node, to cut the edge from
- :param out_port: output port of edge to cut
- :param attrs: attributes of new node
- :param edge_attrs: attributes to be changed/added to new edge
- :return: Node instance of created new_node
- """
- if edge_attrs is None:
- edge_attrs = {'in': 0}
- prev_edge_attrs = copy.deepcopy(node.out_edge(out_port))
- prev_edge_attrs.update(edge_attrs)
- new_edge_attrs = prev_edge_attrs
- if attrs is None:
- attrs = dict()
- new_node = self.add_node(attrs)
- self.graph.add_edge(node.id, new_node.id, **new_edge_attrs)
- return new_node
-
- def create_node(self, inputs: list = None, attrs: dict = None, edge_attrs: dict = None):
- # TODO pass also edge attributes to copy to newly created edges
- # TODO attrs should be matched with attrs()
- if inputs is not None:
- inputs = [Op.extract_port(inp) for inp in inputs]
- else:
- inputs = []
- if attrs is None:
- attrs = dict()
- new_node = self.add_node(attrs)
- for i, inp in enumerate(inputs):
- edge_attr = {'in': i, 'out': inp[1],
- 'in_attrs': ['in', 'permutation'],
- 'out_attrs': ['out', 'permutation'],
- 'data_attrs': []} if not inp[0].has_valid('kind') or inp[0].kind == 'op' \
- else {'in': i, 'in_attrs': ['in', 'permutation']}
-
- # handling of debug information
- if inp[0].has_port('out', inp[1]):
- debug_info = inp[0].out_port(inp[1]).get_tensor_debug_info()
- if debug_info is not None and len(debug_info) > 0:
- edge_attr.update({'fw_tensor_debug_info': debug_info})
- edge_attr['data_attrs'].append('fw_tensor_debug_info')
-
- if edge_attrs is not None:
- edge_attr.update(edge_attrs)
- new_node.add_input_port(i, skip_if_exist=True)
- inp[0].add_output_port(inp[1], skip_if_exist=True)
- self.graph.add_edge(inp[0].id, new_node.id, **edge_attr)
- return new_node
-
- def create_node_with_data(self, inputs: list = None, attrs: dict = None,
- data_nodes: [Node, np.ndarray, list] = None, edge_attrs: list = None):
- """
- Creates a new node with given inputs and attrs and also creates data node that
- holds the op output value. Inputs should be data nodes (not op nodes).
- Work for ops with a single output port only.
- Edge attributes in edge_attrs go in order of items in 'inputs'
- """
- if inputs is None:
- inputs = []
- if attrs is None:
- attrs = {}
- # No need to extract port, because input node should be a data node,
- # so there is no choice.
- new_op_node = self.add_node(attrs)
-
- # TODO Preserve debug information
- inputs_with_edge_attrs = []
- for i, inp in enumerate(inputs):
- if inp is None:
- continue
- edge_attr = {'in': i}
- if edge_attrs is not None and i < len(edge_attrs):
- edge_attr.update(edge_attrs[i])
- inputs_with_edge_attrs.append((inp.id, new_op_node.id, edge_attr))
- new_op_node.add_input_port(i, skip_if_exist=True)
-
- self.graph.add_edges_from(inputs_with_edge_attrs)
-
- # TODO: Extend to the case when multiple output ports
- old_data_value = [None]
- old_data_shape = [None]
- if data_nodes is None:
- data_node = self.graph.unique_id()
- self.graph.add_node(data_node, **add_attrs_props(
- dict(kind='data', name=data_node, value=None, shape=None, data_type=None, infer=None)))
- data_nodes = [Node(self.graph, data_node)]
- else:
- if type(data_nodes) not in [list, np.ndarray]:
- data_nodes = [data_nodes]
- old_data_value = [data_node.value.copy() if data_node.has_valid('value') else None for data_node in
- data_nodes]
- old_data_shape = [data_node.shape.copy() if data_node.has_valid('shape') else None for data_node in
- data_nodes]
- for id, data_node in enumerate(data_nodes):
- self.graph.add_edges_from([(new_op_node.id, data_node.id, {'out': id})])
-
- if new_op_node.has_valid('infer'):
- if log.getLogger().isEnabledFor(log.DEBUG):
- log.debug('Start running infer function for individual op node with attributes: {}'
- ''.format(str(new_op_node)))
- new_op_node.infer(new_op_node)
- if new_op_node.has('nchw_layout'):
- for out_node in new_op_node.out_nodes().values():
- out_node['nchw_layout'] = new_op_node.nchw_layout
- assert all(old_value is None for old_value in old_data_value) or all(
- [strict_compare_tensors(old_data_value[id], data_node.value)
- for id, data_node in enumerate(data_nodes)])
- assert all(old_shape is None for old_shape in old_data_shape) or all(
- [strict_compare_tensors(old_data_shape[id], data_node.shape)
- for id, data_node in enumerate(data_nodes)]), \
- "After re-inference of {} node, old and new shapes do not match. Old shapes: {}, new shapes: {}." \
- "".format(new_op_node.soft_get('name'), [old_data_shape[id] for id in range(len(data_nodes))],
- [data_node.shape for data_node in data_nodes])
- for data_node in data_nodes:
- if log.getLogger().isEnabledFor(log.DEBUG):
- log.debug(
- 'Finished running infer function, data nodes attributes: {}'.format(data_node))
- return data_nodes[0] if len(data_nodes) == 1 else data_nodes
-
- @staticmethod
- def create_data_node(graph: Graph, op_node: Node, attrs: dict = None, edge_attrs: dict = None, out_port=0):
- assert op_node is not None and op_node.kind == 'op'
- assert out_port not in op_node.out_nodes()
-
- if attrs is None:
- attrs = {}
-
- data_node = graph.unique_id(op_node.id)
- default_attrs = dict(kind='data', name=data_node, value=None, shape=None, data_type=None, infer=None)
- default_attrs.update(attrs)
- graph.add_node(data_node, **add_attrs_props(default_attrs))
- data_node = Node(graph, data_node)
- if edge_attrs is not None:
- graph.add_edges_from([(op_node.id, data_node.id, {'out': out_port, **edge_attrs})])
- else:
- graph.add_edges_from([(op_node.id, data_node.id, {'out': out_port})])
- return data_node
-
- @staticmethod
- def _create_data_node(graph: Graph, name: str, attrs: dict = None):
- if attrs is None:
- attrs = {}
-
- data_node = graph.unique_id(name)
- default_attrs = dict(kind='data', name=data_node, value=None, shape=None, data_type=None, infer=None)
- default_attrs.update(attrs)
- graph.add_node(data_node, **add_attrs_props(default_attrs))
- data_node = Node(graph, data_node)
- return data_node
-
- @staticmethod
- def create_input_data_node(graph: Graph, name: str, value: np.array, attrs: dict = None):
- if attrs is None:
- attrs = {}
- data_node = graph.unique_id(name)
- default_attrs = dict(kind='data', name=data_node, value=mo_array(value), shape=mo_array(value.shape),
- data_type=None, infer=None)
- default_attrs.update(attrs)
- graph.add_node(data_node, **add_attrs_props(default_attrs))
- return Node(graph, data_node)
-
- @staticmethod
- def create_and_connect_input_data_node(graph: Graph, op_node: Node, attrs: dict = None, edge_attrs: dict = None):
- assert op_node is not None and op_node.kind == 'op'
- if attrs is None:
- attrs = {}
- if edge_attrs is None:
- edge_attrs = {}
-
- data_node = graph.unique_id(op_node.id)
- default_attrs = dict(kind='data', name=data_node, value=None, shape=None, data_type=None, infer=None)
- default_attrs.update(attrs)
- graph.add_node(data_node, **add_attrs_props(default_attrs))
- data_node = Node(graph, data_node)
- op_node.add_input_port(edge_attrs['in'], skip_if_exist=True)
- graph.add_edges_from([(data_node.id, op_node.id, edge_attrs)])
- return data_node
-
- def update_node(self, node: Node, attrs: dict = None):
- """
- Updates/creates new attributes in node based on self.attrs and attrs.
- """
- new_attrs = {}
- new_attrs.update(self.attrs)
- if attrs:
- new_attrs.update(attrs)
- new_attrs = add_attrs_props(new_attrs)
- update_ie_fields(new_attrs, self.ir_version)
- self.substitute_ie_attrs(new_attrs)
- for k, v in new_attrs.items():
- node[k] = v
- node.update_node()
-
- def get_opset(self):
- """
- Gets the operation set version where the operation was introduced.
- If the version is not defined then consider it an extension
- :return: the string with the opset name
- """
- return self.attrs.get('version', 'extension')
-
- @classmethod
- def update_node_stat(cls, node: Node, attrs: dict = None):
- if attrs is None:
- attrs = dict()
- op = cls(node.graph, attrs)
- op.update_node(node)
-
- def supported_attrs(self):
- """
- Attributes that user should/can set for the operation
- """
- return []
-
- def backend_attrs(self):
- """
- Attributes that will be translated to back-end IR
- """
- return self.supported_attrs()
-
- @staticmethod
- def get_op_class_by_name(name: str):
- return __class__.registered_ops[name]
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.OP
-
- @staticmethod
- def expand_node_shape(node: Node, dims_to_add):
- if node is None or not node.has_valid('value'):
- return
- for idx in range(dims_to_add):
- node.value = np.expand_dims(node.value, axis=-1)
- node.shape = mo_array(node.value.shape)
-
- @staticmethod
- def normalize_outputs(node: Node):
- if node.has_valid('out_ports_count') and len(node.out_edges()) < node.out_ports_count:
- from openvino.tools.mo.ops.result import Result # Import is here to avoid circular import error
- for p in range(node.out_ports_count):
- if p not in node.out_ports():
- node.add_output_port(p)
- if node.out_port(p).disconnected():
- res_node = Result(node.graph, {'name': node.name + '/Fake_output_{}/'.format(p),
- 'keep_output_port': True}).create_node()
- node.out_port(p).connect(res_node.in_port(0))
-
-
-class PermuteAttrs:
- Permutation = namedtuple('Permutation', ['perm', 'inv'])
- Attr = namedtuple('Attr', ['name', 'port', 'func'])
-
- common_permutation = lambda node, permutation, attr: node[attr][permutation.perm]
- slice_permutation = lambda node, permutation, attr: node[attr][ # doesn't depend from permutation variable
- PermuteAttrs.get_nhwc_to_nchw_permutation(len(node[attr])).perm]
- common_permutation_inv = lambda node, permutation, attr: permutation.inv[node[attr]]
-
- # List of default permutations
- common_attrs_permutation = {
- 'dim': common_permutation,
- 'pad': common_permutation,
- 'pads': common_permutation,
- 'shape': common_permutation,
- 'order': lambda node, permutation, attr: permutation.inv[node[attr][permutation.perm]],
- 'stride': common_permutation,
- 'window': common_permutation,
- 'dilation': common_permutation,
- 'kernel_shape': common_permutation,
- 'output_shape': common_permutation,
- 'begin_mask': slice_permutation,
- 'end_mask': slice_permutation,
- 'shrink_axis_mask': slice_permutation,
- 'new_axis_mask': slice_permutation,
- 'ellipsis_mask': slice_permutation,
- 'axes': common_permutation_inv,
- 'axis': common_permutation_inv,
- 'seq_axis': common_permutation_inv,
- 'batch_axis': common_permutation_inv,
- 'batch_dims': common_permutation_inv,
- 'channel_dims': common_permutation_inv,
- 'spatial_dims': common_permutation_inv,
-
- 'input_channel_dim': common_permutation_inv,
- 'output_channel_dim': common_permutation_inv,
- 'kernel_spatial_idx': common_permutation_inv,
- 'input_feature_channel': common_permutation_inv,
- 'output_feature_channel': common_permutation_inv,
- }
-
- @staticmethod
- def __attr(name, port, func=None):
- if func is None:
- if name in PermuteAttrs.common_attrs_permutation:
- func = PermuteAttrs.common_attrs_permutation[name]
- else:
- raise Error('Attr {} is missing in PermuteAttrs.common_attrs_permutation. Please update '
- 'common_attrs_permutation with permutation for your attribute!'.format(name))
-
- if len(port.split(':')) != 2 or port.split(':')[0] not in ['input', 'output']:
- raise Error("Attribute port {} for {} wasn't set correctly!".format(port, name))
-
- return PermuteAttrs.Attr(name=name, port=port, func=func)
-
- def __init__(self):
- self.attrs = {}
-
- def update_attrs(self, attrs):
- for attr in attrs:
- if not isinstance(attr, tuple) or len(attr) not in [2, 3]:
- raise Error('attr object must be a tuple: (attribute_name, port) or (attribute_name, port, func)')
- self.attrs.update({attr[0]: self.__attr(*attr)})
- return self
-
- def permute_attrs(self, node):
- # This function applies permutation for given node
- for attr in self.attrs.keys():
- name, port, func = self.attrs[attr]
- node_type, port = port.split(':')
- port = int(port)
- node_with_permutation = node.in_node(port) if node_type == 'input' else node.out_node(port)
-
- if node_with_permutation.has_valid('permutation'):
- permutation = node_with_permutation.permutation
- if isinstance(permutation, type(lambda: 0)):
- node[name] = func(node, permutation(node), name)
- else:
- node[name] = func(node, permutation, name)
-
- @staticmethod
- def create_permute_attrs(node, attrs=None):
- # Create permute_attrs if not exists
- if not node.has_valid('permute_attrs'):
- node['permute_attrs'] = PermuteAttrs()
- node['permute_attrs'].update_attrs(attrs)
-
- @staticmethod
- def set_permutation(node1, node2, permutation, override=False):
- # This function creates permutation on edge between node1->node2
- edge_attrs = node1.graph.get_edge_data(node1.id, node2.id)[0]
- if 'permutation' not in edge_attrs or override:
- nx.set_edge_attributes(G=node1.graph, values={(node1.id, node2.id, 0): permutation}, name='permutation')
- else:
- # If permutation exists we check that given and already set permutations are equal
- if (edge_attrs['permutation'] is None and permutation is not None) or \
- not np.array_equal(edge_attrs['permutation'], permutation):
- raise Error('Permutation already exists in edge between {} and {}'.format(node1.id, node2.id))
-
- @staticmethod
- def get_inverse_permutation(perm):
- inv = [0] * len(perm)
- # Create reverse permutation
- for index, pos in enumerate(perm):
- inv[pos] = index
- return inv
-
- @staticmethod
- def get_nhwc_to_nchw_permutation(dims_number: int):
- # This function returns permutation from NHWC to NCHW for given dims number
- if dims_number != 3:
- perm = [0, dims_number - 1, *[x for x in range(1, dims_number - 1)]] if dims_number > 1 else \
- [x for x in range(dims_number)]
- else:
- # Exclude 3D shapes from permutation process: identity permutation
- perm = list(range(0, dims_number))
- inv = PermuteAttrs.get_inverse_permutation(perm)
- return PermuteAttrs.Permutation(perm=int64_array(perm), inv=int64_array(inv))
-
- @staticmethod
- def get_nchw_to_nhwc_permutation(dims_number: int):
- # This function returns permutation from NCHW to NHWC for given dims number
- if dims_number != 3:
- perm = [0, *[x for x in range(2, dims_number)], 1] if dims_number > 1 else [x for x in range(dims_number)]
- else:
- # Exclude 3D shapes from permutation process: identity permutation
- perm = list(range(0, dims_number))
- inv = PermuteAttrs.get_inverse_permutation(perm)
- return PermuteAttrs.Permutation(perm=int64_array(perm), inv=int64_array(inv))
diff --git a/tools/mo/openvino/tools/mo/ops/pack.py b/tools/mo/openvino/tools/mo/ops/pack.py
deleted file mode 100644
index b706127d2124bc..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/pack.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class PackOp(Op):
- op = 'Pack'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': __class__.op,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'axis'
- ]
-
diff --git a/tools/mo/openvino/tools/mo/ops/pad.py b/tools/mo/openvino/tools/mo/ops/pad.py
deleted file mode 100644
index 1e2a8344c58f21..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/pad.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, shape_array, undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-
-
-class Pad(Op):
- """ Pad operation that explicitly extends an input tensor at borders.
-
- The operation extends each (not only spatial) dimensions of input tensors by new elements increasing output
- shape.
- The second and third inputs are 1D tensor with number of elements equal to input tensor rank. These inputs
- specify the begin and end paddings.
- The forth input specifies the fill value for 'constant' mode and not used for other cases.
- """
-
- op = 'Pad'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
-
- 'version': 'opset1',
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
-
- 'mode': 'constant',
-
- 'force_precision_in_ports': {
- 1: 'int64',
- 2: 'int64',
- },
-
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return [('pad_mode', 'mode')]
-
- @staticmethod
- def infer(node):
- pad_node_name = node.soft_get('name', node.id)
-
- assert len(node.in_nodes()) in [3, 4], "The node {} must have 3 or 4 inputs".format(pad_node_name)
-
- input_shape = node.in_port(0).data.get_shape()
- input_value = node.in_port(0).data.get_value()
- pad_beg = node.in_port(1).data.get_value()
- pad_end = node.in_port(2).data.get_value()
-
- assert pad_beg is not None, 'The padding begin value is None for node {}'.format(pad_node_name)
- assert pad_end is not None, 'The padding end value is None for node {}'.format(pad_node_name)
- assert input_shape is not None, 'The input shape is None for node {}'.format(pad_node_name)
- assert len(input_shape) == len(pad_beg), \
- 'Length of begin padding "{}" does not correspond to input tensor shape "{}" for node "{}".' \
- ''.format(pad_beg, input_shape, pad_node_name)
- assert len(input_shape) == len(pad_end), \
- 'Length of end padding "{}" does not correspond to input tensor shape "{}" for node "{}".' \
- ''.format(pad_beg, input_shape, pad_node_name)
- assert not node.is_in_port_connected(3) or node.in_port(3).data.get_shape().size == 0, \
- 'Optional 3rd input of Pad operation should be scalar, but has shape {} for node {}' \
- ''.format(node.in_port(3).data.get_shape(), pad_node_name)
-
- node.out_port(0).data.set_shape(input_shape + pad_beg + pad_end)
-
- if input_value is not None and is_fully_defined(pad_beg) and is_fully_defined(pad_end):
- pads = np.insert(pad_end, np.arange(len(pad_end)), pad_beg)
- pads = np.reshape(pads, (len(pad_end), 2))
- pad_val = 0
- if len(node.in_nodes()) == 4:
- pad_val = node.in_port(3).data.get_value() if node.in_port(3).data is not None else 0
- if is_fully_defined(input_value):
- node.out_port(0).data.set_value(np.pad(input_value, pads, constant_values=pad_val, mode='constant'))
- else:
- node.out_port(0).data.set_value(shape_array(np.pad(input_value, pads, constant_values=pad_val,
- mode='constant')))
- # pad values should be permuted during the NHWC->NCHW layout change
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'shape')
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'shape')
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- if input_shape is None and node.is_in_port_connected(2) and node.in_port(2).data.get_shape() is not None:
- shape = undefined_shape_of_rank(node.in_port(2).data.get_shape()[0])
- node.in_port(0).data.set_shape(shape)
-
-
-class AttributedPad(Op):
- """ Pad operation that explicitly extends an input tensor at borders.
-
- This operation is uses the same semantics as Pad but with pad values specified as attributes.
- Pad values are in format [nDims, 2], where [:, 0] - begin pads, [:, 1] - end pads.
- """
-
- op = 'AttributedPad'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
- 'infer': None, # the operation should be replaced before the shape inference
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'mode': 'constant',
- 'fill_value': float(0),
- 'pads': None,
- }, attrs)
-
-
-class TFPad(Op):
- """ Pad operation that explicitly extends an input tensor at borders.
-
- This operation with the TensorFlow semantics with inputs:
- 1. Input tensor.
- 2. Pad values [nDims, 2]
- 3. Fill value (Optional)
- """
-
- op = 'TFPad'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
- 'infer': None, # the operation should be replaced before the shape inference
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'mode': 'constant',
- }, attrs)
-
-
-class ONNXPad(Op):
- """ Pad operation that explicitly extends an input tensor at borders.
-
- This operation with the ONNX semantics with inputs:
- 1. Input tensor.
- 2. Pad values
- 3. Fill value (Optional)
- """
-
- op = 'ONNXPad'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': None,
- 'infer': None, # the operation should be replaced before the shape inference
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'mode': 'constant',
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/parameter.py b/tools/mo/openvino/tools/mo/ops/parameter.py
deleted file mode 100644
index 99581ddbbd4cdb..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/parameter.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import unmask_shape
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.runtime import PartialShape
-
-
-class Parameter(Op):
- op = 'Parameter'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'is_input': True,
- 'data_type': None,
-
- 'type_infer': self.type_infer,
-
- 'out_ports_count': 1,
- 'user_shape': None,
- }
- if 'data_type' not in attrs:
- mandatory_props['data_type'] = np.float32
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def type_infer(node):
- node.out_port(0).set_data_type(node.data_type)
-
- @staticmethod
- def shape_serialize(node):
- if not node.has_valid('user_shape'):
- return ','.join([str(i) for i in unmask_shape(node.shape)])
- shape = node.soft_get('user_shape')
- if isinstance(shape, np.ma.masked_array):
- shape = unmask_shape(shape)
- if isinstance(shape, PartialShape):
- return shape.to_string()
- raise Exception("Unknown shape type in user_shape attribute {}".format(type(shape)))
-
- def supported_attrs(self):
- return [
- ('shape', lambda node: self.shape_serialize(node)),
- ('element_type', lambda node: np_data_type_to_destination_type(node.data_type)),
- ]
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
- assert node.has_valid('shape'), \
- 'Parameter node {} should have `shape` attribute. Please use cli options to set model input shape' \
- ''.format(name)
- node.out_port(0).data.set_shape(node.shape)
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('shape', 'output:0')])
-
- @staticmethod
- def reverse_infer(node: Node):
- # update node 'shape' attribute (if it is not defined) from the output port shape which was calculated
- # during the reverse_infer phase
- shape = node.soft_get('shape', None)
- if shape is None and node.out_port(0).data.get_shape() is not None:
- node['shape'] = node.out_port(0).data.get_shape()
diff --git a/tools/mo/openvino/tools/mo/ops/permute.py b/tools/mo/openvino/tools/mo/ops/permute.py
deleted file mode 100644
index 527697c2ff509d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/permute.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.extractor import attr_getter
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Permute(Op):
- op = 'Permute'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'order': None,
- 'type': __class__.op,
- 'op': __class__.op,
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return [('order', lambda node: attr_getter(node, 'order'))]
diff --git a/tools/mo/openvino/tools/mo/ops/pnorm.py b/tools/mo/openvino/tools/mo/ops/pnorm.py
deleted file mode 100644
index aa2666cee843a5..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/pnorm.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class PNormOp(Op):
- """
- PNorm operation should be replaced by operations:
- Power(P) -> Reshape(n,c*g->n,g,c)-> ReduceSum(axis=1)-> Power(1/P)
- """
- op = 'pnorm'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': self.infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- shape = node.in_port(0).data.get_shape().copy()
- shape[1] = shape[1] // node.group
- node.out_port(0).data.set_shape(shape)
diff --git a/tools/mo/openvino/tools/mo/ops/pooling.py b/tools/mo/openvino/tools/mo/ops/pooling.py
deleted file mode 100644
index 4f6dc9ce5a8ad2..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/pooling.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import tf_window_op_pad_infer, int64_array, shape_array, \
- dynamic_dimension_value, dynamic_dimension, undefined_shape_of_rank
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.front.onnx.extractors.utils import get_backend_pad
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.utils.error import Error
-
-
-poolings_map = {
- 'max': {'version': 'opset8', 'out_ports_count': 2},
- 'avg': {'version': 'opset1', 'out_ports_count': 1}
-}
-
-
-class PoolingV2(Op):
- """
- TensorFlow MaxPoolV2 and AvgPoolV2 operations expect windows_size and strides values from inputs not from
- attributes. This internal operation is introduced to handle that. Only constant windows_size and strides
- values are supported. Eventually will be replaced with the standard pooling operations from the opset.
- """
- op = 'PoolingV2'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'version': None,
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- assert (len(node.in_nodes()) == 3), 'MaxPoolV2 node {} from must have only 3 inputs: input, window size, and ' \
- 'strides but instead got {} inputs'.format(node.soft_get('name', node.id),
- len(node.in_nodes()))
- node['window'] = node.in_port(1).data.get_value()
- node['stride'] = node.in_port(2).data.get_value()
-
- if node['window'] is None:
- raise Error('The non-constant window size for MaxPoolV2 node {} is not supported'
- ''.format(node.soft_get('name', node.id)))
- if node['stride'] is None:
- raise Error('The non-constant strides for MaxPoolV2 node {} is not supported'
- ''.format(node.soft_get('name', node.id)))
-
- Pooling.pool_infer(node)
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- window_shape = node.in_port(1).data.get_shape()
- # use the value of the 'window' input to determine input tensor rank
- if input_shape is None and window_shape is not None:
- node.in_port(0).data.set_shape(undefined_shape_of_rank(window_shape[0]))
-
-
-class Pooling(Op):
- op = 'Pooling'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': poolings_map[attrs.get('pool_method')]['version'],
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1 if attrs.get('version') == 'opset1' else
- poolings_map[attrs.get('pool_method')]['out_ports_count']
- }, attrs)
-
- def backend_attrs(self):
- backend_attrs_list = [
- ('strides', lambda node: ','.join(map(str, node['stride'][node.spatial_dims]))),
- ('kernel', lambda node: ','.join(map(str, node['window'][node.spatial_dims]))),
-
- ('pads_begin', lambda node: ','.join(map(str, get_backend_pad(node.pad, node.spatial_dims, 0)))),
- ('pads_end', lambda node: ','.join(map(str, get_backend_pad(node.pad, node.spatial_dims, 1)))),
-
- ('exclude-pad', lambda node: bool_to_str(node, 'exclude_pad')),
-
- 'rounding_type',
- ('auto_pad', lambda node: node.auto_pad if node.has_valid('auto_pad') else 'explicit')
- ]
-
- if self.attrs.get('pool_method') == 'avg':
- return backend_attrs_list
- else:
- return backend_attrs_list + [
- ('dilations', lambda node: ','.join(map(str, node['dilation'][node.spatial_dims]))),
- 'axis',
- ('index_element_type', lambda node: np_data_type_to_destination_type(node.index_element_type))
- ]
-
- @staticmethod
- def infer(node: Node):
- assert (len(node.in_nodes()) == 1), 'MaxPool node {} from must have only one input but instead got ' \
- '{} inputs'.format(node.soft_get('name', node.id), len(node.in_nodes()))
-
- Pooling.pool_infer(node)
-
- @staticmethod
- def pool_infer(node: Node):
- input_shape = node.in_node(0).shape
- if input_shape is None:
- return
-
- if not node.has_valid('spatial_dims'):
- node['spatial_dims'] = np.delete([x for x in range(len(input_shape))],
- [node.batch_dims[0], node.channel_dims[0]])
-
- input_spatial_shape = input_shape[node.spatial_dims]
-
- # Setting default pad and stride attrs in case if None specified
- if not node.has_valid('pad'):
- node['pad'] = int64_array([[0, 0] for x in range(len(input_shape))])
- if not node.has_valid('pad_spatial_shape'):
- node['pad_spatial_shape'] = node.pad[node.spatial_dims]
-
- if not node.has_valid('stride'):
- node['stride'] = int64_array([1 for x in range(len(input_shape))])
-
- if node.has_and_set('global_pool'):
- node['window'] = np.zeros(len(input_shape), dtype=np.int64)
- node.window[node.spatial_dims] = input_spatial_shape
-
- if not node.has_valid('dilation'):
- node['dilation'] = np.ones(len(input_shape), dtype=np.float32)
-
- if not node.has_valid('axis'):
- node['axis'] = 0
-
- if not node.has_valid('index_element_type'):
- node['index_element_type'] = np.int64
-
- window_spatial_shape = node.window[node.spatial_dims]
- stride_spatial = node.stride[node.spatial_dims]
- dilation_spatial = node.dilation[node.spatial_dims]
- assert any(stride_spatial), 'Stride can not be zero in node {}'.format(node.id)
-
- if node.has_valid('auto_pad') and node.auto_pad != 'explicit':
- node.pad_spatial_shape, node.output_spatial_shape = tf_window_op_pad_infer(input=input_spatial_shape,
- window=window_spatial_shape,
- stride=stride_spatial,
- auto_pad=node.auto_pad,
- dilation=dilation_spatial)
- pad = np.zeros((len(input_shape), 2), dtype=np.int64)
- pad[node.spatial_dims] = node.pad_spatial_shape
- node.pad = pad
- else:
-
- pad_spatial_shape = np.add.reduce(node.pad_spatial_shape, axis=1)
-
- rounding = np.floor
- if node.soft_get('pooling_convention') == 'full' or node.soft_get('rounding_type') == 'ceil':
- rounding = np.ceil
-
- padded_spatial_shape = input_spatial_shape + pad_spatial_shape - ((window_spatial_shape - 1) *
- dilation_spatial + 1)
- if np.any(padded_spatial_shape < 0):
- raise Error("Data after padding has dimension less than window size. " +
- "Possible reason of error is incorrectly specified model input shape(s).")
-
- output_spatial_shape = shape_array([dynamic_dimension_value for _ in range(len(padded_spatial_shape))])
- for idx in range(len(padded_spatial_shape)):
- if padded_spatial_shape[idx] is not dynamic_dimension and stride_spatial[idx] is not dynamic_dimension:
- output_spatial_shape[idx] = int(rounding(padded_spatial_shape[idx] / stride_spatial[idx])) + 1
-
- original_pads = mo_array([i[1] for i in node.pad_spatial_shape])
-
- for i in range(len(input_spatial_shape)):
- if original_pads[i] and (output_spatial_shape[i] - 1) * stride_spatial[i] >= \
- input_spatial_shape[i] + original_pads[i]:
- output_spatial_shape[i] -= 1
-
- node['output_spatial_shape'] = output_spatial_shape
-
- output_shape = input_shape.copy()
- output_shape[node.spatial_dims] = node.output_spatial_shape
- node.out_port(0).data.set_shape(output_shape)
-
- if len(node.out_ports()) == 2 and not node.out_port(1).disconnected():
- node.out_port(1).data.set_shape(output_shape)
-
- if node.has_and_set('pool_method') and node['pool_method'] == 'max':
- node['remove_values_output'] = True
-
- # Add permute_attrs
- PermuteAttrs.create_permute_attrs(node, attrs=[('pad', 'input:0'),
- ('stride', 'input:0'),
- ('window', 'input:0'),
- ('spatial_dims', 'input:0'),
- ('dilation', 'input:0')])
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- window = node.soft_get('window', None)
- if input_shape is None and window is not None:
- node.in_port(0).data.set_shape(undefined_shape_of_rank(len(window)))
diff --git a/tools/mo/openvino/tools/mo/ops/power.py b/tools/mo/openvino/tools/mo/ops/power.py
deleted file mode 100644
index 288ab0d7cb0736..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/power.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.ops.op import Op
-
-
-class AttributedPower(Op):
- op = 'AttributedPower'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': 'Power',
-
- 'power': 1,
- 'scale': 1,
- 'shift': 0,
-
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['power', 'scale', 'shift']
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(data_type_str_to_np(node.graph.graph['cmd_params'].data_type))
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
- connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_inputs) == 1 and 0 in connected_inputs, \
- "AttributedPower should have 1 connected input port, but it doesn't for node: `{}`. Ports: {}" \
- "".format(name, connected_inputs)
-
- assert node.has_valid('scale'), \
- 'AttributedPower operation should have `scale` parameter set, but it doesn`t for node {}'.format(name)
- assert node.has_valid('shift'), \
- 'AttributedPower operation should have `shift` parameter set, but it doesn`t for node {}'.format(name)
- assert node.has_valid('power'), \
- 'AttributedPower operation should have `power` parameter set, but it doesn`t for node {}'.format(name)
-
- eltwise_infer(node, lambda a: np.power(a * node.scale + node.shift, node.power))
diff --git a/tools/mo/openvino/tools/mo/ops/prelu.py b/tools/mo/openvino/tools/mo/ops/prelu.py
deleted file mode 100644
index c79976ced97a45..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/prelu.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class PReLU(Op):
- op = 'PReLU'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
-
- 'force_precision_in_ports': {1: 'float'},
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node):
- if len(node.in_nodes()) == 2:
- gamma_vector = node.in_node(1)
- if np.all(gamma_vector.shape == [1]):
- node['channel_shared'] = 1
- else:
- node['channel_shared'] = 0
- node.in_node(1)['correct_data_type'] = True
-
- copy_shape_infer(node)
diff --git a/tools/mo/openvino/tools/mo/ops/priorbox.py b/tools/mo/openvino/tools/mo/ops/priorbox.py
deleted file mode 100644
index 6cbf4899aa037b..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/priorbox.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import get_width_dim, get_height_dim
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.extractor import attr_getter, bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class PriorBoxOp(Op):
- op = 'PriorBox'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'flip': True,
- 'clip': True,
- 'scale_all_sizes': True,
- 'max_size': mo_array([]),
- 'min_size': mo_array([]),
- 'aspect_ratio': mo_array([]),
- 'density': mo_array([]),
- 'fixed_size': mo_array([]),
- 'fixed_ratio': mo_array([]),
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'type_infer': self.type_infer,
- 'infer': self.priorbox_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'min_size',
- 'max_size',
- 'aspect_ratio',
- 'flip',
- 'clip',
- 'variance',
- 'img_size',
- 'img_h',
- 'img_w',
- 'step',
- 'step_h',
- 'step_w',
- 'offset',
- 'density',
- 'fixed_size',
- 'fixed_ratio',
- ]
-
- def backend_attrs(self):
- return [
- ('flip', lambda node: int(node.flip)), # We need to convert this boolean attribute value to int to keep
- # forward compatibility with OV 2021.2
- ('clip', lambda node: int(node.clip)), # We need to convert this boolean attribute value to int to keep
- # forward compatibility with OV 2021.2
- 'step',
- 'offset',
- ('scale_all_sizes', lambda node: bool_to_str(node, 'scale_all_sizes')),
- ('min_size', lambda node: attr_getter(node, 'min_size')),
- ('max_size', lambda node: attr_getter(node, 'max_size')),
- ('aspect_ratio', lambda node: attr_getter(node, 'aspect_ratio')),
- ('variance', lambda node: attr_getter(node, 'variance')),
- ('density', lambda node: attr_getter(node, 'density')),
- ('fixed_size', lambda node: attr_getter(node, 'fixed_size')),
- ('fixed_ratio', lambda node: attr_getter(node, 'fixed_ratio')),
- ]
-
- @staticmethod
- def type_infer(node):
- node.out_port(0).set_data_type(np.float32)
-
- @staticmethod
- def priorbox_infer(node: Node):
- layout = node.graph.graph['layout']
- data_shape = node.in_node(0).shape
-
- # calculate all different aspect_ratios (the first one is always 1)
- # in aspect_ratio 1/x values will be added for all except 1 if flip is True
- ar_seen = [1.0]
- ar_seen.extend(node.aspect_ratio.copy())
- if node.flip:
- for s in node.aspect_ratio:
- ar_seen.append(1.0 / s)
-
- ar_seen = np.unique(mo_array(ar_seen).round(decimals=6))
-
- num_ratios = 0
- if len(node.min_size) > 0:
- num_ratios = len(ar_seen) * len(node.min_size)
-
- if node.has_valid('fixed_size') and len(node.fixed_size) > 0:
- num_ratios = len(ar_seen) * len(node.fixed_size)
-
- if node.has_valid('density') and len(node.density) > 0:
- for d in node.density:
- if node.has_valid('fixed_ratio') and len(node.fixed_ratio) > 0:
- num_ratios = num_ratios + len(node.fixed_ratio) * (pow(d, 2) - 1)
- else:
- num_ratios = num_ratios + len(ar_seen) * (pow(d, 2) - 1)
-
- num_ratios = num_ratios + len(node.max_size)
-
- if node.has_and_set('V10_infer'):
- assert node.in_node(0).value is not None
- node.out_port(0).data.set_shape([2, np.prod(node.in_node(0).value) * num_ratios * 4])
- else:
- res_prod = data_shape[get_height_dim(layout, 4)] * data_shape[get_width_dim(layout, 4)] * num_ratios * 4
- node.out_port(0).data.set_shape([1, 2, res_prod])
diff --git a/tools/mo/openvino/tools/mo/ops/priorbox_clustered.py b/tools/mo/openvino/tools/mo/ops/priorbox_clustered.py
deleted file mode 100644
index 6dddc3b254b530..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/priorbox_clustered.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import get_width_dim, get_height_dim
-from openvino.tools.mo.front.extractor import attr_getter
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class PriorBoxClusteredOp(Op):
- op = 'PriorBoxClustered'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.priorbox_clustered_infer,
- 'type_infer': self.type_infer,
- 'clip': True,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'width',
- 'height',
- 'flip',
- 'clip',
- 'variance',
- 'img_size',
- 'img_h',
- 'img_w',
- 'step',
- 'step_h',
- 'step_w',
- 'offset'
- ]
-
- def backend_attrs(self):
- return [
- ('clip', lambda node: int(node.clip)), # We need to convert this boolean attribute value to int to keep
- # forward compatibility with OV 2021.2
- 'img_h',
- 'img_w',
- 'step',
- 'step_h',
- 'step_w',
- 'offset',
- ('variance', lambda node: attr_getter(node, 'variance')),
- ('width', lambda node: attr_getter(node, 'width')),
- ('height', lambda node: attr_getter(node, 'height'))
- ]
-
- @staticmethod
- def type_infer(node):
- node.out_port(0).set_data_type(np.float32)
-
- @staticmethod
- def priorbox_clustered_infer(node: Node):
- layout = node.graph.graph['layout']
- data_shape = node.in_node(0).shape
- num_ratios = len(node.width)
-
- if node.has_and_set('V10_infer'):
- assert node.in_node(0).value is not None
- node.out_port(0).data.set_shape([2, np.prod(node.in_node(0).value) * num_ratios * 4])
- else:
- res_prod = data_shape[get_height_dim(layout, 4)] * data_shape[get_width_dim(layout, 4)] * num_ratios * 4
- node.out_port(0).data.set_shape([1, 2, res_prod])
diff --git a/tools/mo/openvino/tools/mo/ops/priorgridgenerator_onnx.py b/tools/mo/openvino/tools/mo/ops/priorgridgenerator_onnx.py
deleted file mode 100644
index 80d4b3e288bd74..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/priorgridgenerator_onnx.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, set_input_shapes
-from openvino.tools.mo.ops.op import Op
-
-
-class ExperimentalDetectronPriorGridGenerator(Op):
- op = 'ExperimentalDetectronPriorGridGenerator'
-
- def __init__(self, graph, attrs):
- mandatory_props = dict(
- type=self.op,
- op=self.op,
- version='opset6',
- infer=self.infer,
- reverse_infer=self.reverse_infer,
- )
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [
- 'flatten',
- 'h',
- 'w',
- 'stride_x',
- 'stride_y',
- ]
-
- @staticmethod
- def infer(node):
- input_shape = node.in_port(0).data.get_shape()
- priors_num = input_shape[0]
- grid_h = node.in_port(1).data.get_shape()[2]
- grid_w = node.in_port(1).data.get_shape()[3]
- if node.flatten:
- out_shape = [grid_h * grid_w * priors_num, 4]
- else:
- out_shape = [grid_h, grid_w, priors_num, 4]
- node.out_port(0).data.set_shape(out_shape)
-
- @staticmethod
- def reverse_infer(node):
- priors_shape = shape_array([dynamic_dimension_value, 4])
- feature_map_shape = shape_array([1, dynamic_dimension_value, dynamic_dimension_value, dynamic_dimension_value])
- image_shape = shape_array([1, dynamic_dimension_value, dynamic_dimension_value, dynamic_dimension_value])
-
- set_input_shapes(node, priors_shape, feature_map_shape, image_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/proposal.py b/tools/mo/openvino/tools/mo/ops/proposal.py
deleted file mode 100644
index 1cb536edea646e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/proposal.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import undefined_shape_of_rank, set_input_shapes
-from openvino.tools.mo.front.extractor import attr_getter, bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ProposalOp(Op):
- op = 'Proposal'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset4',
- 'post_nms_topn': 300, # default in caffe-shared
- 'infer': ProposalOp.proposal_infer,
- 'reverse_infer': self.reverse_infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1 if attrs.get('version') == 'opset1' else 2,
- 'normalize': False,
- 'clip_before_nms': True,
- 'clip_after_nms': False,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'feat_stride',
- 'base_size',
- 'min_size',
- 'ratio',
- 'scale',
- 'pre_nms_topn',
- 'post_nms_topn',
- 'nms_thresh',
- ]
-
- def backend_attrs(self):
- return [
- 'feat_stride',
- 'base_size',
- 'min_size',
- ('ratio', lambda node: attr_getter(node, 'ratio')),
- ('scale', lambda node: attr_getter(node, 'scale')),
- 'pre_nms_topn',
- 'post_nms_topn',
- 'nms_thresh',
- 'framework',
- 'box_coordinate_scale',
- 'box_size_scale',
- ('normalize', lambda node: bool_to_str(node, 'normalize')),
- ('clip_after_nms', lambda node: bool_to_str(node, 'clip_after_nms')),
- ('clip_before_nms', lambda node: bool_to_str(node, 'clip_before_nms')),
- ]
-
- @staticmethod
- def proposal_infer(node: Node):
- input_shape = node.in_node(0).shape
- # rois blob: holds R regions of interest, each is a 5 - tuple
- # (n, x1, y1, x2, y2) specifying an image batch index n and a
- # rectangle(x1, y1, x2, y2)
- node.out_port(0).data.set_shape([input_shape[0] * node.post_nms_topn, 5])
-
- # the second optional output contains box probabilities
- if len(node.out_ports()) == 2 and not node.out_port(1).disconnected():
- node.out_port(1).data.set_shape([input_shape[0] * node.post_nms_topn])
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node, undefined_shape_of_rank(4), undefined_shape_of_rank(4))
diff --git a/tools/mo/openvino/tools/mo/ops/proposal_onnx.py b/tools/mo/openvino/tools/mo/ops/proposal_onnx.py
deleted file mode 100644
index bd5e575a9a93a8..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/proposal_onnx.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, \
- undefined_shape_of_rank, set_input_shapes
-from openvino.tools.mo.ops.op import Op
-
-
-class ExperimentalDetectronGenerateProposalsSingleImage(Op):
- op = 'ExperimentalDetectronGenerateProposalsSingleImage'
-
- def __init__(self, graph, attrs):
- mandatory_props = dict(
- type=self.op,
- op=self.op,
- version='experimental',
- reverse_infer=self.reverse_infer,
- infer=self.infer
- )
-
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [
- 'min_size',
- 'nms_threshold',
- 'post_nms_count',
- 'pre_nms_count'
- ]
-
- @staticmethod
- def infer(node):
- node.out_port(0).data.set_shape([node.post_nms_count, 4])
- node.out_port(1).data.set_shape([node.post_nms_count])
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node,
- undefined_shape_of_rank(1),
- shape_array([dynamic_dimension_value, 4]),
- undefined_shape_of_rank(3),
- undefined_shape_of_rank(3))
diff --git a/tools/mo/openvino/tools/mo/ops/proposal_python_example.py b/tools/mo/openvino/tools/mo/ops/proposal_python_example.py
deleted file mode 100644
index 12a1748ac34032..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/proposal_python_example.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.proposal import ProposalOp
-from openvino.tools.mo.front.caffe.extractor import register_caffe_python_extractor
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ProposalPythonExampleOp(Op):
- op = 'Proposal'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': __class__.op,
- 'op': __class__.op,
- 'post_nms_topn': 300,
- 'infer': ProposalOp.proposal_infer
- }
-
- super().__init__(graph, mandatory_props, attrs)
-
-
-register_caffe_python_extractor(ProposalPythonExampleOp, 'rpn.proposal_layer.ProposalLayer.example')
-Op.excluded_classes.append(ProposalPythonExampleOp)
diff --git a/tools/mo/openvino/tools/mo/ops/psroipooling.py b/tools/mo/openvino/tools/mo/ops/psroipooling.py
deleted file mode 100644
index b890ca649fa04b..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/psroipooling.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.layout import get_batch_dim, shape_for_layout
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, \
- undefined_shape_of_rank, set_input_shapes
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class PSROIPoolingOp(Op):
- op = 'PSROIPooling'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset2',
- 'mode': 'average',
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'trans_std': 0,
- 'no_trans': True,
- 'reverse_infer': self.reverse_infer,
- 'infer': PSROIPoolingOp.psroipooling_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'spatial_scale',
- 'output_dim',
- ('group_size', lambda node: int(node.group_size)),
- 'mode',
- 'spatial_bins_x',
- 'spatial_bins_y',
- ]
-
- @staticmethod
- def psroipooling_infer(node: Node):
- """
- Sets shape of output node according specified parameters input blobs and node
- Sets number from the first input blob, channels from the second one, height and width are specified
- Parameters
- ----------
- node
- """
- shapes = [node.in_node(i).shape for i in range(len(node.in_nodes()))]
- if any(s is None for s in shapes):
- return
- layout = node.graph.graph['layout']
- assert len(layout) == 4
- assert node.has_valid('group_size')
- assert node.group_size == int(node.group_size)
- node['group_size'] = int(node['group_size'])
- node.out_node().shape = shape_for_layout(layout,
- batch=shapes[1][get_batch_dim(layout, 4)],
- features=node.output_dim,
- height=node.group_size,
- width=node.group_size)
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node, undefined_shape_of_rank(4), shape_array([dynamic_dimension_value, 5]))
-
-
-class DeformablePSROIPoolingOp(PSROIPoolingOp):
- op = 'DeformablePSROIPooling'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- updated_attrs = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'mode': 'bilinear_deformable',
- 'in_ports_count': 3,
- 'trans_std': 0,
- }
- updated_attrs.update(attrs)
- super().__init__(graph, updated_attrs)
-
- def supported_attrs(self):
- return super().supported_attrs() + ['trans_std', 'part_size']
-
- @staticmethod
- def reverse_infer(node):
- transformation_values_shape = shape_array(
- [dynamic_dimension_value, dynamic_dimension_value, int(node.group_size), int(node.group_size)])
-
- set_input_shapes(node,
- undefined_shape_of_rank(4),
- shape_array([dynamic_dimension_value, 5]),
- transformation_values_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/quantize_linear.py b/tools/mo/openvino/tools/mo/ops/quantize_linear.py
deleted file mode 100644
index 9fc4efac8ea9e3..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/quantize_linear.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class QuantizeLinear(Op):
- op = 'QuantizeLinear'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'axis': None,
- 'version': None,
- 'infer': copy_shape_infer,
- 'out_ports_count': 1,
- 'in_ports_count': 3,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['axis']
diff --git a/tools/mo/openvino/tools/mo/ops/random_uniform.py b/tools/mo/openvino/tools/mo/ops/random_uniform.py
deleted file mode 100644
index e352133d304d79..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/random_uniform.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-
-
-class RandomUniform(Op):
- """
- RandomUniform operation that generates a sequence of random values from uniform distribution.
- """
- op = 'RandomUniform'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset8',
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'type_infer': self.type_infer,
- 'global_seed': 0,
- 'op_seed': 0,
- 'output_type': np.float32,
- }, attrs)
-
- def backend_attrs(self):
- return [('output_type', lambda node: np_data_type_to_destination_type(node.output_type)),
- 'global_seed',
- 'op_seed']
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(node['output_type'])
-
- @staticmethod
- def infer(node: Node):
- assert node.has_valid('output_type')
-
- node.out_port(0).data.set_shape(node.in_port(0).data.get_value())
-
- # We need to keep data type in data nodes corresponding to min and max values,
- # as min and max value type should be the same as output_type attribute of RandomUniform
- # operation. 'correct_data_type' attribute prevents changes of the data node type when
- # ir data type is not equal to data node type.
- node.in_node(1)['correct_data_type'] = True
- node.in_node(2)['correct_data_type'] = True
-
- PermuteInputs().set_input_permutation(node.in_node(0), node, 'output:0', 'shape')
-
-
-class AttributedRandomUniform(Op):
- """ RandomUniform operation that generates a sequence of random values from uniform distribution.
- This operation uses the same semantics as RandomUniform but output shape, min value or max value
- can be specified as attribute.
- Shape is specified as attribute in ONNX. Min value and max value are specified as attributes
- in RandomUniformInt in TF.
- """
- op = 'AttributedRandomUniform'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'global_seed': 0,
- 'op_seed': 0,
- 'output_type': np.float32,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/range.py b/tools/mo/openvino/tools/mo/ops/range.py
deleted file mode 100644
index e23418acfd237c..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/range.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class Range(Op):
- """
- Some notes on the automatic result data type infer. The tf.range does is differently than np.arange. Numpy
- by default creates array with elements of type int64 and float64, but TF does not widen data types and
- keep them int32 and float32.
- Compare:
-
- >>> tf.range(1, 5, 0.5)
-
- >>> tf.range(1, 5, 2)
-
-
- >>> mo_array([0.5], dtype=np.float32)
- array([0.5], dtype=float32)
- >>> np.arange(mo_array([1], dtype=np.int32), mo_array([5], dtype=np.int32), mo_array([2], dtype=np.int32)).dtype
- dtype('int64')
- >>> np.arange(mo_array([1], dtype=np.int32), mo_array([5], dtype=np.int32), mo_array([0.5], dtype=np.float32)).dtype
- dtype('float64')
- """
- op = 'Range'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
-
- 'version': 'opset4',
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == 'opset4':
- return [
- ('output_type', lambda node: np_data_type_to_destination_type(node.output_type)),
- ]
- elif version == 'opset1':
- return []
- else:
- raise Error('Unknown opset version "{}"'.format(version))
-
- @staticmethod
- def type_infer(node: Node):
- node.out_port(0).set_data_type(node['output_type'])
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
- connected_input_ports = [in_port.idx for in_port in node.in_ports().values() if not in_port.disconnected()]
- assert len(connected_input_ports) == 3 and [0, 1, 2] == sorted(connected_input_ports), \
- 'Range operation should have 3 inputs, {} found for {}'.format(len(connected_input_ports), name)
-
- start = node.in_port(0).data.get_value()
- limit = node.in_port(1).data.get_value()
- delta = node.in_port(2).data.get_value()
-
- for input in (start, limit, delta):
- if input is not None and not node.has_valid('output_type'):
- node['output_type'] = input.dtype
-
- if not is_fully_defined(start) or not is_fully_defined(limit) or not is_fully_defined(delta):
- node.out_port(0).data.set_shape(shape_array([dynamic_dimension_value]))
- else:
- node.out_port(0).data.set_value(np.arange(start, limit, delta, dtype=node['output_type']))
diff --git a/tools/mo/openvino/tools/mo/ops/rank.py b/tools/mo/openvino/tools/mo/ops/rank.py
deleted file mode 100644
index 76cdc6eea483ad..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/rank.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Rank(Op):
- op = 'Rank'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
-
- 'output_type': np.int64,
- 'infer': None,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/read_value.py b/tools/mo/openvino/tools/mo/ops/read_value.py
deleted file mode 100644
index 1147ee0d3a2372..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/read_value.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import numpy as np
-from openvino.runtime import PartialShape
-
-from openvino.tools.mo.front.common.partial_infer.utils import unmask_shape
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-
-
-class ReadValue(Op):
- op = 'ReadValue'
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset6',
- 'infer': self.infer,
- 'type_infer': self.type_infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def shape_serialize(node):
- shape = node.soft_get('variable_shape')
- if isinstance(shape, np.ndarray):
- return shape.tolist()
- if isinstance(shape, np.ma.masked_array):
- shape = unmask_shape(shape)
- if isinstance(shape, PartialShape):
- return shape.to_string()
- raise Exception("Unknown shape type in user_shape attribute {}".format(type(shape)))
-
- def backend_attrs(self):
- return ['variable_id',
- ('variable_shape', lambda node: self.shape_serialize(node)),
- ('variable_type', lambda node: np_data_type_to_destination_type(node.variable_type))]
-
- @staticmethod
- def type_infer(node: Node):
- node.variable_type = node.in_port(0).get_data_type()
- node.out_port(0).set_data_type(node.in_port(0).get_data_type())
-
- @staticmethod
- def infer(node: Node):
- assert node.has_valid('variable_id'), \
- "There is no required attribute variable_id in ReadValue op with name " + node.id
- in_shape = node.in_port(0).data.get_shape()
- node.out_port(0).data.set_shape(in_shape)
- node.variable_shape = in_shape
diff --git a/tools/mo/openvino/tools/mo/ops/regionyolo.py b/tools/mo/openvino/tools/mo/ops/regionyolo.py
deleted file mode 100644
index 7c8161c8939183..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/regionyolo.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.front.common.layout import get_batch_dim, get_height_dim, get_width_dim, shape_for_layout
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, dynamic_dimension_value, \
- undefined_shape_of_rank
-from openvino.tools.mo.front.extractor import attr_getter, bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class RegionYoloOp(Op):
- op = 'RegionYolo'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'reverse_infer': self.reverse_infer,
- 'infer': RegionYoloOp.regionyolo_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'coords',
- 'classes',
- 'num',
- 'axis',
- 'end_axis',
- 'do_softmax',
- 'anchors',
- 'mask'
- ]
-
- def backend_attrs(self):
- return [
- 'coords',
- 'classes',
- 'num',
- 'axis',
- 'end_axis',
- ('do_softmax', lambda node: bool_to_str(node, 'do_softmax')),
- ('anchors', lambda node: attr_getter(node, 'anchors')),
- ('mask', lambda node: attr_getter(node, 'mask'))
- ]
-
- @staticmethod
- def regionyolo_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- axis = get_canonical_axis_index(input_shape, node.axis)
- end_axis = get_canonical_axis_index(input_shape, node.end_axis)
- node.axis = axis
- node.end_axis = end_axis
- if node.do_softmax:
- dims_to_flatten = input_shape[axis: end_axis + 1]
- if is_fully_defined(dims_to_flatten):
- flat_dim = np.ma.prod(dims_to_flatten)
- else:
- flat_dim = dynamic_dimension_value
- node.out_port(0).data.set_shape([*input_shape[:axis], flat_dim, *input_shape[end_axis + 1:]])
- else:
- layout = node.graph.graph['layout']
- assert len(layout) == 4
-
- node.out_port(0).data.set_shape(shape_for_layout(layout,
- batch=input_shape[get_batch_dim(layout, 4)],
- features=(node.classes + node.coords + 1) * len(node.mask),
- height=input_shape[get_height_dim(layout, 4)],
- width=input_shape[get_width_dim(layout, 4)]))
-
- @staticmethod
- def reverse_infer(node):
- if node.in_port(0).data.get_shape() is None:
- node.in_port(0).data.set_shape(undefined_shape_of_rank(4))
diff --git a/tools/mo/openvino/tools/mo/ops/reorgyolo.py b/tools/mo/openvino/tools/mo/ops/reorgyolo.py
deleted file mode 100644
index 8fae9ad8936cea..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/reorgyolo.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.utils.error import Error
-
-
-class ReorgYoloOp(Op):
- op = 'ReorgYolo'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset2',
- 'reverse_infer': self.reverse_infer,
- 'infer': ReorgYoloOp.reorgyolo_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'stride'
- ]
-
- @staticmethod
- def reorgyolo_infer(node: Node):
- input_shape = node.in_node(0).shape
- if input_shape is None:
- raise Error('Input shape for operation "{}" is None'.format(node.soft_get('name', node.id)))
-
- stride = node.stride
-
- output_shape = input_shape.copy()
- output_shape[node.batch_dims] = input_shape[node.batch_dims] # pylint: disable=unsupported-assignment-operation
- output_shape[node.channel_dims] = input_shape[node.channel_dims] * stride ** 2 # pylint: disable=unsupported-assignment-operation
- # Round as in caffe
- output_shape[node.spatial_dims] = np.ma.round(input_shape[node.spatial_dims] / stride) # pylint: disable=unsupported-assignment-operation
-
- node.out_port(0).data.set_shape(output_shape)
- PermuteAttrs.create_permute_attrs(node, attrs=[('channel_dims', 'input:0'), ('spatial_dims', 'input:0')])
-
- @staticmethod
- def reverse_infer(node):
- if node.in_port(0).data.get_shape() is None:
- node.in_port(0).data.set_shape(undefined_shape_of_rank(4))
diff --git a/tools/mo/openvino/tools/mo/ops/reshape.py b/tools/mo/openvino/tools/mo/ops/reshape.py
deleted file mode 100644
index bd3538ff7845f8..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/reshape.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, dynamic_dimension_value, is_fully_defined
-from openvino.tools.mo.front.extractor import bool_to_str
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-
-
-class Reshape(Op):
- op = 'Reshape'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
-
- 'special_zero': True,
- 'reinterp_shape': True,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return [('special_zero', lambda node: bool_to_str(node, 'special_zero'))]
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_inputs) == 2 and all([i in connected_inputs for i in range(2)]), \
- "Reshape should have 2 connected input ports, but it doesn't for node: `{}`. Ports: {}" \
- "".format(name, connected_inputs)
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None
-
- new_shape = node.in_port(1).data.get_value()
- assert new_shape is not None, 'Dynamic Reshape second input is not supported. Node {}'.format(name)
-
- assert np.argwhere(new_shape == -1).size <= 1, \
- 'Reshape second input should not have several `-1` values set. ' \
- 'Node: {}, reshape second input value {}'.format(name, new_shape)
-
- num_of_input_elements = np.prod(input_shape)
- num_of_output_elements = 1
- for index, x in enumerate(new_shape):
- if x is dynamic_dimension:
- num_of_output_elements = dynamic_dimension_value
- elif x == 0 and node.has_and_set('special_zero'):
- if input_shape[index] is not dynamic_dimension:
- num_of_output_elements *= input_shape[index]
- elif x != -1:
- num_of_output_elements *= x
-
- # input_shape = [dynamic, 5, 6], new_shape = [0, -1] => output_shape [dynamic, 30]
- # marker that no dynamic input dimensions or all of them are copied with "0" magic value
- all_dynamic_dimension_are_copied = True
- if not is_fully_defined(input_shape):
- for index, x in enumerate(input_shape):
- if x is dynamic_dimension:
- if index >= len(new_shape) or new_shape[index] != 0:
- all_dynamic_dimension_are_copied = False
-
- undefined_dim = dynamic_dimension
- if num_of_output_elements is not dynamic_dimension and all_dynamic_dimension_are_copied and \
- is_fully_defined(new_shape):
- undefined_dim = num_of_input_elements // num_of_output_elements
- output_shape = []
- for index, x in enumerate(new_shape):
- if x == 0 and node.has_and_set('special_zero'):
- output_shape.append(input_shape[index])
- elif x == -1:
- output_shape.append(undefined_dim)
- else:
- output_shape.append(x)
-
- # even if the new_shape contains some dynamic values we can calculate the actual value by deducing it from the
- # input shape if it is static: input_shape = [5, 3, 8], new_shape = [4, d] => output_shape = [4, 30]
- if is_fully_defined(input_shape) and not is_fully_defined(new_shape):
- dynamic_indices = np.argwhere([item is dynamic_dimension for item in new_shape])
- num_of_output_elements = 1
- if dynamic_indices.size == 1:
- for index, x in enumerate(new_shape):
- if x == 0 and node.has_and_set('special_zero'):
- num_of_output_elements *= input_shape[index]
- elif x is not dynamic_dimension and x != -1:
- num_of_output_elements *= x
- assert num_of_input_elements % num_of_output_elements == 0, \
- 'Incorrect number of output elements deduced for node {}: '.format(name)
- output_shape[dynamic_indices[0][0]] = num_of_input_elements // num_of_output_elements
-
- assert not is_fully_defined(input_shape) or not is_fully_defined(output_shape) or \
- np.prod(input_shape) == np.prod(output_shape), \
- "Number of elements in input {} and output {} of reshape node {} mismatch" \
- "".format(input_shape, output_shape, name)
-
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'output:0', 'shape')
-
- if node.in_port(0).data.get_value() is not None and is_fully_defined(output_shape):
- node.out_port(0).data.set_value(node.in_port(0).data.get_value().reshape(output_shape))
- else:
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/resize.py b/tools/mo/openvino/tools/mo/ops/resize.py
deleted file mode 100644
index d39d2af9ac50ee..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/resize.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class ResizeOp(Op):
- enabled = False
- op = 'Resize'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.resize_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'mode',
- ]
-
- def backend_attrs(self):
- return [
- 'mode',
- ]
-
- @staticmethod
- def resize_infer(node: Node):
- layout = node.graph.graph['layout']
- assert len(layout) == 4
-
- input_shape = node.in_node(0).shape
- if input_shape is None:
- raise Error('Input shape for operation "{}" is None'.format(node.soft_get('name', node.id)))
-
- scale_value = node.in_node(1).value
-
- node.out_port(0).data.set_shape(input_shape * scale_value)
-
diff --git a/tools/mo/openvino/tools/mo/ops/resize_factor_utils.py b/tools/mo/openvino/tools/mo/ops/resize_factor_utils.py
deleted file mode 100644
index 961d02a135c6f9..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/resize_factor_utils.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-
-def factor_update(factor: float, real_factor: list, in_shape: list, out_shape: list, name: str):
- """ Updates factor value for layers related to image resizing such as Resample and Interp. """
- if factor is None:
- if real_factor[0] != real_factor[1]:
- log.warning(
- 'Cannot deduce a single zoom factor for both height and widths for node {}: [{},{}]/[{},{}] = [{},{}]. '
- 'This model will not reshape in IE.'.format(
- name,
- out_shape[0],
- out_shape[1],
- in_shape[0],
- in_shape[1],
- real_factor[0],
- real_factor[1]
- )
- )
- else:
- factor = real_factor[0]
- return factor
diff --git a/tools/mo/openvino/tools/mo/ops/restrictedattentioncomponent.py b/tools/mo/openvino/tools/mo/ops/restrictedattentioncomponent.py
deleted file mode 100644
index ff9fdfe30eeeb2..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/restrictedattentioncomponent.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class RestrictedAttentionComponent(Op):
- op = 'restrictedattentioncomponent'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'has_default': False,
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/result.py b/tools/mo/openvino/tools/mo/ops/result.py
deleted file mode 100644
index 38da327d1a6ca0..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/result.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Result(Op):
- """
- Operation that should be added after the output node of the graph. It is a marker of the graph output.
- This type of nodes is used in the dead nodes elimination pass and not dumped into the IR.
- """
- op = 'Result'
-
- def __init__(self, graph: Graph, attrs: dict = None):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
- 'infer': lambda x: None,
- 'value': None,
- 'data_type': None,
- 'in_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/reverse_sequence.py b/tools/mo/openvino/tools/mo/ops/reverse_sequence.py
deleted file mode 100644
index bbf3ec33c41b3a..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/reverse_sequence.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-class ReverseSequence(Op):
- op = 'ReverseSequence'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'version': 'opset1',
- 'seq_axis': None,
- 'batch_axis': 0,
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'seq_axis', 'batch_axis',
- ]
-
- @staticmethod
- def infer(node):
- input_data_shape = node.in_port(0).data.get_shape()
- assert input_data_shape is not None
- assert node.has_valid('seq_axis')
- assert node.has_valid('batch_axis')
-
- assert len(node.out_nodes()) == 1
- node.out_port(0).data.set_shape(input_data_shape)
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('seq_axis', 'input:0')])
- PermuteAttrs.create_permute_attrs(node, attrs=[('batch_axis', 'input:0')])
diff --git a/tools/mo/openvino/tools/mo/ops/roialign.py b/tools/mo/openvino/tools/mo/ops/roialign.py
deleted file mode 100644
index 169dfbdc792c41..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/roialign.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.layout import get_features_dim, shape_for_layout
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, \
- undefined_shape_of_rank, set_input_shapes, compatible_dims
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ROIAlign(Op):
- op = 'ROIAlign'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'mode' in attrs, '`mode` attribute is not set for ROIAlign during creation'
- assert 'pooled_h' in attrs, '`pooled_h` attribute is not set for ROIAlign during creation'
- assert 'pooled_w' in attrs, '`pooled_w` attribute is not set for ROIAlign during creation'
- assert 'sampling_ratio' in attrs, '`sampling_ratio` attribute is not set for ROIAlign during creation'
- assert 'spatial_scale' in attrs, '`spatial_scale` attribute is not set for ROIAlign during creation'
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset9',
-
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
-
- 'in_ports_count': 3,
- 'out_ports_count': 1,
-
- 'aligned_mode': 'asymmetric',
- }, attrs)
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == 'opset3':
- return [
- ('mode', lambda node: str(node.mode)),
- ('pooled_h', lambda node: str(int(node.pooled_h))),
- ('pooled_w', lambda node: str(int(node.pooled_w))),
- ('sampling_ratio', lambda node: str(int(node.sampling_ratio))),
- ('spatial_scale', lambda node: str(float(node.spatial_scale))),
- ]
- elif version == 'opset9':
- return [
- ('mode', lambda node: str(node.mode)),
- ('pooled_h', lambda node: str(int(node.pooled_h))),
- ('pooled_w', lambda node: str(int(node.pooled_w))),
- ('sampling_ratio', lambda node: str(int(node.sampling_ratio))),
- ('spatial_scale', lambda node: str(float(node.spatial_scale))),
- ('aligned_mode', lambda node: str(node.aligned_mode))
- ]
-
- @staticmethod
- def infer(node):
-
- layout = node.graph.graph['layout']
- node_name = node.soft_get('name', node.id)
- assert len([port for port in node.in_ports().values() if not port.disconnected()]) == 3, \
- 'The node "{}" must 3 inputs'.format(node_name)
-
- assert node.has_valid('pooled_w'), '"pooled_w" attribute is not set for node "{}"'.format(node_name)
- assert node.has_valid('pooled_h'), '"pooled_h" attribute is not set for node "{}"'.format(node_name)
- assert node.has_valid('mode'), '"mode" attribute is not set for node "{}"'.format(node_name)
- assert node.mode in ['avg', 'max'], \
- '"mode" attribute range of values is ["avg", "max"], got {} for node "{}"'.format(node.mode, node_name)
- if node.get_opset() == 'opset9':
- assert node.aligned_mode in ['asymmetric', 'half_pixel_for_nn', 'half_pixel'], \
- '"aligned_mode" attribute range of values is ["asymmetric", "half_pixel_for_nn", "half_pixel"]'
- input_shape = node.in_port(0).data.get_shape()
- rois_shape = node.in_port(1).data.get_shape()
- indices_shape = node.in_port(2).data.get_shape()
- assert input_shape is not None and rois_shape is not None and indices_shape is not None, \
- 'The node "{}" input shape is None'.format(node_name)
- assert compatible_dims(rois_shape[0], indices_shape[0]), 'The number of batch indices does not correspond ' \
- 'to number of ROIs for node "{}"'.format(node_name)
- assert compatible_dims(rois_shape[1], 4), 'The size of ROI element must be 4 for node "{}"'.format(node_name)
- assert len(input_shape) == 4, 'The rank of port 0 input tensor of node "{}" must be 4.'.format(node_name)
- node.out_port(0).data.set_shape(
- shape_for_layout(layout,
- batch=rois_shape[0],
- features=input_shape[get_features_dim(layout, 4)],
- height=node.pooled_h,
- width=node.pooled_w)
- )
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node,
- undefined_shape_of_rank(4),
- shape_array([dynamic_dimension_value, 4]),
- undefined_shape_of_rank(1))
diff --git a/tools/mo/openvino/tools/mo/ops/roifeatureextractor_onnx.py b/tools/mo/openvino/tools/mo/ops/roifeatureextractor_onnx.py
deleted file mode 100644
index e399b1f16342c4..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/roifeatureextractor_onnx.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, set_input_shapes
-from openvino.tools.mo.ops.op import Op
-
-
-class ExperimentalDetectronROIFeatureExtractor(Op):
- op = 'ExperimentalDetectronROIFeatureExtractor'
-
- def __init__(self, graph, attrs):
- mandatory_props = dict(
- type=self.op,
- op=self.op,
- version='opset6',
- infer=self.infer,
- reverse_infer=self.reverse_infer,
- out_ports_count=2,
- )
-
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return [
- ('pyramid_scales', lambda node: ','.join(map(str, node['pyramid_scales']))),
- 'output_size',
- 'sampling_ratio',
- ('aligned', lambda node: str(bool(node.soft_get('aligned', False))).lower())]
-
- @staticmethod
- def infer(node):
- input_rois_shape = node.in_port(0).data.get_shape()
- rois_num = input_rois_shape[0]
- input_features_level_0_shape = node.in_port(1).data.get_shape()
- channels_num = input_features_level_0_shape[1]
- node.out_port(0).data.set_shape([rois_num, channels_num, node.output_size, node.output_size])
- if not node.out_port(1).disconnected():
- node.out_port(1).data.set_shape([rois_num, 4])
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node,
- shape_array([dynamic_dimension_value, 4]),
- shape_array([1, dynamic_dimension_value, dynamic_dimension_value, dynamic_dimension_value]))
diff --git a/tools/mo/openvino/tools/mo/ops/roipooling.py b/tools/mo/openvino/tools/mo/ops/roipooling.py
deleted file mode 100644
index fef0c0554ab876..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/roipooling.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.roipooling import roipooling_infer
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, \
- undefined_shape_of_rank, set_input_shapes
-from openvino.tools.mo.ops.op import Op
-
-
-class ROIPooling(Op):
- op = 'ROIPooling'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'type': __class__.op,
- 'op': __class__.op,
- 'version': 'opset2',
- 'pooled_h': None,
- 'pooled_w': None,
- 'spatial_scale': 0.0625,
- 'method': 'max',
- 'infer': roipooling_infer,
- 'reverse_infer': self.reverse_infer,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['pooled_h', 'pooled_w', 'spatial_scale', 'method']
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node, undefined_shape_of_rank(4), shape_array([dynamic_dimension_value, 5]))
diff --git a/tools/mo/openvino/tools/mo/ops/roll.py b/tools/mo/openvino/tools/mo/ops/roll.py
deleted file mode 100644
index 4216d83b1916d0..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/roll.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-
-
-class Roll(Op):
- """
- Roll operation that shifts elements of a tensor along specified axes.
- """
- op = 'Roll'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset7',
- 'infer': roll_infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
- 'in_ports_count': 3,
- 'out_ports_count': 1
- }, attrs)
-
-
-class AttributedRoll(Op):
- """ Roll operation that shifts elements of a tensor along specified axes.
- This operation uses the same semantics as Roll but with shift and axes specified as attributes.
- Shift and axes are specified as attributes in MxNet.
- """
-
- op = 'AttributedRoll'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': None,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'shift': None,
- 'axes': None
- }, attrs)
-
-
-def roll_infer(node: Node):
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'axis')
- copy_shape_infer(node)
diff --git a/tools/mo/openvino/tools/mo/ops/scale_shift.py b/tools/mo/openvino/tools/mo/ops/scale_shift.py
deleted file mode 100644
index c9baac5cedfa79..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/scale_shift.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ScaleShiftOp(Op):
- op = 'ScaleShift'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'infer': copy_shape_infer,
- 'type': __class__.op,
- 'op': __class__.op,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/scatter.py b/tools/mo/openvino/tools/mo/ops/scatter.py
deleted file mode 100644
index f33ec01959abc0..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/scatter.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes, reverse_bypass_infer, shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Scatter(Op):
- enabled = False
-
- op = op_type = None
- version = None
-
- def __init__(self, graph: Graph, attrs: dict):
- assert self.op is not None and self.op_type is not None and self.version is not None, \
- 'Please use specialized Scatter operation class, Scatter is base class'
-
- mandatory_props = {
- 'op': self.op,
- 'type': self.op_type,
- 'version': self.version,
-
- 'is_scatter': True, # is used for gathering all types of scatters in common transformations
- 'infer': self.infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node, in_ports=[0]),
-
- 'reduction': None,
- 'use_init_val': None,
-
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
-
- input_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- updates_shape = node.in_port(2).data.get_shape()
- assert input_shape is not None and updates_shape is not None and indices_shape is not None, \
- 'The node "{}" input shape is None'.format(node_name)
-
- node.out_port(0).data.set_shape(input_shape)
-
-
-class ScatterElementsAdd(Scatter):
- op = 'ScatterElementsAdd'
- op_type = None
- version = None
-
-
-class ScatterElementsDiv(Scatter):
- op = 'ScatterElementsDiv'
- op_type = None
- version = None
-
-
-class ScatterElementsMax(Scatter):
- op = 'ScatterElementsMax'
- op_type = None
- version = None
-
-
-class ScatterElementsMin(Scatter):
- op = 'ScatterElementsMin'
- op_type = None
- version = None
-
-
-class ScatterElementsMul(Scatter):
- op = 'ScatterElementsMul'
- op_type = None
- version = 'opset3'
-
-
-class ScatterElementsSub(Scatter):
- op = 'ScatterElementsSub'
- op_type = None
- version = None
-
-
-class ScatterElementsUpdate(Scatter):
- op = op_type = 'ScatterElementsUpdate'
- version = 'opset3'
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == 'opset12':
- return ['reduction', 'use_init_val']
- else:
- return []
-
- @staticmethod
- def infer(node: Node):
- Scatter.infer(node)
-
- node_name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 4, \
- "Incorrect number of inputs for {} node".format(node_name)
-
- input_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- updates_value = node.in_port(2).data.get_value()
-
- input_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- updates_shape = node.in_port(2).data.get_shape()
-
- assert len(input_shape) == len(indices_shape), 'data and indices inputs for node "{}" must be of the ' \
- 'same rank. Instead got {} and {}'.format(node_name,
- len(input_shape),
- len(indices_shape))
- assert compatible_shapes(indices_shape, updates_shape), \
- 'updates and indices shapes for node "{}" must be equal. Instead got {} and {}.' \
- ''.format(node_name, indices_shape, updates_shape)
-
- axis = node.in_port(3).data.get_value()
- opset = node.soft_get('version', 'default')
- is_opset12_reduction = opset == 'opset12' and (node.soft_get('reduction') != 'none' or not node.soft_get('use_init_val'))
- if input_value is not None and indices_value is not None and updates_value is not None and axis is not None and not is_opset12_reduction:
- assert axis.size == 1, "The node {} has axis input value size equal to {} but it should be exactly 1.".format(
- node_name, axis.size)
- axis = axis.item()
- out_value = input_value.copy()
- for idx in np.ndindex(*indices_shape):
- data_idx = list(idx)
- data_idx[axis] = indices_value[idx]
- out_value[tuple(data_idx)] = updates_value[idx]
- node.out_port(0).data.set_value(out_value)
-
-
-class ScatterAdd(Scatter):
- op = 'ScatterAdd'
- op_type = None
- version = None
-
-
-class ScatterDiv(Scatter):
- op = 'ScatterDiv'
- op_type = None
- version = None
-
-
-class ScatterMax(Scatter):
- op = 'ScatterMax'
- op_type = None
- version = None
-
-
-class ScatterMin(Scatter):
- op = 'ScatterMin'
- op_type = None
- version = None
-
-
-class ScatterMul(Scatter):
- op = 'ScatterMul'
- op_type = None
- version = None
-
-
-class ScatterSub(Scatter):
- op = 'ScatterSub'
- op_type = None
- version = None
-
-
-class ScatterUpdate(Scatter):
- op = op_type = 'ScatterUpdate'
- version = 'opset3'
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- Scatter.infer(node)
-
- input_shape = node.in_port(0).data.get_shape()
-
- input_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- updates_value = node.in_port(2).data.get_value()
-
- axis = node.in_port(3).data.get_value()
-
- if input_value is not None and indices_value is not None and updates_value is not None and axis is not None:
- assert axis.size == 1, "The node {} has axis input value size equal to {} but it should be exactly 1.".format(
- node_name, axis.size)
- axis = axis.item()
- if axis < 0:
- axis = len(input_shape) + axis
-
- out_value = input_value.copy()
- for idx in np.ndindex(*input_shape[:axis]):
- out_value[idx][indices_value] = updates_value[idx]
- # update value can be dynamic, we need to create masked array in that case
- if isinstance(updates_value, np.ma.masked_array):
- out_value = shape_array(out_value, dtype=out_value.dtype)
- node.out_port(0).data.set_value(out_value)
diff --git a/tools/mo/openvino/tools/mo/ops/scatternd.py b/tools/mo/openvino/tools/mo/ops/scatternd.py
deleted file mode 100644
index 1934dd12ac8dd1..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/scatternd.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes, strict_compare_tensors, \
- is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class ScatterNDBase(Op):
- enabled = False
-
- op = op_type = None
- version = None
-
- def __init__(self, graph: Graph, attrs: dict):
- assert self.op is not None and self.op_type is not None and self.version is not None, \
- 'Please use specialized ScatterNDBase operation class, ScatterNDBase is base class'
-
- mandatory_props = {
- 'op': self.op,
- 'type': self.op_type,
- 'version': self.version,
-
- 'infer': self.infer,
-
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
-
- input_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- updates_shape = node.in_port(2).data.get_shape()
- assert input_shape is not None and updates_shape is not None and indices_shape is not None, \
- 'The node "{}" input shape is None'.format(node_name)
-
- # check that shapes are correct
- # 1. ranks of both input and indices must be at least 1
- assert len(input_shape) >= 1 and len(indices_shape) >= 1, \
- 'The node "{}" input and indices ranks must be at least 1'.format(node_name)
-
- # 2. the last dimension of indices shape must be at most a rank of input
- assert not is_fully_defined(indices_shape[-1]) or indices_shape[-1] <= len(input_shape), \
- 'The last dimension of indices shape must be at most a rank of input for the node "{}"'.format(node_name)
-
- # 3. updates is a tensor of shape indices_shape[:-1] + input_shape[indices_shape[-1]:]
- # if expected updates shape is scalar, updates can be tensor with the single element (for example, of shape
- # [1], [[1]], etc.)
- expected_updates_shape = np.ma.concatenate((indices_shape[:-1], input_shape[indices_shape[-1]:]), axis=0)
- assert compatible_shapes(updates_shape, expected_updates_shape) or \
- (strict_compare_tensors(expected_updates_shape, []) and
- strict_compare_tensors(updates_shape, np.ones(len(updates_shape), dtype=np.int64))), \
- 'The updates shape must be equal to indices_shape[:-1] + input_shape[indices_shape[-1]:] for the node ' \
- '"{}"'.format(node_name)
-
- node.out_port(0).data.set_shape(input_shape)
-
- @staticmethod
- def type_infer(node: Node):
- assert node.in_port(0).get_source().get_data_type() == node.in_port(2).get_source().get_data_type(), \
- 'The data type of the first and the third inputs must be equal for the node {}'.format(node.name)
- node.out_port(0).set_data_type(node.in_port(0).get_data_type())
-
-
-class ScatterNDUpdate(ScatterNDBase):
- op = op_type = 'ScatterNDUpdate'
- version = 'opset4'
-
- @staticmethod
- def infer(node: Node):
- ScatterNDBase.infer(node)
-
- input_value = node.in_port(0).data.get_value()
- indices_shape = node.in_port(1).data.get_shape()
- indices_value = node.in_port(1).data.get_value()
- updates_value = node.in_port(2).data.get_value()
-
- # compute output value if all inputs are constant
- if input_value is not None and is_fully_defined(indices_value) and updates_value is not None:
- output_value = input_value.copy()
- indx_range = indices_shape[:-1]
- for indx in np.ndindex(tuple(indx_range)):
- if indx == ():
- # a case when updates is a scalar
- indx = 0
- updates_value = [updates_value]
- insert_index = indices_value[indx]
- # we check and change index type explicitly to avoid error in indexing ndarray by another ndarray
- if isinstance(insert_index, np.ndarray):
- insert_index = tuple(insert_index)
- output_value[insert_index] = updates_value[indx]
-
- node.out_port(0).data.set_value(output_value)
-
-
-class TFScatterND(Op):
- """
- TFScatterND operation comes from TensorFlow and will be replaced by TFScatterNDDecomposition.
- """
- op = 'TFScatterND'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': None
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/select.py b/tools/mo/openvino/tools/mo/ops/select.py
deleted file mode 100644
index 3da9fbe7fe4780..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/select.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes, dynamic_dimension, shape_array, is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph, Error
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.broadcasting import bi_directional_shape_broadcasting, bi_directional_broadcasting
-
-
-class Select(Op):
- op = 'Select'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'type_infer': self.type_infer,
- 'auto_broadcast': 'numpy'
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return ['auto_broadcast']
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- assert len([port for port in node.in_ports().values() if not port.disconnected()]) == 3, \
- "Select operation must have 3 inputs: 'condition', 'then' and 'else' tensors for node {}".format(node_name)
-
- condition_value = node.in_port(0).data.get_value()
- condition_shape = node.in_port(0).data.get_shape()
- resulting_tensors = [node.in_port(1).data.get_value(), node.in_port(2).data.get_value()]
-
- a_shape = node.in_port(1).data.get_shape()
- b_shape = node.in_port(2).data.get_shape()
- broadcast_rule = node.soft_get('auto_broadcast', 'numpy')
-
- if broadcast_rule == 'numpy':
- msg = "In Select node '{}' condition and then/else shapes must be broadcastable. " \
- "But instead got: cond_shape={}, then_shape={}, else_shape={}".format(
- node_name, condition_shape, a_shape, b_shape)
-
- output_shape = bi_directional_shape_broadcasting(a_shape, b_shape)
- assert output_shape is not None, msg
-
- output_is_scalar = len(output_shape) == 0
-
- # if Select was created from TF Where operations then 1D condition must have the same size
- # as 0-index dimension of output_shape. This condition is different from being numpy compatible
- # but by adding ones to the end we can achieve numpy compatibility, as in transformation SelectBroadcast.py
- if node.has_valid('format') and node['format'] == 'tf' and len(condition_shape) == 1:
- # https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/ops/array_ops.py#L4596-L4598
- msg_tf = "In Select node '{}' if 'condition' is a 1D tensor then it's size " \
- "must be matching with the first dimension of then/else branches. " \
- "But instead got: cond_shape={}, then_shape={}, else_shape={}".format(
- node_name, condition_shape, a_shape, b_shape)
-
- # check equality only if both values non-dynamic
- if is_fully_defined(condition_shape[0]) and not output_is_scalar and is_fully_defined(output_shape[0]):
- assert condition_shape[0] == output_shape[0], msg_tf
- ones_shape = len(output_shape) if output_is_scalar else len(output_shape) - 1
- condition_shape = np.concatenate((condition_shape, np.ones(ones_shape, dtype=np.int64)))
-
- output_shape = bi_directional_shape_broadcasting(output_shape, condition_shape)
- assert output_shape is not None, msg
-
- elif broadcast_rule == 'pdpd':
- # todo: add pdpd broadcasting rule
- # note that additionally to output_shape resulting_tensors must be broadcasted as well
- raise Error("PDPD broadcasting rule is not implemented yet")
- else: # broadcasting is not allowed
- assert compatible_shapes(a_shape, b_shape) and compatible_shapes(condition_shape, a_shape), \
- 'In node \'{}\' for Select operation when broadcasting is off all inputs must be of the same shape. ' \
- 'But instead got: cond_shape={}, then_shape={}, else_shape={}'.format(
- node_name, condition_shape, a_shape, b_shape)
- output_shape = shape_array([i if i is not dynamic_dimension else j for i, j in zip(a_shape, b_shape)])
-
- node.out_port(0).data.set_shape(output_shape)
-
- if condition_value is not None:
- if is_fully_defined(condition_value) and np.all(condition_value == condition_value.item(0)):
- # in some graphs Select condition is always True[False] and
- # one of the branches is None (which is not selected)
- # if we use np.where for such cases then dtype of output_value will be object (non numeric type)
- # and subsequent numpy operation on such tensors will fail
- output_value = resulting_tensors[not bool(condition_value.item(0))]
- if output_value is None:
- return
- if broadcast_rule == 'numpy':
- output_value = bi_directional_broadcasting(output_value, output_shape)
- elif broadcast_rule == 'pdpd':
- # todo: add pdpd broadcasting rule
- raise Error("PDPD broadcasting rule is not implemented yet")
-
- node.out_port(0).data.set_value(output_value)
- elif resulting_tensors[0] is not None and resulting_tensors[1] is not None:
- output_value = np.ma.where(condition_value, resulting_tensors[0], resulting_tensors[1])
- node.out_port(0).data.set_value(output_value)
-
- @staticmethod
- def type_infer(node: Node):
- assert node.in_port(1).get_source().get_data_type() == node.in_port(2).get_source().get_data_type(), \
- 'The data type of the second and the third inputs must be equal for the node {}'.format(node.name)
- node.out_port(0).set_data_type(node.in_port(1).get_source().get_data_type())
diff --git a/tools/mo/openvino/tools/mo/ops/shape.py b/tools/mo/openvino/tools/mo/ops/shape.py
deleted file mode 100644
index e576087d0925d8..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/shape.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class Shape(Op):
- op = 'ShapeOf'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset3',
-
- 'output_type': np.int64,
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- version = self.get_opset()
- if version == 'opset3':
- return [
- ('output_type', lambda node: np_data_type_to_destination_type(node.output_type)),
- ]
- elif version == 'opset1':
- return []
- else:
- raise Error('Unknown opset version "{}"'.format(version))
-
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 1, \
- 'ShapeOf operation should have exact one input node, but it has {}'.format(len(connected_in_ports))
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, \
- 'Input shape is undefined for ShapeOf node `{}`'.format(node.soft_get('name', node.id))
-
- assert node.has_valid('output_type'), \
- '`output_type` attribute is not set for ShapeOf node `{}`'.format(name)
- assert node.output_type in [np.int64, np.int32], \
- 'ShapeOf `output_type` attribute must be int32 or int64, `{}` found'.format(np.dtype(node.output_type).name)
-
- if node.has_and_set('stop_value_propagation'):
- node.out_port(0).data.set_shape(input_shape.shape)
- else:
- node.out_port(0).data.set_value(shape_array(mo_array(input_shape, dtype=node.output_type)))
-
- @staticmethod
- def type_infer(node):
- node.out_port(0).set_data_type(node.output_type)
diff --git a/tools/mo/openvino/tools/mo/ops/shufflechannel.py b/tools/mo/openvino/tools/mo/ops/shufflechannel.py
deleted file mode 100644
index 711780801b62ee..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/shufflechannel.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class ShuffleChannels(Op):
- op = 'ShuffleChannels'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset3',
-
- 'infer': self.infer,
-
- 'axis': 1,
- 'group': None,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def backend_attrs(self):
- return ['group', 'axis']
-
- @staticmethod
- def infer(node: Node):
- node_name = node.soft_get('name', node.id)
- assert node.soft_get('group') is not None, 'The attribute "group" must be set for node {}'.format(node_name)
- node.out_port(0).data.set_shape(node.in_port(0).data.get_shape())
diff --git a/tools/mo/openvino/tools/mo/ops/size.py b/tools/mo/openvino/tools/mo/ops/size.py
deleted file mode 100644
index 72212bef026950..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/size.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, shape_array, dynamic_dimension_value
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Size(Op):
- op = 'Size'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'output_type' in attrs, 'Size has mandatory `output_type` attribute'
-
- mandatory_props = {
- 'type': None,
- 'op': self.op,
-
- 'output_type': np.int64,
- 'infer': self.infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
- connected_in_ports = [port for port in node.in_ports().values() if not port.disconnected()]
- assert len(connected_in_ports) == 1, \
- 'Size operation should have exact one input node, but it has {}'.format(len(connected_in_ports))
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, \
- 'Input shape is undefined for Size node `{}`'.format(node.soft_get('name', node.id))
-
- assert node.has_valid('output_type'), \
- '`output_type` attribute is not set for Size node `{}`'.format(name)
- assert node.output_type in [np.int64, np.int32], \
- 'Size `output_type` attribute must be int32 or int64, `{}` found'.format(np.dtype(node.output_type).name)
-
- if is_fully_defined(input_shape):
- node.out_port(0).data.set_value(mo_array(np.prod(input_shape), dtype=node.output_type))
- else:
- node.out_port(0).data.set_value(shape_array(dynamic_dimension_value))
diff --git a/tools/mo/openvino/tools/mo/ops/slice.py b/tools/mo/openvino/tools/mo/ops/slice.py
deleted file mode 100644
index c59aba17799a82..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/slice.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import get_shape_from_slice, shape_array, \
- dynamic_dimension_value, \
- dynamic_dimension, is_dynamic_slice
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-"""
-Slicing operations have different semantic or different parameters/inputs in different frameworks. To distinguish them
-several internal operations are introduced. The internal MO Slice operation behaves same as Slice in ONNX opset >= 10.
-A number of transformations take place on the front phase to convert framework slicing:
- - AttributedSlice, TFSlice -> Slice
- - CaffeSlice -> Split
-"""
-
-
-class AttributedSlice(Op):
- """
- AttributedSlice is used in old versions of ONNX models (opset version < 10).
- Is replaced with internal Slice on the front phase.
- """
- op = 'AttributedSlice'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': None,
- }, attrs)
-
-
-class CaffeSlice(Op):
- """
- Slice in Caffe is equivalent to Split operation in OpenVINO.
- https://caffe.berkeleyvision.org/tutorial/layers/slice.html
- Is replaced with Split from opset on the front phase.
- """
- op = 'CaffeSlice'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': None,
- }, attrs)
-
-
-class TFSlice(Op):
- """
- TFSlice differs from Slice in ONNX, Caffe.
- TFSlice has 'begin' and 'size' inputs while Slice has 'start', 'end', 'step', and 'axis' inputs.
- https://www.tensorflow.org/api_docs/python/tf/slice
- Is replaced with internal Slice op on the front phase.
- """
- op = 'TFSlice'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'infer': None,
- }, attrs)
-
-
-def slice_infer(node: Node, steps_idx: int, axes_idx: int):
- input_value = node.in_port(0).data.get_value()
- input_shape = node.in_port(0).data.get_shape()
-
- starts = node.in_port(1).data.get_value()
- ends = node.in_port(2).data.get_value()
- if node.is_in_port_connected(steps_idx):
- steps = node.in_port(steps_idx).data.get_value()
- else:
- steps = np.ones(len(starts), dtype=np.int64)
-
- if node.is_in_port_connected(axes_idx):
- axes = node.in_port(axes_idx).data.get_value()
- else:
- axes = [x for x in range(len(starts))]
-
- if starts is None or ends is None or steps is None or axes is None:
- node.out_port(0).data.set_shape(shape_array([dynamic_dimension_value] * len(input_shape)))
- return
-
- slice_idx = [slice(0, in_shape, 1) for in_shape in input_shape]
- for i in range(len(axes)):
- # Ranged for output value for specified axis
- slice_idx[axes[i]] = slice(starts[i], ends[i], steps[i])
- if input_value is None or any(is_dynamic_slice(s) for s in slice_idx):
- output_shape = get_shape_from_slice(input_shape, slice_idx)
- node.out_port(0).data.set_shape(output_shape)
- else:
- node.out_port(0).data.set_value(input_value[tuple(slice_idx)])
-
-
-class Slice(Op):
- """
- Semantic of Slice is identical to Slice in ONNX opset >= 10.
- It has 'starts', 'ends', 'steps', and 'axes' inputs.
- SliceConverter replaces it with StridedSlice from opset.
- """
- op = 'Slice'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict = None):
- super().__init__(graph, {
- 'type': None,
- 'op': 'Slice',
- 'in_ports_count': 5,
- 'out_ports_count': 1,
- 'infer': self.infer
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- slice_infer(node, 4, 3)
-
-
-class OvSlice(Op):
- """
- Semantic of OvSlice is identical to Slice in Openvino opset8.
- It is introduced for usage in MO IR Reader.
- """
- op = 'OvSlice'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict = None):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 5,
- 'out_ports_count': 1,
- 'infer': self.infer
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- slice_infer(node, 3, 4)
diff --git a/tools/mo/openvino/tools/mo/ops/slice_like.py b/tools/mo/openvino/tools/mo/ops/slice_like.py
deleted file mode 100644
index efa71efe3cfe15..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/slice_like.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, is_fully_defined
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class SliceLike(Op):
- op = 'slice_like'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'axes' in attrs, 'Please set mandatory `axes` attribute for `slice_like` operation'
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- }, attrs)
-
- @staticmethod
- def infer(node):
- input_shape = node.in_port(0).data.get_shape()
- input_value = node.in_port(0).data.get_value()
- shape_like = node.in_port(1).data.get_shape()
-
- new_shape = shape_array(input_shape.copy())
- if node.axes is not None:
- node.axes = sorted([get_canonical_axis_index(input_shape, i) for i in node.axes])
- for i in node.axes:
- new_shape[i] = shape_like[i]
- else:
- assert input_shape.size == shape_like.size,\
- 'Input shape ranks are inconsistent: {} and {}'.format(input_shape.size, shape_like.size)
- node.axes = int64_array(range(shape_like.size))
- new_shape = shape_like.copy()
- node.out_port(0).data.set_shape(new_shape)
-
- if input_value is not None and is_fully_defined(new_shape):
- out_value = np.copy(input_value)
-
- slice_indexes = []
- for s in out_value.shape:
- slice_indexes.append(slice(0, s))
-
- for axis in node.axes:
- slice_indexes[axis] = slice(0, new_shape[axis])
- out_value = out_value[tuple(slice_indexes)]
- node.out_port(0).data.set_value(out_value)
diff --git a/tools/mo/openvino/tools/mo/ops/softmax.py b/tools/mo/openvino/tools/mo/ops/softmax.py
deleted file mode 100644
index 38cdc416c1bd2d..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/softmax.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-class Softmax(Op):
- op = 'SoftMax'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset8',
- 'infer': self.infer,
- 'axis': 1,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- def supported_attrs(self):
- return ['axis']
-
- @staticmethod
- def infer(node: Node):
- copy_shape_infer(node)
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
-
-class SoftmaxONNX(Op):
- op = 'SoftMaxONNX'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'infer': None,
- 'axis': 1,
- 'type': None, # this operation will be replaced with a
- # Reshape(Softmax(Flatten(x, axis), -1), x.shape) sub-graph
- 'op': __class__.op,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/space_to_batch.py b/tools/mo/openvino/tools/mo/ops/space_to_batch.py
deleted file mode 100644
index 97096419a4b0a8..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/space_to_batch.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, dynamic_dimension
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-
-
-class SpaceToBatch(Op):
- op = 'SpaceToBatch'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'version': 'opset2',
- 'infer': self.infer,
- }, attrs)
-
- @staticmethod
- def infer(node):
- """
- https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/space-to-batch
- """
- input_shape = node.in_port(0).data.get_shape()
- node_name = node.soft_get('name', node.id)
- assert len(node.in_nodes()) == 4, 'Some inputs are not connected for the operation SpaceToBatch with name {}' \
- ''.format(node_name)
-
- block_size = node.in_port(1).data.get_value()
- pads_begin = node.in_port(2).data.get_value()
- pads_end = node.in_port(3).data.get_value()
- assert block_size is not None and pads_begin is not None and pads_end is not None,\
- 'Some inputs are not defined for SpaceToBatch operation with name {}'.format(node_name)
-
- pads = pads_begin + input_shape + pads_end
-
- if is_fully_defined(block_size):
- block_elements_count = np.prod(block_size)
- else:
- block_elements_count = dynamic_dimension
- node.out_port(0).data.set_shape([input_shape[0] * block_elements_count,
- *[x for x in (pads[1:] // block_size[1:])]])
-
- # block_shape, pads_begin, pads_end should be permuted during the NHWC->NCHW layout change
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'shape')
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'shape')
- PermuteInputs().set_input_permutation(node.in_node(3), node, 'input:0', 'shape')
-
-
-class BatchToSpace(Op):
- op = 'BatchToSpace'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'kind': 'op',
- 'op': self.op,
- 'type': self.op,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- 'version': 'opset2',
- 'infer': self.infer
- }, attrs)
-
- @staticmethod
- def infer(node):
- input_shape = node.in_node(0).shape
- if input_shape is None:
- return
-
- if len(node.in_nodes()) != 4:
- return
-
- block_size = node.in_port(1).data.get_value()
- crops_begin = node.in_port(2).data.get_value()
- crops_end = node.in_port(3).data.get_value()
- if block_size is None or crops_begin is None or crops_end is None:
- return
-
- pads = block_size * input_shape
-
- sizes = pads[1:] - crops_begin[1:] - crops_end[1:]
- if is_fully_defined(block_size):
- block_elements_count = np.prod(block_size)
- else:
- block_elements_count = dynamic_dimension
- batch = input_shape[0] // block_elements_count
-
- node.out_port(0).data.set_shape([batch, *sizes])
-
- # block_shape, crops_begin, crops_end values should be permuted during the NHWC->NCHW layout change
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'shape')
- PermuteInputs().set_input_permutation(node.in_node(2), node, 'input:0', 'shape')
- PermuteInputs().set_input_permutation(node.in_node(3), node, 'input:0', 'shape')
diff --git a/tools/mo/openvino/tools/mo/ops/space_to_depth.py b/tools/mo/openvino/tools/mo/ops/space_to_depth.py
deleted file mode 100644
index 424ee3bddc47de..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/space_to_depth.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.layout import shape_for_layout, get_height_dim, get_batch_dim, get_features_dim, get_width_dim
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class SpaceToDepth(Op):
- op = 'SpaceToDepth'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'mode': 'blocks_first',
-
- 'infer': self.infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return ['mode', 'block_size']
-
- @staticmethod
- def infer(node: Node):
- in_shape = node.in_node().shape
- if in_shape.size != 4:
- raise Error('TensorFlow SpaceToDepth operation is supported for 4D \'NHWC\' input layout only. '
- 'Current input shape is \'{}\''.format(in_shape))
-
- layout = node.graph.graph['layout']
- N = in_shape[get_batch_dim(layout, 4)]
- H = in_shape[get_height_dim(layout, 4)]
- W = in_shape[get_width_dim(layout, 4)]
- C = in_shape[get_features_dim(layout, 4)]
-
- block_size = node['block_size']
- if (H is not dynamic_dimension and H % block_size) or (W is not dynamic_dimension and W % block_size):
- raise Error('Spatial dimensions of input tensor of SpaceToDepth operation have to be divisible by '
- 'SpaceToDepth \'block_size\' parameter. Input tensor shape = {}. Spatial dimensions = {},{}. '
- 'block_size = {}'.format(in_shape, H, W, block_size))
-
- out_shape = shape_for_layout(layout,
- batch=N,
- features=C * (block_size ** 2),
- height=H // block_size,
- width=W // block_size)
-
- node.out_port(0).data.set_shape(out_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/sparse_fill_empty_rows.py b/tools/mo/openvino/tools/mo/ops/sparse_fill_empty_rows.py
deleted file mode 100644
index 53a8da6a87bace..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/sparse_fill_empty_rows.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, is_fully_defined
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class SparseFillEmptyRows(Op):
- """
- The operation fills empty rows in the input 2-D sparse tensor with a default value.
- For more details see https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/sparse-fill-empty-rows
-
- 4 inputs:
- - [0, required] input indices of the sparse tensor (2D),
- - [1, required] input values of the sparse tensor (1D),
- - [2, required] shape of the sparse tensor. Value of this input is required for the Model Optimizer (1D),
- - [3, required] default value to insert at rows missing from the input sparse tensor (0D),
-
- 3 outputs:
- - [0, optional] indices of the filled sparse tensor (2D)
- - [1, optional] values of the filled sparse tensor (1D)
- - [2, optional] indicator of whether the dense row was missing in the input sparse tensor (1D)
- """
- op = 'SparseFillEmptyRows'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'version': 'experimental',
- 'infer': self.infer,
- 'in_ports_count': 4,
- 'out_ports_count': 3
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) == 4
-
- # check that shape value is defined that is needed for shape inference
- shape = node.in_node(2)
- assert shape.value is not None and shape.value.size == 2, \
- "SparseFillEmptyRows is supported only with constant shape value"
-
- shape_value = int64_array(shape.value)
-
- # check that default value is scalar
- default_value = node.in_node(3)
- assert default_value.shape is not None and len(default_value.shape) == 0, \
- "Default value for SparseFillEmptyRows must be scalar"
-
- if node.is_out_port_connected(0): # set a shape for output indices
- if is_fully_defined(shape_value):
- node.out_port(0).data.set_shape([np.prod(shape_value), 2])
- else:
- node.out_port(0).data.set_shape([dynamic_dimension_value, 2])
- if node.is_out_port_connected(1): # set a shape for output values
- if is_fully_defined(shape_value):
- node.out_port(1).data.set_shape([np.prod(shape_value)])
- else:
- node.out_port(1).data.set_shape([dynamic_dimension_value])
- if node.is_out_port_connected(2): # set a shape for empty row indicator
- node.out_port(2).data.set_shape([shape_value[0]])
diff --git a/tools/mo/openvino/tools/mo/ops/sparse_reshape.py b/tools/mo/openvino/tools/mo/ops/sparse_reshape.py
deleted file mode 100644
index 3de474e58317a8..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/sparse_reshape.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, is_fully_defined, shape_array, strict_compare_tensors, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class SparseReshape(Op):
- """
- SparseReshape operation reshapes a sparse tensor in Coordinate list (COO) format
- It recomputes indices for a new dense shape.
- """
- op = 'SparseReshape'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'infer': self.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 2,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- input_indices_shape = node.in_port(0).data.get_shape()
- input_indices_value = node.in_port(0).data.get_value()
- input_shape = node.in_port(1).data.get_value()
- new_shape = node.in_port(2).data.get_value()
- new_shape_shape = node.in_port(2).data.get_shape()
-
- assert input_shape is not None and new_shape is not None, \
- "Values for input shape and new shape must be defined"
- assert len(np.argwhere(new_shape == -1)) <= 1, \
- "Value -1 occurs in new shape value more than once"
- assert len(np.argwhere(new_shape < -1)) == 0, \
- "Only non-negative or -1 values are allowed"
-
- output_shape = np.ma.masked_array(new_shape, mask=new_shape == -1, fill_value=dynamic_dimension_value)
- assert not is_fully_defined(input_shape) or not is_fully_defined(output_shape) or \
- np.prod(input_shape) == np.prod(output_shape), \
- "Number of elements in input {} and output {} of dynamic reshape node {} mismatch" \
- "".format(input_shape, output_shape, name)
-
- # we can deduce -1 only if input_shape is fully defined and
- # there is one dynamic dimension in output_shape
- if is_fully_defined(input_shape) and np.ma.count_masked(output_shape) == 1:
- undefined_dim_size = np.prod(input_shape) // np.prod(output_shape)
-
- undefined_idx = np.where(output_shape == dynamic_dimension)[0][0]
- output_shape[undefined_idx] = undefined_dim_size
- output_shape.mask[undefined_idx] = False
-
- node.out_port(1).data.set_value(shape_array(output_shape))
- output_indices_shape = np.concatenate((input_indices_shape[0:1], new_shape_shape))
- node.out_port(0).data.set_shape(output_indices_shape)
-
- # TODO: implement constant value propagation for common case with scipy.sparse.coo_matrix.reshape
- # instead of compatible_shapes we intentionally use np.array_equal
- if strict_compare_tensors(input_shape, output_shape) and input_indices_value is not None:
- node.out_port(0).data.set_value(input_indices_value)
diff --git a/tools/mo/openvino/tools/mo/ops/sparse_segment_mean.py b/tools/mo/openvino/tools/mo/ops/sparse_segment_mean.py
deleted file mode 100644
index 798578f525f9af..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/sparse_segment_mean.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class SparseSegmentMean(Op):
- ''' The operation computes the mean along sparse segments of a tensor
- For more details, see https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/sparse-segment-mean.
-
- Three inputs:
- - [0, required] Data tensor from which rows are selected for the mean (ND),
- - [1, required] Tensor of indices of selected rows from the first input tensor along 0 dimension (1D),
- - [2, required] Tensor of segment IDs to which selected rows for the mean belong.
- Selected rows belonging to the same segment are computed with the mean. The tensor has the same size as the second input.
- Values must be sorted and can be repeated. (1D).
-
- One output:
- - [0, required] The output has the same shape as the data tensor, except for dimension 0, which has a size equal to a number of segments (ND)
- '''
- op = 'SparseSegmentMean'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'version': 'experimental',
- 'infer': __class__.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
-
- @staticmethod
- def infer(node: Node):
- # check a number of input/output edges
- assert len(node.in_nodes()) == 3
- assert len(node.out_nodes()) == 1
-
- data_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- segment_ids_shape = node.in_port(2).data.get_shape()
- data_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- segment_ids_value = node.in_port(2).data.get_value()
-
- # check input shapes
- assert data_shape is not None, \
- "Shape for input data tensor to SparseSegmentMean must be defined"
- assert indices_shape is not None and indices_shape.size == 1, \
- "SparseSegmentMean supports only 1D indices tensor"
- assert segment_ids_shape is not None and segment_ids_shape.size == 1, \
- "SparseSegmentMean supports only 1D segment IDs tensor"
- assert compatible_shapes(segment_ids_shape, indices_shape), \
- "Indices and segment IDs tensors must have compatible shapes"
-
- # computes output shape
- output_shape = data_shape
- output_shape[0] = segment_ids_shape[0]
- node.out_port(0).data.set_shape(output_shape)
-
- # infer if all input is constant
- if data_value is None or indices_value is None or segment_ids_value is None:
- return
-
- # check that values in segment_ids are sorted
- for i in range(1, len(segment_ids_value)):
- assert segment_ids_value[i-1] <= segment_ids_value[i], \
- "Values in segment IDs are not sorted"
- num_segments = int(segment_ids_value[-1]) + 1
-
- # check that indices are in a range [0, data_shape[0])
- assert np.all(indices_value >= 0) and np.all(indices_value < data_shape[0]), \
- "Some value in indices tensor is out of range"
-
- # infer
- num_adds = np.zeros(num_segments, dtype=int)
- output_value = np.zeros([num_segments] + data_shape[1:].tolist(), dtype=np.float32)
- output_shape = output_value.shape
- for i in range(len(segment_ids_value)):
- segment_id = int(segment_ids_value[i])
- indice = int(indices_value[i])
- output_value[segment_id, :] += data_value[indice, :]
- num_adds[segment_id] += 1
-
- for segment_id in range(num_segments):
- if num_adds[segment_id] != 0:
- output_value[segment_id, :] /= num_adds[segment_id]
- node.out_port(0).data.set_shape(output_shape)
- node.out_port(0).data.set_value(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/sparse_segment_sqrtn.py b/tools/mo/openvino/tools/mo/ops/sparse_segment_sqrtn.py
deleted file mode 100644
index b48df5ecda3391..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/sparse_segment_sqrtn.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class SparseSegmentSqrtN(Op):
- ''' The operation computes the sum along sparse segments of a tensor and divides it by the square root of N, where N is a number of rows in a segment.
- For more details, see https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/sparse-segment-sqrt-n.
-
- Three inputs:
- - [0, required] Data tensor from which rows are selected for the sum divided by sqrt of N (ND),
- - [1, required] Tensor of indices of selected rows from the first input tensor along 0 dimension (1D),
- - [2, required] Tensor of segment IDs to which selected rows belong.
- Selected rows belonging to the same segment are summed up. The tensor has the same size as the second input.
- Values must be sorted and can be repeated. (1D).
-
- One output:
- - [0, required] The output has the same shape as the data tensor, except for dimension 0, which has a size equal to a number of segments (ND).
- '''
- op = 'SparseSegmentSqrtN'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'version': 'experimental',
- 'infer': __class__.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
-
- @staticmethod
- def infer(node: Node):
- # check a number of input/output edges
- assert len(node.in_nodes()) == 3
- assert len(node.out_nodes()) == 1
-
- data_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- segment_ids_shape = node.in_port(2).data.get_shape()
- data_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- segment_ids_value = node.in_port(2).data.get_value()
-
- # check input shapes
- assert data_shape is not None, \
- "Shape for input data tensor to SparseSegmentSqrtN must be defined"
- assert indices_shape is not None and indices_shape.size == 1, \
- "SparseSegmentSqrtN supports only 1D indices tensor"
- assert segment_ids_shape is not None and segment_ids_shape.size == 1, \
- "SparseSegmentSqrtN supports only 1D segment IDs tensor"
- assert compatible_shapes(segment_ids_shape, indices_shape), \
- "Indices and segment IDs tensors must have compatible shapes"
-
- # computes output shape
- output_shape = data_shape
- output_shape[0] = segment_ids_shape[0]
- node.out_port(0).data.set_shape(output_shape)
-
- # infer if all input is constant
- if data_value is None or indices_value is None or segment_ids_value is None:
- return
-
- # check that values in segment_ids are sorted
- for i in range(1, len(segment_ids_value)):
- assert segment_ids_value[i-1] <= segment_ids_value[i], \
- "Values in segment IDs are not sorted"
- num_segments = int(segment_ids_value[-1]) + 1
-
- # check that indices are in a range [0, data_shape[0])
- assert np.all(indices_value >= 0) and np.all(indices_value < data_shape[0]), \
- "Some value in indices tensor is out of range"
-
- # infer
- num_adds = np.zeros(num_segments, dtype=int)
- output_value = np.zeros([num_segments] + data_shape[1:].tolist(), dtype=np.float32)
- output_shape = output_value.shape
- for i in range(len(segment_ids_value)):
- segment_id = int(segment_ids_value[i])
- indice = int(indices_value[i])
- output_value[segment_id, :] += data_value[indice, :]
- num_adds[segment_id] += 1
-
- num_adds = np.sqrt(num_adds)
- for segment_id in range(num_segments):
- if num_adds[segment_id] != 0:
- output_value[segment_id, :] /= num_adds[segment_id]
- node.out_port(0).data.set_shape(output_shape)
- node.out_port(0).data.set_value(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/sparse_segment_sum.py b/tools/mo/openvino/tools/mo/ops/sparse_segment_sum.py
deleted file mode 100644
index 34af7d8dae70a6..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/sparse_segment_sum.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import compatible_shapes
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class SparseSegmentSum(Op):
- ''' The operation computes the sum along sparse segments of a tensor.
- For more details, see https://www.tensorflow.org/api_docs/cc/class/tensorflow/ops/sparse-segment-sum.
-
- Three inputs:
- - [0, required] Data tensor from which rows are selected for the sum (ND),
- - [1, required] Tensor of indices of selected rows from the first input tensor along 0 dimension (1D),
- - [2, required] Tensor of segment IDs to which selected rows for the sum belong.
- Selected rows belonging to the same segment are summed up. The tensor has the same size as the second input.
- Values must be sorted and can be repeated. (1D).
-
- One output:
- - [0, required] The output has the same shape as the data tensor, except for dimension 0, which has a size equal to a number of segments. (ND)
- '''
- op = 'SparseSegmentSum'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'version': 'experimental',
- 'infer': __class__.infer,
- 'in_ports_count': 3,
- 'out_ports_count': 1,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return []
-
- @staticmethod
- def infer(node: Node):
- # check a number of input/output edges
- assert len(node.in_nodes()) == 3
- assert len(node.out_nodes()) == 1
-
- data_shape = node.in_port(0).data.get_shape()
- indices_shape = node.in_port(1).data.get_shape()
- segment_ids_shape = node.in_port(2).data.get_shape()
- data_value = node.in_port(0).data.get_value()
- indices_value = node.in_port(1).data.get_value()
- segment_ids_value = node.in_port(2).data.get_value()
-
- # check input shapes
- assert data_shape is not None, \
- "Shape for input data tensor to SparseSegmentSum must be defined"
- assert indices_shape is not None and indices_shape.size == 1, \
- "SparseSegmentSum supports only 1D indices tensor"
- assert segment_ids_shape is not None and segment_ids_shape.size == 1, \
- "SparseSegmentSum supports only 1D segment IDs tensor"
- assert compatible_shapes(segment_ids_shape, indices_shape), \
- "Indices and segment IDs tensors must have compatible shapes"
-
- # computes output shape
- output_shape = data_shape
- output_shape[0] = segment_ids_shape[0]
- node.out_port(0).data.set_shape(output_shape)
-
- # infer if all input is constant
- if data_value is None or indices_value is None or segment_ids_value is None:
- return
-
- # check that values in segment_ids are sorted
- for i in range(1, len(segment_ids_value)):
- assert segment_ids_value[i-1] <= segment_ids_value[i], \
- "Values in segment IDs are not sorted"
- num_segments = int(segment_ids_value[-1]) + 1
-
- # check that indices are in a range [0, data_shape[0])
- assert np.all(indices_value >= 0) and np.all(indices_value < data_shape[0]), \
- "Some value in indices tensor is out of range"
-
- # infer
- output_value = np.zeros([num_segments] + data_shape[1:].tolist(), dtype=np.float32)
- output_shape = output_value.shape
- for i in range(len(segment_ids_value)):
- segment_id = int(segment_ids_value[i])
- indice = int(indices_value[i])
- output_value[segment_id, :] += data_value[indice, :]
- node.out_port(0).data.set_shape(output_shape)
- node.out_port(0).data.set_value(output_value)
diff --git a/tools/mo/openvino/tools/mo/ops/splice.py b/tools/mo/openvino/tools/mo/ops/splice.py
deleted file mode 100644
index 9457591dec71f1..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/splice.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class Splice(Op):
- op = 'Splice'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': self.op,
- 'const_dim': 0,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': self.infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- output_shape = input_shape.copy()
- output_shape[1] = node.const_dim + (input_shape[1] - node.const_dim) * len(node.context)
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/split.py b/tools/mo/openvino/tools/mo/ops/split.py
deleted file mode 100644
index fc8b464bb8ebd8..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/split.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, dynamic_dimension, shape_delete, \
- clarify_partial_shape, shape_array, mo_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-def delete_out_port(idx, node: Node):
- for k in range(idx + 1, node.out_ports_count):
- node.out_port(k).get_connection().set_source(node.out_port(k - 1))
- node.out_ports_count -= 1
-
-
-class VariadicSplitBase(Op):
- op = None
- enabled = False
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
-
- op = node.soft_get('op', None)
- assert op is not None and op in ['VariadicSplit', 'AttributedVariadicSplit'], \
- 'Unexpected `op`={} attribute for Split-like node {}'.format(op, name)
-
- num_in_ports = 1 if op == 'AttributedVariadicSplit' else 3 if op == 'VariadicSplit' else None
- assert num_in_ports in [1, 3], \
- 'VariadicSplitBase supports AttributedVariadicSplit with 1 input and VariadicSplit with 3 inputs, ' \
- 'but it is {} for {} node {}'.format(num_in_ports, op, name)
-
- connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_inputs) == num_in_ports and all([i in connected_inputs for i in range(num_in_ports)]), \
- "{} should have {} connected input ports, but it doesn't for node: `{}`. Ports: {}" \
- "".format(op, num_in_ports, name, connected_inputs)
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None
-
- axis = node.in_port(1).data.get_value() if op == 'VariadicSplit' else node.soft_get('axis', None)
- assert axis is not None, '{} `axis` is unknown for node {}'.format(op, name)
- assert axis.ndim == 0 or (axis.ndim == 1 and axis.shape[0] == 1), \
- '{} `axis` should be scalar or tensor with shape [1], but it`s not for node {}'.format(op, name)
-
- split_lengths = node.in_port(2).data.get_value() if op == 'VariadicSplit' else node.soft_get('split_lengths',
- None)
- assert split_lengths is not None, '{} `split_lengths` is unknown for node {}'.format(op, name)
-
- undefined_elements = np.argwhere(split_lengths == -1).flatten()
- assert undefined_elements.size <= 1, \
- '{} split_lengths=`{}` is a list with output sizes, only one of which could be -1. Node: {}' \
- ''.format(op, split_lengths, name)
-
- input_elements = input_shape[axis]
- assert undefined_elements.size != 0 or input_elements is dynamic_dimension or \
- input_elements == np.sum(split_lengths), 'The sum of split_lengths=`{}` must match data.shape[axis]=' \
- '`{}`. Node: {}'.format(split_lengths, input_elements, name)
-
- assert len(split_lengths) >= len([port for i, port in node.out_ports().items() if not port.disconnected()]), \
- 'Number of split_lengths=`{}` is less than connected output ports. Node: {}'.format(split_lengths, name)
-
- # in split_lengths some value can be 0, in this case we will ignore it:
- # * remove according branch
- # * remove 0 from split_lengths
- for i in reversed(range(len(split_lengths))):
- if split_lengths[i] == 0:
- if node.out_port(i).disconnected():
- split_lengths = shape_delete(split_lengths, i)
- if op == 'VariadicSplit':
- node.in_port(2).data.set_value(split_lengths)
- else:
- node['split_lengths'] = split_lengths
- delete_out_port(i, node)
- else:
- log.warning("Zero dimension on {} branch after Split node {}".format(i, node.id))
-
- # shape propagation
- idxs, curr_pos = [], 0
- for i, piece in enumerate(split_lengths):
- assert piece >= -1, 'VariadicSplit split_lengths=`{}` should be non-negative'.format(split_lengths)
- out_shape = input_shape.copy()
-
- split_length = piece if piece > -1 else input_elements - (np.sum(split_lengths) + 1)
- out_shape[axis] = split_length
- curr_pos = curr_pos + split_length
- idxs.append(curr_pos)
-
- if not node.out_port(i).disconnected():
- node.out_port(i).data.set_shape(out_shape)
-
- # value propagation
- input_value = node.in_port(0).data.get_value()
- if input_value is not None:
- split = np.split(input_value, mo_array(idxs[:-1], dtype=split_lengths.dtype), axis)
- for i, port in node.out_ports().items():
- if not port.disconnected():
- port.data.set_value(split[i])
-
- if op == 'VariadicSplit':
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
- elif op == 'AttributedVariadicSplit':
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
- @staticmethod
- def reverse_infer(node: Node):
- if node.in_port(0).data.get_shape() is not None:
- return
-
- axis = node.in_port(1).data.get_value() if node.op == 'VariadicSplit' else node.soft_get('axis', None)
- assert axis is not None, '{} `axis` is unknown for node {}'.format(node.op, node.soft_get('name', node.id))
- split_lengths = node.in_port(2).data.get_value() if node.op == 'VariadicSplit' else node.soft_get('split_lengths', None)
- assert split_lengths is not None, '{} `split_lengths` is unknown for node {}'.format(node.op, node.soft_get('name', node.id))
-
- split_reverse_infer(node, len(split_lengths), axis)
-
-
-class VariadicSplit(VariadicSplitBase):
- op = 'VariadicSplit'
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'axis' not in attrs, \
- 'Please use `AttributedVariadicSplit` instead of `VariadicSplit` operation to create node with `axis` ' \
- 'parameter set or keep using VariadicSplit operation, but express axis as a scalar second input of ' \
- 'VariadicSplit operation'
-
- assert 'size_splits' not in attrs, \
- 'Please use `AttributedVariadicSplit` instead of `VariadicSplit` operation to create node with ' \
- '`size_splits` parameter set or keep using VariadicSplit operation, but express size_splits as a 1D ' \
- 'third input of VariadicSplit operation'
-
- assert 'out_ports_count' in attrs, 'Please set `out_ports_count` attribute for VariadicSplit while creating'
-
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
-
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
-
- 'in_ports_count': 3,
- }, attrs)
-
- def supported_attrs(self):
- return ['axis']
-
-
-class AttributedVariadicSplit(VariadicSplitBase):
- op = 'AttributedVariadicSplit'
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'axis' in attrs, 'AttributedVariadicSplit operation should have `axis` parameter set while creation'
- assert 'size_splits' in attrs, \
- 'AttributedVariadicSplit operation should have `size_splits` parameter set while creation'
-
- if 'out_ports_count' not in attrs:
- attrs['out_ports_count'] = len(attrs['size_splits'])
-
- super().__init__(graph, {
- 'op': self.op,
- 'type': 'VariadicSplit',
- 'version': 'opset1',
-
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
-
- 'in_ports_count': 1,
- }, attrs)
-
-
-class SplitBase(Op):
- op = None
- enabled = False
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
-
- op = node.soft_get('op', None)
- assert op is not None and op in ['Split', 'AttributedSplit'], \
- 'Unexpected `op`={} attribute for Split-like node {}'.format(op, name)
-
- num_in_ports = 1 if op == 'AttributedSplit' else 2 if op == 'Split' else None
- assert num_in_ports in [1, 2], \
- 'SplitBase supports AttributedSplit with 1 input and Split with 2 inputs, but it is {} for {} node {}' \
- ''.format(num_in_ports, op, name)
-
- connected_inputs = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_inputs) == num_in_ports and all([i in connected_inputs for i in range(num_in_ports)]), \
- "{} should have {} connected input ports, but it doesn't for node: `{}`. Ports: {}" \
- "".format(op, num_in_ports, name, connected_inputs)
-
- input_shape = node.in_port(0).data.get_shape()
- assert input_shape is not None, 'Input shape is unknown for node {}'.format(name)
- assert node.has_valid('num_splits'), 'Parameter `num_splits` is unknown for node {}'.format(name)
- num_splits = node.num_splits
-
- axis = node.in_port(1).data.get_value() if op == 'Split' else node.soft_get('axis', None)
- assert axis is not None, '{} `axis` is unknown for node {}'.format(op, name)
- assert axis.ndim == 0, '{} `axis` should be scalar, but it`s not for node {}'.format(op, name)
-
- assert not is_fully_defined(input_shape[axis]) or input_shape[axis] % num_splits == 0, \
- 'Input shape is not evenly divided by `num_splits` of {} node {}. `input_shape`={}, `axis`={}, ' \
- '`num_splits`={}'.format(op, name, input_shape, axis, num_splits)
-
- out_shape = input_shape.copy()
- out_shape[axis] = input_shape[axis] // num_splits
-
- input_value = node.in_port(0).data.get_value()
- output_value = np.split(input_value.copy(), axis=axis, indices_or_sections=num_splits) \
- if input_value is not None else None
-
- for idx, port in node.out_ports().items():
- if idx in node.out_nodes():
- port.data.set_shape(out_shape)
- if output_value is not None:
- port.data.set_value(output_value[idx])
-
- if op == 'Split':
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
- elif op == 'AttributedSplit':
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
- @staticmethod
- def reverse_infer(node: Node):
- if node.in_port(0).data.get_shape() is not None:
- return
-
- assert hasattr(node, 'num_splits')
- axis = node.in_port(1).data.get_value() if node.op == 'Split' else node.soft_get('axis', None)
- assert axis is not None, '{} `axis` is unknown for node {}'.format(node.op, node.soft_get('name', node.id))
- split_reverse_infer(node, node['num_splits'], axis)
-
-
-class Split(SplitBase):
- op = 'Split'
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'num_splits' in attrs, 'Split operation should have `num_splits` while creation'
- if 'out_ports_count' not in attrs:
- attrs['out_ports_count'] = attrs['num_splits']
-
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
-
- 'in_ports_count': 2,
- }, attrs)
-
- assert 'axis' not in self.attrs, \
- 'Please use `AttributedSplit` instead of `Split` operation to create node with `axis` parameter set or' \
- ' keep using Split operation, but express axis as a scalar second input of Split operation'
-
- def supported_attrs(self):
- return ['num_splits']
-
-
-class AttributedSplit(SplitBase):
- op = 'AttributedSplit'
-
- def __init__(self, graph: Graph, attrs: dict):
- assert 'num_splits' in attrs, 'AttributedSplit operation should have `num_splits` while creation'
- if 'out_ports_count' not in attrs:
- attrs['out_ports_count'] = attrs['num_splits']
-
- super().__init__(graph, {
- 'op': self.op,
- 'type': 'Split',
- 'version': 'opset1',
-
- 'axis': 1,
-
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
-
- 'in_ports_count': 1,
- }, attrs)
-
- assert 'axis' in self.attrs, 'AttributedSplit operation should have `axis` parameter set while creation'
-
- def supported_attrs(self):
- return ['num_splits', 'axis']
-
-
-def split_reverse_infer(node: Node, num_splits: int, axis: int):
- aggregated_size_along_axis = 0
- shapes = []
- for i in range(num_splits):
- shape = node.out_port(i).data.get_shape() if not node.out_port(i).disconnected() else None
- if shape is not None:
- # if out_shape_1 = [dyn, 4, 3], out_shape_2 = [7, dyn, 3], axis = 2
- # to get the original source shape [7, 4, 6]
- # dimensions along axis must be summed while
- # for other dimensions clarify_partial_shape should be called
- aggregated_size_along_axis += shape[axis]
- # in order to be able to call clarify_partial_shape axis dimension is masked into dynamic
- shape[axis] = dynamic_dimension
- shapes.append(shape_array(shape))
- else:
- # if at least one output shape is None/undefined
- # set value of shape along axis into dynamic
- # dynamic_dimension + static_value = dynamic_dimension
- aggregated_size_along_axis = dynamic_dimension
- continue
-
- if len(shapes) == 0:
- return
-
- res_partial_shape = clarify_partial_shape(shapes)
- res_partial_shape[axis] = aggregated_size_along_axis
- node.in_port(0).data.set_shape(res_partial_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/squeeze.py b/tools/mo/openvino/tools/mo/ops/squeeze.py
deleted file mode 100644
index bca11bb8cf03ee..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/squeeze.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import get_canonical_axis_index
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension, shape_delete, is_fully_defined, \
- undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class Squeeze(Op):
- op = 'Squeeze'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
- 'squeeze_dims': None,
- 'reinterp_shape': True,
- 'keep_at_least_1d': 0,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- real_squeeze_dims = int64_array([])
- input_shape = node.in_port(0).data.get_shape()
- node_name = node.soft_get('name', node.id)
- if input_shape is None:
- raise Error('Input shape is not defined for node {}'.format(node_name))
-
- output_shape = input_shape.copy()
- assert len(node.in_nodes()) == 2, 'The Squeeze node {} must have 2 inputs'.format(node_name)
-
- # TODO remove the following 'if' statement when OV start support 0D tensors
- squeeze_dims = node.in_port(1).data.get_value()
- if squeeze_dims.ndim == 0:
- squeeze_dims = squeeze_dims.reshape([1])
-
- for dim in squeeze_dims:
- if output_shape[dim] == 1 or output_shape[dim] is dynamic_dimension:
- real_squeeze_dims = np.ma.append(real_squeeze_dims, get_canonical_axis_index(output_shape, dim))
- else:
- raise Error('Trying to squeeze dimension not equal to 1 for node "{}"'.format(node_name))
-
- # if squeeze_dims empty then all 1s should be removed (tf specification of Squeeze op)
- if squeeze_dims.size == 0:
- for i in range(output_shape.size):
- if output_shape[i] == 1:
- real_squeeze_dims = np.ma.append(real_squeeze_dims, get_canonical_axis_index(output_shape, i))
-
- assert is_fully_defined(real_squeeze_dims), 'Squeeze dimension(s) is not defined for op "{}"'.format(node_name)
- output_shape = shape_delete(output_shape, real_squeeze_dims)
- node.out_port(0).data.set_shape(output_shape)
-
- # make dimensions positive to correctly translate from NHWC to NCHW layout
- if node.in_port(1).get_source().node.op == 'Const':
- node.in_port(1).data.set_value(real_squeeze_dims)
-
- if node.in_port(0).data.get_value() is not None:
- node.out_port(0).data.set_value(node.in_port(0).data.get_value().reshape(output_shape))
-
- # the squeeze_dim attribute will be converted to the second input in the end of the Middle phase
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- output_shape = node.out_port(0).data.get_shape()
- squeeze_dims = node.in_port(1).data.get_value()
- if input_shape is None and output_shape is not None and squeeze_dims is not None:
- num_squeeze_dims = 1 if int64_array(squeeze_dims).ndim == 0 else len(squeeze_dims)
- shape = undefined_shape_of_rank(len(output_shape) + num_squeeze_dims)
- node.in_port(0).data.set_shape(shape)
diff --git a/tools/mo/openvino/tools/mo/ops/stop_gradient.py b/tools/mo/openvino/tools/mo/ops/stop_gradient.py
deleted file mode 100644
index 507c420fdd2223..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/stop_gradient.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class StopGradientOp(Op):
- op = 'StopGradient'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'identity': True,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- 'infer': copy_shape_infer
- }, attrs)
-
diff --git a/tools/mo/openvino/tools/mo/ops/strided_slice.py b/tools/mo/openvino/tools/mo/ops/strided_slice.py
deleted file mode 100644
index c113df3d4fab97..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/strided_slice.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from typing import List, Tuple
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import get_shape_from_slice, dynamic_dimension, dynamic_dimension_value, \
- is_dynamic_slice
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.utils import array_to_str
-
-
-class StridedSlice(Op):
- op = 'StridedSlice'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': 'StridedSlice',
- 'version': 'opset1',
- 'in_ports_count': 4,
- 'out_ports_count': 1,
- 'infer': self.infer
- }, attrs)
- for mask_name in StridedSlice.get_mask_names():
- assert mask_name in attrs, 'Attribute {} of the StridedSlice node is not given.'.format(mask_name)
-
- @staticmethod
- def get_mask_names():
- return ['begin_mask', 'end_mask', 'new_axis_mask', 'shrink_axis_mask', 'ellipsis_mask']
-
- def backend_attrs(self):
- al = list()
-
- def convert(attr):
- return lambda node: array_to_str(node, attr)
-
- for a in StridedSlice.get_mask_names():
- al.append((a, convert(a)))
- return al
-
- @staticmethod
- def infer(node: Node):
- data_shape = node.in_port(0).data.get_shape()
- data_value = node.in_port(0).data.get_value()
- slices = StridedSlice.get_slices(node, data_shape)
-
- if data_value is not None and dynamic_dimension_value not in slices and \
- all(not is_dynamic_slice(s) for s in slices):
- node.out_port(0).data.set_value(data_value[tuple(slices)])
- else:
- node.out_port(0).data.set_shape(get_shape_from_slice(data_shape, slices))
-
- node['slices'] = slices
- node['force_precision_in_ports'] = {port: 'int64' for port in range(1, len(node.in_nodes()))}
-
- # StridedSliceNormalizer inserts nodes that change original begin, end, and strides data nodes
- # and since input permutations are stored in data nodes we end up having permutations
- # in the wrong place of the graph.
- # Therefore, PermuteInputs will be set after StridedSliceNormalizer.
-
- @staticmethod
- def get_slices(node: Node, data_shape: Tuple) -> List:
- input_rank = len(data_shape)
- slice_rank = node.in_port(1).data.get_shape()[0]
- begin = node.in_port(1).data.get_value()
- end = node.in_port(2).data.get_value()
- strides = node.in_port(3).data.get_value() if node.is_in_port_connected(3) else \
- np.ones([slice_rank], dtype=np.int64)
-
- # from now slices are without ellipsis
- slices = [[]] * slice_rank
- in_idx = 0 # index along input tensor shapes, note that input_rank not necessary is equal to slice_rank
- for i in range(slice_rank):
- if i < len(node.new_axis_mask) and node.new_axis_mask[i]:
- slices[i] = np.newaxis
- elif i < len(node.shrink_axis_mask) and node.shrink_axis_mask[i]:
- if begin is not None and begin[i] is not dynamic_dimension:
- slices[i] = int(begin[i])
- # the normalization is needed for the ConvertGroupedStridedSlice transformation
- if slices[i] < 0 and data_shape[in_idx] is not dynamic_dimension:
- slices[i] += int(data_shape[in_idx])
- else:
- slices[i] = dynamic_dimension_value
- elif i < len(node.ellipsis_mask) and node.ellipsis_mask[i]:
- slices[i] = ...
- in_idx += input_rank - slice_rank + np.count_nonzero(node.new_axis_mask)
- else:
- if begin is not None and end is not None and strides is not None:
- start, stop = begin[i], end[i]
- if i < len(node.begin_mask) and not node.begin_mask[i]: # if begin, and end are not specified take the whole range
- start = None
- if i < len(node.end_mask) and not node.end_mask[i]:
- stop = None
- slices[i] = slice(start, stop, strides[i])
- else:
- slices[i] = dynamic_dimension_value
- in_idx += 1 if i < len(node.new_axis_mask) and not node.new_axis_mask[i] else 0
- return slices
-
- @staticmethod
- def align_mask_with_slice_rank(node: Node, slice_rank: int):
- # align masks sizes with slice_rank (not confuse with extending, mask_alignment != mask_extending)
- for mask_name in StridedSlice.get_mask_names():
- num_insertations = slice_rank - len(node[mask_name])
- val = 0 if mask_name not in ['begin_mask', 'end_mask'] else 1 # extend with ones only for begin and end
- node[mask_name] = np.append(node[mask_name], [val] * num_insertations).astype(int)
-
diff --git a/tools/mo/openvino/tools/mo/ops/swapaxis.py b/tools/mo/openvino/tools/mo/ops/swapaxis.py
deleted file mode 100644
index 5a34a5613649ac..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/swapaxis.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import PermuteAttrs, Op
-
-
-class SwapAxis(Op):
- op = 'SwapAxis'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- node['order'] = list(range(node.in_node().shape.size))
- node.order[node.dim2], node.order[node.dim1] = node.order[node.dim1], node.order[node.dim2]
-
- input_shape = node.in_port(0).data.get_shape().copy()
- node.out_port(0).data.set_shape(input_shape[node.order])
- if node.in_port(0).data.get_value() is not None:
- node.out_port(0).data.set_value(np.transpose(node.in_port(0).data.get_value(), axes=node.order))
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('order', 'input:0')])
-
- @staticmethod
- def reverse_infer(node: Node):
- output_shape = node.out_port(0).data.get_shape()
- if node.in_port(0).data.get_shape() is None and output_shape is not None:
- input_shape = output_shape.data.copy()
- input_shape[node.dim2], input_shape[node.dim1] = input_shape[node.dim1], input_shape[node.dim2]
- node.in_port(0).data.set_shape(shape_array(input_shape))
diff --git a/tools/mo/openvino/tools/mo/ops/switch.py b/tools/mo/openvino/tools/mo/ops/switch.py
deleted file mode 100644
index 43c27cc534e18f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/switch.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, is_fully_defined
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Switch(Op):
- op = 'Switch'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'infer': self.infer,
- 'cf_infer': self.control_flow_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def infer(node: Node):
- assert len(node.in_nodes()) == 2
- tensor = node.in_node(0)
- port_id = node.in_node(1)
-
- output_shape = shape_array(tensor.shape)
- for out_port_id in range(2):
- if node.is_out_port_connected(out_port_id):
- node.out_port(out_port_id).data.set_shape(output_shape)
-
- if port_id.has_valid('value'):
- output_value = tensor.value
- if output_value is not None:
- for out_port_id in range(2):
- if node.is_out_port_connected(out_port_id):
- node.out_port(out_port_id).data.set_value(output_value.copy())
-
- @staticmethod
- def control_flow_infer(node: Node, is_executable: bool, mark_executability: callable):
- """
- Infers control flow through switch operation node. It marks output data nodes executability according to
- executability of current node and switch data value
- :param node: Node instance to infer control flow through
- :param is_executable: if current node is executable
- :param mark_executability: function to mark executability of node
- """
- out_data_nodes = node.out_nodes(control_flow=True)
- node_with_switch_value = node.in_node(1)
-
- switch_data_0_port_node_id = [out_data_nodes[0].id] if 0 in out_data_nodes else []
- switch_data_1_port_node_id = [out_data_nodes[1].id] if 1 in out_data_nodes else []
- assert 1 <= len(switch_data_0_port_node_id) + len(switch_data_1_port_node_id) <= 2
-
- if not node_with_switch_value.has_valid('value') or not is_fully_defined(node_with_switch_value.value):
- # Mark both ports as executable
- resulting_switch_data_node_ids = switch_data_0_port_node_id + switch_data_1_port_node_id
- for n in resulting_switch_data_node_ids:
- mark_executability(n, True)
- else:
- switch_value = node_with_switch_value.value.item(0)
- resulting_switch_data_node_ids = [switch_data_0_port_node_id, switch_data_1_port_node_id]
-
- for n in resulting_switch_data_node_ids[not switch_value]:
- mark_executability(n, False)
- for n in resulting_switch_data_node_ids[switch_value]:
- mark_executability(n, is_executable)
diff --git a/tools/mo/openvino/tools/mo/ops/tdnncomponent.py b/tools/mo/openvino/tools/mo/ops/tdnncomponent.py
deleted file mode 100644
index 415ab7f6b584bc..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/tdnncomponent.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TdnnComponent(Op):
- op = 'tdnncomponent'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/tensor_iterator.py b/tools/mo/openvino/tools/mo/ops/tensor_iterator.py
deleted file mode 100644
index 899971bb917130..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/tensor_iterator.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-from copy import copy, deepcopy
-from math import ceil
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, is_fully_defined, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node, dict_includes, Graph
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.utils.error import Error
-
-
-class TensorIterator(Op):
- """
- Loop layer that iterates over tensors and execute embedded sub-graph.
- """
-
- op = 'TensorIterator'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'input_port_map': [], # a list of dicts with such attrs as external_port_id, etc.
- 'output_port_map': [], # a list of dicts with such attrs as external_port_id, etc.
- 'back_edges': [], # a list of dicts with such attrs as from_layer, from_port, etc.
- 'body': None, # an Graph object with a body sub-graph
- 'sub_graphs': ['body'], # built-in attribute with all sub-graph
- 'infer': self.infer,
- 'type_infer': self.ti_type_infer,
- }
- super().__init__(graph, mandatory_props, attrs)
-
- @staticmethod
- def cover_body_input_data_nodes_with_parameter_ops(ti: Node):
- body = ti.body
-
- op_port_map = []
- for record in ti.input_port_map:
- operation_node = get_internal_node_by_layer_id(ti, record['internal_layer_id'])
- real_in_port = TensorIterator.special_port_to_real_port(operation_node, copy(record['internal_port_id']))
- op_port_map.append((operation_node, real_in_port))
-
- for operation_node, in_port in op_port_map:
- data_node = operation_node.in_node(in_port)
-
- attrs = deepcopy(body.get_edge_data(data_node.id, operation_node.id)[0])
- body.remove_edge(data_node.id, operation_node.id)
-
- assert data_node.has_valid('shape'), \
- 'Data node should have `shape` attribute set, but it`s not for node {}'.format(data_node.id)
- shape = data_node['shape'].copy()
- parameter_data_node = Parameter(body, {'shape': shape_array(shape)}).create_node_with_data()
-
- body.create_edge(src_node=parameter_data_node, dst_node=operation_node,
- out_port=0, in_port=in_port, edge_attrs=attrs)
- del body.get_edge_data(parameter_data_node.id, operation_node.id)[0]['out']
-
- @staticmethod
- def cover_body_constant_data_nodes_with_const_ops(ti: Node):
- body = ti.body
- for data_node in body.get_data_nodes():
- if len(data_node.in_nodes()) == 0 and len(data_node.out_nodes()) != 0:
- assert data_node.has_valid('shape'), \
- 'Data node should have `shape` attribute set, but it`s not for node {}'.format(data_node.id)
- assert data_node.has_valid('value'), \
- 'Data node should have `value` attribute set, but it`s not for node {}'.format(data_node.id)
- shape = data_node['shape'].copy()
- value = data_node['value'].copy()
- const_node = Const(body, {'shape': shape, 'value': value}).create_node()
- body.create_edge(src_node=const_node, dst_node=data_node, out_port=0, in_port=0)
-
- @staticmethod
- def special_port_to_real_port(node: Node, special_port_id: int, direction: str = 'in'):
- assert node.kind == 'op'
- assert direction in ['in', 'out']
-
- port_type = 'external_port_id' if node.has_valid('body') else 'internal_port_id'
-
- if direction == 'in':
- edges = node.in_edges()
- else:
- edges = node.out_edges()
-
- suitable_edges = {}
- for idx, attrs in edges.items():
- if port_type in attrs and attrs[port_type] == special_port_id:
- suitable_edges[idx] = attrs
- assert len(suitable_edges) == 1
- return list(suitable_edges.keys())[0]
-
- @staticmethod
- def set_internal_layer_id_for_nodes(ti: Node, nodes: list):
- max_internal_layer_id_used = max([n.soft_get('internal_layer_id', 0) for n in ti.body.get_op_nodes()])
-
- for node in nodes:
- if not node.has_valid('internal_layer_id'):
- node['internal_layer_id'] = max_internal_layer_id_used = max_internal_layer_id_used + 1
-
- @staticmethod
- def update_back_edge_map(ti, direction, old_layer_id, old_port_id, new_layer_id, new_port_id=None):
- assert direction in ['from', 'to']
- layer_attr_name = direction + '_layer'
- port_attr_name = direction + '_port'
-
- for record in ti.back_edges:
- if record[layer_attr_name] != old_layer_id:
- continue
- if (port_attr_name in record and record[port_attr_name] == old_port_id) or new_port_id is not None:
- record[layer_attr_name] = new_layer_id
- if new_port_id is None:
- del record[port_attr_name]
- else:
- record[port_attr_name] = new_port_id
-
- @staticmethod
- def validate_maps(ti):
- def check_by_attribute(port_map, appropriate_attribute, inappropriate_attribute, node_type):
- for record in port_map:
- node = get_internal_node_by_layer_id(ti, record[appropriate_attribute])
- assert node.soft_get('type') == node_type
- assert inappropriate_attribute not in record, record[inappropriate_attribute]
-
- check_by_attribute(ti.input_port_map, 'internal_layer_id', 'internal_port_id', 'Parameter')
- check_by_attribute(ti.output_port_map, 'internal_layer_id', 'internal_port_id', 'Result')
- check_by_attribute(ti.back_edges, 'from_layer', 'from_port', 'Result')
- check_by_attribute(ti.back_edges, 'to_layer', 'to_port', 'Parameter')
-
- @staticmethod
- def normalize_internal_ids(ti):
- assert ti.has_valid('input_port_map')
- assert ti.has_valid('output_port_map')
- assert ti.has_valid('back_edges')
-
- body = ti.body
-
- TensorIterator.set_internal_layer_id_for_nodes(ti, body.get_op_nodes(type='Parameter'))
- TensorIterator.set_internal_layer_id_for_nodes(ti, body.get_op_nodes(type='Result'))
-
- node_map = {copy(node.internal_layer_id): node for node in body.get_op_nodes() if
- node.has_valid('internal_layer_id')}
-
- for record in ti.input_port_map:
- assert 'internal_layer_id' in record
- assert 'internal_port_id' in record
- assert 'external_port_id' in record
-
- internal_node_id = copy(record['internal_layer_id'])
- assert internal_node_id in node_map
- internal_node = node_map[internal_node_id]
-
- in_port = TensorIterator.special_port_to_real_port(internal_node, copy(record['internal_port_id']))
- assert in_port in internal_node.in_ports() and not internal_node.in_port(in_port).disconnected()
-
- internal_input_node = internal_node.in_port(in_port).get_source().node
- assert internal_input_node.soft_get('type') == 'Parameter'
-
- TensorIterator.update_back_edge_map(ti=ti, direction='to', old_layer_id=internal_node_id,
- old_port_id=record['internal_port_id'],
- new_layer_id=internal_input_node.internal_layer_id)
- del record['internal_port_id']
- record['internal_layer_id'] = internal_input_node['internal_layer_id']
-
- for record in ti.output_port_map:
- assert 'internal_layer_id' in record
- assert 'internal_port_id' in record
- assert 'external_port_id' in record
-
- internal_node_id = copy(record['internal_layer_id'])
- assert internal_node_id in node_map
- internal_node = node_map[internal_node_id]
-
- out_port = TensorIterator.special_port_to_real_port(internal_node, copy(record['internal_port_id']), 'out')
- assert out_port in internal_node.out_ports() and not internal_node.out_port(out_port).disconnected()
-
- assert len(internal_node.out_port(out_port).get_destinations()) >= 1
-
- internal_output_node = None
- for dst in internal_node.out_port(out_port).get_destinations():
- possible_output_node = dst.node
- if possible_output_node.soft_get('type') == 'Result':
- assert internal_output_node is None, 'Several Result operations on the same output port of {}'.format(
- internal_node)
- internal_output_node = possible_output_node
- assert internal_output_node is not None
- TensorIterator.update_back_edge_map(ti=ti, direction='from', old_layer_id=internal_node_id,
- old_port_id=record['internal_port_id'],
- new_layer_id=internal_output_node.internal_layer_id)
-
- del record['internal_port_id']
- record['internal_layer_id'] = internal_output_node.internal_layer_id
-
- for record in ti.back_edges:
- assert 'from_layer' in record
- assert 'to_layer' in record
-
- internal_node_id = record['from_layer']
- assert internal_node_id in node_map
- internal_node = node_map[internal_node_id]
-
- if internal_node.soft_get('type') != 'Result':
- # this output won't get out of the body, but it is still Result and needed on non first iterations of TI
- assert 'from_port' in record
- out_port = TensorIterator.special_port_to_real_port(internal_node, record['from_port'], 'out')
- assert out_port in internal_node.out_ports() and not internal_node.out_port(out_port).disconnected()
- assert len(internal_node.out_port(out_port).get_destinations()) >= 1
-
- internal_output_node = None
- for dst in internal_node.out_port(out_port).get_destinations():
- possible_output_node = dst.node
- if possible_output_node.soft_get('type') == 'Result':
- assert internal_output_node is None, 'Several Result operations on the same output port of {}' \
- ''.format(internal_node)
- internal_output_node = possible_output_node
- assert internal_output_node is not None
- TensorIterator.update_back_edge_map(ti=ti, direction='from', old_layer_id=internal_node_id,
- old_port_id=record['from_port'],
- new_layer_id=internal_output_node.internal_layer_id)
-
- TensorIterator.validate_maps(ti)
-
- def port_map_attrs(self):
- return [
- 'external_port_id',
- 'internal_layer_id',
- 'internal_port_id',
- 'axis',
- 'start',
- 'stride',
- 'end',
- 'part_size',
- ]
-
- def substitute_ie_attrs(self, new_attrs: dict):
- """
- Replace standard list of attribute in layer/data by attributes
- delivered by backend_attrs
- """
-
- port_map_attrs = self.port_map_attrs()
-
- back_edges_attrs = [
- ('from-layer', 'from_layer'),
- ('to-layer', 'to_layer'),
- ]
-
- new_attrs.update({
- 'IE': [(
- 'layer',
- [('id', lambda node: node.node), 'name', 'type', 'version'],
- [
- ('data', self.backend_attrs() + self.default_backend_attrs, []),
- '@ports',
- ('port_map', [], [
- ('@list', lambda node: self.generate_port_map(node, node.input_port_map, 'in'),
- ('input', port_map_attrs, [])),
- ('@list', lambda node: self.generate_port_map(node, node.output_port_map, 'out'),
- ('output', port_map_attrs, [])),
- ]),
- ('back_edges', [], [
- ('@list', lambda node: self.generate_back_edges(node), ('edge', back_edges_attrs, [])),
- ]),
- ('body', [], [('@network', 'body')]),
- ])]
- })
-
- @staticmethod
- def find_port_id(node: Node, virtual_id: str, attr: str):
- attrs = node.edge({attr: virtual_id})[2]
- assert bool('in' in attrs) != bool('out' in attrs), attrs
- return attrs['in' if 'in' in attrs else 'out']
-
- @staticmethod
- def find_internal_layer_id(graph: Graph, virtual_id):
- internal_nodes = list(
- filter(lambda d: dict_includes(d[1], {'internal_layer_id': virtual_id}), graph.nodes(data=True)))
- assert len(internal_nodes) == 1, 'Nodes: {}, virtual_id: {}'.format(internal_nodes, virtual_id)
- return internal_nodes[0][0]
-
- @staticmethod
- def generate_port_map(node: Node, src_port_map, dir: str):
- """ Extract port_map attributes from node and node.body attributes.
-
- It iterates over src_port_map and substitute external_port_id, internal_port_id and
- internal_layer_id by real values queried from node ports and node.body attributes.
- """
- result_list = []
- for map_item in src_port_map:
- result = dict(map_item)
- assert result is not map_item
- result['external_port_id'] = __class__.find_port_id(node, result['external_port_id'], 'external_port_id')
- result['internal_layer_id'] = __class__.find_internal_layer_id(node.body, result['internal_layer_id'])
- result_list.append(result)
- return result_list
-
- @staticmethod
- def generate_back_edges(node: Node):
- ''' Extract back_edges attributes from node and node.body attributes. '''
- result_list = []
- for back_edge in node.back_edges:
- result = dict(back_edge)
- assert result is not back_edge
- result['from_layer'] = __class__.find_internal_layer_id(node.body, result['from_layer'])
- result['to_layer'] = __class__.find_internal_layer_id(node.body, result['to_layer'])
- result_list.append(result)
- return result_list
-
- @staticmethod
- def infer(node: Node):
- return
- raise Error('TensorIterator.infer is not implemented. '
- 'Do not insert TensorIterator before middle-end in Model Optimizer')
-
- @staticmethod
- def ti_type_infer(node):
- from openvino.tools.mo.middle.passes.infer import type_infer
- ti_graph = node.body
-
- for record in node.input_port_map:
- internal_node = get_internal_node_by_layer_id(node, record['internal_layer_id'])
- assert internal_node.soft_get('type') == 'Parameter', internal_node.soft_get('type')
-
- real_external_port_idx = TensorIterator.special_port_to_real_port(node, record['external_port_id'])
- external_data_type = node.in_port(real_external_port_idx).get_connection().get_source().get_data_type()
- internal_node.data_type = external_data_type
-
- fake_input_const_nodes = []
- # create fake const node to make type inference work correctly for all TI input nodes
- 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
- for record in node.output_port_map:
- internal_node = get_internal_node_by_layer_id(node, record['internal_layer_id'])
- assert internal_node.soft_get('type') == 'Result', internal_node.soft_get('type')
-
- internal_data_type = internal_node.in_port(0).get_data_type()
- real_external_port_idx = TensorIterator.special_port_to_real_port(node, record['external_port_id'], 'out')
- node.out_port(real_external_port_idx).set_data_type(internal_data_type)
-
- ti_graph.remove_nodes_from([node.id for node in fake_input_const_nodes])
-
- @staticmethod
- def find_iterations_count_for_output(ti_node):
- def check_field(record, field):
- return field in record and record[field] is not None
- iterations_count = dynamic_dimension_value
- # find out iterations count from inputs.
- # If no input contains 'axis' attribute then no slicing is in TI and it has only one iteration
- # If several inputs have axis attribute with different iterations count then we use maximum value.
- for in_rec in ti_node.input_port_map:
- if not check_field(in_rec, 'axis'):
- continue
- assert check_field(in_rec, 'external_port_id'), "external_port_id not set for input of {} node".format(ti_node.id)
- in_shape = ti_node.in_port(in_rec['external_port_id']).data.get_shape()
- if check_field(in_rec, 'end') and in_rec['end'] >= 0 and \
- check_field(in_rec, 'start') and in_rec['start'] >= 0:
- in_rec_end = in_rec['end']
- in_rec_start = in_rec['start']
- elif check_field(in_rec, 'end') and in_rec['end'] >= 0:
- in_rec_end = in_rec['end']
- in_rec_start = in_shape[in_rec['axis']] if not check_field(in_rec, 'start') else \
- in_shape[in_rec['axis']] + 1 + in_rec['start']
- elif check_field(in_rec, 'start') and in_rec['start'] >= 0:
- in_rec_end = in_shape[in_rec['axis']] if not check_field(in_rec, 'end') else \
- in_shape[in_rec['axis']] + 1 + in_rec['end']
- in_rec_start = in_rec['start']
- elif check_field(in_rec, 'end') and in_rec['end'] < 0 and \
- check_field(in_rec, 'start') and in_rec['start'] < 0:
- in_rec_end = in_rec['end']
- in_rec_start = in_rec['start']
- else:
- in_rec_end = ti_node.in_port(in_rec['external_port_id']).data.get_shape()[in_rec['axis']]
- in_rec_start = 0
-
- if check_field(in_rec, 'stride'):
- in_rec_stride = in_rec['stride']
- else:
- in_rec_stride = 1
-
- # in case of dynamic iterations count don't continue any calculations on this iteration
- if not is_fully_defined(in_rec_end) or not is_fully_defined(in_rec_start):
- continue
-
- if iterations_count is not dynamic_dimension_value and \
- ceil((in_rec_end - in_rec_start) / in_rec_stride) != iterations_count:
- raise Error("TensorIterator node {} have inputs with different iterations count".format(ti_node.id))
- iterations_count = ceil((in_rec_end - in_rec_start) / in_rec_stride)
-
- return iterations_count
-
-
-def get_internal_node_by_layer_id(ti, internal_layer_id):
- suitable_nodes = ti.body.get_op_nodes(internal_layer_id=internal_layer_id)
- assert len(suitable_nodes) == 1, \
- 'Expected 1 node with `internal_layer_id`={}, {} found'.format(internal_layer_id, len(suitable_nodes))
- return suitable_nodes[0]
-
-
-# Some utils for TI
-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.
- """
- mapping = {}
- ordered_nodes = graph.pseudo_topological_sort()
- for node in ordered_nodes:
- if node.kind == 'op' and node.has_valid('internal_layer_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']
- mapping = _get_internal_idxs_to_names_dict(node['body'], 'out')
- for out in outputs:
- if out['external_port_id'] == external_port:
- 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']
- mapping = _get_internal_idxs_to_names_dict(node['body'], 'in')
- for inp in inputs:
- if inp['external_port_id'] == external_port:
- return mapping[inp['internal_layer_id']]
diff --git a/tools/mo/openvino/tools/mo/ops/tile.py b/tools/mo/openvino/tools/mo/ops/tile.py
deleted file mode 100644
index 7c05da33cb49e1..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/tile.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension_value, dynamic_dimension, \
- is_fully_defined, shape_array, shape_insert
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-
-
-class Tile(Op):
- op = 'Tile'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
-
- 'infer': self.infer,
-
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) == 2 and 0 in connected_in_ports and 1 in connected_in_ports, \
- "Tile should have 2 connected input port, but it doesn't for node: `{}`. Ports: {}" \
- "".format(name, connected_in_ports)
-
- shape = node.in_port(0).data.get_shape()
- assert shape is not None, "Undefined input shape for Tile node '{}'.".format(name)
- tile_array = node.in_port(1).data.get_value()
- assert tile_array is not None, "Undefined `repeats` (1st port input value) of Tile node '{}'".format(name)
-
- # align ranks of the tile_array tensor and input shape node
- if shape.size < tile_array.size:
- shape = shape_insert(shape, 0, [1] * (tile_array.size - shape.size))
- elif shape.size > tile_array.size:
- tile_array = shape_insert(tile_array, 0, [1] * (shape.size - tile_array.size))
-
- input_value = node.in_port(0).data.get_value()
- if input_value is not None and is_fully_defined(shape) and is_fully_defined(tile_array):
- node.out_port(0).data.set_value(np.tile(input_value.reshape(shape), tile_array))
- else:
- node.out_port(0).data.set_shape(shape * tile_array)
-
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'shape')
-
-
-class AttributedTile(Op):
- op = 'AttributedTile'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': 'Tile',
- 'version': 'opset1',
-
- 'infer': self.infer,
-
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
-
- assert 'axis' in self.attrs
- assert 'tiles' in self.attrs
-
- def supported_attrs(self):
- return ['axis', 'tiles']
-
- @staticmethod
- def infer(node):
- name = node.soft_get('name', node.id)
-
- connected_in_ports = {idx: port for idx, port in node.in_ports().items() if not port.disconnected()}
- assert len(connected_in_ports) == 1 and 0 in connected_in_ports, \
- "AttributedTile should have 1 connected input port, but it doesn't for node: `{}`. Ports: {}" \
- "".format(name, connected_in_ports)
-
- shape = node.in_port(0).data.get_shape()
- assert shape is not None, "Undefined input shape for AttributedTile node '{}'.".format(name)
- axis = node.soft_get('axis', None)
- assert axis is not None
- tiles = node.soft_get('tiles', None)
- assert tiles is not None, "Undefined `tiles` attribute of Tile node '{}'".format(name)
-
- tile_array = int64_array(np.ones(shape.size))
- tile_array[node.axis] = node.tiles
-
- node.out_port(0).data.set_shape(shape * tile_array)
- if node.in_port(0).data.get_value() is not None:
- node.out_port(0).data.set_value(np.tile(node.in_port(0).data.get_value(), tile_array))
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
diff --git a/tools/mo/openvino/tools/mo/ops/timeheightconvolution.py b/tools/mo/openvino/tools/mo/ops/timeheightconvolution.py
deleted file mode 100644
index 16fdabb5e27580..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/timeheightconvolution.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class TimeHeightConvolutionComponent(Op):
- op = 'timeheightconvolutioncomponent'
- enabled = False
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': None,
- 'op': self.op,
- 'infer': None,
- 'in_ports_count': 1,
- 'out_ports_count': 1,
- }, attrs)
diff --git a/tools/mo/openvino/tools/mo/ops/topk.py b/tools/mo/openvino/tools/mo/ops/topk.py
deleted file mode 100644
index 3e62c44cd8854f..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/topk.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-from openvino.tools.mo.ops.op import Op, PermuteAttrs
-from openvino.tools.mo.utils.error import Error
-
-
-class TopK(Op):
- op = 'TopK'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset3',
- 'infer': self.infer,
- 'type_infer': self.type_infer,
-
- 'index_element_type': np.int32,
- 'axis': None,
- 'mode': 'max',
- 'sort': 'none',
- 'force_precision_in_ports': {
- 1: 'int32'},
- 'in_ports_count': 3,
- 'out_ports_count': 2,
- }, attrs)
-
- def backend_attrs(self):
- version = self.get_opset()
- if version in 'opset11':
- return ['axis', 'mode', 'sort', 'stable',
- ('index_element_type', lambda node: np_data_type_to_destination_type(node.index_element_type))]
- elif version in 'opset3':
- return ['axis', 'mode', 'sort',
- ('index_element_type', lambda node: np_data_type_to_destination_type(node.index_element_type))]
- elif version == 'opset1':
- return ['axis', 'mode', 'sort']
- else:
- raise Error('Unknown opset version "{}"'.format(version))
-
- @staticmethod
- def infer(node):
- in_ports = node.in_ports()
- connected_ports = [port for port in in_ports.values() if not port.disconnected()]
- assert len(connected_ports) == 2, 'The number of inputs to the TopK layer name "{}" must be equal to 2.' \
- ''.format(node.soft_get('name'))
-
- k = node.in_port(1).data.get_value()
- if k is None:
- k = dynamic_dimension
- assert node.has_valid('axis'), 'The "axis" attribute is not defined for node {}'.format(node.name)
-
- input_shape = node.in_port(0).data.get_shape()
- node.axis = len(input_shape) + node.axis if node.axis < 0 else node.axis
- output_shape = input_shape.copy()
- output_shape[node.axis] = k
-
- PermuteAttrs.create_permute_attrs(node, attrs=[('axis', 'input:0')])
-
- # setting shape and value if applicable
- if not node.out_port(0).disconnected():
- node.out_port(0).data.set_shape(output_shape)
- if not node.out_port(1).disconnected():
- node.out_port(1).data.set_shape(output_shape)
- if node.in_port(0).data.get_value() is not None:
- # TODO implement value propagation
- pass
-
- @staticmethod
- def type_infer(node):
- node.out_port(0).set_data_type(node.in_port(0).get_data_type())
- if node.get_opset() in ['opset3', 'opset11']:
- node.out_port(1).set_data_type(node.index_element_type)
- else:
- node.out_port(1).set_data_type(np.int32)
diff --git a/tools/mo/openvino/tools/mo/ops/topkrois_onnx.py b/tools/mo/openvino/tools/mo/ops/topkrois_onnx.py
deleted file mode 100644
index 6054182940f27e..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/topkrois_onnx.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, set_input_shapes
-from openvino.tools.mo.ops.op import Op
-
-
-class ExperimentalDetectronTopKROIs(Op):
- op = 'ExperimentalDetectronTopKROIs'
-
- def __init__(self, graph, attrs):
- mandatory_props = dict(
- type=self.op,
- op=self.op,
- version='experimental',
- reverse_infer=self.reverse_infer,
- infer=self.infer
- )
- super().__init__(graph, mandatory_props, attrs)
-
- def backend_attrs(self):
- return ['max_rois', ]
-
- @staticmethod
- def infer(node):
- node.out_port(0).data.set_shape([node.max_rois, 4])
-
- @staticmethod
- def reverse_infer(node):
- set_input_shapes(node, shape_array([dynamic_dimension_value, 4]), shape_array([dynamic_dimension_value]))
diff --git a/tools/mo/openvino/tools/mo/ops/transpose.py b/tools/mo/openvino/tools/mo/ops/transpose.py
deleted file mode 100644
index 0430f90cd12e81..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/transpose.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.op import Op
-
-
-class Transpose(Op):
- op = 'Transpose'
- enabled = True
-
- def __init__(self, graph: Graph, attrs: dict):
- super().__init__(graph, {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset1',
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- 'force_precision_in_ports': {1: 'int64'},
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- }, attrs)
-
- @staticmethod
- def infer(node: Node):
- # order parameter calculation and checks
- in_ports = node.in_ports()
- connected_ports = [port for port in in_ports.values() if not port.disconnected()]
- input_shape = node.in_port(0).data.get_shape()
-
- if node.has_and_set('reverse_order'):
- assert len(connected_ports) == 1 and 0 in in_ports, \
- 'Cannot infer `{}` due to both order and reverse_order was set'.format(node.soft_get('name'))
- order = np.arange(len(input_shape))[::-1] # Reverse order
- else:
- # we import PermuteInputs locally because it uses Transpose inside and we have recursive imports
- from openvino.tools.mo.graph.perm_inputs import PermuteInputs
- assert len(connected_ports) == 2 and 0 in in_ports and 1 in in_ports, \
- "{} node `{}` should have 2 input ports, where 0-input is a data input and 1-input represents " \
- "Transpose `order`".format(node.op, node.id)
- order = node.in_port(1).data.get_value()
- assert order is not None, 'Cannot infer `{}` because order is None'.format(node.soft_get('name'))
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'order')
-
- # setting shape and value if applicable
- if node.in_port(0).data.get_value() is not None:
- node.out_port(0).data.set_value(np.transpose(node.in_port(0).data.get_value(), axes=order))
- else:
- node.out_port(0).data.set_shape(input_shape[order])
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- output_shape = node.out_port(0).data.get_shape()
- order = node.in_port(1).data.get_value()
-
- if input_shape is None and output_shape is not None and order is not None:
- output_shape_unmasked = output_shape.data.copy()
- input_shape_unmasked = output_shape.data.copy()
- for curr_out_size, order_axis in zip(output_shape_unmasked, order):
- input_shape_unmasked[order_axis] = curr_out_size
- input_shape = shape_array(input_shape_unmasked)
- node.in_port(0).data.set_shape(input_shape)
diff --git a/tools/mo/openvino/tools/mo/ops/unique.py b/tools/mo/openvino/tools/mo/ops/unique.py
deleted file mode 100644
index 7cbed7ce2cd052..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/unique.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array, int64_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class Unique(Op):
- ''' The operation finds unique elements in 1-D tensor.
- For more details see https://www.tensorflow.org/api_docs/python/tf/unique
-
- attributes:
- - sorted, indicates whether to sort the unique elements in ascending order or
- to return in the same order as they occur in the input
- - return_inverse, indicates whether to output indices
- - return_counts, indicates whether to output the counts of each unique element
-
- 1 input:
- - [0, required] input tensor (1D)
-
- 2 outputs:
- - [0, required] tensor containing all of the unique elements of the input
- and sorted in the same order as in the input (1D)
- - [1, optional] tensor of indices for each value of the input
- in the tensor of unique elements (1D)
- - [2, optional] tensor with a number of occurrences for each unique element
- in the input (1D)
- '''
- op = 'Unique'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': None,
- 'op': __class__.op,
- 'version': 'experimental',
- 'infer': __class__.infer,
- 'in_ports_count': 1,
- 'out_ports_count': 3
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'sorted',
- 'return_inverse',
- 'return_counts',
- ]
-
- @staticmethod
- def infer(node: Node):
- # check that all required attributes are set
- assert node.has('sorted') and node.sorted in ['true', 'false'], \
- "Unique does not have valid sorted attribute"
- assert node.has('return_inverse') and node.return_inverse in ['true', 'false'], \
- "Unique does not have valid return_inverse attribute"
- assert node.has('return_counts') and node.return_counts in ['true', 'false'], \
- "Unique does not have valid return_counts attribute"
-
- # check a number of input and output nodes
- assert len(node.in_nodes()) == 1, "Unique must have one input"
- assert len(node.out_nodes()) <= 3, "Unique must have less or equal to 3 outputs"
-
- # compute maximum number of outputs if no output port is pruned
- max_num_outputs = 1
- if node.return_inverse == 'true':
- max_num_outputs += 1
- if node.return_counts == 'true':
- max_num_outputs += 1
-
- # check a number of outputs
- assert len(node.out_nodes()) <= max_num_outputs, \
- "The number of outputs in IR Unique layer must be less or equal to framework graph one"
-
- # check that the output with unique elements remains in a graph after pruning
- # since this is required output
- assert 0 in node.out_nodes(), \
- "The output with unique elements must remain in a graph"
-
- # check if outputs with indices and counts remain in a graph after pruning
- # and update attributes
- if len(node.out_nodes()) == 1:
- node.return_inverse = 'false'
- node.return_counts = 'false'
- if len(node.out_nodes()) == 2 and 1 in node.out_nodes() \
- and node.return_inverse == 'true' and node.return_counts == 'true':
- node.return_counts = 'false'
- if len(node.out_nodes()) == 2 and 2 in node.out_nodes() \
- and node.return_inverse == 'true' and node.return_counts == 'true':
- node.return_inverse = 'false'
-
- # check that input is 1-D tensor
- input_shape = node.in_node(0).shape
- assert input_shape is not None and input_shape.size == 1, \
- "Unique accepts only 1-D input"
-
- # determine a shape for each output
- for out_node_ind in node.out_nodes():
- assert (out_node_ind < max_num_outputs), "Unique has three outputs at most"
- # all outputs have the same shape equal to the input shape
- node.out_node(out_node_ind).shape = input_shape
-
- input_value = node.in_node(0).value
- if input_value is None:
- return
-
- # check that input value is 1-D
- assert len(input_value.shape) == 1, \
- "Unique accepts only 1-D input"
-
- is_sorted = (node.sorted == 'true')
- return_inverse = (node.return_inverse == 'true')
- return_counts = (node.return_counts == 'true')
-
- # infer if the input is constant
- if is_sorted:
- unique_output = np.unique(input_value, return_inverse = return_inverse,
- return_counts = return_counts, return_index = False)
- if not return_inverse and not return_counts:
- unique_output = [unique_output]
- else:
- # np.unique can only return unique elements in sorted order
- # so this case should be handled separately
- sorted_uniques, sorted_index, sorted_inverse, sorted_counts = np.unique(input_value, return_index = True,
- return_inverse = True, return_counts = True)
- # compute uniques that are in the same order as they occur in the input,
- # indices of input values in uniques, counts for each unique element
- uniques = []
- inverse = []
- counts = []
- old_ind_by_elem = dict(zip(sorted_uniques, range(len(sorted_index))))
- new_ind_by_elem = dict()
- new_ind = 0
- for ind in np.sort(sorted_index):
- uniques.append(input_value[ind])
- old_ind = old_ind_by_elem[input_value[ind]]
- counts.append(sorted_counts[old_ind])
- new_ind_by_elem[input_value[ind]] = new_ind
- new_ind += 1
- inverse = [new_ind_by_elem[input_value[ind]] for ind in range(len(input_value))]
-
- # pack unique_output
- unique_output = []
- unique_output.append(uniques)
- if return_inverse:
- unique_output.append(inverse)
- if return_counts:
- unique_output.append(counts)
-
- # write result to output nodes
- j = 0
- for out_node_ind in node.out_nodes():
- node.out_node(out_node_ind).value = mo_array(unique_output[j], dtype=float)
- node.out_node(out_node_ind).shape = int64_array(node.out_node(out_node_ind).value.shape)
- j += 1
diff --git a/tools/mo/openvino/tools/mo/ops/unsqueeze.py b/tools/mo/openvino/tools/mo/ops/unsqueeze.py
deleted file mode 100644
index 21dbcce5920dd3..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/unsqueeze.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, is_fully_defined, shape_insert, undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.graph.perm_inputs import PermuteInputs
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.error import Error
-
-
-class Unsqueeze(Op):
- """
- The operation that inserts dimensions of size one into specific positions of the input layer. The dimensions are
- specified in the second input.
- """
- op = 'Unsqueeze'
- enabled = False
-
- def __init__(self, graph, attrs: dict):
- super().__init__(graph, {
- 'op': self.op,
- 'type': self.op,
- 'version': 'opset1',
- 'unsqueeze_dims': None,
- 'reinterp_shape': True,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': self.infer,
- 'reverse_infer': self.reverse_infer,
- }, attrs)
-
- @staticmethod
- def infer(node):
- if len(node.in_nodes()) <= 1:
- raise Error('There is no input with unsqueeze dims for the node {}'.format(node.soft_get('name')))
- unsqueeze_dims = node.in_port(1).data.get_value()
- if unsqueeze_dims is None:
- raise Error('The dimensions to unsqueeze are not defined for the node {}'.format(node.soft_get('name')))
- unsqueeze_dims = int64_array(unsqueeze_dims)
-
- input_value = node.in_port(0).data.get_value()
- input_shape = node.in_port(0).data.get_shape()
-
- # TODO remove the following line when the OpenVINO plugins support 0D tensors
- if unsqueeze_dims.ndim == 0:
- unsqueeze_dims = int64_array([unsqueeze_dims.item()])
-
- # make dimensions positive to correctly translate from NHWC to NCHW layout
- unsqueeze_dims = int64_array([dim + len(node.in_port(0).data.get_shape()) + 1 if dim < 0 else dim
- for dim in unsqueeze_dims])
- if node.in_port(1).get_source().node.op == 'Const':
- node.in_port(1).data.set_value(unsqueeze_dims)
-
- output_shape = input_shape.copy()
- for dim in unsqueeze_dims:
- output_shape = shape_insert(output_shape, dim, 1)
-
- if input_value is not None and is_fully_defined(output_shape):
- node.out_port(0).data.set_value(input_value.reshape(output_shape))
- else:
- node.out_port(0).data.set_shape(output_shape)
-
- PermuteInputs().set_input_permutation(node.in_node(1), node, 'input:0', 'axis')
-
- @staticmethod
- def reverse_infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- output_shape = node.out_port(0).data.get_shape()
- unsqueeze_dims = node.in_port(1).data.get_value()
- if input_shape is None and output_shape is not None and unsqueeze_dims is not None:
- num_unsqueeze_dims = 1 if int64_array(unsqueeze_dims).ndim == 0 else len(unsqueeze_dims)
- shape = undefined_shape_of_rank(len(output_shape) - num_unsqueeze_dims)
- node.in_port(0).data.set_shape(shape)
diff --git a/tools/mo/openvino/tools/mo/ops/upsample.py b/tools/mo/openvino/tools/mo/ops/upsample.py
deleted file mode 100644
index 2afa8d4375409c..00000000000000
--- a/tools/mo/openvino/tools/mo/ops/upsample.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import math
-
-from openvino.tools.mo.front.common.layout import get_batch_dim, get_features_dim, get_height_dim, get_width_dim, shape_for_layout
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class UpsampleOp(Op):
- op = 'Upsample'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'op': self.op,
- 'in_ports_count': 2,
- 'out_ports_count': 1,
- 'infer': UpsampleOp.upsample_infer
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'height_scale',
- 'width_scale',
- 'mode',
- ]
-
- @staticmethod
- def upsample_infer(node: Node):
- node_name = node.soft_get('name', node.id)
- layout = node.graph.graph['layout']
- assert len(layout) == 4, 'Input tensor rank must be equal to 4 for node "{}"'.format(node_name)
-
- input_shape = node.in_port(0).data.get_shape()
-
- if len(node.in_nodes()) == 1:
- in_height = input_shape[get_height_dim(layout, 4)]
- in_width = input_shape[get_width_dim(layout, 4)]
- assert node.has('width_scale') is not None and node.has('height_scale') is not None
- if in_height is not dynamic_dimension:
- out_height = math.floor(in_height * node.height_scale)
- else:
- out_height = dynamic_dimension
- if in_width is not dynamic_dimension:
- out_width = math.floor(in_width * node.width_scale)
- else:
- out_width = dynamic_dimension
- node.out_port(0).data.set_shape(shape_for_layout(layout,
- batch=input_shape[get_batch_dim(layout, 4)],
- features=input_shape[get_features_dim(layout, 4)],
- height=out_height,
- width=out_width))
- else:
- scales = node.in_port(1).data.get_value()
- assert scales is not None, 'The input with scales for node "{}" is not constant'.format(node_name)
- eps = 1e-5 # This is to make rounding in case of very close number to round to closest instead of down
- # generic output shape calculation to support 5D input shape case
- output_shape = shape_array([dynamic_dimension for _ in range(len(input_shape))])
- for idx in range(len(output_shape)):
- if input_shape[idx] is not dynamic_dimension:
- output_shape[idx] = int((input_shape[idx] + eps) * scales[idx])
- else:
- output_shape[idx] = dynamic_dimension_value
- node.out_port(0).data.set_shape(output_shape)
diff --git a/tools/mo/openvino/tools/mo/pipeline/__init__.py b/tools/mo/openvino/tools/mo/pipeline/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/pipeline/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/pipeline/common.py b/tools/mo/openvino/tools/mo/pipeline/common.py
deleted file mode 100644
index cae68d40042475..00000000000000
--- a/tools/mo/openvino/tools/mo/pipeline/common.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import logging as log
-import os
-from operator import itemgetter
-
-import networkx as nx
-import numpy as np
-
-from openvino.tools.mo.back.RemoveUselessConvert import RemoveUselessConvert
-from openvino.tools.mo.back.ResultRename import ResultRename
-from openvino.tools.mo.back.ie_ir_ver_2.emitter import port_renumber, serialize_constants, generate_ie_ir, \
- serialize_mean_image
-from openvino.tools.mo.back.op_versioning import OpVersioning
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes import tensor_names, convert_data_type
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_np
-from openvino.tools.mo.middle.passes.infer import type_infer
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.utils.error import Error
-
-
-def determined_sort(outputs: list):
- op_order = []
- data_order = []
- stack = list(outputs)
- visited = set()
- while len(stack) != 0:
- node = stack.pop(0)
- node_id = node.id
- visited.add(node_id)
- has_child = False
- in_names = [n for n, d in node.get_inputs()]
- for in_node_name in in_names:
- if in_node_name not in visited:
- stack.insert(0, node)
- stack.insert(0, Node(node.graph, in_node_name))
- has_child = True
- break
- if not has_child:
- if node.kind == 'op':
- op_order.append(node_id)
- if node.kind == 'data':
- data_order.append(node_id)
- return op_order, data_order
-
-
-def get_fw_tensor_debug_info(node: Node):
- while not node.has_valid('fw_tensor_debug_info') and not node.has_valid('output_sort_order') \
- and len(node.in_nodes()):
- try:
- node = node.in_node()
- except Exception as e:
- log.warning('Was not able to determine tensor debug info for node {}'.format(node.name))
- return "dummy_node_name"
- if node.has_valid('output_sort_order'):
- return node.soft_get('output_sort_order')
- return node.soft_get('fw_tensor_debug_info')
-
-
-def get_sorted_outputs(graph: Graph):
- outputs = []
- outputs_for_sort = {}
- for node in graph.nodes():
- if len(graph.out_edges(node)) == 0:
- outputs.append(Node(graph, node))
- if len(outputs) == 1:
- return outputs
- for node in outputs:
- debug_info = get_fw_tensor_debug_info(node)
- if isinstance(debug_info, str):
- outputs_for_sort[node.id] = debug_info
- elif isinstance(debug_info, list):
- outputs_for_sort[node.id] = debug_info[0][0] + '_' + str(debug_info[0][1])
- else:
- raise Error('Unsupported type of the variable with debug information used to sort output nodes')
- if len(outputs_for_sort) != len(set(outputs_for_sort.values())):
- log.warning('There are at least two output nodes with the same key used to sort the outputs. This means that '
- 'IRs with different order of nodes may be generated between Model Optimizer runs. The dictionary '
- 'with outputs is: {}'.format(outputs_for_sort))
- return [Node(graph, key) for key, value in sorted(outputs_for_sort.items(), key=itemgetter(1))]
-
-
-def collect_sub_graphs(graph: Graph):
- """ Go over all nodes and sub_graphs in the graph recursively; returns all found sub-graphs. """
- result = []
- for node in graph.nodes():
- node = Node(graph, node)
- if node.has_valid('sub_graphs'):
- for sub_graph in node.sub_graphs:
- result.append(node[sub_graph])
- result += collect_sub_graphs(node[sub_graph])
- return result
-
-
-def relabel_nodes_inplace_safe(graph: Graph, new_labels: dict):
- """ Safely relabels graph in-place without graph copy.
-
- Safety in this place means that it is guaranteed that
- there won't be collisions during relabeling process.
- """
- # Relabel nodes in two stages
- intermediate_map = {node: graph.unique_id('__relabel__{}__'.format(str(i))) for i, node in enumerate(graph.nodes())}
- final_map = {dst: new_labels[src] for src, dst in intermediate_map.items()}
- assert len(set(intermediate_map.keys()).intersection(set(intermediate_map.values()))) == 0
- assert len(set(final_map.keys()).intersection(set(final_map.values()))) == 0
- nx.relabel_nodes(graph, intermediate_map, copy=False)
- nx.relabel_nodes(graph, final_map, copy=False)
-
-
-def convert_const_node_value_type(const_node: Node, np_data_type):
- assert const_node.type == 'Const'
- log.warning('Converting type of Const node "{}" to "{}"'.format(const_node.name, np_data_type))
- const_node.value = const_node.value.astype(np_data_type)
- const_node.data_type = np_data_type
- const_node.infer(const_node)
- const_node.type_infer(const_node)
-
- # if the Const node has an input data node then need to update it also
- if len(const_node.in_nodes()) == 1:
- input_data = const_node.in_node(0)
- assert input_data.kind == 'data'
- input_data.value = input_data.value.astype(const_node.data_type)
- input_data.data_type = const_node.data_type
-
-
-def convert_inputs_of_specific_ops(graph: Graph):
- type_port = {'Broadcast': {1: 'int64', 2: 'int64'},
- 'ConvolutionBackpropData': {2: 'int64'},
- 'Deconvolution': {2: 'int64'},
- 'Gather': {2: 'int64'},
- 'GroupConvolutionBackpropData': {2: 'int64'},
- 'Interpolate': {1: 'int64'},
- 'LRN': {1: 'int64'},
- 'NonMaxSuppression': {2: 'int64'},
- 'NormalizeL2': {1: 'int64'},
- 'OneHot': {1: 'int64'},
- 'Pad': {1: 'int64', 2: 'int64'},
- 'PriorBox': {0: 'int64', 1: 'int64'},
- 'PriorBoxClustered': {0: 'int64', 1: 'int64'},
- 'ReduceLogicalAnd': {1: 'int64'},
- 'ReduceLogicalOr': {1: 'int64'},
- 'ReduceMax': {1: 'int64'},
- 'ReduceMean': {1: 'int64'},
- 'ReduceMin': {1: 'int64'},
- 'ReduceProd': {1: 'int64'},
- 'ReduceSum': {1: 'int64'},
- 'Reshape': {1: 'int64'},
- 'Squeeze': {1: 'int64'},
- 'StridedSlice': {1: 'int64', 2: 'int64', 3: 'int64'},
- 'Split': {1: 'int64'},
- 'Tile': {1: 'int64'},
- 'Transpose': {1: 'int64'},
- 'Unsqueeze': {1: 'int64'},
- 'VariadicSplit': {1: 'int64', 2: 'int64'},
- }
-
- for node in graph.get_op_nodes():
- if node.soft_get('version') != "opset11":
- # opset11 cannot be produced by legacy MO frontends, it can only be read by MO IR Reader
- if node.soft_get('type') in type_port:
- ports_to_update = type_port[node.soft_get('type')]
- for port_id, precision in ports_to_update.items():
- if port_id in node.in_ports() and not node.in_port(port_id).disconnected():
- log.debug('Converting value for the input port "{}" of op "{}" to "{}".'
- ''.format(port_id, node.soft_get('name', node.id), precision))
- in_port = node.in_port(port_id)
- np_type = data_type_str_to_np(precision)
- in_node = node.in_port(port_id).get_source().node
- in_type = in_node.out_port(0).get_data_type()
-
- if in_node.type == 'Const':
- if np.issubdtype(in_type, np.integer) and np.issubdtype(np_type, np.integer):
- # do not convert Constant value if both source and destination types are of integer types
- # otherwise, it affects compatibility of MO IR Engine and TF FE
- # TF FE intents to use original model type for layers if it is possible
- continue
- convert_const_node_value_type(in_node, np_type)
- else:
- allowed_int_types = [np.int32, np.int64, np.uint32, np.uint64]
- if in_type in allowed_int_types and np_type in allowed_int_types:
- # do not convert if both source and destination types are within the set of
- # int32/int64/uint32/uint64. It prevents from getting different IRs from the original
- # cpp serializer and from the legacy serialized when restored with ir_reader_utils
- continue
- in_port.get_connection().insert_node(Cast(graph, {'dst_type': np_type}).create_node())
-
-
-def set_default_tensor_names_for_parameters_results(graph: Graph):
- for node in graph.get_op_nodes():
- if node.soft_get('type') == 'Result' and node.is_in_port_connected(0):
- port = node.in_port(0).get_connection().get_source()
- elif node.soft_get('type') == 'Parameter' and node.is_out_port_connected(0):
- port = node.out_port(0)
- else:
- continue
- if node.has_and_set('keep_output_port'):
- continue
-
- tensors = port.get_tensor_names()
- if tensors is not None and isinstance(tensors, list) and len(tensors) > 0:
- continue
- new_tensor_name = port.get_default_tensor_name()
- op_name = port.node.soft_get('name')
- port.add_tensor_names([new_tensor_name, op_name])
-
-
-def prepare_emit_ir(graph: Graph, data_type: str, output_dir: str, output_model_name: str,
- mean_data: [list, None] = None, input_names: list = None, meta_info: dict = None,
- use_temporary_path=False, convert_types=False, rename_results=True):
- if input_names is None:
- input_names = []
- if meta_info is None:
- meta_info = {}
- graph.strict_mode = False
-
- if convert_types:
- # convert Parameter data types
- convert_data_type.convert_parameters_data_type(graph, data_type)
- # convert blobs (usually weights and biases)
- for sub_graph in [graph] + collect_sub_graphs(graph):
- 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
- for_graph_and_each_sub_graph_recursively(graph, convert_inputs_of_specific_ops)
-
- 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
- type_infer(graph)
-
- for_graph_and_each_sub_graph_recursively(graph, RemoveUselessConvert().find_and_replace_pattern)
-
- if rename_results:
- ResultRename().find_and_replace_pattern(graph)
- set_default_tensor_names_for_parameters_results(graph)
-
- for sub_graph in [graph] + collect_sub_graphs(graph):
- op_order, data_order = determined_sort(get_sorted_outputs(sub_graph))
- mapping = {v: u for u, v in enumerate(op_order)}
- mapping.update({v: u for u, v in enumerate(data_order, start=len(sub_graph))})
- relabel_nodes_inplace_safe(sub_graph, mapping)
- port_renumber(sub_graph)
-
- tensor_names.propagate_op_name_to_tensor(graph)
-
- ir_path_suffix = "_tmp" if use_temporary_path else ""
-
- bin_file = os.path.join(output_dir, '{}{}.bin'.format(output_model_name, ir_path_suffix))
- serialize_constants(graph, bin_file)
-
- mean_offset = None
- mean_size = None
- if mean_data:
- mean_offset, mean_size = serialize_mean_image(bin_file, mean_data=mean_data)
-
- generate_ie_ir(graph=graph,
- file_name=os.path.join(output_dir, '{}{}.xml'.format(output_model_name, ir_path_suffix)),
- input_names=input_names,
- mean_offset=mean_offset,
- mean_size=mean_size,
- meta_info=meta_info)
- tensor_names.output_tensor_names_map(graph, os.path.join(output_dir,
- '{}{}.mapping'.format(output_model_name, ir_path_suffix)))
-
-
-def get_ir_version(argv: argparse.Namespace):
- """
- Determine IR version based on command line arguments and the default version.
- :param argv: the parsed command line arguments
- :return: the IR version
- """
- return 11
diff --git a/tools/mo/openvino/tools/mo/pipeline/unified.py b/tools/mo/openvino/tools/mo/pipeline/unified.py
deleted file mode 100644
index 619e579ea527ce..00000000000000
--- a/tools/mo/openvino/tools/mo/pipeline/unified.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.pipeline.common import get_ir_version
-from openvino.tools.mo.utils import class_registration
-
-
-def unified_pipeline(argv: argparse.Namespace):
- graph = Graph(cmd_params=argv, name=argv.model_name, ir_version=get_ir_version(argv))
- class_registration.apply_replacements(graph, [
- class_registration.ClassType.LOADER,
- class_registration.ClassType.FRONT_REPLACER,
- class_registration.ClassType.MIDDLE_REPLACER,
- class_registration.ClassType.BACK_REPLACER
- ])
- return graph
diff --git a/tools/mo/openvino/tools/mo/subprocess_main.py b/tools/mo/openvino/tools/mo/subprocess_main.py
deleted file mode 100644
index 0b8eb5069e000f..00000000000000
--- a/tools/mo/openvino/tools/mo/subprocess_main.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import os
-import subprocess # nosec
-import sys
-
-
-def log_ie_not_found():
- log.error("Could not find the OpenVINO or Python API.\n"
- "Consider building the OpenVINO and Python APIs"
- " from sources or try to install OpenVINO (TM) Toolkit using pip \npip install openvino")
-
-
-def log_mo_root_dir_not_found():
- log.error("Could not find the ModelOptimizer root module directory.\n"
- "Consider setting PYTHONPATH to the openvino tools folder (usually openvino/tools/mo)")
-
-
-def setup_env():
- mo_root_path = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)
-
- # Check that MO root directory already set to the PYTHONPATH
- def is_mo_imported():
- try:
- status = subprocess.run([sys.executable, os.path.join(mo_root_path, 'openvino/tools/mo/utils/check_mo_import.py')],
- env=os.environ)
- return status.returncode == 0
- except:
- return False
-
- if not is_mo_imported():
- # If no, we try to set it manually based on relative path
- python_path_key = 'PYTHONPATH'
- if python_path_key not in os.environ:
- os.environ[python_path_key] = mo_root_path
- else:
- os.environ[python_path_key] = os.pathsep.join([os.environ[python_path_key], mo_root_path])
-
- sys.path.append(mo_root_path)
-
- if not is_mo_imported():
- log_mo_root_dir_not_found()
- sys.exit(1)
-
- ie_found = True
- try:
- from openvino.tools.mo.utils.find_ie_version import find_ie_version # pylint: disable=no-name-in-module
- ie_found = find_ie_version(silent=True)
- except Exception as e:
- log.error(e)
- ie_found = False
-
- if not ie_found:
- log_ie_not_found()
- sys.exit(1)
-
- return True
-
-
-def subprocess_main(framework=None):
- """
- Please keep this file compatible with python2 in order to check user python version.
-
- This function checks that OpenVINO Python API available and working as expected
- and then in sub-process it executes main_.py files. Due to some OSs specifics we can't
- just add paths to Python modules and libraries into current env. So to make OpenVINO
- Python API to be available inside MO we need to use subprocess with new env.
- """
- setup_env()
-
- path_to_main = os.path.join(os.path.realpath(os.path.dirname(__file__)),
- 'main_{}.py'.format(framework) if framework else 'main.py')
-
- # python2 compatible code. Do not remove.
- args = [sys.executable, path_to_main]
-
- for arg in sys.argv[1:]:
- args.append(arg)
- status = subprocess.run(args, env=os.environ)
- sys.exit(status.returncode)
diff --git a/tools/mo/openvino/tools/mo/utils/__init__.py b/tools/mo/openvino/tools/mo/utils/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/utils/broadcasting.py b/tools/mo/openvino/tools/mo/utils/broadcasting.py
deleted file mode 100644
index b93fea86f66a75..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/broadcasting.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, shape_array, shape_insert, is_fully_defined, \
- dynamic_dimension_value
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-
-
-def make_equal_rank(shape_1: np.ndarray, shape_2: np.ndarray):
- """
- Prepend shape with smaller length with 1. Return updates shapes
- :param shape_1: first shape
- :param shape_2: second shape
- :return: tuple with updated shapes
- """
- while len(shape_1) < len(shape_2):
- shape_1 = shape_insert(shape_1, 0, 1)
-
- while len(shape_2) < len(shape_1):
- shape_2 = shape_insert(shape_2, 0, 1)
-
- return shape_1, shape_2
-
-
-def uni_directional_shape_broadcasting(input_shape: np.array, target_shape: np.array):
- """
- Uni-directional broadcasting of two shapes following the numpy semantic
- :param input_shape: input shape to broadcast
- :param target_shape: target shape
- :return: broadcasted shape or None if broadcasting cannot be performed
- """
- input = input_shape.copy()
-
- # in one-directional broadcasting the target shape rank can be higher or equal than input shape
- if len(input_shape) > len(target_shape):
- log.debug('The shape "{}" cannot be broadcasted to "{}"'.format(input_shape, target_shape))
- return None
-
- # prepend input shape with 1s
- input, target_shape = make_equal_rank(input, target_shape)
- result_shape = []
- for left, right in zip(input, target_shape):
- if left != right and left != 1 and right is not dynamic_dimension:
- log.debug('The shape "{}" cannot be broadcasted to "{}"'.format(input_shape, target_shape))
- return None
- if right is dynamic_dimension and left is not dynamic_dimension and left != 1:
- result_shape.append(left)
- else:
- result_shape.append(right)
- return shape_array(result_shape)
-
-
-def bi_directional_shape_broadcasting(input_shape_1: np.array, input_shape_2: np.array):
- """
- Bi-directional broadcasting of two shapes following numpy semantic
- :param input_shape_1: first shape to broadcast
- :param input_shape_2: second shape to broadcast
- :return: broadcasted shape or None if broadcasting cannot be performed
- """
- shape_1 = input_shape_1.copy()
- shape_2 = input_shape_2.copy()
- shape_1, shape_2 = make_equal_rank(shape_1, shape_2)
- result = list()
-
- for left, right in zip(shape_1, shape_2):
- if left != right and left != 1 and right != 1 and left is not dynamic_dimension and \
- right is not dynamic_dimension:
- log.debug('The shape "{}" cannot be broadcasted to "{}"'.format(input_shape_1, input_shape_2))
- return None
- if left is not dynamic_dimension and right is not dynamic_dimension:
- result.append(max(left, right))
- elif left is not dynamic_dimension and left != 1:
- result.append(left)
- elif right is not dynamic_dimension and right != 1:
- result.append(right)
- else:
- result.append(dynamic_dimension_value)
-
- return shape_array(result)
-
-
-def explicit_shape_broadcasting(input_shape: np.array, target_shape: np.array, axes_mapping: np.array) -> [np.array, np.array]:
- """
- Explicit shape broadcasting of input tensor. Function only asserts that values are correct and normalizes axes.
- Resulting shape is equal to target_shape.
- :param input_shape: input value to broadcast
- :param target_shape: target shape
- :param axes_mapping: a list of axis indices, each index maps an axis from the input_value to axis in the output
- :return: broadcasted shape and normalized axes
- """
- assert np.all(np.diff(axes_mapping) >= 0), "axes_mapping is not sorted"
- assert len(axes_mapping) == len(input_shape), "size of axes_mapping does not match to rank of input"
- axes_mapping = mo_array(list(map(lambda axis: axis + len(target_shape) if axis < 0 else axis, axes_mapping)))
-
- res = target_shape.copy()
- for i, axis in enumerate(axes_mapping):
- assert 0 <= axis < len(res), "axis value from axes_mapping exceeds rank of target_shape"
- assert res[axis] == input_shape[i], "specified mapping axis in target_shape differs from axis in input_shape"
- return res, axes_mapping
-
-
-def uni_directional_broadcasting(input_value: np.array, target_shape: np.array):
- """
- Uni-directional broadcasting of input tensor to target shape following the numpy semantic
- :param input_value: input value to broadcast
- :param target_shape: target shape
- :return: broadcasted value
- """
- assert is_fully_defined(target_shape)
- assert uni_directional_shape_broadcasting(shape_array(input_value.shape), target_shape) is not None, \
- 'The tensor of shape "{}" cannot be uni-directionally broadcasted to shape "{}"'.format(input_value.shape,
- target_shape)
- return input_value * np.ones(target_shape).astype(input_value.dtype)
-
-
-def bi_directional_broadcasting(input_value: np.array, second_shape: np.array):
- """
- Bi-directional broadcasting of input tensor to target shape following the numpy semantic
- :param input_value: input value to broadcast
- :param second_shape: second tensor shape
- :return: broadcasted value
- """
- output_shape = bi_directional_shape_broadcasting(shape_array(input_value.shape), second_shape)
- assert output_shape is not None, 'The tensor of shape "{}" cannot be bi-directionally broadcasted to shape "{}"' \
- ''.format(input_value.shape, second_shape)
- assert is_fully_defined(output_shape)
- return input_value * np.ones(second_shape).astype(input_value.dtype)
-
-
-def explicit_broadcasting(input_value: np.array, target_shape: np.array, axes_mapping: np.array) -> np.array:
- """
- Explicit broadcasting of input tensor. Resulting shape is equal to target_shape except for axes specified in axes_mapping
- :param input_value: input value to broadcast
- :param target_shape: target shape
- :param axes_mapping: a list of axis indices, each index maps an axis from the input_value to axis in the output
- :return: broadcasted value
- """
- res_shape, normalized_axes_mapping = explicit_shape_broadcasting(input_value.shape, target_shape, axes_mapping)
- #TODO: Function 'expand_dims' should be replaced with 'numpy.expand_dims' if numpy version will be >=18.x in requirements.
- expand_dim_axis = set(np.arange(len(target_shape))) - set(normalized_axes_mapping)
- input_expanded = input_value.copy()
-
- for axis in sorted(list(expand_dim_axis)):
- input_expanded = np.expand_dims(input_expanded, axis)
- return np.broadcast_to(input_expanded, res_shape)
diff --git a/tools/mo/openvino/tools/mo/utils/check_ie_bindings.py b/tools/mo/openvino/tools/mo/utils/check_ie_bindings.py
deleted file mode 100644
index ae10b3e617def7..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/check_ie_bindings.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import platform
-import sys
-
-try:
- import openvino.tools.mo
- execution_type = "mo"
-except ModuleNotFoundError:
- mo_root_path = os.path.normpath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
- sys.path.insert(0, mo_root_path)
- execution_type = "install_prerequisites.{}".format("bat" if platform.system() == "Windows" else "sh")
-
-import openvino.tools.mo.utils.version as v
-try:
- import openvino_telemetry as tm # pylint: disable=import-error,no-name-in-module
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-from openvino.tools.mo.utils.error import classify_error_type
-from openvino.tools.mo.utils.telemetry_utils import init_mo_telemetry
-
-
-def send_telemetry(mo_version: str, message: str, event_type: str):
- t = init_mo_telemetry('Version Checker')
- # do not trigger new session if we are executing from the check from within the MO because it is actually not model
- # conversion run which we want to send
- if execution_type != 'mo':
- t.start_session(execution_type)
- t.send_event(execution_type, event_type, message)
- if execution_type != "mo":
- t.end_session(execution_type)
- t.force_shutdown(1.0)
-
-
-def import_core_modules(silent: bool, path_to_module: str):
- """
- This function checks that OpenVINO Python API is available
- and necessary python modules exists. So the next list of imports
- must contain all IE/NG Python API imports that are used inside MO.
-
- :param silent: enables or disables logs printing to stdout
- :param path_to_module: path where python API modules were found
- :return: True if all imports were successful and False otherwise
- """
- try:
- from openvino._offline_transformations import apply_moc_transformations, apply_moc_legacy_transformations,\
- apply_low_latency_transformation, apply_fused_names_cleanup # pylint: disable=import-error,no-name-in-module
- from openvino._offline_transformations import apply_make_stateful_transformation # pylint: disable=import-error,no-name-in-module
-
- from openvino.runtime import Model, serialize, get_version # pylint: disable=import-error,no-name-in-module
- from openvino.runtime.op import Parameter # pylint: disable=import-error,no-name-in-module
- from openvino.runtime import PartialShape, Dimension # pylint: disable=import-error,no-name-in-module
- from openvino.frontend import FrontEndManager, FrontEnd # pylint: disable=no-name-in-module,import-error
-
- import openvino.frontend # pylint: disable=import-error,no-name-in-module
-
- if silent:
- return True
-
- ie_version = str(get_version())
- mo_version = str(v.get_version()) # pylint: disable=no-member,no-name-in-module
-
- print("{}: \t{}".format("OpenVINO runtime found in", os.path.dirname(openvino.__file__)))
- print("{}: \t{}".format("OpenVINO runtime version", ie_version))
- print("{}: \t{}".format("Model Optimizer version", mo_version))
-
- versions_mismatch = False
-
- mo_hash = v.extract_hash_from_version(mo_version)
- ie_hash = v.extract_hash_from_version(ie_version)
-
- if mo_hash is not None and ie_hash is not None:
- min_length = min(len(mo_hash), len(ie_hash))
- mo_hash = mo_hash[:min_length]
- ie_hash = ie_hash[:min_length]
-
- if mo_hash != ie_hash or mo_hash is None or ie_hash is None:
- versions_mismatch = True
- extracted_mo_release_version = v.extract_release_version(mo_version)
- mo_is_custom = extracted_mo_release_version == (None, None)
-
- print("[ WARNING ] Model Optimizer and OpenVINO runtime versions do not match.")
- print("[ WARNING ] Consider building the OpenVINO Python API from sources or reinstall OpenVINO "
- "(TM) toolkit using", end=" ")
- if mo_is_custom:
- print("\"pip install openvino\" (may be incompatible with the current Model Optimizer version)")
- else:
- print("\"pip install openvino=={}.{}\"".format(*extracted_mo_release_version))
-
- simplified_mo_version = v.get_simplified_mo_version()
- message = str(dict({
- "platform": platform.system(),
- "mo_version": simplified_mo_version,
- "ie_version": v.get_simplified_ie_version(version=ie_version),
- "versions_mismatch": versions_mismatch,
- }))
- send_telemetry(simplified_mo_version, message, 'ie_version_check')
-
- return True
- except Exception as e:
- # Do not print a warning if module wasn't found or silent mode is on
- if "No module named 'openvino" not in str(e):
- print("[ WARNING ] Failed to import OpenVINO Python API in: {}".format(path_to_module))
- print("[ WARNING ] {}".format(e))
-
- # Send telemetry message about warning
- simplified_mo_version = v.get_simplified_mo_version()
- message = str(dict({
- "platform": platform.system(),
- "mo_version": simplified_mo_version,
- "ie_version": v.get_simplified_ie_version(env=os.environ),
- "python_version": sys.version,
- "error_type": classify_error_type(e),
- }))
- send_telemetry(simplified_mo_version, message, 'ie_import_failed')
-
- return False
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser()
- parser.add_argument("--silent", action="store_true")
- parser.add_argument("--path_to_module")
- args = parser.parse_args()
-
- if not import_core_modules(args.silent, args.path_to_module):
- exit(1)
diff --git a/tools/mo/openvino/tools/mo/utils/check_mo_import.py b/tools/mo/openvino/tools/mo/utils/check_mo_import.py
deleted file mode 100644
index beba4447baa214..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/check_mo_import.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-try:
- import openvino.tools.mo
-except:
- exit(1)
diff --git a/tools/mo/openvino/tools/mo/utils/class_registration.py b/tools/mo/openvino/tools/mo/utils/class_registration.py
deleted file mode 100644
index a232a953742af0..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/class_registration.py
+++ /dev/null
@@ -1,343 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import os
-from enum import Enum
-
-import networkx as nx
-
-from openvino.tools.mo.front.common.custom_replacement_registry import CustomReplacementRegistry
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.eliminate import shape_inference
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.utils.error import Error, InternalError, FrameworkError
-from openvino.tools.mo.utils.logger import progress_bar # pylint: disable=no-name-in-module,import-error
-
-_registered_classes_dict = {}
-
-
-def _check_unique_ids():
- """
- Check that idxs is unique for all registered replacements.
- """
- unique_idxs = set()
- for class_type, classes_set in _registered_classes_dict.items():
- for cls in classes_set:
- replacers = [c for c in cls.registered_cls if not hasattr(c, 'op')] + \
- [c for op, c in cls.registered_ops.items() if c]
- for replacer_cls in replacers:
- if hasattr(replacer_cls, 'id'):
- id_cls = getattr(replacer_cls, 'id')
-
- if id_cls in unique_idxs:
- raise Error('Found replacer {} with not unique id!'.format(replacer_cls))
- unique_idxs.add(id_cls)
- log.debug("All replacers has unique idxs.")
-
-
-def get_enabled_and_disabled_transforms():
- """
- :return: tuple of lists with force enabled and disabled id of transformations.
- """
- disabled_transforms = os.environ['MO_DISABLED_TRANSFORMS'] if 'MO_DISABLED_TRANSFORMS' in os.environ else ''
- enabled_transforms = os.environ['MO_ENABLED_TRANSFORMS'] if 'MO_ENABLED_TRANSFORMS' in os.environ else ''
-
- assert isinstance(enabled_transforms, str)
- assert isinstance(disabled_transforms, str)
-
- disabled_transforms = disabled_transforms.split(',')
- enabled_transforms = enabled_transforms.split(',')
-
- return enabled_transforms, disabled_transforms
-
-
-class ClassType(Enum):
- EXTRACTOR = 0
- OP = 1
- FRONT_REPLACER = 2
- MIDDLE_REPLACER = 3
- BACK_REPLACER = 4
- IR_READER_EXTENDER = 5
- LOADER = 6
-
-
-def _update(cls, registered_list: list, registered_dict: dict, key: str, enabled_transforms: list,
- disabled_transforms: list, exclude_modules: set):
- new_keys = {} # maps a custom name to class
- new_keys_lower = {} # translates lowered custom name to its original form
- # print('Registering new subclasses for', cls)
-
- for c in cls.__subclasses__():
- if need_exclude_class(c, exclude_modules):
- continue
- # Force enabling operations
- if hasattr(c, 'id') and c.id in enabled_transforms or \
- ".".join([c.__module__, c.__name__]) in enabled_transforms:
- setattr(c, 'enabled', True)
-
- # Force disabling operations
- if hasattr(c, 'id') and c.id in disabled_transforms or \
- ".".join([c.__module__, c.__name__]) in disabled_transforms:
- setattr(c, 'enabled', False)
-
- if c not in registered_list:
- if hasattr(cls, 'excluded_classes') and c in cls.excluded_classes:
- continue
- registered_list.append(c)
- log.info('New subclass: {}'.format(c))
- if hasattr(c, key) and getattr(c, key) is not None:
- k = getattr(c, key)
- if k.lower() in new_keys_lower:
- # log.warning('Attempt to register of custom name {} for the second time as class {}. '
- # 'Note that custom names are case-insensitive. ' + refer_to_faq_msg(55), k, c)
- continue
- else:
- new_keys_lower[k.lower()] = k
- new_keys[k] = c
- log.info('Registered a new subclass with key: {}'.format(k))
- else:
- log.warning('Skipped {} registration because it was already registered or it was disabled. '.format(c))
- registered_dict.update(new_keys)
-
-
-def update_registration(classes: list, enabled_transforms: list, disabled_transforms: list, exclude_modules: set):
- for cls in classes:
- _update(cls, cls.registered_cls, cls.registered_ops, 'op', enabled_transforms, disabled_transforms, exclude_modules)
- _registered_classes_dict.setdefault(cls.class_type(), set()).add(cls)
-
-
-class DependencyGraph(Graph):
- def __init__(self, data=None, **attr):
- super().__init__(data, **attr)
-
- def dump_graph_for_graphviz(self, node_attrs: list = [], edge_attrs: list = [], nodes_to_dump: list = None,
- save_to_svg=False, highlight_nodes: list = None):
- log.debug("---- GRAPHVIZ OUTPUT STARTS ----")
- if nodes_to_dump is None:
- nodes_to_dump = self.nodes()
- string = '\ndigraph {\n'
- string += 'node [color=lightblue2, style=filled, shape=box];\n'
-
- for node in nodes_to_dump:
- attrs = ""
- if hasattr(node, 'enabled') and not node.enabled:
- attrs += "color=gray70,"
- string += '"{}" [{}];\n'.format(node, attrs)
-
- visited_nodes = set()
- for src_node_name, dst_node_name, attrs in self.edges(data=True):
- visited_nodes.add(src_node_name)
- visited_nodes.add(dst_node_name)
- if src_node_name not in nodes_to_dump or dst_node_name not in nodes_to_dump:
- continue
- src_node = self.node[src_node_name]
- dst_node = self.node[dst_node_name]
- src_node_string = str(src_node_name) + '\\n'.join(
- [str(key) + '=' + str(src_node.get(key, 'None')) for key in node_attrs if key in src_node])
- dst_node_string = str(dst_node_name) + '\\n'.join(
- [str(key) + '=' + str(dst_node.get(key, 'None')) for key in node_attrs if key in dst_node])
- edge_string = ' '.join([str(key) + '=' + str(attrs.get(key, 'None')) for key in edge_attrs if key in attrs])
- string += '"{}" -> "{}" [label = "{}"];\n'.format(src_node_string, dst_node_string, edge_string)
-
- for node in nodes_to_dump:
- if node not in visited_nodes:
- string += '"{}";\n'.format(node)
- visited_nodes.add(node)
-
- string += '}'
- log.debug(string)
- log.debug("---- GRAPHVIZ OUTPUT ENDS ----")
-
- if save_to_svg:
- try:
- import graphviz
- import os
- file_name = "{}_{}.txt".format(self.name.replace('/', '_'), 0)
- id = 1
- while os.path.exists(file_name):
- file_name = "{}_{}.txt".format(self.name.replace('/', '_'), id)
- id += 1
- with open(file_name, "w") as f:
- f.write(string)
- graphviz.render('dot', 'svg', file_name)
- print('Graph was saved to {}.{}'.format(file_name, 'svg'))
- except ImportError:
- raise ImportError('Can\'t import graphviz')
- except Exception as e:
- raise Error('Can\'t save graph to svg') from e
-
- return string
-
- def cycle_check(self):
- try:
- list(nx.topological_sort(self))
- except nx.NetworkXUnfeasible as exception:
- cycles = nx.simple_cycles(self)
- raise Error(
- 'There is(are) cyclic dependency(ies) between replacers. One of the cycles is the following: {}',
- ' -> '.join([str(node) for node in list(cycles)[0]])) from exception
-
- def repeated_cls_names_check(self):
- name_to_class_map = {}
- for transform_class in self.node:
- transform_name = transform_class.__name__
- assert transform_name not in name_to_class_map, \
- 'Transform name `{}` is not unique: at least {} and {} exist' \
- ''.format(transform_name, transform_class, name_to_class_map[transform_name])
- name_to_class_map[transform_name] = transform_class
-
- def sort_util(self, v, visited, stack):
- visited.append(v)
- for i in sorted([child for _, child in self.out_edges(v)], key=lambda x: x.__name__):
- if i not in visited:
- self.sort_util(i, visited, stack)
- stack.insert(0, v)
-
- def determined_sort(self):
- self.cycle_check()
- self.repeated_cls_names_check()
- transforms = sorted([cls for cls in self.nodes() if len(self.in_edges(cls)) == 0], key=lambda x: x.__name__)
- order, visited = [], []
- for transform in transforms:
- self.sort_util(transform, visited, order)
-
- graph_copy = self.copy()
- for i in range(len(order) - 1):
- graph_copy.add_edge(order[i], order[i + 1])
- try:
- nx_order = list(nx.topological_sort(graph_copy))
- except Exception as e:
- raise InternalError(
- "Internal DependencyGraph determined_sort function behaves unexpectedly: cycle found") from e
- assert nx_order == order, \
- "Internal DependencyGraph determined_sort function behaves unexpectedly: nx_order != order"
- return order
-
-
-def need_exclude_class(class_type, excluded_frameworks):
- for framework in excluded_frameworks:
- if "." + framework + "." in str(class_type):
- return True
- return False
-
-
-def get_replacers_order(transform_types: list):
- """
- Gets all transforms that do not have 'op'.
- If two or more classes replaces the same op (both have op class attribute and values match), such
- pattern is not applied (while registration it will warn user that we have a conflict).
- """
- dependency_graph = DependencyGraph(name="UnifiedPipeline" if len(transform_types) != 1 else transform_types[0].name)
-
- replacers = []
- for class_type, classes_set in _registered_classes_dict.items():
- if class_type in transform_types:
- for cls in classes_set:
- cur_cls_replacers = [c for c in cls.registered_cls if not hasattr(c, 'op')] + \
- [c for op, c in cls.registered_ops.items() if c]
- replacers.extend(
- [replacer for replacer in cur_cls_replacers if replacer not in cls.excluded_replacers])
-
- for replacer_cls in replacers:
- dependency_graph.add_node(replacer_cls)
-
- for i, replacer_cls in enumerate(replacers):
- for cls_after in replacer_cls().run_before():
- if cls_after in replacers:
- dependency_graph.add_edge(replacer_cls, cls_after)
- for cls_before in replacer_cls().run_after():
- if cls_before in replacers:
- dependency_graph.add_edge(cls_before, replacer_cls)
-
- replacers_order = dependency_graph.determined_sort()
-
- debug_msg_list = ['| id | enabled | class ']
- for i, replacer_cls in enumerate(replacers_order):
- debug_msg_list.append('|{:5} |{:^9}| {}'.format(i, str(getattr(replacer_cls, 'enabled', None)), replacer_cls))
- log.debug('Replacers execution order: \n{}'.format('\n'.join(debug_msg_list)))
-
- return replacers_order
-
-
-@progress_bar
-def apply_transform(graph: Graph, replacer_cls, **kwargs):
- """
- Safely executes transform if it should be and validates graph after transform execution
- """
- replacer = replacer_cls()
- replacement_id = 'REPLACEMENT_ID'
- if hasattr(replacer, 'replacement_id'):
- replacement_id = replacer.replacement_id
-
- if hasattr(replacer, 'enabled') and not replacer.enabled:
- log.info("Skip replacer {} (enabled = False)".format(replacer_cls))
- return
-
- if hasattr(replacer, 'graph_condition') and \
- not all([condition(graph) for condition in replacer.graph_condition]):
- log.info("Skip replacer {} (graph_condition not satisfied)".format(replacer_cls))
- return
-
- log.debug("Run replacer {}".format(replacer_cls))
-
- try:
- if hasattr(replacer, 'run_not_recursively') and replacer.run_not_recursively:
- replacer.find_and_replace_pattern(graph)
- else:
- for_graph_and_each_sub_graph_recursively(graph, replacer.find_and_replace_pattern)
-
- if hasattr(replacer, 'force_clean_up') and replacer.force_clean_up:
- for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up())
-
- if hasattr(replacer, 'force_shape_inference') and replacer.force_shape_inference:
- shape_inference(graph)
-
- if hasattr(replacer, 'run_not_recursively') and replacer.run_not_recursively:
- graph.check_empty_graph(replacer_cls)
- graph.check_shapes_consistency()
- else:
- for_graph_and_each_sub_graph_recursively(graph, lambda _: graph.check_empty_graph(replacer_cls))
- for_graph_and_each_sub_graph_recursively(graph, lambda _: graph.check_shapes_consistency())
-
- except Error as err:
- raise Error('Exception occurred during running replacer "{}" ({}): {}'.format(
- replacement_id,
- replacer_cls,
- str(err).replace('[REPLACEMENT_ID]', replacement_id),
- )) from err
- except FrameworkError as err:
- raise FrameworkError('{}'.format(str(err))) from err
- except Exception as err:
- raise Exception('Exception occurred during running replacer "{} ({})": {}'.format(
- replacement_id,
- replacer_cls,
- str(err).replace('[REPLACEMENT_ID]', replacement_id),
- )) from err
-
-
-def apply_replacements_list(graph: Graph, replacers_order: list):
- """
- Apply all transformations from replacers_order
- """
- for i, replacer_cls in enumerate(replacers_order):
- apply_transform(
- graph=graph,
- replacer_cls=replacer_cls,
- curr_transform_num=i,
- num_transforms=len(replacers_order))
-
-
-def apply_replacements(graph: Graph, replacements_type: list):
- """
- Apply all patterns that do not have 'op' first, then apply patterns from registered_ops.
- If two or more classes replaces the same op (both have op class attribute and values match), such
- pattern is not applied (while registration it will warn user that we have a conflict).
- """
- replacers_order = get_replacers_order(replacements_type)
- apply_replacements_list(graph, replacers_order)
-
-
-def clear_registered_classes_dict():
- CustomReplacementRegistry.registry = {}
- _registered_classes_dict.clear()
diff --git a/tools/mo/openvino/tools/mo/utils/cli_parser.py b/tools/mo/openvino/tools/mo/utils/cli_parser.py
deleted file mode 100644
index edea30d077878b..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/cli_parser.py
+++ /dev/null
@@ -1,2030 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import ast
-import logging as log
-import os
-import re
-from collections import OrderedDict, namedtuple
-from itertools import zip_longest
-from pathlib import Path
-from operator import xor
-from typing import List, Union
-import numbers
-import inspect
-
-import numpy as np
-from openvino.runtime import Layout, PartialShape, Dimension, Shape, Type
-
-import openvino
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg, get_mo_root_dir
-from openvino.tools.mo.utils.help import get_convert_model_help_specifics, get_to_string_methods_for_params
-
-
-def strtobool(value):
- """
- Converts a string representation to true or false.
-
- :param value: a string which will be converted to bool.
- :return: boolean value of the input string.
- """
- value = value.lower()
- if value in ('y', 'yes', 't', 'true', 'on', '1'):
- return 1
- elif value in ('n', 'no', 'f', 'false', 'off', '0'):
- return 0
- else:
- raise ValueError(f"Invalid truth value: {value}.")
-
-
-def extension_path_to_str_or_extensions_class(extension):
- if isinstance(extension, str):
- return extension
- elif isinstance(extension, Path):
- return str(extension)
- else:
- # Return unknown object as is.
- # The type of the object will be checked by frontend.add_extension() method
- return extension
-
-
-def transformations_config_to_str(value):
- if value is None:
- return value
- return extension_path_to_str_or_extensions_class(value)
-
-
-def extensions_to_str_or_extensions_class(extensions):
- if extensions is None:
- return None
- extensions_list = []
- if isinstance(extensions, str):
- extensions_list = extensions.split(',')
- elif isinstance(extensions, list):
- for ext in extensions:
- ext = extension_path_to_str_or_extensions_class(ext)
- extensions_list.append(ext)
- else:
- extensions_list = [extension_path_to_str_or_extensions_class(extensions)]
-
- for ext in extensions_list:
- if isinstance(ext, str):
- readable_file_or_dir(ext)
- return extensions_list
-
-
-def path_to_str(path):
- if path is None:
- return None
- if isinstance(path, str):
- return path
- elif isinstance(path, Path):
- return str(path)
- else:
- raise Exception("Incorrect type of {} expected str or Path, got {}".format(path, type(path)))
-
-
-def path_to_str_or_object(value):
- if value is None or isinstance(value, str):
- return value
- elif isinstance(value, Path):
- return str(value)
- else:
- return value
-
-
-def paths_to_str(paths):
- if paths is None:
- return None
- if isinstance(paths, list):
- paths_str = []
- for path in paths:
- paths_str.append(path_to_str(path))
- return ','.join(paths_str)
- else:
- path_to_str(paths)
-
-
-def str_list_to_str(values):
- if values is None:
- return None
- if isinstance(values, str):
- return values
- elif isinstance(values, list):
- for value in values:
- if not isinstance(value, str):
- raise Error("Incorrect argument. {} expected to string, got type {}.".format(value, type(value)))
- return ','.join(values)
- else:
- raise Error("Incorrect argument. {} expected to string or list of strings, got type {}.".format(values, type(values)))
-
-
-def is_shape_type(value):
- if isinstance(value, PartialShape):
- return True
- if isinstance(value, Shape):
- return True
- if isinstance(value, list) or isinstance(value, tuple):
- for dim in value:
- if not (isinstance(dim, Dimension) or isinstance(dim, int)):
- return False
- return True
- return False
-
-
-def value_to_str(value, separator):
- if isinstance(value, np.ndarray):
- values = []
- for x in np.nditer(value):
- values.append(str(x))
- return "[" + separator.join(values) + "]"
- if isinstance(value, list):
- values = []
- for x in value:
- if not isinstance(x, numbers.Number):
- raise Exception("Incorrect value type. Expected numeric value, got {}".format(type(x)))
- values.append(str(x))
- return "[" + separator.join(values) + "]"
- if isinstance(value, bool):
- return "True" if value else "False"
- raise Exception("Incorrect value type. Expected np.ndarray or list, got {}".format(type(value)))
-
-
-def single_input_to_input_cut_info(input: [str, tuple, list, PartialShape, Type, type]):
- """
- Parses parameters of single input to InputCutInfo.
- :param input: input cut parameters of single input
- :return: InputCutInfo
- """
- if isinstance(input, str):
- # Parse params from string
- node_name, shape, value, data_type = parse_input_value(input)
- return openvino.tools.mo.InputCutInfo(node_name,
- PartialShape(shape) if shape is not None else None,
- data_type,
- value)
- if isinstance(input, openvino.tools.mo.InputCutInfo):
- # Wrap input.shape to PartialShape if possible and wrap to InputCutInfo
- return openvino.tools.mo.InputCutInfo(input.name,
- PartialShape(input.shape) if input.shape is not None else None,
- input.type,
- input.value)
- if isinstance(input, (tuple, list, PartialShape)):
- # If input represents list with shape, wrap it to list. Single PartialShape also goes to this condition.
- # Check of all dimensions will be in is_shape_type(val) method below
- if len(input) > 0 and isinstance(input[0], (int, Dimension)):
- input = [input]
-
- # Check values of tuple or list and collect to InputCutInfo
- name = None
- inp_type = None
- shape = None
- for val in input:
- if isinstance(val, str):
- if name is not None:
- raise Exception("More than one input name provided: {}".format(input))
- name = val
- elif isinstance(val, (type, Type)):
- if inp_type is not None:
- raise Exception("More than one input type provided: {}".format(input))
- inp_type = val
- elif is_shape_type(val):
- if shape is not None:
- raise Exception("More than one input shape provided: {}".format(input))
- shape = PartialShape(val)
- else:
- raise Exception("Incorrect input parameters provided. Expected tuple with input name, "
- "input type or input shape. Got unknown object: {}".format(val))
- return openvino.tools.mo.InputCutInfo(name,
- PartialShape(shape) if shape is not None else None,
- inp_type,
- None)
- # Case when only type is set
- if isinstance(input, (type, Type)):
- return openvino.tools.mo.InputCutInfo(None, None, input, None)
-
- # We don't expect here single unnamed value. If list of int is set it is considered as shape.
- # Setting of value is expected only using InputCutInfo or string analog.
-
- raise Exception("Unexpected object provided for input. Expected openvino.toos.mo.InputCutInfo "
- "or tuple or str. Got {}".format(type(input)))
-
-
-def input_to_input_cut_info(input: [str, tuple, list]):
- """
- Parses 'input' to list of InputCutInfo.
- :param input: input cut parameters passed by user
- :return: list of InputCutInfo with input cut parameters
- """
- if input is None:
- return []
- if isinstance(input, str):
- inputs = []
- # Split to list of string
- for input_value in split_inputs(input):
-
- # Parse string with parameters for single input
- node_name, shape, value, data_type = parse_input_value(input_value)
- inputs.append(openvino.tools.mo.InputCutInfo(node_name,
- PartialShape(shape) if shape is not None else None,
- data_type,
- value))
- return inputs
- if isinstance(input, openvino.tools.mo.InputCutInfo):
- # Wrap to list and return
- return [input]
- if isinstance(input, tuple):
- # Case when input is single shape set in tuple
- if len(input) > 0 and isinstance(input[0], (int, Dimension)):
- input = [input]
- # Case when input is set as tuple. Expected that it is always single input.
- return [single_input_to_input_cut_info(input)]
- if isinstance(input, list):
- # Case when input is single shape set in list
- if len(input) > 0 and isinstance(input[0], (int, Dimension)):
- input = [input]
- inputs = []
- # Case when input is set as list. Expected that it is list of params for different inputs.
- for inp in input:
- inputs.append(single_input_to_input_cut_info(inp))
- return inputs
- # Case when single type or value is set, or unknown object
- return [single_input_to_input_cut_info(input)]
-
-
-def input_shape_to_input_cut_info(input_shape: [str, Shape, PartialShape, list, tuple], inputs: list):
- """
- Parses 'input_shape' to list of PartialShape and updates 'inputs'.
- :param input_shape: input shapes passed by user
- :param inputs: list of InputCutInfo with information from 'input' parameter
- """
- if input_shape is None:
- return
- if isinstance(input_shape, str):
- # Split input_shape to list of string
- input_shape = split_shapes(input_shape)
- if isinstance(input_shape, (Shape, PartialShape)):
- # Whap single shape to list
- input_shape = [input_shape]
- if isinstance(input_shape, (list, tuple)):
- # Check case when single shape is passed as list or tuple
- if len(input_shape) > 0 and isinstance(input_shape[0], (int, Dimension)):
- input_shape = [input_shape]
-
- if len(inputs) > 0 and len(input_shape) > 0:
- assert len(inputs) == len(input_shape), "Different numbers of inputs were specified in \"input\" parameter " \
- "and \"input_shapes\". \"input\" has {} items, \"input_shape\" has {} item.".format(len(inputs), len(input_shape))
-
- # Update inputs with information from 'input_shape'
- if len(inputs) > 0:
- for idx, shape in enumerate(input_shape):
- shape = PartialShape(shape)
- assert inputs[idx].shape is None, "Shape was set in both \"input\" and in \"input_shape\" parameter." \
- "Please use either \"input\" or \"input_shape\" for shape setting."
- inputs[idx] = openvino.tools.mo.InputCutInfo(inputs[idx].name, shape, inputs[idx].type, inputs[idx].value)
-
- else:
- for shape in input_shape:
- inputs.append(openvino.tools.mo.InputCutInfo(None, PartialShape(shape), None, None))
- return
-
- raise Exception("Unexpected object provided for input_shape. Expected PartialShape, Shape, tuple, list or str. "
- "Got {}".format(type(input_shape)))
-
-
-def freeze_placeholder_to_input_cut_info(argv_freeze_placeholder_with_value: str, inputs: list):
- """
- Parses 'argv_freeze_placeholder_with_value' to dictionary and collects unnamed inputs from 'inputs' to list.
- :param argv_freeze_placeholder_with_value: string set by user.
- As it was planned to be deprecated no Python analogs were made.
- :param inputs: list of InputCutInfo with information from 'input' parameter
- :returns (placeholder_values, unnamed_placeholder_values), where
- placeholder_values - dictionary where key is node name, value is node value,
- unnamed_placeholder_values - list with unnamed node values
- """
- # Parse argv_freeze_placeholder_with_value to dictionary with names and values
- placeholder_values = parse_freeze_placeholder_values(argv_freeze_placeholder_with_value)
- unnamed_placeholder_values = []
-
- # Collect values for freezing from 'inputs'
- if inputs is not None and len(inputs) > 0:
- for input in inputs:
- node_name = input.name
- value = input.value
- if value is None:
- continue
- # Check for value conflict
- if node_name in placeholder_values and placeholder_values[node_name] != value:
- raise Error("Overriding replacement value of the placeholder with name '{}': old value = {}, new value = {}"
- ".".format(node_name, placeholder_values[node_name], value))
- if node_name is not None:
- # Named input case, add to dictionary
- placeholder_values[node_name] = value
- else:
- # Unnamed input case, add to list
- unnamed_placeholder_values.append(value)
-
- return placeholder_values, unnamed_placeholder_values
-
-
-def mean_scale_value_to_str(value):
- # default empty value
- if isinstance(value, tuple) and len(value) == 0:
- return value
-
- if isinstance(value, str):
- return value
- if isinstance(value, dict):
- values_str = []
- for op_name, val in value.items():
- if not isinstance(op_name, str):
- raise Exception("Incorrect operation name type. Expected string, got {}".format(type(op_name)))
- values_str.append(op_name + value_to_str(val, ","))
- return ",".join(values_str)
- if isinstance(value, list) or isinstance(value, tuple):
- list_of_lists = False
- for val in value:
- if isinstance(val, list) or isinstance(val, tuple):
- list_of_lists = True
- break
- if list_of_lists:
- values_str = []
- for val in value:
- values_str.append(value_to_str(val, ","))
- return ",".join(values_str)
- else:
- return value_to_str(value, ",")
- return value_to_str(value, ",")
-
-
-def layout_to_str(layout):
- if isinstance(layout, str):
- return layout
- if isinstance(layout, Layout):
- return layout.to_string()
- raise Exception("Incorrect layout type. Expected Layout or string or dictionary, "
- "where key is operation name and value is layout or list of layouts, got {}".format(type(layout)))
-
-
-def source_target_layout_to_str(value):
- # default empty value
- if isinstance(value, tuple) and len(value) == 0:
- return value
-
- if isinstance(value, str):
- return value
- if isinstance(value, dict):
- values_str = []
- for op_name, layout in value.items():
- if not isinstance(op_name, str):
- raise Exception("Incorrect operation name type. Expected string, got {}".format(type(op_name)))
- values_str.append(op_name + "(" + layout_to_str(layout) + ")")
- return ",".join(values_str)
-
- return layout_to_str(value)
-
-
-def layoutmap_to_str(value):
- if isinstance(value, str):
- return value
- if isinstance(value, openvino.tools.mo.LayoutMap):
- assert value.source_layout is not None, "Incorrect layout map. 'source_layout' should be set."
- source_layout = layout_to_str(value.source_layout)
- if value.target_layout is not None:
- target_layout = layout_to_str(value.target_layout)
- source_layout += "->" + target_layout
- return source_layout
- return layout_to_str(value)
-
-
-def layout_param_to_str(value):
- # default empty value
- if isinstance(value, tuple) and len(value) == 0:
- return value
-
- if isinstance(value, str):
- return value
-
- if isinstance(value, dict):
- values_str = []
- for op_name, layout in value.items():
- if not isinstance(op_name, str):
- raise Exception("Incorrect operation name type. Expected string, got {}".format(type(op_name)))
- values_str.append(op_name + "(" + layoutmap_to_str(layout) + ")")
- return ",".join(values_str)
- if isinstance(value, openvino.tools.mo.LayoutMap):
- return layoutmap_to_str(value)
- if isinstance(value, list) or isinstance(value, tuple):
- values_str = []
- for layout in value:
- values_str.append(layoutmap_to_str(layout))
- return ",".join(values_str)
-
- return layoutmap_to_str(value)
-
-
-def batch_to_int(value):
- if value is None or isinstance(value, int):
- return value
- if isinstance(value, Dimension):
- if not value.is_static:
- # TODO: Ticket 88676
- raise Exception("Dynamic batch for \"batch\" parameter is not supported.")
- else:
- return value.get_length()
- raise Exception("Incorrect batch value. Expected int, got {}.".format(type(value)))
-
-
-def transform_param_value_to_str(value):
- # This function supports parsing of parameters of MakeStateful, LowLatency2, Pruning.
- # If available transforms list is extended this method should be extended for new transforms.
- if isinstance(value, str):
- return value
- if isinstance(value, bool):
- return str(value)
- if isinstance(value, dict):
- # param_res_names dictionary for MakeStateful transform
- values_str = []
- for input_name, output_name in value.items():
- assert isinstance(input_name, str), "Incorrect input name. " \
- "Expected string, got {}".format(type(input_name))
- assert isinstance(output_name, str), "Incorrect output name. " \
- "Expected string, got {}".format(type(output_name))
- values_str.append("\'{}\':\'{}\'".format(input_name, output_name))
- return "{" + ','.join(values_str) + "}"
- raise Exception("Unknown parameter type.")
-
-
-def transform_to_str(value):
- from openvino.tools.mo.back.offline_transformations import get_available_transformations # pylint: disable=no-name-in-module,import-error
-
- if isinstance(value, str):
- return value
-
- if isinstance(value, tuple):
- assert 1 <= len(value) <= 2, "Incorrect definition of transformation in transform argument: " \
- "expected two elements in tuple, provided {}. " \
- "Supported transforms are: {}".format(
- len(value),
- list(get_available_transformations().keys()))
- transform_name = value[0]
- assert isinstance(transform_name, str), "Incorrect transform name type. " \
- "Expected string, got {}".format(type(transform_name))
- if len(value) == 2:
- params = value[1]
- assert isinstance(params, dict), "Incorrect transform params type. " \
- "Expected dictionary, got {}".format(type(params))
- params_str_list = []
- for param_name, val in params.items():
- assert isinstance(param_name, str), "Incorrect transform parameter name type. " \
- "Expected string, got {}".format(type(param_name))
- val_str = transform_param_value_to_str(val)
- params_str_list.append(param_name + "=" + val_str)
- transform_name += '[' + ','.join(params_str_list) + ']'
- return transform_name
- raise Exception("Incorrect transform type. Expected tuple with transform name and "
- "dictionary with transform parameters. Got object of type {}".format(type(value)))
-
-
-def transform_param_to_str(value):
- if value is None or isinstance(value, str):
- return value
- if isinstance(value, list):
- transforms_str = []
- for transform in value:
- transforms_str.append(transform_to_str(transform))
- return ','.join(transforms_str)
- return transform_to_str(value)
-
-
-ParamDescription = namedtuple("ParamData",
- ["description", "cli_tool_description", "to_string"])
-
-
-def get_mo_convert_params():
- mo_convert_docs = openvino.tools.mo.convert_model.__doc__
- mo_convert_params = {}
- group = "Optional parameters:"
- mo_convert_params[group] = {}
-
- mo_convert_docs = mo_convert_docs[:mo_convert_docs.find('Returns:')]
-
- while len(mo_convert_docs) > 0:
- param_idx1 = mo_convert_docs.find(":param")
- if param_idx1 == -1:
- break
- param_idx2 = mo_convert_docs.find(":", param_idx1+1)
- param_name = mo_convert_docs[param_idx1+len(':param '):param_idx2]
-
- param_description_idx = mo_convert_docs.find(":param", param_idx2+1)
- param_description = mo_convert_docs[param_idx2+1: param_description_idx]
-
- group_name_idx = param_description.rfind('\n\n')
- group_name = ''
- if group_name_idx != -1:
- group_name = param_description[group_name_idx:].strip()
-
- param_description = param_description[:group_name_idx]
- param_description = param_description.strip()
-
- mo_convert_params[group][param_name] = ParamDescription(param_description, "", None)
-
- mo_convert_docs = mo_convert_docs[param_description_idx:]
-
- if group_name != '':
- mo_convert_params[group_name] = {}
- group = group_name
-
- # TODO: remove this when internal converting of params to string is removed
- params_converted_to_string = get_to_string_methods_for_params()
-
- params_with_paths = get_params_with_paths_list()
- cli_tool_specific_descriptions = get_convert_model_help_specifics()
-
- for group_name, param_group in mo_convert_params.items():
- for param_name, d in param_group.items():
- to_str_method = None
- if param_name in params_converted_to_string:
- to_str_method = params_converted_to_string[param_name]
- elif param_name in params_with_paths:
- to_str_method = path_to_str
-
- cli_tool_description = None
- if param_name in cli_tool_specific_descriptions:
- cli_tool_description = cli_tool_specific_descriptions[param_name]
-
- desc = ParamDescription(d.description,
- cli_tool_description,
- to_str_method)
- mo_convert_params[group_name][param_name] = desc
-
- return mo_convert_params
-
-
-class DeprecatedStoreTrue(argparse.Action):
- def __init__(self, nargs=0, **kw):
- super().__init__(nargs=nargs, **kw)
-
- def __call__(self, parser, namespace, values, option_string=None):
- dep_msg = "Use of deprecated cli option {} detected. Option use in the following releases will be fatal. ".format(option_string)
- if 'fusing' in option_string:
- dep_msg += 'Please use --finegrain_fusing cli option instead'
- log.error(dep_msg, extra={'is_warning': True})
- setattr(namespace, self.dest, True)
-
-
-class DeprecatedOptionCommon(argparse.Action):
- def __call__(self, parser, args, values, option_string):
- dep_msg = "Use of deprecated cli option {} detected. Option use in the following releases will be fatal. ".format(option_string)
- log.error(dep_msg, extra={'is_warning': True})
- setattr(args, self.dest, values)
-
-
-class IgnoredAction(argparse.Action):
- def __init__(self, nargs=0, **kw):
- super().__init__(nargs=nargs, **kw)
-
- def __call__(self, parser, namespace, values, option_string=None):
- 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)
-
-
-def canonicalize_and_check_paths(values: Union[str, List[str]], param_name,
- try_mo_root=False, check_existence=True) -> List[str]:
- if values is not None:
- list_of_values = list()
- if isinstance(values, str):
- if values != "":
- list_of_values = values.split(',')
- elif isinstance(values, list):
- list_of_values = values
- else:
- raise Error('Unsupported type of command line parameter "{}" value'.format(param_name))
-
- if not check_existence:
- return [get_absolute_path(path) for path in list_of_values]
-
- for idx, val in enumerate(list_of_values):
- list_of_values[idx] = val
-
- error_msg = 'The value for command line parameter "{}" must be existing file/directory, ' \
- 'but "{}" does not exist.'.format(param_name, val)
- if os.path.exists(val):
- continue
- elif not try_mo_root or val == '':
- raise Error(error_msg)
- elif try_mo_root:
- path_from_mo_root = get_mo_root_dir() + '/mo/' + val
- list_of_values[idx] = path_from_mo_root
- if not os.path.exists(path_from_mo_root):
- raise Error(error_msg)
-
- return [get_absolute_path(path) for path in list_of_values]
-
-
-class CanonicalizePathAction(argparse.Action):
- """
- Expand user home directory paths and convert relative-paths to absolute.
- """
-
- def __call__(self, parser, namespace, values, option_string=None):
- list_of_paths = canonicalize_and_check_paths(values, param_name=option_string,
- try_mo_root=False, check_existence=False)
- setattr(namespace, self.dest, ','.join(list_of_paths))
-
-
-class CanonicalizeTransformationPathCheckExistenceAction(argparse.Action):
- """
- Convert relative to the current and relative to mo root paths to absolute
- and check specified file or directory existence.
- """
-
- def __call__(self, parser, namespace, values, option_string=None):
- list_of_paths = canonicalize_and_check_paths(values, param_name=option_string,
- try_mo_root=True, check_existence=True)
- setattr(namespace, self.dest, ','.join(list_of_paths))
-
-
-class CanonicalizePathCheckExistenceAction(argparse.Action):
- """
- Expand user home directory paths and convert relative-paths to absolute and check specified file or directory
- existence.
- """
-
- def __call__(self, parser, namespace, values, option_string=None):
- list_of_paths = canonicalize_and_check_paths(values, param_name=option_string,
- try_mo_root=False, check_existence=True)
- setattr(namespace, self.dest, ','.join(list_of_paths))
-
-
-class CanonicalizeExtensionsPathCheckExistenceAction(argparse.Action):
- """
- Expand user home directory paths and convert relative-paths to absolute and check specified file or directory
- existence.
- """
-
- def __call__(self, parser, namespace, values, option_string=None):
- list_of_paths = canonicalize_and_check_paths(values, param_name=option_string,
- try_mo_root=False, check_existence=True)
- # Extensions paths are needed to be stored as list
- setattr(namespace, self.dest, list_of_paths)
-
-
-class CanonicalizePathCheckExistenceIfNeededAction(CanonicalizePathCheckExistenceAction):
-
- def __call__(self, parser, namespace, values, option_string=None):
- if values is not None:
- if isinstance(values, str):
- if values != "":
- super().__call__(parser, namespace, values, option_string)
- else:
- setattr(namespace, self.dest, values)
-
-
-class DeprecatedCanonicalizePathCheckExistenceAction(CanonicalizePathCheckExistenceAction):
- def __call__(self, parser, namespace, values, option_string=None):
- dep_msg = "Use of deprecated cli option {} detected. Option use in the following releases will be fatal. ".format(
- option_string)
- log.error(dep_msg, extra={'is_warning': True})
- super().__call__(parser, namespace, values, option_string)
-
-
-def readable_file(path: str):
- """
- Check that specified path is a readable file.
- :param path: path to check
- :return: path if the file is readable
- """
- if not os.path.isfile(path):
- raise Error('The "{}" is not existing file'.format(path))
- elif not os.access(path, os.R_OK):
- raise Error('The "{}" is not readable'.format(path))
- else:
- return path
-
-
-def readable_file_or_dir(path: str):
- """
- Check that specified path is a readable file or directory.
- :param path: path to check
- :return: path if the file/directory is readable
- """
- if not os.path.isfile(path) and not os.path.isdir(path):
- raise Error('The "{}" is not existing file or directory'.format(path))
- elif not os.access(path, os.R_OK):
- raise Error('The "{}" is not readable'.format(path))
- else:
- return path
-
-
-def readable_dirs(paths: str):
- """
- Checks that comma separated list of paths are readable directories.
- :param paths: comma separated list of paths.
- :return: comma separated list of paths.
- """
- paths_list = [readable_dir(path) for path in paths.split(',')]
- return ','.join(paths_list)
-
-
-def readable_dirs_or_empty(paths: str):
- """
- Checks that comma separated list of paths are readable directories of if it is empty.
- :param paths: comma separated list of paths.
- :return: comma separated list of paths.
- """
- if paths:
- return readable_dirs(paths)
- return paths
-
-
-def readable_dirs_or_files_or_empty(paths: str):
- """
- Checks that comma separated list of paths are readable directories, files or a provided path is empty.
- :param paths: comma separated list of paths.
- :return: comma separated list of paths.
- """
- if paths:
- paths_list = [readable_file_or_dir(path) for path in paths.split(',')]
- return ','.join(paths_list)
- return paths
-
-
-def readable_dir(path: str):
- """
- Check that specified path is a readable directory.
- :param path: path to check
- :return: path if the directory is readable
- """
- if not os.path.isdir(path):
- raise Error('The "{}" is not existing directory'.format(path))
- elif not os.access(path, os.R_OK):
- raise Error('The "{}" is not readable'.format(path))
- else:
- return path
-
-
-def writable_dir(path: str):
- """
- Checks that specified directory is writable. The directory may not exist but it's parent or grandparent must exist.
- :param path: path to check that it is writable.
- :return: path if it is writable
- """
- if path is None:
- raise Error('The directory parameter is None')
- if os.path.exists(path):
- if os.path.isdir(path):
- if os.access(path, os.W_OK):
- return path
- else:
- raise Error('The directory "{}" is not writable'.format(path))
- else:
- raise Error('The "{}" is not a directory'.format(path))
- else:
- cur_path = path
- while os.path.dirname(cur_path) != cur_path:
- if os.path.exists(cur_path):
- break
- cur_path = os.path.dirname(cur_path)
- if cur_path == '':
- cur_path = os.path.curdir
- if os.access(cur_path, os.W_OK):
- return path
- else:
- raise Error('The directory "{}" is not writable'.format(cur_path))
-
-
-def add_args_by_description(args_group, params_description):
- signature = inspect.signature(openvino.tools.mo.convert_model)
- filepath_args = get_params_with_paths_list()
- cli_tool_specific_descriptions = get_convert_model_help_specifics()
- for param_name, param_description in params_description.items():
- if param_name == 'help':
- continue
- cli_param_name = "--"+param_name
- if cli_param_name not in args_group._option_string_actions:
- # Get parameter specifics
- param_specifics = cli_tool_specific_descriptions[param_name] if param_name in \
- cli_tool_specific_descriptions else {}
- help_text = param_specifics['description'] if 'description' in param_specifics \
- else param_description.description
- action = param_specifics['action'] if 'action' in param_specifics else None
- param_type = param_specifics['type'] if 'type' in param_specifics else None
- param_alias = param_specifics['aliases'] if 'aliases' in param_specifics else {}
- param_version = param_specifics['version'] if 'version' in param_specifics else None
- param_choices = param_specifics['choices'] if 'choices' in param_specifics else None
-
- # Bool params common setting
- if signature.parameters[param_name].annotation == bool and param_name != 'version':
- default_flag = signature.parameters[param_name].default
- # tools.mo.convert_model by default does not compress,
- # but if we convert from cli we need to compress_to_fp16 if user did not specify otherwise
- if param_name == 'compress_to_fp16':
- default_flag = True
- args_group.add_argument(
- cli_param_name, *param_alias,
- type=check_bool if param_type is None else param_type,
- nargs="?",
- const=True,
- help=help_text,
- default=default_flag)
- # File paths common setting
- elif param_name in filepath_args:
- action = action if action is not None else CanonicalizePathCheckExistenceAction
- args_group.add_argument(
- cli_param_name, *param_alias,
- type=str if param_type is None else param_type,
- action=action,
- help=help_text,
- default=signature.parameters[param_name].default)
- # Other params
- else:
- additional_params = {}
- if param_version is not None:
- additional_params['version'] = param_version
- if param_type is not None:
- additional_params['type'] = param_type
- if param_choices is not None:
- additional_params['choices'] = param_choices
- args_group.add_argument(
- cli_param_name, *param_alias,
- help=help_text,
- default=signature.parameters[param_name].default,
- action=action,
- **additional_params
- )
-
-
-def get_common_cli_parser(parser: argparse.ArgumentParser = None):
- if not parser:
- parser = argparse.ArgumentParser()
- common_group = parser.add_argument_group('Framework-agnostic parameters')
- mo_convert_params = get_mo_convert_params()
- mo_convert_params_common = mo_convert_params['Framework-agnostic parameters:']
-
- # Command line tool specific params
- common_group.add_argument('--model_name', '-n',
- help='Model_name parameter passed to the final create_ir transform. ' +
- 'This parameter is used to name ' +
- 'a network in a generated IR and output .xml/.bin files.')
- common_group.add_argument('--output_dir', '-o',
- help='Directory that stores the generated IR. ' +
- 'By default, it is the directory from where the Model Conversion is launched.',
- default=get_absolute_path('.'),
- action=CanonicalizePathAction,
- type=writable_dir)
-
- # Deprecated params
- common_group.add_argument('--freeze_placeholder_with_value',
- help='Replaces input layer with constant node with '
- 'provided value, for example: "node_name->True". '
- 'It will be DEPRECATED in future releases. '
- 'Use "input" option to specify a value for freezing.',
- default=None)
- common_group.add_argument('--static_shape',
- help='Enables IR generation for fixed input shape (folding `ShapeOf` operations and '
- 'shape-calculating sub-graphs to `Constant`). Changing model input shape using '
- 'the OpenVINO Runtime API in runtime may fail for such an IR.',
- action='store_true', default=False)
- common_group.add_argument("--use_new_frontend",
- help='Force the usage of new Frontend for model conversion into IR. '
- 'The new Frontend is C++ based and is available for ONNX* and PaddlePaddle* models. '
- 'Model Conversion API uses new Frontend for ONNX* and PaddlePaddle* by default that means '
- '`use_new_frontend` and `use_legacy_frontend` options are not specified.',
- action='store_true', default=False)
- common_group.add_argument("--use_legacy_frontend",
- help='Force the usage of legacy Frontend for model conversion into IR. '
- 'The legacy Frontend is Python based and is available for TensorFlow*, ONNX*, '
- 'Caffe*, and Kaldi* models.',
- action='store_true', default=False)
- add_args_by_description(common_group, mo_convert_params_common)
- return parser
-
-
-def get_common_cli_options(model_name):
- d = OrderedDict()
- d['input_model'] = '- Path to the Input Model'
- d['output_dir'] = ['- Path for generated IR', lambda x: x if x != '.' else os.getcwd()]
- d['model_name'] = ['- IR output name', lambda x: x if x else model_name]
- d['log_level'] = '- Log level'
- d['batch'] = ['- Batch', lambda x: x if x else 'Not specified, inherited from the model']
- d['input'] = ['- Input layers', lambda x: x if x else 'Not specified, inherited from the model']
- d['output'] = ['- Output layers', lambda x: x if x else 'Not specified, inherited from the model']
- d['input_shape'] = ['- Input shapes', lambda x: x if x else 'Not specified, inherited from the model']
- d['source_layout'] = ['- Source layout', lambda x: x if x else 'Not specified']
- d['target_layout'] = ['- Target layout', lambda x: x if x else 'Not specified']
- d['layout'] = ['- Layout', lambda x: x if x else 'Not specified']
- d['mean_values'] = ['- Mean values', lambda x: x if x else 'Not specified']
- d['scale_values'] = ['- Scale values', lambda x: x if x else 'Not specified']
- d['scale'] = ['- Scale factor', lambda x: x if x else 'Not specified']
- d['transform'] = ['- User transformations', lambda x: x if x else 'Not specified']
- d['reverse_input_channels'] = '- Reverse input channels'
- d['static_shape'] = '- Enable IR generation for fixed input shape'
- d['transformations_config'] = '- Use the transformations config file'
- return d
-
-
-def get_advanced_cli_options():
- d = OrderedDict()
- d['use_legacy_frontend'] = '- Force the usage of legacy Frontend for model conversion into IR'
- d['use_new_frontend'] = '- Force the usage of new Frontend for model conversion into IR'
- return d
-
-
-def get_caffe_cli_options():
- d = {
- 'input_proto': ['- Path to the Input prototxt', lambda x: x],
- 'caffe_parser_path': ['- Path to Python Caffe* parser generated from caffe.proto', lambda x: x],
- 'k': '- Path to CustomLayersMapping.xml',
- }
-
- return OrderedDict(sorted(d.items(), key=lambda t: t[0]))
-
-
-def get_tf_cli_options():
- d = {
- 'input_model_is_text': '- Input model in text protobuf format',
- 'tensorflow_custom_operations_config_update': '- Update the configuration file with input/output node names',
- 'tensorflow_object_detection_api_pipeline_config': '- Use configuration file used to generate the model with '
- 'Object Detection API',
- 'tensorflow_custom_layer_libraries': '- List of shared libraries with TensorFlow custom layers implementation',
- 'tensorboard_logdir': '- Path to model dump for TensorBoard'
- }
-
- return OrderedDict(sorted(d.items(), key=lambda t: t[0]))
-
-
-def get_kaldi_cli_options():
- d = {
- 'counts': '- A file name with full path to the counts file or empty string if you want to use counts from model',
- 'remove_output_softmax': '- Removes the SoftMax layer that is the output layer',
- 'remove_memory': '- Removes the Memory layer and use additional inputs and outputs instead'
- }
-
- return OrderedDict(sorted(d.items(), key=lambda t: t[0]))
-
-
-def get_onnx_cli_options():
- d = {
- }
-
- return OrderedDict(sorted(d.items(), key=lambda t: t[0]))
-
-
-def get_params_with_paths_list():
- return ['input_model', 'output_dir', 'caffe_parser_path', 'extensions', 'k', 'output_dir',
- 'input_checkpoint', 'input_meta_graph', 'input_proto', 'input_symbol',
- 'pretrained_model_name', 'saved_model_dir', 'tensorboard_logdir',
- 'tensorflow_custom_layer_libraries', 'tensorflow_custom_operations_config_update',
- 'tensorflow_object_detection_api_pipeline_config',
- 'transformations_config']
-
-
-def get_caffe_cli_parser(parser: argparse.ArgumentParser = None):
- """
- Specifies cli arguments for Model Conversion for Caffe*
-
- Returns
- -------
- ArgumentParser instance
- """
- if not parser:
- parser = argparse.ArgumentParser(usage='%(prog)s [options]')
- get_common_cli_parser(parser=parser)
-
- caffe_group = parser.add_argument_group('Caffe*-specific parameters')
- mo_convert_params_caffe = get_mo_convert_params()['Caffe*-specific parameters:']
- add_args_by_description(caffe_group, mo_convert_params_caffe)
- return parser
-
-
-def get_tf_cli_parser(parser: argparse.ArgumentParser = None):
- """
- Specifies cli arguments for Model Conversion for TF
-
- Returns
- -------
- ArgumentParser instance
- """
- if not parser:
- parser = argparse.ArgumentParser(usage='%(prog)s [options]')
- get_common_cli_parser(parser=parser)
- mo_convert_params_tf = get_mo_convert_params()['TensorFlow*-specific parameters:']
-
- tf_group = parser.add_argument_group('TensorFlow*-specific parameters')
- add_args_by_description(tf_group, mo_convert_params_tf)
- return parser
-
-
-def get_kaldi_cli_parser(parser: argparse.ArgumentParser = None):
- """
- Specifies cli arguments for Model Conversion for Kaldi*
-
- Returns
- -------
- ArgumentParser instance
- """
- if not parser:
- parser = argparse.ArgumentParser(usage='%(prog)s [options]')
- get_common_cli_parser(parser=parser)
-
- kaldi_group = parser.add_argument_group('Kaldi-specific parameters')
- mo_convert_params_kaldi = get_mo_convert_params()['Kaldi-specific parameters:']
- add_args_by_description(kaldi_group, mo_convert_params_kaldi)
- return parser
-
-
-def get_onnx_cli_parser(parser: argparse.ArgumentParser = None):
- """
- Specifies cli arguments for Model Conversion for ONNX
-
- Returns
- -------
- ArgumentParser instance
- """
- if not parser:
- parser = argparse.ArgumentParser(usage='%(prog)s [options]')
- get_common_cli_parser(parser=parser)
-
- return parser
-
-
-def get_all_cli_parser():
- """
- Specifies cli arguments for Model Conversion
-
- Returns
- -------
- ArgumentParser instance
- """
- parser = argparse.ArgumentParser(usage='%(prog)s [options]')
- mo_convert_params_optional = get_mo_convert_params()['Optional parameters:']
- add_args_by_description(parser, mo_convert_params_optional)
-
- get_common_cli_parser(parser=parser)
- get_tf_cli_parser(parser=parser)
- get_caffe_cli_parser(parser=parser)
- get_kaldi_cli_parser(parser=parser)
- get_onnx_cli_parser(parser=parser)
-
- return parser
-
-
-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.
- :param input_value: string passed as input to the "input" command line parameter
- :return: string without type specification
- """
- return re.sub(r'\{.*\}', '', input_value)
-
-
-def get_data_type_from_input_value(input_value: str):
- """
- Returns the numpy data type corresponding to the data type specified in the input value string
- :param input_value: string passed as input to the "input" command line parameter
- :return: the corresponding numpy data type and None if the data type is not specified in the input value
- """
- data_type_match = re.match(r'.*\{(.*)\}.*', input_value)
- return destination_type_to_np_data_type(data_type_match.group(1)) if data_type_match is not None else None
-
-
-def remove_shape_from_input_value(input_value: str):
- """
- Removes the shape specification from the input string. The shape specification is a string enclosed with square
- brackets.
- :param input_value: string passed as input to the "input" command line parameter
- :return: string without shape specification
- """
- assert '->' not in input_value, 'The function should not be called for input_value with constant value specified'
- return re.sub(r'[(\[]([0-9\.?, -]*)[)\]]', '', input_value)
-
-
-def get_shape_from_input_value(input_value: str):
- """
- Returns PartialShape corresponding to the shape specified in the input value string
- :param input_value: string passed as input to the "input" command line parameter
- :return: the corresponding shape and None if the shape is not specified in the input value
- """
- # remove the tensor value from the input_value first
- input_value = input_value.split('->')[0]
-
- # parse shape
- shape = re.findall(r'[(\[]([0-9\.\?, -]*)[)\]]', input_value)
- if len(shape) == 0:
- shape = None
- elif len(shape) == 1 and shape[0] in ['', ' ']:
- # this shape corresponds to scalar
- shape = PartialShape([])
- elif len(shape) == 1:
- dims = re.split(r', *| +', shape[0])
- dims = list(filter(None, dims))
- shape = PartialShape([Dimension(dim) for dim in dims])
- else:
- raise Error("Wrong syntax to specify shape. Use \"input\" "
- "\"node_name[shape]->value\"")
- return shape
-
-
-def get_node_name_with_port_from_input_value(input_value: str):
- """
- Returns the node name (optionally with input/output port) from the input value
- :param input_value: string passed as input to the "input" command line parameter
- :return: the corresponding node name with input/output port
- """
- return remove_shape_from_input_value(remove_data_type_from_input_value(input_value.split('->')[0]))
-
-
-def get_value_from_input_value(input_value: str):
- """
- Returns the value from the input value string
- :param input_value: string passed as input to the "input" command line parameter
- :return: the corresponding value or None if it is not specified
- """
- parts = input_value.split('->')
- value = None
- if len(parts) == 2:
- value = parts[1]
- if value[0] == '[' and value[-1] != ']' or value[0] != '[' and value[-1] == ']':
- raise Error("Wrong syntax to specify value. Use \"input\"=\"node_name[shape]->value\"")
- if '[' in value.strip(' '):
- value = value.replace('[', '').replace(']', '')
- if ',' in value:
- value = value.replace(' ', '')
- value = value.split(',')
- else:
- value = value.split(' ')
- if not isinstance(value, list):
- value = ast.literal_eval(value)
- elif len(parts) > 2:
- raise Error("Wrong syntax to specify value. Use \"input\"=\"node_name[shape]->value\"")
- return value
-
-
-def partial_shape_prod(shape: [PartialShape, tuple]):
- assert not (isinstance(shape, PartialShape) and shape.is_dynamic), \
- "Unable to calculate prod for dynamic shape {}.".format(shape)
-
- prod = 1
- for dim in shape:
- prod *= dim.get_min_length()
- return prod
-
-
-def parse_input_value(input_value: str):
- """
- Parses a value of the "input" command line parameter and gets a node name, shape and value.
- The node name includes a port if it is specified.
- Shape and value is equal to None if they are not specified.
- Parameters
- ----------
- input_value
- string with a specified node name, shape, value and data_type.
- E.g. 'node_name:0[4]{fp32}->[1.0 2.0 3.0 4.0]'
-
- Returns
- -------
- Node name, shape, value, data type
- E.g. 'node_name:0', '4', [1.0 2.0 3.0 4.0], np.float32
- """
- data_type = get_data_type_from_input_value(input_value)
- node_name = get_node_name_with_port_from_input_value(input_value)
- value = get_value_from_input_value(input_value)
- shape = get_shape_from_input_value(input_value)
- value_size = np.prod(len(value)) if isinstance(value, list) else 1
-
- if value is not None and shape is not None:
- for dim in shape:
- if isinstance(dim, Dimension) and dim.is_dynamic:
- raise Error("Cannot freeze input with dynamic shape: {}".format(shape))
-
- if shape is not None and value is not None and partial_shape_prod(shape) != value_size:
- raise Error("The shape '{}' of the input node '{}' does not correspond to the number of elements '{}' in the "
- "value: {}".format(shape, node_name, value_size, value))
- return node_name, shape, value, data_type
-
-
-def split_str_avoiding_square_brackets(s: str) -> list:
- """
- Splits a string by comma, but skips commas inside square brackets.
- :param s: string to split
- :return: list of strings split by comma
- """
- res = list()
- skipping = 0
- last_idx = 0
- for i, c in enumerate(s):
- if c == '[':
- skipping += 1
- elif c == ']':
- skipping -= 1
- elif c == ',' and skipping == 0:
- res.append(s[last_idx:i])
- last_idx = i + 1
- res.append(s[last_idx:])
- return res
-
-
-def split_layouts_by_arrow(s: str) -> tuple:
- """
- Splits a layout string by first arrow (->).
- :param s: string to split
- :return: tuple containing source and target layouts
- """
- arrow = s.find('->')
- if arrow != -1:
- source_layout = s[:arrow]
- target_layout = s[arrow + 2:]
- if source_layout == '':
- source_layout = None
- if target_layout == '':
- target_layout = None
- return source_layout, target_layout
- else:
- return s, None
-
-
-def validate_layout(layout: str):
- """
- Checks if layout is of valid format.
- :param layout: string containing layout
- :raises: if layout is incorrect
- """
- error_msg = 'Invalid layout parsed: {}'.format(layout)
- if layout:
- incorrect_brackets = xor(layout[0] == '[', layout[-1] == ']')
- if incorrect_brackets or layout[-1] == '-':
- error_msg += ', did you forget quotes?'
- else:
- valid_layout_re = re.compile(r'\[?[^\[\]\(\)\-\s]*\]?')
- if valid_layout_re.fullmatch(layout):
- return
- raise Error(error_msg)
-
-
-def write_found_layout(name: str, found_layout: str, parsed: dict, dest: str = None):
- """
- Writes found layout data to the 'parsed' dict.
- :param name: name of the node to add layout
- :param found_layout: string containing layout for the node
- :param parsed: dict where result will be stored
- :param dest: type of the command line:
- * 'source' is "source_layout"
- * 'target' is "target_layout"
- * None is "layout"
- """
- s_layout = None
- t_layout = None
- if name in parsed:
- s_layout = parsed[name]['source_layout']
- t_layout = parsed[name]['target_layout']
- if dest == 'source':
- s_layout = found_layout
- elif dest == 'target':
- t_layout = found_layout
- else:
- s_layout, t_layout = split_layouts_by_arrow(found_layout)
- validate_layout(s_layout)
- validate_layout(t_layout)
- parsed[name] = {'source_layout': s_layout, 'target_layout': t_layout}
-
-
-def write_found_layout_list(idx: int, found_layout: str, parsed: list, dest: str = None):
- """
- Writes found layout data to the 'parsed' dict.
- :param idx: idx of of the node to add layout
- :param found_layout: string containing layout for the node
- :param parsed: list where result will be stored
- :param dest: type of the command line:
- * 'source' is "source_layout"
- * 'target' is "target_layout"
- * None is "layout"
- """
- s_layout = None
- t_layout = None
- if idx < len(parsed):
- s_layout = parsed[idx]['source_layout']
- t_layout = parsed[idx]['target_layout']
- if dest == 'source':
- s_layout = found_layout
- elif dest == 'target':
- t_layout = found_layout
- else:
- s_layout, t_layout = split_layouts_by_arrow(found_layout)
- validate_layout(s_layout)
- validate_layout(t_layout)
-
- if idx < len(parsed):
- parsed[idx] = {'source_layout': s_layout, 'target_layout': t_layout}
- else:
- parsed.append({'source_layout': s_layout, 'target_layout': t_layout})
-
-
-def parse_layouts_by_destination(s: str, parsed: dict, parsed_list: list, dest: str = None) -> None:
- """
- Parses layout command line to get all names and layouts from it. Adds all found data in the 'parsed' dict.
- :param s: string to parse
- :param parsed: dict where result will be stored
- :param dest: type of the command line:
- * 'source' is "source_layout"
- * 'target' is "target_layout"
- * None is "layout"
- """
- list_s = split_str_avoiding_square_brackets(s)
- if len(list_s) == 1 and (list_s[0][-1] not in ')]' or (list_s[0][0] == '[' and list_s[0][-1] == ']')):
- # single layout case
- write_found_layout('', list_s[0], parsed, dest)
- else:
- for idx, layout_str in enumerate(list_s):
- # case for: "name1(nhwc->[n,c,h,w])"
- p1 = re.compile(r'([^\[\]\(\)]*)\((\S+)\)')
- m1 = p1.match(layout_str)
- # case for: "name1[n,h,w,c]->[n,c,h,w]"
- p2 = re.compile(r'([^\[\]\(\)]*)(\[\S*\])')
- m2 = p2.match(layout_str)
- if m1:
- found_g = m1.groups()
- elif m2:
- found_g = m2.groups()
- else:
- # case for layout without name
- write_found_layout_list(idx, layout_str, parsed_list, dest)
- continue
- if len(found_g[0]) > 0:
- write_found_layout(found_g[0], found_g[1], parsed, dest)
- else:
- write_found_layout_list(idx, found_g[1], parsed_list, dest)
-
-
-def get_layout_values(argv_layout: str = '', argv_source_layout: str = '', argv_target_layout: str = ''):
- """
- Parses layout string.
- :param argv_layout: string with a list of layouts passed as a "layout".
- :param argv_source_layout: string with a list of layouts passed as a "source_layout".
- :param argv_target_layout: string with a list of layouts passed as a "target_layout".
- :return: dict with names and layouts associated
- """
- if argv_layout and (argv_source_layout or argv_target_layout):
- raise Error("\"layout\" is used as well as \"source_layout\" and/or \"target_layout\" which is not allowed, please "
- "use one of them.")
- res = {}
- res_list = []
- if argv_layout:
- parse_layouts_by_destination(argv_layout, res, res_list)
- if argv_source_layout:
- parse_layouts_by_destination(argv_source_layout, res, res_list, 'source')
- if argv_target_layout:
- parse_layouts_by_destination(argv_target_layout, res, res_list, 'target')
- if len(res) > 0 and len(res_list) > 0:
- raise Error("Some layout values are provided with names, and some without names. "
- "Please provide ether all layouts with names or all layouts without names.")
- if len(res) > 0:
- return res
- else:
- return res_list
-
-
-def parse_freeze_placeholder_values(argv_freeze_placeholder_with_value: str):
- """
- Parses parse_freeze_placeholder_values string.
- :param argv_freeze_placeholder_with_value: string information on freezing placeholders
- :return: dictionary where key is node name, value is node value.
- """
- placeholder_values = {}
- if argv_freeze_placeholder_with_value is not None:
- for plh_with_value in argv_freeze_placeholder_with_value.split(','):
- plh_with_value = plh_with_value.split('->')
- if len(plh_with_value) != 2:
- raise Error("Wrong replacement syntax. Use \"freeze_placeholder_with_value\" "
- "\"node1_name->value1,node2_name->value2\"")
- node_name = plh_with_value[0]
- value = plh_with_value[1]
- if node_name in placeholder_values and placeholder_values[node_name] != value:
- raise Error("Overriding replacement value of the placeholder with name '{}': old value = {}, new value = {}"
- ".".format(node_name, placeholder_values[node_name], value))
- if '[' in value.strip(' '):
- value = value.replace('[', '').replace(']', '').split(' ')
- placeholder_values[node_name] = value
- return placeholder_values
-
-
-def get_freeze_placeholder_values(argv_input: str, argv_freeze_placeholder_with_value: str):
- """
- Parses values for placeholder freezing and input node names
-
- Parameters
- ----------
- argv_input
- string with a list of input layers: either an empty string, or strings separated with comma.
- 'node_name1[shape1]->value1,node_name2[shape2]->value2,...'
- argv_freeze_placeholder_with_value
- string with a list of input shapes: either an empty string, or tuples separated with comma.
- 'placeholder_name1->value1, placeholder_name2->value2,...'
-
- Returns
- -------
- parsed placeholders with values for freezing
- input nodes cleaned from shape info
- """
- placeholder_values = parse_freeze_placeholder_values(argv_freeze_placeholder_with_value)
- input_node_names = None
-
- if argv_input is not None:
- input_node_names = ''
- # walkthrough all input values and save values for freezing
- for input_value in split_inputs(argv_input):
- node_name, _, value, _ = parse_input_value(input_value)
- input_node_names = input_node_names + ',' + node_name if input_node_names != '' else node_name
- if value is None: # no value is specified for freezing
- continue
- if node_name in placeholder_values and placeholder_values[node_name] != value:
- raise Error("Overriding replacement value of the placeholder with name '{}': old value = {}, new value = {}"
- ".".format(node_name, placeholder_values[node_name], value))
- placeholder_values[node_name] = value
-
- return placeholder_values, input_node_names
-
-
-def split_inputs(input_str):
- brakets_count = 0
- inputs = []
- while input_str:
- idx = 0
- for c in input_str:
- if c == '[':
- brakets_count += 1
- if c == ']':
- brakets_count -= 1
- if c == ',':
- if brakets_count != 0:
- idx += 1
- continue
- else:
- break
- idx += 1
- if idx >= len(input_str)-1:
- inputs.append(input_str)
- break
- inputs.append(input_str[:idx])
- input_str = input_str[idx+1:]
- return inputs
-
-
-
-def split_shapes(argv_input_shape: str):
- range_reg = r'([0-9]*\.\.[0-9]*)'
- first_digit_reg = r'([0-9 ]+|-1|\?|{})'.format(range_reg)
- next_digits_reg = r'(,{})*'.format(first_digit_reg)
- tuple_reg = r'((\({}{}\))|(\[{}{}\]))'.format(first_digit_reg, next_digits_reg,
- first_digit_reg, next_digits_reg)
-
- full_reg = r'^{}(\s*,\s*{})*$|^$'.format(tuple_reg, tuple_reg)
- if not re.match(full_reg, argv_input_shape):
- raise Error('Input shape "{}" cannot be parsed. ' + refer_to_faq_msg(57), argv_input_shape)
- return re.findall(r'[(\[]([0-9,\.\? -]+)[)\]]', argv_input_shape)
-
-def get_placeholder_shapes(argv_input: str, argv_input_shape: str, argv_batch=None):
- """
- Parses input layers names and input shapes from the cli and returns the parsed object.
- All shapes are specified only through one command line option either "input" or "input_shape".
-
- Parameters
- ----------
- argv_input
- string with a list of input layers: either an empty string, or strings separated with comma.
- E.g. 'inp1,inp2', 'node_name1[shape1]->value1,node_name2[shape2]->value2'
- argv_input_shape
- string with a list of input shapes: either an empty string, or tuples separated with comma.
- E.g. '[1,2],[3,4]'.
- Only positive integers are accepted.
- '?' marks dynamic dimension.
- Partial shape is specified with ellipsis. E.g. '[1..10,2,3]'
- argv_batch
- integer that overrides batch size in input shape
-
- Returns
- -------
- parsed shapes in form of {'name of input':tuple} if names of inputs are provided with shapes
- parsed shapes in form of {'name of input':None} if names of inputs are provided without shapes
- tuple if only one shape is provided and no input name
- None if neither shape nor input were provided
- """
- if argv_input_shape and argv_batch:
- raise Error("Both \"input_shape\" and \"batch\" were provided. Please provide only one of them. " +
- refer_to_faq_msg(56))
-
- # attempt to extract shapes from "input" parameters
- placeholder_shapes = dict()
- placeholder_data_types = dict()
- are_shapes_specified_through_input = False
- inputs_list = list()
- if argv_input:
- for input_value in split_inputs(argv_input):
- node_name, shape, _, data_type = parse_input_value(input_value)
- placeholder_shapes[node_name] = shape
- inputs_list.append(node_name)
- if data_type is not None:
- placeholder_data_types[node_name] = data_type
- if shape is not None:
- are_shapes_specified_through_input = True
-
- if argv_input_shape and are_shapes_specified_through_input:
- raise Error("Shapes are specified using both \"input\" and \"input_shape\" command-line parameters, but only one "
- "parameter is allowed.")
-
- if argv_batch and are_shapes_specified_through_input:
- raise Error("Shapes are specified using both \"input\" and \"batch\" command-line parameters, but only one "
- "parameter is allowed.")
-
- if are_shapes_specified_through_input:
- return inputs_list, placeholder_shapes, placeholder_data_types
-
- shapes = list()
- inputs = list()
- inputs_list = list()
- placeholder_shapes = None
-
-
- if argv_input_shape:
- shapes = split_shapes(argv_input_shape)
-
- if argv_input:
- inputs = split_inputs(argv_input)
- inputs = [remove_data_type_from_input_value(inp) for inp in inputs]
-
- # check number of shapes with no input provided
- if argv_input_shape and not argv_input:
- placeholder_shapes = [PartialShape(shape) for shape in shapes]
- if len(placeholder_shapes) == 1:
- placeholder_shapes = PartialShape(placeholder_shapes[0])
- # check if number of shapes does not match number of passed inputs
- elif argv_input and (len(shapes) == len(inputs) or len(shapes) == 0):
- # clean inputs from values for freezing
- inputs_without_value = list(map(lambda x: x.split('->')[0], inputs))
- placeholder_shapes = dict(zip_longest(inputs_without_value,
- map(lambda x: PartialShape(x) if x else None, shapes)))
- for inp in inputs:
- if '->' not in inp:
- inputs_list.append(inp)
- continue
- shape = placeholder_shapes[inp.split('->')[0]]
- inputs_list.append(inp.split('->')[0])
-
- if shape is None:
- continue
- for dim in shape:
- if isinstance(dim, Dimension) and not dim.is_static:
- raise Error("Cannot freeze input with dynamic shape: {}".format(shape))
-
- elif argv_input:
- raise Error('Please provide each input layers with an input layer shape. ' + refer_to_faq_msg(58))
-
- return inputs_list, placeholder_shapes, placeholder_data_types
-
-
-def parse_tuple_pairs(argv_values: str):
- """
- Gets mean/scale values from the given string parameter
- Parameters
- ----------
- argv_values
- string with a specified input name and list of mean values: either an empty string, or a tuple
- in a form [] or ().
- E.g. 'data(1,2,3)' means 1 for the RED channel, 2 for the GREEN channel, 3 for the BLUE channel for the data
- input layer, or tuple of values in a form [] or () if input is specified separately, e.g. (1,2,3),[4,5,6].
-
- Returns
- -------
- dictionary with input name and tuple of values or list of values if mean/scale value is specified with input,
- e.g.:
- "data(10,20,30),info(11,22,33)" -> { 'data': [10,20,30], 'info': [11,22,33] }
- "(10,20,30),(11,22,33)" -> [mo_array(10,20,30), mo_array(11,22,33)]
- """
- res = {}
- if not argv_values:
- return res
-
- matches = [m for m in re.finditer(r'[(\[]([0-9., -]+)[)\]]', argv_values, re.IGNORECASE)]
-
- error_msg = 'Mean/scale values should consist of name and values specified in round or square brackets ' \
- 'separated by comma, e.g. data(1,2,3),info[2,3,4],egg[255] or data(1,2,3). Or just plain set of ' \
- 'values without names: (1,2,3),(2,3,4) or [1,2,3],[2,3,4].' + refer_to_faq_msg(101)
- if not matches:
- raise Error(error_msg, argv_values)
-
- name_start_idx = 0
- name_was_present = False
- for idx, match in enumerate(matches):
- input_name = argv_values[name_start_idx:match.start(0)]
- name_start_idx = match.end(0) + 1
- tuple_value = np.fromstring(match.groups()[0], dtype=float, sep=',')
-
- if idx != 0 and (name_was_present ^ bool(input_name)):
- # if node name firstly was specified and then subsequently not or vice versa
- # e.g. (255),input[127] or input(255),[127]
- raise Error(error_msg, argv_values)
-
- name_was_present = True if input_name != "" else False
- if name_was_present:
- res[input_name] = tuple_value
- else:
- res[idx] = tuple_value
-
- if not name_was_present:
- # return a list instead of a dictionary
- res = sorted(res.values(), key=lambda v: v[0])
- return res
-
-
-def get_tuple_values(argv_values: str or tuple, num_exp_values: int = 3, t=float or int):
- """
- Gets mean values from the given string parameter
- Args:
- argv_values: string with list of mean values: either an empty string, or a tuple in a form [] or ().
- E.g. '(1,2,3)' means 1 for the RED channel, 2 for the GREEN channel, 4 for the BLUE channel.
- t: either float or int
- num_exp_values: number of values in tuple
-
- Returns:
- tuple of values
- """
-
- digit_reg = r'(-?[0-9. ]+)' if t == float else r'(-?[0-9 ]+)'
-
- assert num_exp_values > 1, 'Can not parse tuple of size 1'
- content = r'{0}\s*,{1}\s*{0}'.format(digit_reg, (digit_reg + ',') * (num_exp_values - 2))
- tuple_reg = r'((\({0}\))|(\[{0}\]))'.format(content)
-
- if isinstance(argv_values, tuple) and not len(argv_values):
- return argv_values
-
- if not len(argv_values) or not re.match(tuple_reg, argv_values):
- raise Error('Values "{}" cannot be parsed. ' +
- refer_to_faq_msg(59), argv_values)
-
- mean_values_matches = re.findall(r'[(\[]([0-9., -]+)[)\]]', argv_values)
-
- for mean in mean_values_matches:
- if len(mean.split(',')) != num_exp_values:
- raise Error('{} channels are expected for given values. ' +
- refer_to_faq_msg(60), num_exp_values)
-
- return mean_values_matches
-
-
-def split_node_in_port(node_id: str):
- """Split node_id in form port:node to separate node and port, where port is converted to int"""
- if isinstance(node_id, str):
- separator = ':'
- parts = node_id.split(separator)
- if len(parts) > 1:
- if parts[0].isdigit():
- node_name = separator.join(parts[1:])
- try:
- port = int(parts[0])
- return node_name, port
- except ValueError as err:
- log.warning('Didn\'t recognize port:node format for "{}" because port is not an integer.'.format(
- node_id))
- else:
- node_name = separator.join(parts[:-1])
- try:
- port = int(parts[-1])
- return node_name, port
- except ValueError as err:
- log.warning('Didn\'t recognize node:port format for "{}" because port is not an integer.'.format(
- node_id))
-
- return node_id, None
-
-
-def get_mean_scale_dictionary(mean_values, scale_values, argv_input: list):
- """
- This function takes mean_values and scale_values, checks and processes them into convenient structure
-
- Parameters
- ----------
- mean_values dictionary, contains input name and mean values passed py user (e.g. {data: np.array[102.4, 122.1, 113.9]}),
- or list containing values (e.g. np.array[102.4, 122.1, 113.9])
- scale_values dictionary, contains input name and scale values passed py user (e.g. {data: np.array[102.4, 122.1, 113.9]})
- or list containing values (e.g. np.array[102.4, 122.1, 113.9])
-
- Returns
- -------
- The function returns a dictionary e.g.
- mean = { 'data': np.array, 'info': np.array }, scale = { 'data': np.array, 'info': np.array }, input = "data, info" ->
- { 'data': { 'mean': np.array, 'scale': np.array }, 'info': { 'mean': np.array, 'scale': np.array } }
-
- """
- res = {}
- # collect input names
- if argv_input:
- inputs = [get_node_name_with_port_from_input_value(input_value) for input_value in split_inputs(argv_input)]
- else:
- inputs = []
- if type(mean_values) is dict:
- inputs = list(mean_values.keys())
- if type(scale_values) is dict:
- for name in scale_values.keys():
- if name not in inputs:
- inputs.append(name)
-
- # create unified object containing both mean and scale for input
- if type(mean_values) is dict and type(scale_values) is dict:
- if not mean_values and not scale_values:
- return res
-
- for inp_scale in scale_values.keys():
- if inp_scale not in inputs:
- raise Error("Specified scale_values name '{}' do not match to any of inputs: {}. "
- "Please set 'scale_values' that correspond to values from input.".format(inp_scale, inputs))
-
- for inp_mean in mean_values.keys():
- if inp_mean not in inputs:
- raise Error("Specified mean_values name '{}' do not match to any of inputs: {}. "
- "Please set 'mean_values' that correspond to values from input.".format(inp_mean, inputs))
-
- for inp in inputs:
- inp, port = split_node_in_port(inp)
- if inp in mean_values or inp in scale_values:
- res.update(
- {
- inp: {
- 'mean':
- mean_values[inp] if inp in mean_values else None,
- 'scale':
- scale_values[inp] if inp in scale_values else None
- }
- }
- )
- return res
-
- # user specified input and mean/scale separately - we should return dictionary
- if inputs:
- if mean_values and scale_values:
- if len(inputs) != len(mean_values):
- raise Error('Numbers of inputs and mean values do not match. ' +
- refer_to_faq_msg(61))
- if len(inputs) != len(scale_values):
- raise Error('Numbers of inputs and scale values do not match. ' +
- refer_to_faq_msg(62))
-
- data = list(zip(mean_values, scale_values))
-
- for i in range(len(data)):
- res.update(
- {
- inputs[i]: {
- 'mean':
- data[i][0],
- 'scale':
- data[i][1],
-
- }
- }
- )
- return res
- # only mean value specified
- if mean_values:
- data = list(mean_values)
- for i in range(len(data)):
- res.update(
- {
- inputs[i]: {
- 'mean':
- data[i],
- 'scale':
- None
-
- }
- }
- )
- return res
-
- # only scale value specified
- if scale_values:
- data = list(scale_values)
- for i in range(len(data)):
- res.update(
- {
- inputs[i]: {
- 'mean':
- None,
- 'scale':
- data[i]
-
- }
- }
- )
- return res
- # mean and/or scale are specified without inputs
- return list(zip_longest(mean_values, scale_values))
-
-
-def get_model_name(path_input_model: str) -> str:
- """
- Deduces model name by a given path to the input model
- Args:
- path_input_model: path to the input model
-
- Returns:
- name of the output IR
- """
- parsed_name, extension = os.path.splitext(os.path.basename(path_input_model))
- return 'model' if parsed_name.startswith('.') or len(parsed_name) == 0 else parsed_name
-
-
-def get_model_name_from_args(argv: argparse.Namespace):
- model_name = ""
- if hasattr(argv, 'model_name'):
- if argv.model_name:
- model_name = argv.model_name
- elif argv.input_model:
- model_name = get_model_name(argv.input_model)
- elif argv.saved_model_dir:
- model_name = "saved_model"
- elif argv.input_meta_graph:
- model_name = get_model_name(argv.input_meta_graph)
- elif argv.input_symbol:
- model_name = get_model_name(argv.input_symbol)
- argv.model_name = model_name
- return model_name
-
-
-def get_absolute_path(path_to_file: str) -> str:
- """
- Deduces absolute path of the file by a given path to the file
- Args:
- path_to_file: path to the file
-
- Returns:
- absolute path of the file
- """
- file_path = os.path.expanduser(path_to_file)
- if not os.path.isabs(file_path):
- file_path = os.path.join(os.getcwd(), file_path)
- return file_path
-
-
-def isfloat(value):
- try:
- float(value)
- return True
- except ValueError:
- return False
-
-
-def isbool(value):
- try:
- strtobool(value)
- return True
- except ValueError:
- return False
-
-
-def isdict(value):
- try:
- evaluated = ast.literal_eval(value)
- return isinstance(evaluated, dict)
- except ValueError:
- return False
-
-
-def convert_string_to_real_type(value: str):
- if isdict(value):
- return ast.literal_eval(value)
-
- values = value.split(',')
- for i in range(len(values)):
- value = values[i]
- if value.isdigit():
- values[i] = int(value)
- elif isfloat(value):
- values[i] = float(value)
- elif isbool(value):
- values[i] = strtobool(value)
-
- return values[0] if len(values) == 1 else values
-
-
-def parse_transform(transform: str) -> list:
- transforms = []
-
- if len(transform) == 0:
- return transforms
-
- all_transforms = re.findall(r"([a-zA-Z0-9]+)(\[([^\]]+)\])*(,|$)", transform)
-
- # Check that all characters were matched otherwise transform key value is invalid
- key_len = len(transform)
- for transform in all_transforms:
- # In regexp we have 4 groups where 1st group - transformation_name,
- # 2nd group - [args],
- # 3rd group - args, <-- nested group
- # 4th group - EOL
- # And to check that regexp matched all string we decrease total length by the length of matched groups (1,2,4)
- # In case if no arguments were given to transformation then 2nd and 3rd groups will be empty.
- if len(transform) != 4:
- raise Error("Unexpected transform key structure: {}".format(transform))
- key_len -= len(transform[0]) + len(transform[1]) + len(transform[3])
-
- if key_len != 0:
- raise Error("Unexpected transform key structure: {}".format(transform))
-
- for transform in all_transforms:
- name = transform[0]
- args = transform[2]
-
- args_dict = {}
-
- if len(args) != 0:
- for arg in args.split(';'):
- m = re.match(r"^([_a-zA-Z]+)=(.+)$", arg)
- if not m:
- raise Error("Unrecognized attributes for transform key: {}".format(transform))
-
- args_dict[m.group(1)] = convert_string_to_real_type(m.group(2))
-
- transforms.append((name, args_dict))
-
- return transforms
-
-
-def check_available_transforms(transforms: list):
- """
- This function check that transformations specified by user are available.
- :param transforms: list of user specified transformations
- :return: raises an Error if transformation is not available
- """
- from openvino.tools.mo.back.offline_transformations import get_available_transformations # pylint: disable=no-name-in-module,import-error
- available_transforms = get_available_transformations()
-
- missing_transformations = []
- for name, _ in transforms:
- if name not in available_transforms.keys():
- missing_transformations.append(name)
-
- if len(missing_transformations) != 0:
- raise Error('Following transformations ({}) are not available. '
- 'List with available transformations ({})'.format(','.join(missing_transformations),
- ','.join(available_transforms.keys())))
- return True
-
-
-def check_positive(value):
- try:
- int_value = int(value)
- if int_value <= 0:
- raise ValueError
- except ValueError:
- raise argparse.ArgumentTypeError("expected a positive integer value")
-
- return int_value
-
-
-def check_bool(value):
- if isinstance(value, bool):
- return value
- elif isinstance(value, str):
- if value.lower() not in ['true', 'false']:
- raise argparse.ArgumentTypeError("expected a True/False value")
- return value.lower() == 'true'
- else:
- raise argparse.ArgumentTypeError("expected a bool or str type")
-
-
-def depersonalize(value: str, key: str):
- dir_keys = [
- 'output_dir', 'extensions', 'saved_model_dir', 'tensorboard_logdir', 'caffe_parser_path'
- ]
- if isinstance(value, list):
- updated_value = []
- for elem in value:
- updated_value.append(depersonalize(elem, key))
- return updated_value
-
- if not isinstance(value, str):
- return value
- res = []
- for path in value.split(','):
- if os.path.isdir(path) and key in dir_keys:
- res.append('DIR')
- elif os.path.isfile(path):
- res.append(os.path.join('DIR', os.path.split(path)[1]))
- else:
- res.append(path)
- return ','.join(res)
-
-def get_available_front_ends(fem=None):
- # Use this function as workaround to avoid IR frontend usage by MO
- if fem is None:
- return []
- available_moc_front_ends = fem.get_available_front_ends()
- if 'ir' in available_moc_front_ends:
- available_moc_front_ends.remove('ir')
-
- return available_moc_front_ends
diff --git a/tools/mo/openvino/tools/mo/utils/convert.py b/tools/mo/openvino/tools/mo/utils/convert.py
deleted file mode 100755
index fe4d02e66571de..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/convert.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import sys
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-try:
- import tensorflow.compat.v1 as tf_v1
-except ImportError:
- import tensorflow as tf_v1
-
-#in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
-tf_v1.get_logger().setLevel("ERROR")
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
-from openvino.tools.mo.front.tf.loader import load_tf_graph_def
-
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
-
-
-def argparser():
- parser = argparse.ArgumentParser()
- parser.add_argument("--to_pbtxt", dest='pb', type=str, help="Path to TensorFlow binary model")
- parser.add_argument('--to_pb', dest='pbtxt', type=str, help="Path to TensorFlow text model")
- return parser.parse_args()
-
-
-def convert(filename: str, is_text: bool):
- if not os.path.isfile(filename):
- raise FileNotFoundError("File doesn't exist: {}".format(filename))
- new_ext = ".pbtxt" if is_text else ".pb"
- head, tail = os.path.split(os.path.abspath(filename))
- print("Convert: {} \n to: {}".format(filename, os.path.join(head, tail + new_ext)))
- graph_def, _, _, _ = load_tf_graph_def(graph_file_name=filename, is_binary=is_text)
- tf_v1.import_graph_def(graph_def, name='')
- tf_v1.train.write_graph(graph_def, head, tail + new_ext, as_text=is_text)
-
-
-if __name__ == '__main__':
- argv = argparser()
- if argv.pb is None and argv.pbtxt is None:
- print("Please provide model to convert --to_pb or --to_pbtxt")
- sys.exit(1)
- if argv.pb is not None:
- convert(argv.pb, True)
- if argv.pbtxt is not None:
- convert(argv.pbtxt, False)
diff --git a/tools/mo/openvino/tools/mo/utils/custom_replacement_config.py b/tools/mo/openvino/tools/mo/utils/custom_replacement_config.py
deleted file mode 100644
index 83656f2f863f06..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/custom_replacement_config.py
+++ /dev/null
@@ -1,417 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import json
-import logging as log
-import os
-from re import compile, match
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.graph import nodes_matching_name_pattern, sub_graph_between_nodes
-from openvino.tools.mo.utils.json_schema import schema_dict
-from openvino.tools.mo.utils.utils import get_mo_root_dir, refer_to_faq_msg
-
-
-class CustomReplacementDescriptor(object):
- registered_types = dict()
-
- def __init__(self, replacement_id: str, attrs: dict = None):
- """
- Create class instance based on attrs dictionary which is read from the configuration file.
- :param attrs:
- """
- super(CustomReplacementDescriptor, self).__setattr__('replacement_id', replacement_id)
- if attrs is not None:
- super(CustomReplacementDescriptor, self).__setattr__('custom_attributes',
- attrs.setdefault('custom_attributes', {}))
- super(CustomReplacementDescriptor, self).__setattr__('_replacement_desc', attrs.copy())
-
- def __getattr__(self, k):
- return self._replacement_desc[k]
-
- def __setattr__(self, k, v):
- # you can assign only existing attributes
- if k not in self._replacement_desc:
- raise AttributeError
- self._replacement_desc[k] = v
-
- def has(self, attr):
- """
- Check that attribute 'attr' is defined for the CustomReplacementDescriptor.
- :param attr: attribute to check.
- :return: True if the attribute exists and False otherwise.
- """
- return attr in self._replacement_desc
-
- @classmethod
- def register_type(cls, match_kind: str, class_type: object):
- if match_kind in cls.registered_types:
- log.warning('Class for match kind "{}" is already registered'.format(match_kind))
- else:
- cls.registered_types[match_kind] = class_type
-
- @classmethod
- def create_instance(cls, match_kind: str, replacement_id: str, attrs: dict = None):
- """
- Fabric method to create proper object based on match_kind.
- :param match_kind: match kind.
- :param replacement_id: id of the replacement.
- :param attrs: optional attributes to be set.
- :return: object of the sub-class of the CustomLayerDescriptor class or None if the match kind is not registered.
- """
- if attrs is None:
- attrs = dict()
- if match_kind in cls.registered_types:
- return cls.registered_types[match_kind](replacement_id, attrs)
- else:
- raise Error('No class registered for match kind "{}". Supported match kinds are "{}". '.format(
- match_kind, list(cls.registered_types.keys())) +
- refer_to_faq_msg(65))
-
- def sub_graph_instances(self):
- raise Exception("The function 'get_sub_graph_instances' must be implemented in the sub-class.")
-
- def get_config_file_representation(self):
- result = {
- 'match_kind': self.match_kind, 'instances': self.instances,
- 'inputs': self.inputs, 'outputs': self.outputs,
- 'custom_attributes': self.custom_attributes, 'id': self.id
- }
- if self.has('op'):
- result.update({'op': self.op})
- return result
-
- def get_inputs_description(self):
- """
- Returns description of inputs of the layer with id 'layer_id'. The format of inputs is the following: list of
- lists where each list contains information about nodes consuming the same tensor from outside of the graph. Each
- element of the list is a pair where first element is a regular expression for the name of the node in the
- sub-graph and the second is the input port of this node.
- :return: description of inputs or None if layer with such id is not registered or information about inputs is
- not available.
- """
- if 'inputs' not in self._replacement_desc:
- log.error("Information about inputs of layer with id '{}' is not available".format(self.replacement_id))
- return None
- result = list()
- for index, input_desc in enumerate(self._replacement_desc['inputs']):
- result.append([(inp['node'], inp['port']) for inp in input_desc])
- return result
-
- def get_outputs_description(self):
- """
- Returns description of outputs of the layer with id 'layer_id'. The format of outputs is the following: list of
- pairs where the first element of the pair is a regular expression for the name of the node that produces output
- of the sub-graph and the second is the output port of this node.
- :return: description of outputs or None if layer with such id is not registered or information about outputs is
- not available.
- """
- if 'outputs' not in self._replacement_desc:
- log.error("Information about outputs of layer with id '{}' is not available")
- return None
- return [(out['node'], out['port']) for out in self._replacement_desc['outputs']]
-
- def update_custom_replacement_attributes(self, graph: Graph):
- """
- The function run specific functions to update attributes of the custom replacement description. Currently it
- updates information about input/output nodes.
- :param graph: graph to operate on.
- :return: True if the update process completed successfully.
- """
- raise Exception("The function 'update_custom_layer_attributes' must be implemented in the sub-class.")
-
- def validate_data(self):
- """
- Validates layer description dictionary.
- :return: list of errors identified.
- """
- errors = list()
- if not self.has('id'):
- errors.append("Replacement id is not specified for custom replacement '{}'".format(self.replacement_id))
- if not self.has('instances') or self.instances == '':
- errors.append("Attribute 'instances' is not specified for replacement '{}'".format(self.replacement_id))
- if not self.has('match_kind'):
- errors.append("Replacement match type is not specified for replacement '{}'".format(self.replacement_id))
- return errors
-
-
-class CustomReplacementDescriptorPoints(CustomReplacementDescriptor):
- """
- Class that is used to describe custom replacement which is a sub-graph specified by start and end points.
- """
-
- def __init__(self, replacement_id: str, attrs: dict = None):
- super().__init__(replacement_id, attrs)
- if not self.has('include_inputs_to_sub_graph'):
- super(CustomReplacementDescriptorPoints, self).__setattr__('include_inputs_to_sub_graph', True)
- if not self.has('include_outputs_to_sub_graph'):
- super(CustomReplacementDescriptorPoints, self).__setattr__('include_outputs_to_sub_graph', True)
-
- def get_config_file_representation(self):
- result = {
- 'match_kind': self.match_kind, 'instances': self.instances,
- 'custom_attributes': self.custom_attributes, 'id': self.id,
- 'include_inputs_to_sub_graph': bool(self.include_inputs_to_sub_graph),
- 'include_outputs_to_sub_graph': bool(self.include_outputs_to_sub_graph)
- }
- if self.has('op'):
- result.update({'op': self.op})
- return result
-
- def get_inputs_description(self):
- return [[('^' + node_name + '$', 0)] for node_name in self.instances['start_points']]
-
- def get_outputs_description(self):
- return [('^' + node_name + '$', 0) for node_name in self.instances['end_points']]
-
- def get_internal_input_nodes(self, graph: Graph):
- """
- Gets list of node names getting input from outside of the sub-graph. This function checks whether input nodes
- specified in the configuration file should be added to the sub-graph or not. If they should not be added to the
- sub-graph then input nodes of the sub-graph are children of these nodes.
- :param graph: graph to operate on.
- :return: list of input node names.
- """
- if not self.include_inputs_to_sub_graph:
- log.debug('Do not include inputs to sub-graph for replacement with id {}'.format(self.replacement_id))
- new_start_nodes = set()
- for start_node in self.instances['start_points']:
- for _, out_node_name in graph.out_edges(start_node):
- new_start_nodes.add(out_node_name)
- start_nodes = list(new_start_nodes)
- log.debug('New inputs are: {}'.format(start_nodes))
- return start_nodes
- else:
- return self.instances['start_points']
-
- def get_internal_output_nodes(self, graph: Graph):
- """
- Gets list of node names producing output outside of the sub-graph. This function checks whether output nodes
- specified in the configuration file should be added to the sub-graph or not. If they should not be added to the
- sub-graph then output nodes of the sub-graph are parents of these nodes.
- :param graph: graph to operate on.
- :return: list of output node names.
- """
- if not self.include_outputs_to_sub_graph:
- log.debug('Do not include outputs of sub-graph for replacement with id {}'.format(self.replacement_id))
- new_end_nodes = set()
- for end_node in self.instances['end_points']:
- for in_node_name, _ in graph.in_edges(end_node):
- new_end_nodes.add(in_node_name)
- end_nodes = list(new_end_nodes)
- log.debug('New outputs are: {}'.format(end_nodes))
- return end_nodes
- else:
- return self.instances['end_points']
-
- def update_custom_replacement_attributes(self, graph: Graph):
- if not self.has('instances'):
- raise Error("No instance(s) is(are) defined for the custom replacement '{}'. ".format(self.replacement_id) +
- refer_to_faq_msg(66))
- if not isinstance(self.instances, dict):
- raise Error("The instance must be a single dictionary for the custom replacement with id '{}'. ".format(
- self.replacement_id) +
- refer_to_faq_msg(67))
-
- start_points = self.get_internal_input_nodes(graph)
- end_points = self.get_internal_output_nodes(graph)
-
- matched_nodes = sub_graph_between_nodes(graph, start_points, end_points, include_control_flow=False)
- output_tensors = set()
- input_nodes_mapping = dict() # key is the input tensor name, value is the pair: (input_port, output_node_name)
- for src_node_name, dst_node_name, edge_attrs in graph.edges(data=True):
- dst_node = graph.node[dst_node_name]
-
- # edge outside sub-graph into sub-graph
- if (src_node_name not in matched_nodes) and (dst_node_name in matched_nodes):
- tensor_name = src_node_name + ":" + str(edge_attrs['out'])
- if tensor_name not in input_nodes_mapping:
- input_nodes_mapping[tensor_name] = list()
- input_nodes_mapping[tensor_name].append(('^' + dst_node_name + '$', edge_attrs['in']))
-
- # edge from inside sub-graph to outside sub-graph
- if (src_node_name in matched_nodes) and (dst_node_name not in matched_nodes):
- output_tensors.add(('^' + dst_node['pb'].input[edge_attrs['in']] + '$', edge_attrs['out']))
-
- for node_name in graph.nodes():
- node = Node(graph, node_name)
- if node_name in matched_nodes and len(node.out_nodes()) == 0 and node['pb'].op != 'Const':
- log.debug("Node {} doesn't have output edges. Consider it output".format(node_name))
- output_tensors.add(('^' + node_name + '$', 0))
-
- if not self.has('inputs'):
- self._replacement_desc['inputs'] = [[{'node': desc[0], 'port': desc[1]} for desc in inp]
- for inp in sorted(input_nodes_mapping.values())]
- log.debug('Updated inputs of sub-graph for instance "{}"'.format(self.instances))
-
- if not self.has('outputs'):
- self._replacement_desc['outputs'] = [{'node': node, 'port': port} for node, port in sorted(output_tensors)]
- log.debug('Updated outputs of sub-graph for instance "{}"'.format(self.instances))
-
- def sub_graph_instances(self):
- return [self.instances]
-
-
-CustomReplacementDescriptor.register_type('points', CustomReplacementDescriptorPoints)
-
-
-class CustomReplacementDescriptorScope(CustomReplacementDescriptor):
- """
- Class that is used to describe custom layer which is a sub-graph specified by scope name.
- """
-
- def __init__(self, replacement_id: str, attrs: dict = None):
- super().__init__(replacement_id, attrs)
-
- def update_custom_replacement_attributes(self, graph: Graph):
- if not self.has('instances') or len(self.instances) == 0:
- raise Error("No instances are defined for replacement with id '{}'. ".format(self.replacement_id) +
- refer_to_faq_msg(68))
-
- pattern = self.instances[0] # use the first instance pattern to find input/output nodes patterns
- # TODO verify that all instances will produce the same sub-graph
- matched_nodes = nodes_matching_name_pattern(graph, pattern)
-
- output_tensors = set()
- input_nodes_mapping = dict() # key is the input tensor name, value is the pair: (input_port, output_node_name)
- for src_node_name, dst_node_name, edge_attrs in graph.edges(data=True):
- dst_node = graph.node[dst_node_name]
-
- # edge outside sub-graph into sub-graph
- if (src_node_name not in matched_nodes) and (dst_node_name in matched_nodes):
- tensor_name = src_node_name + ":" + str(edge_attrs['out'])
- if tensor_name not in input_nodes_mapping:
- input_nodes_mapping[tensor_name] = list()
- input_nodes_mapping[tensor_name].append((generate_pattern_for_node(graph, pattern, dst_node_name),
- edge_attrs['in']))
-
- # edge from inside sub-graph to outside sub-graph
- if (src_node_name in matched_nodes) and (dst_node_name not in matched_nodes):
- output_tensors.add(
- (generate_pattern_for_node(graph, pattern, dst_node['pb'].input[edge_attrs['in']]),
- edge_attrs['out']))
-
- for node_name in graph.nodes():
- node = Node(graph, node_name)
- if node_name in matched_nodes and len(node.out_nodes()) == 0 and node['pb'].op != 'Const':
- log.debug("Node {} doesn't have output edges. Consider it output".format(node_name))
- output_tensors.add((generate_pattern_for_node(graph, pattern, node_name), 0))
-
- if not self.has('inputs') or len(self._replacement_desc['inputs']) == 0:
- self._replacement_desc['inputs'] = [[{'node': desc[0], 'port': desc[1]} for desc in inp]
- for inp in sorted(input_nodes_mapping.values())]
- log.debug('Updated inputs of sub-graph for instance "{}"'.format(self.instances))
-
- if not self.has('outputs') or len(self._replacement_desc['outputs']) == 0:
- self._replacement_desc['outputs'] = [{'node': node, 'port': port} for node, port in sorted(output_tensors)]
- log.debug('Updated outputs of sub-graph for instance "{}"'.format(self.instances))
-
- def sub_graph_instances(self):
- return self.instances
-
-
-CustomReplacementDescriptor.register_type('scope', CustomReplacementDescriptorScope)
-
-
-class CustomReplacementDescriptorGeneral(CustomReplacementDescriptor):
- def __init__(self, replacement_id: str, attrs: dict = None):
- super().__init__(replacement_id, attrs)
-
- def validate_data(self):
- """
- Validates layer description dictionary.
- :return: list of errors identified.
- """
- errors = list()
- if not self.has('id'):
- errors.append("Replacement id is not specified for custom replacement '{}'".format(self.replacement_id))
- if not self.has('match_kind'):
- errors.append("Replacement match type is not specified for replacement '{}'".format(self.replacement_id))
- return errors
-
-
-CustomReplacementDescriptor.register_type('general', CustomReplacementDescriptorGeneral)
-
-
-def parse_custom_replacement_config_file(file_name: str):
- """
- Reads custom replacement configuration file file_name.
- :param file_name: name of the file to read from.
- :return: The dictionary where key is the layer id and value is an instance of the CustomLayerDescriptor object.
- """
- if not os.path.exists(file_name):
- raise Error("Custom replacements configuration file '{}' does not exist. ".format(file_name) +
- refer_to_faq_msg(69))
-
- data = load_and_validate_json_config(file_name)
- result = list()
- validation_errors = list()
- for attrs in data:
- if 'id' not in attrs:
- raise Error('One of the custom replacements in the configuration file "{}" does not contain attribute '
- '"id". '.format(file_name) +
- refer_to_faq_msg(71))
- if 'match_kind' not in attrs:
- raise Error('One of the custom replacements in the configuration file "{}" does not contain attribute '
- '"match_kind". Possible values are "points", "scope" and "general". '.format(file_name) +
- refer_to_faq_msg(71))
- desc = CustomReplacementDescriptor.create_instance(attrs['match_kind'], attrs['id'], attrs)
- validation_errors.extend(desc.validate_data())
- result.append(desc)
- if len(validation_errors) > 0:
- raise Error("File '{}' validation failed:\n{}. ".format(file_name, "\n".join(validation_errors)) +
- refer_to_faq_msg(72))
- return result
-
-
-def generate_pattern_for_node(graph: Graph, sub_graph_pattern: str, node_name: str):
- if sub_graph_pattern == '':
- return node_name
- node_name_components = node_name.split("/")
- cur_name = ''
- matched_index = None # index of the node name component to start new pattern from
- compiled_pattern = compile(sub_graph_pattern)
- for index in range(0, len(node_name_components)):
- cur_name += node_name_components[index] + "/"
- if match(compiled_pattern, cur_name):
- matched_index = index
- break
- if matched_index is None:
- raise RuntimeError('Node name "{}" does not match pattern "{}"'.format(node_name, sub_graph_pattern))
-
- if sub_graph_pattern == '' or sub_graph_pattern[-1] != '/':
- sub_graph_pattern += '/'
-
- sub_graph_nodes = nodes_matching_name_pattern(graph, sub_graph_pattern)
- name_suffix = '/'.join(node_name_components[matched_index + 1:]) + '$'
- if len([node for node in sub_graph_nodes if match(sub_graph_pattern + name_suffix, node)]) == 1:
- return name_suffix
-
- raise RuntimeError('The pattern that uniquely identifies node "{}" using sub-graph pattern "{}" has not been found'.
- format(node_name, sub_graph_pattern))
-
-
-def load_and_validate_json_config(config_file_name: str):
- """
- Reads and validate custom replacement configuration file config_file_name.
- :param config_file_name: name of the file to read from.
- :return: A dictionary serialized from json config file.
- """
- try:
- with open(config_file_name, 'r') as f:
- json_config = json.load(f)
- try:
- import fastjsonschema as json_validate
-
- validator = json_validate.compile(schema_dict)
- validator(json_config)
- except ModuleNotFoundError as e:
- log.error("Module 'fastjsonschema' for json validation not installed. Please update requirements.",
- extra={'is_warning': True})
-
- except Exception as e:
- raise Error("Failed to parse custom replacements configuration file '{}': {}. ".format(config_file_name, e) +
- refer_to_faq_msg(70)) from e
-
- return json_config
diff --git a/tools/mo/openvino/tools/mo/utils/dsu.py b/tools/mo/openvino/tools/mo/utils/dsu.py
deleted file mode 100644
index 9e92f735203420..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/dsu.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-class DSUElem:
- """
- An object that represents one DSU element.
- """
- name = ''
- parent = ''
- rank = 1
-
- def __init__(self, name):
- self.name = name
- self.parent = name
- self.rank = 1
-
-
-class DSU:
- """
- Naive implementation of the "disjoint set union" data structure.
- """
- map = dict()
-
- def __init__(self, elems: list):
- self.map = {elem.name: elem for elem in elems}
- pass
-
- def find_elem(self, name: str):
- return self.map[name]
-
- def find_parent(self, elem: DSUElem):
- if elem.parent == elem.name:
- return elem
- parent_elem = self.find_parent(self.find_elem(elem.parent))
- elem.parent = parent_elem.name
- return parent_elem
-
- def union(self, elem1: DSUElem, elem2: DSUElem):
- elem1 = self.find_parent(elem1)
- elem2 = self.find_parent(elem2)
- if elem1.name == elem2.name: # already in the same set
- return
-
- if elem1.rank < elem2.rank:
- elem1.parent = elem2.name
- elif elem1.rank > elem2.rank:
- elem2.parent = elem1.name
- else:
- elem1.parent = elem2.name
- elem2.rank = elem2.rank + 1
diff --git a/tools/mo/openvino/tools/mo/utils/environment_setup_utils.py b/tools/mo/openvino/tools/mo/utils/environment_setup_utils.py
deleted file mode 100644
index 90e42988d715e7..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/environment_setup_utils.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import sys
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-
-
-def get_imported_module_version(imported_module):
- """
- Get imported module version
- :return: version(str) or raise AttributeError exception
- """
- version_attrs = ("__version__", "VERSION", "version")
- installed_version = None
- for attr in version_attrs:
- installed_version = getattr(imported_module, attr, None)
- if isinstance(installed_version, str):
- return installed_version
- else:
- installed_version = None
-
- if installed_version is None:
- raise AttributeError("{} module doesn't have version attribute".format(imported_module))
- else:
- return installed_version
-
-
-def get_environment_setup(framework):
- """
- Get environment setup such as Python version, TensorFlow version
- :param framework: framework name
- :return: a dictionary of environment variables
- """
- env_setup = dict()
- python_version = "{}.{}.{}".format(sys.version_info.major,
- sys.version_info.minor,
- sys.version_info.micro)
- env_setup['python_version'] = python_version
- try:
- if framework == 'tf':
- exec("import tensorflow")
- env_setup['tensorflow'] = get_imported_module_version(sys.modules["tensorflow"])
- exec("del tensorflow")
- except (AttributeError, ImportError):
- pass
- env_setup['sys_platform'] = sys.platform
- return env_setup
diff --git a/tools/mo/openvino/tools/mo/utils/error.py b/tools/mo/openvino/tools/mo/utils/error.py
deleted file mode 100644
index af936093924eed..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/error.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import re
-
-
-class BasicError(Exception):
- """ Base class for all exceptions in Model Conversion API
-
- It operates like Exception but when it is converted to str,
- it formats string as args[0].format(*args[1:]), where
- args are arguments provided when an exception instance is
- created.
- """
-
- def __str__(self):
- if len(self.args) <= 1:
- return Exception.__str__(self)
- return self.args[0].format(*self.args[1:]) # pylint: disable=unsubscriptable-object
-
-
-class FrameworkError(BasicError):
- """ User-friendly error: raised when the error on the framework side. """
- pass
-
-
-class Error(BasicError):
- """ User-friendly error: raised when the error on the user side. """
- pass
-
-
-class InternalError(BasicError):
- """ Not user-friendly error: user cannot fix it and it points to the bug inside MO. """
- pass
-
-
-def classify_error_type(e):
- patterns = [
- # Example: No module named 'openvino._offline_transformations.offline_transformations_api'
- r"No module named \'\S+\'",
- # Example: cannot import name 'IECore' from 'openvino.inference_engine' (unknown location)
- r"cannot import name \'\S+\'",
- ]
- error_message = str(e)
- for pattern in patterns:
- m = re.search(pattern, error_message)
- if m:
- return m.group(0)
- return "undefined"
-
-
-def legacy_path_error(functionality_description):
- raise Exception("{}Please try to install openvino-dev and use convert_model() "
- "from openvino.tools.mo.".format(functionality_description))
diff --git a/tools/mo/openvino/tools/mo/utils/find_ie_version.py b/tools/mo/openvino/tools/mo/utils/find_ie_version.py
deleted file mode 100644
index 47f069af0329fc..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/find_ie_version.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import sys
-import platform
-import subprocess # nosec
-
-lib_env_key = "PATH" if platform.system() == "Windows" else "LD_LIBRARY_PATH"
-if lib_env_key not in os.environ:
- os.environ[lib_env_key] = ""
-
-python_path_key = "PYTHONPATH"
-if python_path_key not in os.environ:
- os.environ[python_path_key] = ""
-
-lib_path_orig = os.environ[lib_env_key]
-python_path_orig = os.environ[python_path_key]
-
-
-def setup_env(module="", libs=[]):
- """
- Update os.environ variables with given values.
- :param module: path to python module
- :param libs: list with paths to libraries
- """
- os.environ[python_path_key] = os.pathsep.join([module, os.environ[python_path_key]])
- os.environ[lib_env_key] = os.pathsep.join([*libs, os.environ[lib_env_key]])
-
-
-def reset_env():
- """
- Reset os.environ variables to default values
- """
- os.environ[python_path_key] = python_path_orig
- os.environ[lib_env_key] = lib_path_orig
-
-
-def try_to_import_ie(module="", libs=[], silent=False):
- """
- Check if OpenVINO Python API modules exists and in case of success
- environment will be set with given values.
- :param module: path to python module
- :param libs: list with paths to libraries
- :param silent: hide all output
- """
- path_to_script = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'check_ie_bindings.py')
- # We need to execute python modules checker in subprocess to avoid issue with environment
- # in case if previous import was unsuccessful it can fail further imports even if sys.path
- # will be restored to initial default values.
- # To pass environment to sub-process PATH/LD_LIBRARY_PATH and PYTHONPATH are used from
- # os.environ that is set after setup_env()
- setup_env(module=module, libs=libs)
- cmd_args = [sys.executable, path_to_script, "--path_to_module", "PYTHONPATH" if module == "" else module]
- if silent:
- cmd_args.append("--silent")
-
- status = subprocess.run(cmd_args, env=os.environ)
- if status.returncode == 0:
- return True
- else:
- reset_env()
- return False
-
-
-def find_ie_version(silent=False):
- """
- Tries to import OpenVINO Python API bindings. In case of successful import
- PATH/LD_LIBRARY_PATH and PYTHONPATH environment variables will be set
- This variables must be passed to subprocess in order to execute OV python bindings.
- Example:
- if find_ie_version():
- subprocess.run([sys.executable, path_to_script], env=os.environ)
-
- """
- if try_to_import_ie(silent=silent):
- return True
-
- script_path = os.path.realpath(os.path.dirname(__file__))
-
- # Windows
- bindings_paths_windows = [
- # Local builds
- {
- "module": os.path.join(script_path, '../../../../../../bin/intel64/Release/python/'),
- "libs": [
- os.path.join(script_path, '../../../../../../bin/intel64/Release'),
- os.path.join(script_path, '../../../../../../temp/tbb/bin'),
- ]
- },
- {
- "module": os.path.join(script_path, '../../../../../../bin/intel64/Debug/python/'),
- "libs": [
- os.path.join(script_path, '../../../../../../bin/intel64/Debug'),
- os.path.join(script_path, '../../../../../../temp/tbb/bin'),
- ]
- },
- ]
-
- # Linux / Darwin
- bindings_paths_linux = [
- # Local builds
- {
- "module": os.path.join(script_path, '../../../../../../bin/intel64/Release/python/'),
- "libs": [
- os.path.join(script_path, '../../../../../../bin/intel64/Release'),
- ]
- },
- {
- "module": os.path.join(script_path, '../../../../../../bin/intel64/RelWithDebInfo/python'),
- "libs": [
- os.path.join(script_path, '../../../../../../bin/intel64/RelWithDebInfo'),
- ]
- },
- {
- "module": os.path.join(script_path, '../../../../../../bin/intel64/Debug/python'),
- "libs": [
- os.path.join(script_path, '../../../../../../bin/intel64/Debug'),
- ]
- }
- ]
-
- bindings_paths = bindings_paths_windows if platform.system() == "Windows" else bindings_paths_linux
- for item in bindings_paths:
- module = item['module']
- if not os.path.exists(module):
- continue
- if try_to_import_ie(module=os.path.normpath(module), libs=item['libs'] if 'libs' in item else [], silent=silent):
- return True
-
- return False
-
-
-if __name__ == "__main__":
- if not find_ie_version():
- exit(1)
diff --git a/tools/mo/openvino/tools/mo/utils/find_inputs.py b/tools/mo/openvino/tools/mo/utils/find_inputs.py
deleted file mode 100644
index a52733412beb48..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/find_inputs.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import networkx as nx
-
-from openvino.tools.mo.graph.graph import Node, Graph
-
-
-def find_nodes_by_attribute_value(graph: Graph, attr: str, attr_name: str):
- return [id for id, v in nx.get_node_attributes(graph, attr).items() if v == attr_name]
-
-
-def find_inputs(graph: Graph):
- return find_nodes_by_attribute_value(graph, 'type', 'Parameter')
-
-
-def find_outputs(graph: Graph):
- outputs = []
- for node_id in find_nodes_by_attribute_value(graph, 'op', 'Result'):
- parents = Node(graph, node_id).in_nodes()
- assert len(parents) == 1, 'Result node should have exactly one input'
- parent = parents[0].id
- outputs.append(parent)
- return list(set(outputs))
diff --git a/tools/mo/openvino/tools/mo/utils/get_ov_update_message.py b/tools/mo/openvino/tools/mo/utils/get_ov_update_message.py
deleted file mode 100644
index effd438af75597..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/get_ov_update_message.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import datetime
-
-msg_fmt = 'Check for a new version of Intel(R) Distribution of OpenVINO(TM) toolkit here {0} ' \
- 'or on https://github.com/openvinotoolkit/openvino'
-
-
-def get_ov_update_message():
- expected_update_date = datetime.date(year=2024, month=12, day=1)
- current_date = datetime.date.today()
-
- link = 'https://software.intel.com/content/www/us/en/develop/tools/openvino-toolkit/download.html?cid=other&source=prod&campid=ww_2023_bu_IOTG_OpenVINO-2023-1&content=upg_all&medium=organic'
-
- return msg_fmt.format(link) if current_date >= expected_update_date else None
-
-
-def get_compression_message():
- link = "https://docs.openvino.ai/2023.0/openvino_docs_MO_DG_FP16_Compression.html"
- message = '[ INFO ] Generated IR will be compressed to FP16. ' \
- 'If you get lower accuracy, please consider disabling compression explicitly ' \
- 'by adding argument --compress_to_fp16=False.\n' \
- 'Find more information about compression to FP16 at {}'.format(link)
- return message
-
-
-def get_try_legacy_fe_message():
- message = '[ INFO ] You can also try to use legacy TensorFlow Frontend by using argument --use_legacy_frontend.\n'
- return message
-
-
-def get_ovc_message():
- link = "https://docs.openvino.ai/2023.2/openvino_docs_OV_Converter_UG_prepare_model_convert_model_MO_OVC_transition.html"
- message = '[ INFO ] MO command line tool is considered as the legacy conversion API as of OpenVINO 2023.2 release.\n' \
- 'In 2025.0 MO command line tool and openvino.tools.mo.convert_model() will be removed. ' \
- 'Please use OpenVINO Model Converter (OVC) or openvino.convert_model(). ' \
- 'OVC represents a lightweight alternative of MO and provides simplified model conversion API. \n' \
- 'Find more information about transition from MO to OVC at {}'.format(link)
-
- return message
diff --git a/tools/mo/openvino/tools/mo/utils/graph.py b/tools/mo/openvino/tools/mo/utils/graph.py
deleted file mode 100644
index 90938d85d3cfdc..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/graph.py
+++ /dev/null
@@ -1,312 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from collections import deque
-from re import match, compile
-
-import networkx as nx
-
-from openvino.tools.mo.graph.graph import Node, Graph, set_edge_attribute_between_nodes, get_edge_attribute_between_nodes
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-def backward_bfs_for_operation(start_node: Node, op_names: list, skip_op_list: list = None):
- """
- Find node with 'op' attribute equal to one of from 'op_name', searching in the backward direction.
- In case of branching algorithm goes into each branch, but if it can't find layer in one of them it returns
- empty list.
-
- :param start_node: Start node for BFS algorithm
- :param op_names: The list with names of operations to search
- :param skip_op_list: list of operations to be stopped at if they are met
- """
- if skip_op_list is None:
- skip_op_list = []
- ret = []
- q = deque([start_node])
- while len(q) != 0:
- node = q.popleft()
- in_nodes_size = len(node.in_nodes())
- for id in range(in_nodes_size): # in_nodes() can return either list or dict
- pnode = node.in_node(id)
- if pnode.kind == 'op':
- if pnode.has_valid('op') and pnode.op in op_names:
- if pnode.id not in ret:
- ret.append(pnode.id)
- else:
- if pnode.op not in skip_op_list:
- q.append(pnode)
- elif pnode.kind == 'data' and pnode.value is None:
- q.append(pnode)
- return [Node(start_node.graph, x) for x in ret]
-
-
-def bfs_search(graph: Graph, start_nodes: list = list()):
- """
- Performs breadth-first search over a graph and returns a list of nodes in the BFS order.
- :param graph: networkx graph to traverse.
- :param start_nodes: list of start nodes of the graph. If the list is empty then start from all nodes that do not
- have input nodes.
- :return: the list of nodes in the BFS order.
- """
- result = list()
- if len(start_nodes) == 0:
- start_nodes = [node_name for node_name in graph.nodes() if len(graph.in_edges(node_name)) == 0]
-
- visited = set(start_nodes)
- d = deque(start_nodes)
-
- while len(d) != 0:
- cur_node_name = d.popleft()
- result.append(cur_node_name)
- for src_node, dst_node in graph.out_edges(cur_node_name):
- if dst_node not in visited:
- d.append(dst_node)
- visited.add(dst_node)
- return result
-
-
-def nodes_matching_name_pattern(graph: Graph, pattern: str):
- """
- Returns list of node names of the graph that match regular expression.
- :param graph: graph to operate on.
- :param pattern: regular expression describing node name pattern.
- :return: list of matched node names.
- """
- compiled_pattern = compile(pattern)
- return [node_name for node_name in list(graph.nodes()) if match(compiled_pattern, node_name)]
-
-
-def is_connected_component(graph: Graph, node_names: list):
- """
- Checks that specified list of nodes forms a connected sub-graph. It ignores edges direction.
- The algorithm is the following. Run BFS from one of the nodes from the node_names list ignoring edges order and
- visiting only nodes from the node_names list. Prepare list of visited nodes. If this list is equal to the
- node_names list (we actually check that the node_names set is sub-set of 'visited' set that is equivalent) then the
- sub-graph is connected.
- :param graph: graph to operate on.
- :param node_names: list of node names to be checked.
- :return: Result of the check.
- """
- if len(node_names) == 0:
- return True
-
- d = deque([node_names[0]])
- visited = set([node_names[0]])
- while len(d) != 0:
- cur_node_name = d.popleft()
- visited.add(cur_node_name)
- # find adjacent nodes from the list of node_names. Ignoring edges direction
- adj_nodes = [src_node for src_node, _ in graph.in_edges(cur_node_name) if src_node in node_names] + \
- [dst_node for _, dst_node in graph.out_edges(cur_node_name) if dst_node in node_names]
- for adj_node in adj_nodes:
- if adj_node not in visited:
- d.append(adj_node)
- visited.add(adj_node)
- return set(node_names).issubset(visited)
-
-
-def sub_graph_between_nodes(graph: Graph, start_nodes: list, end_nodes: list, detect_extra_start_node: callable=None,
- include_control_flow=True, allow_non_reachable_end_nodes=False):
- """
- Finds nodes of the sub-graph between 'start_nodes' and 'end_nodes'. Input nodes for the sub-graph nodes are also
- added to the sub-graph. Constant inputs of the 'start_nodes' are also added to the sub-graph.
- :param graph: graph to operate on.
- :param start_nodes: list of nodes names that specifies start nodes.
- :param end_nodes: list of nodes names that specifies end nodes.
- :param detect_extra_start_node: callable function to add additional nodes to the list of start nodes instead of
- traversing the graph further. The list of additional start nodes is returned of the function is not None.
- :param include_control_flow: flag to specify whether to follow the control flow edges or not
- :param allow_non_reachable_end_nodes: do not fail if the end nodes are not reachable from the start nodes
- :return: list of nodes of the identified sub-graph or None if the sub-graph cannot be extracted.
- """
- sub_graph_nodes = list()
- visited = set(start_nodes)
- d = deque(start_nodes)
- extra_start_nodes = []
-
- nx.set_node_attributes(G=graph, name='prev', values=None)
- while len(d) != 0:
- cur_node_id = d.popleft()
- sub_graph_nodes.append(cur_node_id)
- if cur_node_id not in end_nodes: # do not add output nodes of the end_nodes
- for _, dst_node_name, attrs in graph.out_edges(cur_node_id, data=True):
- if dst_node_name not in visited and (include_control_flow or not attrs.get('control_flow_edge', False)):
- d.append(dst_node_name)
- visited.add(dst_node_name)
- graph.node[dst_node_name]['prev'] = cur_node_id
-
- for src_node_name, _, attrs in graph.in_edges(cur_node_id, data=True):
- # add input nodes for the non-start_nodes
- if cur_node_id not in start_nodes and src_node_name not in visited and\
- (include_control_flow or not attrs.get('control_flow_edge', False)):
- if detect_extra_start_node is not None and detect_extra_start_node(Node(graph, cur_node_id)):
- extra_start_nodes.append(cur_node_id)
- else:
- d.append(src_node_name)
- graph.node[src_node_name]['prev'] = cur_node_id
- visited.add(src_node_name)
-
- # use forward dfs to check that all end nodes are reachable from at least one of input nodes
- forward_visited = set()
- for start_node in start_nodes:
- graph.dfs(start_node, forward_visited)
- for end_node in end_nodes:
- if not allow_non_reachable_end_nodes and end_node not in forward_visited:
- raise Error('End node "{}" is not reachable from start nodes: {}. '.format(end_node, start_nodes) +
- refer_to_faq_msg(74))
-
- for node_id in sub_graph_nodes:
- # sub-graph should not contain Placeholder nodes
- if graph.node[node_id].get('op', '') == 'Parameter':
- path = list()
- cur_node = node_id
- while cur_node and 'prev' in graph.node[cur_node]:
- path.append(str(cur_node))
- cur_node = graph.node[cur_node]['prev']
- log.debug("The path from input node is the following: {}".format('\n'.join(path)))
- raise Error('The matched sub-graph contains network input node "{}". '.format(node_id) +
- refer_to_faq_msg(75))
- if detect_extra_start_node is None:
- return sub_graph_nodes
- else:
- return sub_graph_nodes, extra_start_nodes
-
-
-def invert_sub_graph_between_nodes(graph: Graph, start_nodes: list, end_nodes: list, detect_extra_start_node: callable=None):
- """
- Finds nodes of the sub-graph between 'start_nodes' and 'end_nodes'. But doing it from start_nodes stepping
- backward by in edges.
-
- Input nodes for the sub-graph nodes are also added to the sub-graph. Constant inputs of the 'start_nodes'
- are also added to the sub-graph.
- :param graph: graph to operate on.
- :param start_nodes: list of nodes names that specifies start nodes.
- :param end_nodes: list of nodes names that specifies end nodes.
- :return: list of nodes of the identified sub-graph or None if the sub-graph cannot be extracted.
- """
- sub_graph_nodes = list()
- visited = set(start_nodes)
- d = deque(start_nodes)
- extra_start_nodes = []
-
- nx.set_node_attributes(G=graph, name='prev', values=None)
- while len(d) != 0:
- cur_node_name = d.popleft()
- sub_graph_nodes.append(cur_node_name)
- if cur_node_name not in start_nodes and \
- detect_extra_start_node is not None and detect_extra_start_node(Node(graph, cur_node_name)):
- extra_start_nodes.append(cur_node_name)
- else:
- if cur_node_name not in end_nodes: # do not add output nodes of the end_nodes
- for src_node_name, _ in graph.in_edges(cur_node_name):
- if src_node_name not in visited:
- d.append(src_node_name)
- visited.add(src_node_name)
- graph.node[cur_node_name]['prev'] = src_node_name
-
- for node_name in sub_graph_nodes:
- # sub-graph should not contain Input nodes
- if graph.node[node_name].get('op', '') == 'Parameter':
- path = list()
- cur_node = node_name
- while cur_node and 'prev' in graph.node[cur_node]:
- path.append(str(cur_node))
- cur_node = graph.node[cur_node]['prev']
- log.debug("The path from input node is the following: {}".format('\n'.join(path)))
- raise Error('The matched sub-graph contains network input node "{}". '.format(node_name) +
- refer_to_faq_msg(75))
- if detect_extra_start_node is None:
- return sub_graph_nodes
- else:
- return sub_graph_nodes, extra_start_nodes
-
-
-def node_neighbourhood(node_name: str, depth: int, next_node_fn):
- """
- Find neighbourhood of the node..
- :param node_name: name of the node to find neighbourhood for.
- :param depth: maximum depth of search nodes.
- :param next_node_fn: callable that accepts node name and should return list of adjacent nodes.
- :return: list of names of nodes in the neighbourhood.
- """
- dist = dict()
- dist[node_name] = 0
- deq = deque([node_name])
- while len(deq) != 0:
- cur_node_name = deq.popleft()
- cur_dist = dist[cur_node_name]
- if cur_dist < depth:
- for next_node_name in next_node_fn(cur_node_name):
- next_dist = dist.setdefault(next_node_name, depth + 1)
- if next_dist > cur_dist + 1:
- dist[next_node_name] = cur_dist + 1
- deq.append(next_node_name)
- return list(dist.keys())
-
-
-def node_incoming_neighbourhood(graph: Graph, node_name: str, depth: int):
- """
- Find input neighbourhood of the node.
- :param graph: graph to operate on.
- :param node_name: name of the node to find neighbourhood for.
- :param depth: maximum depth of input nodes.
- :return: list of names of nodes in the neighbourhood.
- """
- return node_neighbourhood(node_name, depth, lambda node_name: [u for u, v in graph.in_edges([node_name])])
-
-
-def node_outcoming_neighbourhood(graph: Graph, node_name: str, depth: int):
- """
- Find output neighbourhood of the node.
- :param graph: graph to operate on.
- :param node_name: name of the node to find neighbourhood for.
- :param depth: maximum depth of output nodes.
- :return: list of names of nodes in the neighbourhood.
- """
- return node_neighbourhood(node_name, depth, lambda node_name: [v for u, v in graph.out_edges([node_name])])
-
-
-def scope_output_nodes(graph: Graph, scope: str, scope_delimiter: str='/'):
- """
- The function returns nodes producing output of the sub-graph defined by scope (name prefix). The node is considered
- output of the scope if it is in this scope and it's output is outside of the scope.
- :param graph: graph to operate on.
- :param scope: string with scope (prefix of the node name).
- :param scope_delimiter: delimiter between scope parts.
- :return: list of Node objects which are outputs of the scope.
- """
- if scope[-1] != scope_delimiter:
- scope += scope_delimiter
-
- result = set()
- for node_id in graph.nodes():
- if node_id.startswith(scope):
- for _, out_node_name in graph.out_edges(node_id):
- if not out_node_name.startswith(scope):
- result.add(node_id)
- break
- return [Node(graph, node_id) for node_id in result]
-
-
-def clear_tensor_names_info(nodes: list):
- """
- Clears tensor names information from 'fw_tensor_debug_info' attribute for all edges outgoing from
- given nodes.
- This method is used in cases when transformation adds postprocessing and the result does not
- correspond to the original tensor.
- This method should only be used during the front phase.
- :param nodes: list of Node objects.
- """
- for node in nodes:
- for out_idx in node.out_nodes():
- out_node = node.out_node(out_idx)
- fw_info_list = get_edge_attribute_between_nodes(node, out_node, 'fw_tensor_debug_info')
- new_fw_info = []
- for fw_info in fw_info_list:
- if fw_info is not None and len(fw_info) >= 2:
- new_fw_info.append((fw_info[0], fw_info[1], None))
- set_edge_attribute_between_nodes(node, out_node, 'fw_tensor_debug_info', new_fw_info)
-
diff --git a/tools/mo/openvino/tools/mo/utils/guess_framework.py b/tools/mo/openvino/tools/mo/utils/guess_framework.py
deleted file mode 100644
index d9058bed878e76..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/guess_framework.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import re
-from argparse import Namespace
-
-from openvino.tools.mo.utils.error import Error
-
-
-def deduce_legacy_frontend_by_namespace(argv: Namespace):
- if not hasattr(argv, 'framework') or not argv.framework:
- if getattr(argv, 'saved_model_dir', None) or getattr(argv, 'input_meta_graph', None):
- argv.framework = 'tf'
- elif getattr(argv, 'input_proto', None):
- argv.framework = 'caffe'
- elif argv.input_model is None:
- raise Error('Path to input model is required: use --input_model.')
- else:
- argv.framework = guess_framework_by_ext(argv.input_model)
-
- return map(lambda x: argv.framework == x, ['tf', 'caffe', 'kaldi', 'onnx'])
-
-
-def guess_framework_by_ext(input_model_path: str) -> int:
- if re.match(r'^.*\.caffemodel$', input_model_path):
- return 'caffe'
- elif re.match(r'^.*\.pb$', input_model_path):
- return 'tf'
- elif re.match(r'^.*\.pbtxt$', input_model_path):
- return 'tf'
- elif re.match(r'^.*\.nnet$', input_model_path):
- return 'kaldi'
- elif re.match(r'^.*\.mdl', input_model_path):
- return 'kaldi'
- elif re.match(r'^.*\.onnx$', input_model_path):
- return 'onnx'
diff --git a/tools/mo/openvino/tools/mo/utils/help.py b/tools/mo/openvino/tools/mo/utils/help.py
deleted file mode 100644
index 2b80f1d8c52def..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/help.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-def get_convert_model_help_specifics():
- from openvino.tools.mo.utils.cli_parser import CanonicalizeTransformationPathCheckExistenceAction, \
- CanonicalizePathCheckExistenceAction, CanonicalizeExtensionsPathCheckExistenceAction, \
- CanonicalizePathCheckExistenceIfNeededAction, readable_file_or_dir, readable_dirs_or_files_or_empty, \
- check_positive
- from openvino.tools.mo.utils.version import VersionChecker
- return {
- 'input_model':
- {'description':
- 'Tensorflow*: a file with a pre-trained model '
- '(binary or text .pb file after freezing). '
- 'Caffe*: a model proto file with model weights.', 'action': CanonicalizePathCheckExistenceAction,
- 'type': readable_file_or_dir,
- 'aliases': {'-w', '-m'}},
- 'input_shape':
- {'description':
- 'Input shape(s) that should be fed to an input node(s) '
- 'of the model. Shape is defined as a comma-separated '
- 'list of integer numbers enclosed in parentheses or '
- 'square brackets, for example [1,3,227,227] or '
- '(1,227,227,3), where the order of dimensions depends '
- 'on the framework input layout of the model. For '
- 'example, [N,C,H,W] is used for ONNX* models and '
- '[N,H,W,C] for TensorFlow* models. The shape can '
- 'contain undefined dimensions (? or -1) and should fit '
- 'the dimensions defined in the input operation of the '
- 'graph. Boundaries of undefined dimension can be '
- 'specified with ellipsis, for example '
- '[1,1..10,128,128]. One boundary can be undefined, for '
- 'example [1,..100] or [1,3,1..,1..]. If there are '
- 'multiple inputs in the model, --input_shape should '
- 'contain definition of shape for each input separated '
- 'by a comma, for example: [1,3,227,227],[2,4] for a '
- 'model with two inputs with 4D and 2D shapes. '
- 'Alternatively, specify shapes with the --input option.'},
- 'input':
- {'description':
- 'Quoted list of comma-separated input nodes names with '
- 'shapes, data types, and values for freezing. The order '
- 'of inputs in converted model is the same as order of '
- 'specified operation names. The shape and value are '
- 'specified as comma-separated lists. The data type of '
- 'input node is specified in braces and can have one of '
- 'the values: f64 (float64), f32 (float32), f16 '
- '(float16), i64 (int64), i32 (int32), u8 (uint8), '
- 'boolean (bool). Data type is optional. If it\'s not '
- 'specified explicitly then there are two options: if '
- 'input node is a parameter, data type is taken from the '
- 'original node dtype, if input node is not a parameter, '
- 'data type is set to f32. Example, to set `input_1` '
- 'with shape [1,100], and Parameter node `sequence_len` '
- 'with scalar input with value `150`, and boolean input '
- '`is_training` with `False` value use the following '
- 'format: \n '
- '\"input_1[1,100],sequence_len->150,is_training->False\". '
- 'Another example, use the following format to set input '
- 'port 0 of the node `node_name1` with the shape [3,4] '
- 'as an input node and freeze output port 1 of the node '
- '\"node_name2\" with the value [20,15] of the int32 type '
- 'and shape [2]: \n '
- '\"0:node_name1[3,4],node_name2:1[2]{i32}->[20,15]\".'},
- 'mean_values':
- {'description':
- 'Mean values to be used for the input image per '
- 'channel. Values to be provided in the (R,G,B) or '
- '[R,G,B] format. Can be defined for desired input of '
- 'the model, for example: "--mean_values '
- 'data[255,255,255],info[255,255,255]". The exact '
- 'meaning and order of channels depend on how the '
- 'original model was trained.'},
- 'scale_values':
- {'description':
- 'Scale values to be used for the input image per '
- 'channel. Values are provided in the (R,G,B) or [R,G,B] '
- 'format. Can be defined for desired input of the model, '
- 'for example: "--scale_values '
- 'data[255,255,255],info[255,255,255]". The exact '
- 'meaning and order of channels depend on how the '
- 'original model was trained. If both --mean_values and '
- '--scale_values are specified, the mean is subtracted '
- 'first and then scale is applied regardless of the '
- 'order of options in command line.'},
- 'source_layout':
- {'description':
- 'Layout of the input or output of the model in the '
- 'framework. Layout can be specified in the short form, '
- 'e.g. nhwc, or in complex form, e.g. \"[n,h,w,c]\". '
- 'Example for many names: \"in_name1([n,h,w,c]),in_name2('
- 'nc),out_name1(n),out_name2(nc)\". Layout can be '
- 'partially defined, \"?\" can be used to specify '
- 'undefined layout for one dimension, \"...\" can be used '
- 'to specify undefined layout for multiple dimensions, '
- 'for example \"?c??\", \"nc...\", \"n...c\", etc.'},
- 'transform':
- {'description':
- 'Apply additional transformations. Usage: \"--transform '
- 'transformation_name1[args],transformation_name2...\" '
- 'where [args] is key=value pairs separated by '
- 'semicolon. Examples: \"--transform LowLatency2\" or \"--'
- 'transform Pruning" or "--transform '
- 'LowLatency2[use_const_initializer=False]" or "--'
- 'transform "MakeStateful[param_res_names= {\'input_name_1\':'
- '\'output_name_1\',\'input_name_2\':\'output_name_2\'}]\" \n'
- 'Available transformations: "LowLatency2", "MakeStateful", "Pruning"'},
- 'extensions':
- {'description':
- 'Paths or a comma-separated list of paths to libraries '
- '(.so or .dll) with extensions. For the legacy MO path '
- '(if `--use_legacy_frontend` is used), a directory or a '
- 'comma-separated list of directories with extensions '
- 'are supported. To disable all extensions including '
- 'those that are placed at the default location, pass an empty string.',
- 'action': CanonicalizeExtensionsPathCheckExistenceAction,
- 'type': readable_dirs_or_files_or_empty},
- 'transformations_config':
- {'description':
- 'Use the configuration file with transformations '
- 'description. Transformations file can be specified as '
- 'relative path from the current directory, as absolute '
- 'path or as arelative path from the mo root directory.',
- 'action': CanonicalizeTransformationPathCheckExistenceAction},
- 'counts':
- {'action': CanonicalizePathCheckExistenceIfNeededAction},
- 'version':
- {'action': 'version',
- 'version': 'Version of Model Optimizer is: {}'.format(VersionChecker().get_ie_version())},
- 'scale':
- {'type': float,
- 'aliases': {'-s'}},
- 'batch':
- {'type': check_positive,
- 'aliases': {'-b'}},
- 'input_proto':
- {'aliases': {'-d'}},
- 'log_level':
- {'choices': ['CRITICAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET']}
- }
-
-
-# TODO: remove this when internal converting of params to string is removed
-def get_to_string_methods_for_params():
- from openvino.tools.mo.utils.cli_parser import path_to_str_or_object, str_list_to_str, \
- mean_scale_value_to_str, source_target_layout_to_str, layout_param_to_str, transform_param_to_str, \
- extensions_to_str_or_extensions_class, batch_to_int, transformations_config_to_str
- return {
- 'input_model': path_to_str_or_object,
- 'output': str_list_to_str,
- 'mean_values': mean_scale_value_to_str,
- 'scale_values': mean_scale_value_to_str,
- 'source_layout': source_target_layout_to_str,
- 'target_layout': source_target_layout_to_str,
- 'layout': layout_param_to_str,
- 'transform': transform_param_to_str,
- 'extensions': extensions_to_str_or_extensions_class,
- 'batch': batch_to_int,
- 'transformations_config': transformations_config_to_str,
- 'saved_model_tags': str_list_to_str
- }
diff --git a/tools/mo/openvino/tools/mo/utils/ie_version.py b/tools/mo/openvino/tools/mo/utils/ie_version.py
deleted file mode 100644
index dce2cd0e5765a6..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ie_version.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-def get_ie_version():
- try:
- from openvino.runtime import get_version # pylint: disable=import-error,no-name-in-module
- return get_version()
- except:
- return None
-
-
-if __name__ == "__main__":
- print(get_ie_version())
diff --git a/tools/mo/openvino/tools/mo/utils/import_extensions.py b/tools/mo/openvino/tools/mo/utils/import_extensions.py
deleted file mode 100644
index f408b50ff2dd5b..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/import_extensions.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import importlib
-import logging as log
-import os
-import pkgutil
-import sys
-
-from openvino.tools.mo.back.replacement import BackReplacementPattern
-from openvino.tools.mo.load.loader import Loader
-from openvino.tools.mo.middle.replacement import MiddleReplacementPattern
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.class_registration import _check_unique_ids, update_registration, \
- get_enabled_and_disabled_transforms, clear_registered_classes_dict
-from openvino.tools.mo.utils.model_analysis import AnalyzeAction
-
-
-def get_internal_dirs(framework: str, get_front_classes: callable):
- front_classes = get_front_classes()
- return {
- ('ops', ): [Op],
- ('analysis',): [AnalyzeAction],
- ('load', framework): [Loader],
- ('front', ): front_classes,
- ('front', framework): front_classes,
- ('front', framework, 'extractors'): front_classes,
- ('middle', ): [MiddleReplacementPattern],
- ('back', ): [BackReplacementPattern]}
-
-def import_by_path(path: str, middle_names: list = (), prefix: str = ''):
- for module_loader, name, ispkg in pkgutil.iter_modules([path]):
- importlib.import_module('{}{}.{}'.format(prefix, '.'.join(middle_names), name))
-
-
-def default_path():
- EXT_DIR_NAME = '.'
- return os.path.abspath(os.getcwd().join(EXT_DIR_NAME))
-
-
-def load_dir(framework: str, path: str, get_front_classes: callable):
- """
- Assuming the following sub-directory structure for path:
-
- front/
- /
- .py
- /
- .py
- ops/
- .py
- middle/
- .py
- back/
- .py
-
- This function loads modules in the following order:
- 1. ops/.py
- 2. front/.py
- 3. front//.py
- 4. middle/.py
- 5. back/.py
-
- Handlers loaded later override earlier registered handlers for an op.
- 1, 2, 3 can concur for the same op, but 4 registers a transformation pass
- and it shouldn't conflict with any stuff loaded by 1, 2 or 3.
- It doesn't load files from front/
- """
- log.info("Importing extensions from: {}".format(path))
- root_dir, ext = os.path.split(path)
- sys.path.insert(0, root_dir)
-
- enabled_transforms, disabled_transforms = get_enabled_and_disabled_transforms()
-
- internal_dirs = get_internal_dirs(framework, get_front_classes)
- prefix = 'openvino.tools.' if ext == 'mo' else ''
-
- exclude_modules = {'tf', 'onnx', 'kaldi', 'caffe'}
- exclude_modules.remove(framework)
-
- for p in internal_dirs.keys():
- import_by_path(os.path.join(path, *p), [ext, *p], prefix)
- update_registration(internal_dirs[p], enabled_transforms, disabled_transforms, exclude_modules)
- sys.path.remove(root_dir)
-
-
-def load_dirs(framework: str, dirs: list, get_front_classes: callable):
- if dirs is None:
- return
- internal_dirs = get_internal_dirs(framework, get_front_classes)
-
- for p, dir_names in internal_dirs.items():
- for d in dir_names:
- d.registered_cls = []
- d.registered_ops = {}
- clear_registered_classes_dict()
-
- mo_inner_extensions = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'mo'))
- dirs.insert(0, mo_inner_extensions)
- dirs = [os.path.abspath(e) for e in dirs]
- if default_path() not in dirs:
- dirs.insert(0, default_path())
- for path in dirs:
- load_dir(framework, path, get_front_classes)
-
- _check_unique_ids()
diff --git a/tools/mo/openvino/tools/mo/utils/ir_engine/__init__.py b/tools/mo/openvino/tools/mo/utils/ir_engine/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_engine/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/utils/ir_engine/compare_graphs.py b/tools/mo/openvino/tools/mo/utils/ir_engine/compare_graphs.py
deleted file mode 100644
index 523e8e4eb9fa54..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_engine/compare_graphs.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from collections import deque
-from numbers import Number
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Graph, Node
-
-
-def compare_node(node_ref, node, ref_attr_value, attr_value, attr, errors_list: list):
- from openvino.tools.mo.utils.ir_engine.ir_engine import IREngine
-
- def err_format_string():
- return 'Current node "{}" with type "{}" and reference node "{}" with type "{}" have different attr "{}" : ' \
- '{} and {}'.format(node.id, node.soft_get('type', None), node_ref.id, node_ref.soft_get('type', None),
- attr, attr_value, ref_attr_value)
-
- if type(ref_attr_value) in [np.ndarray, list]:
- if not np.array_equal(attr_value, ref_attr_value):
- errors_list.append(err_format_string())
- elif isinstance(ref_attr_value, tuple):
- if len(ref_attr_value) != len(attr_value):
- errors_list.append(err_format_string())
- else:
- for ref_item, item in zip(ref_attr_value, attr_value):
- compare_node(node_ref, node, ref_item, item, attr, errors_list)
- elif isinstance(ref_attr_value, dict):
- ref_keys = sorted(list(ref_attr_value.keys()))
- keys = sorted(list(attr_value.keys()))
- if ref_keys != keys:
- errors_list.append(err_format_string())
- else:
- for key in keys:
- compare_node(node_ref, node, ref_attr_value[key], attr_value[key], key, errors_list)
- elif isinstance(attr_value, Number):
- eps = 5e-2 if node.has('precision') and node['precision'] == 'FP16' else 1e-4
- if abs(attr_value - ref_attr_value) > eps:
- errors_list.append(err_format_string())
- elif isinstance(attr_value, IREngine):
- resp, err_log = attr_value.compare(ref_attr_value)
- if not resp:
- errors_list.extend(err_log)
- elif isinstance(attr_value, np.ma.masked_array):
- if not np.ma.allequal(attr_value, ref_attr_value):
- errors_list.append(err_format_string())
- elif isinstance(attr_value, np.ndarray):
- if not np.array_equal(attr_value, ref_attr_value):
- errors_list.append(err_format_string())
- elif attr_value != ref_attr_value:
- errors_list.append(err_format_string())
-
-
-def compare_graphs(graph: Graph, graph_ref: Graph, last_node: str, last_node_ref=None, check_op_attrs=False):
- stderr = []
- if last_node_ref is None:
- last_node_ref = last_node
-
- if 'statistics' in graph.graph and 'statistics' in graph_ref.graph:
- assert graph.graph['statistics'] == graph_ref.graph['statistics'], "int8 statistics comparison failed"
-
- q = deque([last_node])
- q_ref = deque([last_node_ref])
-
- checked_nodes = []
- checked_nodes_ref = []
-
- while len(q_ref) != 0:
- if len(q) == 0:
- stderr.append('Graphs have different number of nodes')
- return (False, stderr)
- node = Node(graph, q.popleft())
- node_ref = Node(graph_ref, q_ref.popleft())
-
- checked_nodes.append(node.id)
- checked_nodes_ref.append(node_ref.id)
-
- # Check that nodes has same amount of output nodes
- if len(node_ref.out_nodes()) != len(node.out_nodes()):
- stderr.append('Current node "{}" and reference node "{}" have different amount of output nodes: {} vs {}'.\
- format(node.id, node_ref.id, len(node.out_nodes()), len(node_ref.out_nodes())))
- continue
-
- # Check that nodes has same amount of input nodes
- if len(node_ref.in_nodes()) != len(node.in_nodes()):
- stderr.append('Current node "{}" and reference node "{}" have different amount of input nodes: {} vs {}'.\
- format(node.id, node_ref.id, len(node.in_nodes()), len(node_ref.in_nodes())))
- continue
-
- # Check that nodes has same 'kind'
- if node_ref.kind != node.kind:
- stderr.append('Current node "{}" and reference node "{}" have different kind parameter'.\
- format(node.id, node_ref.id))
- return (False, stderr)
-
- # Check can_be_fused attr
- if node_ref.has_valid('can_be_fused'):
- if node_ref.soft_get('can_be_fused') != node.soft_get('can_be_fused'):
- stderr.append('Current node "{}" and reference node "{}" have different "can_be_fused" parameter ' \
- '{} and {}'.format(node.id, node_ref.id, node.soft_get('can_be_fused'),
- node_ref.soft_get('can_be_fused')))
-
- if node_ref.kind == 'op':
- # Check that nodes has same operation
- if check_op_attrs:
- cur_node_type = node.type if node.has_valid("type") else None
- ref_node_type = node_ref.type if node_ref.has_valid("type") else None
- for attr in graph_ref.node[node_ref.id]:
- if graph_ref.node[node_ref.id][attr] is None or attr in \
- ['name', 'id', '_in_ports', '_out_ports', 'infer', 'IE', 'biases', 'weights', 'custom',
- 'offset', 'ir_data_attrs', 'rt_info']:
- continue
- if attr not in graph.node[node.id]:
- stderr.append('Current node "{}" with type {} has missing attribute {}'
- ''.format(node.id, cur_node_type, attr))
- continue
-
- def align_strided_slice_masks(curr_node: Node, rank: int):
- from openvino.tools.mo.ops.strided_slice import StridedSlice
- for mask_name in StridedSlice.get_mask_names():
- if isinstance(curr_node[mask_name], int):
- curr_node[mask_name] = [curr_node[mask_name]]
- elif isinstance(curr_node[mask_name], str): # if mask is an empty string ''
- assert len(curr_node[mask_name]) == 0
- curr_node[mask_name] = []
-
- num_insertions = rank - len(curr_node[mask_name])
- curr_node[mask_name] = np.append(curr_node[mask_name], [0] * num_insertions).astype(int)
-
- # Need to align StridedSlice masks since such masks as [] and [0]; [] and [0,0]; [] and [0,0,0]
- # or [1] and [1,0]; [1] and [1,0,0] and so on for the input with rank 4 do exactly the same slicing and
- # should be treated as equal. Therefore, before attr comparison we align all masks to the input rank
- if cur_node_type == 'StridedSlice' and node.in_node(1).has('shape') \
- and node.in_node(1).shape is not None:
- slice_rank = node.in_node(1).shape.item()
- align_strided_slice_masks(node, slice_rank)
- align_strided_slice_masks(node_ref, slice_rank)
-
- if attr == 'value':
- if not values_are_equal(node.value, node_ref.value):
- stderr.append('Current node "{}" with type {} and reference node "{}" with type "{}" have '
- 'different values \n{} \nand \n{}'.format(
- node.id, cur_node_type, node_ref.id, ref_node_type, node.value, node_ref.value))
- continue
- compare_node(node_ref, node, graph_ref.node[node_ref.id][attr], graph.node[node.id][attr], attr,
- stderr)
- else:
- if node_ref.has_valid('shape') and not node.has_valid('shape'):
- stderr.append('{} has None shape'.format(node.id))
- if node_ref.has_valid('value') and not node.has_valid('value'):
- stderr.append('{} has None value'.format(node.id))
-
- # Check that nodes has same shape and value
- if node_ref.has_valid('shape') and node_ref.shape is not None and not np.array_equal(node_ref.shape,
- node.shape):
- stderr.append('Current node "{}" and reference node "{}" have different shapes {} and {}'.\
- format(node.id, node_ref.id, node.shape, node_ref.shape))
- continue
-
- if node_ref.has_valid('value') and node_ref.value is not None and \
- not values_are_equal(node.value, node_ref.value):
- stderr.append('Current node "{}" and reference node "{}" have different values \n{} \nand \n{}'.\
- format(node.id, node_ref.id, node.value, node_ref.value))
- ports = sorted(node.in_nodes().keys()) if node.kind == 'op' else None
- in_nodes = [node.in_node(k) for k in ports] if node.kind == 'op' else node.in_nodes()
- for in_node in in_nodes:
- if in_node.id not in checked_nodes and in_node.id not in q:
- q.append(in_node.id)
-
- ports_ref = sorted(node_ref.in_nodes().keys()) if node_ref.kind == 'op' else None
- if ports != ports_ref:
- stderr.append('Current node "{}" and reference node "{}" have different ports'.format(node.id, node_ref.id))
- return (False, stderr)
-
- in_nodes = [node_ref.in_node(k) for k in ports] if node_ref.kind == 'op' else node_ref.in_nodes()
- for in_node in in_nodes:
- if in_node.id not in checked_nodes_ref and in_node.id not in q_ref:
- q_ref.append(in_node.id)
-
- if node.kind == 'op':
- out_nodes = sorted_by_name([Node(graph, v) for v, _ in node.get_outputs()])
- else:
- out_nodes = sorted_by_name(node.out_nodes())
- for out_node in out_nodes:
- if out_node.id not in checked_nodes and out_node.id not in q:
- q.append(out_node.id)
-
- if node_ref.kind == 'op':
- out_nodes = sorted_by_name([Node(graph_ref, v) for v, _ in node_ref.get_outputs()])
- else:
- out_nodes = sorted_by_name(node_ref.out_nodes())
- for out_node in out_nodes:
- if out_node.id not in checked_nodes_ref and out_node.id not in q_ref:
- q_ref.append(out_node.id)
-
- return (False, stderr) if stderr else (True, [])
-
-
-def sorted_by_name(nodes_list):
- return sorted(nodes_list, key=lambda x: x.soft_get('name', x.id))
-
-
-def values_are_equal(value, value_ref):
- dtype = np.asarray(value).dtype
- if dtype == 'uint8':
- eps = 0
- elif dtype == 'float16':
- eps = 5e-2
- else:
- eps = 1e-4
- return np.allclose(value_ref, value, rtol=eps, atol=eps)
-
diff --git a/tools/mo/openvino/tools/mo/utils/ir_engine/ir_engine.py b/tools/mo/openvino/tools/mo/utils/ir_engine/ir_engine.py
deleted file mode 100644
index aec4049c6b32e8..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_engine/ir_engine.py
+++ /dev/null
@@ -1,548 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import hashlib
-import logging as log
-import os
-import sys
-from argparse import Namespace
-from collections import namedtuple, defaultdict, OrderedDict
-from pathlib import Path
-
-import defusedxml.ElementTree as ET
-import numpy as np
-from defusedxml import defuse_stdlib
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from openvino.tools.mo.utils.runtime_info import RTInfo, OldAPIMapOrder, OldAPIMapElementType
-
-log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.DEBUG, stream=sys.stdout)
-
-# defuse_stdlib provide patched version of xml.etree.ElementTree which allows to use objects from xml.etree.ElementTree
-# in a safe manner without including unsafe xml.etree.ElementTree
-ElementTree = defuse_stdlib()[ET].ElementTree
-
-
-def read_rt_info_attr(elem):
- if len(elem) == 0:
- if 'value' not in elem.attrib:
- return None
- value = elem.attrib['value']
- return value
- val_dict = {}
- for child in elem:
- child_val = read_rt_info_attr(child)
- val_dict[child.attrib.get('name', child.tag)] = child_val
- return val_dict
-
-
-class IREngine(object):
- def __init__(self, path_to_xml: str, path_to_bin=None, precision="FP32", xml_tree=None):
- if not xml_tree and not os.path.exists(path_to_xml):
- raise AttributeError("File {} do not exists!".format(path_to_xml))
-
- if path_to_bin and not os.path.exists(path_to_bin):
- raise AttributeError("File {} do not exists!".format(path_to_bin))
-
- self.path_to_xml = str(path_to_xml)
- self.path_to_bin = str(path_to_bin) if path_to_bin else None
- self.xml_tree = xml_tree
- self.input_node = None
- self.ir_version = None
- self.meta_data = dict()
-
- if precision.upper() not in ['FP32', 'FP16']:
- raise AttributeError("Precision {} is not supported!".format(precision))
- self.__load_ir()
-
- def __load_xml(self):
- xml_tree = self.xml_tree or ET.parse(self.path_to_xml)
- xml_root = xml_tree.getroot()
- xml_layers = {}
- xml_edges = []
- statistics = {}
-
- Edge = namedtuple('edge', ['from_layer', 'from_port', 'to_layer', 'to_port'])
-
- # Create graph with operations only
- self.graph = Graph()
- self.graph.graph['hashes'] = {}
-
- self.graph.graph['ir_version'] = int(xml_root.attrib['version']) if xml_root.attrib.get('version') is not None else None
-
- # NOTE: THis is MO internal attribute, it cannot be used for
- # defining graph input layout. We set it to NCHW as in MO back stage
- # during conversion for correct shape inference of layout specific
- # operations (ExtractImagePatches, SpaceToDepth, etc.)
- self.graph.graph['layout'] = 'NCHW'
-
- self.graph.name = xml_root.attrib['name'] if xml_root.attrib.get('name') is not None else None
-
- self.graph.inputs_order = []
- self.graph.outputs_order = []
-
- # Parse XML
- for child in xml_root:
- if child.tag == 'layers':
- for layer in child:
- layer_id, layer_attrs = self.__load_layer(layer)
- xml_layers.update({layer_id: layer_attrs})
- if layer_attrs['type'] == 'Parameter':
- self.graph.inputs_order.append(layer_attrs['name'])
- if layer_attrs['type'] == 'Result':
- self.graph.outputs_order.append(layer_attrs['name'])
- elif child.tag == 'edges':
- for edge in child:
- xml_edges.append(Edge(edge.attrib['from-layer'], int(edge.attrib['from-port']),
- edge.attrib['to-layer'], int(edge.attrib['to-port'])))
- elif child.tag == 'statistics':
- layers = child.findall('layer')
- for layer in layers:
- statistics[layer.find('name').text] = {'min': layer.find('min').text, 'max': layer.find('max').text}
- elif child.tag == 'rt_info':
- for elem in child:
- self.meta_data[elem.attrib.get('name', elem.tag)] = read_rt_info_attr(elem)
-
- # TODO: Remove this part when POT updates to using of rt_info
- elif child.tag == 'quantization_parameters':
- # Section with Post Optimization Toolkit parameters
- self.meta_data['quantization_parameters'] = dict()
- for elem in child:
- if elem.tag == 'config':
- self.meta_data['quantization_parameters']['config'] = elem.text
- elif elem.tag in ['version', 'cli_params']:
- self.meta_data['quantization_parameters'][elem.tag] = elem.attrib['value']
-
- self.graph.graph['cmd_params'] = Namespace(**self.meta_data) # TODO check what we need all this attrs
-
- if len(statistics):
- self.graph.graph['statistics'] = statistics
-
- for layer in xml_layers.keys():
- self.graph.add_node(layer, **xml_layers[layer])
-
- xml_edges.sort(key=lambda x: x.to_layer)
-
- for edge in xml_edges:
- self.graph.add_edges_from(
- [(edge.from_layer, edge.to_layer, {'from_port': edge.from_port, 'to_port': edge.to_port})])
-
- # Insert data nodes between op nodes and insert data nodes with weights
- nodes = list(self.graph.nodes())
- for node in nodes:
- out_edges = Node(self.graph, node).get_outputs()
- data_nodes = {}
- for port in self.graph.node[node]['ports']:
- data = self.graph.unique_id(prefix='data_')
- self.graph.add_node(data, **{'kind': 'data', 'shape': self.graph.node[node]['ports'][port][0],
- 'value': None})
- self.graph.add_edges_from([(node, data, {'out': port})])
- data_nodes.update({port: data})
-
- for out_node, edge_attrs in out_edges:
- self.graph.remove_edge(node, out_node)
- if edge_attrs['from_port'] in data_nodes:
- data = data_nodes[edge_attrs['from_port']]
- else:
- raise RuntimeError("SMTH wrong with IR! There is an edge from not existing port")
- self.graph.add_edges_from([(data, out_node, {'in': edge_attrs['to_port']})])
-
- def __load_bin(self):
- bin_buff = np.fromfile(file=self.path_to_bin, dtype=np.uint8)
- graph = self.graph
- nodes = [node for node in graph.nodes()]
- hashes = defaultdict(dict)
- for node in nodes:
- for w in ['weights', 'biases', 'custom']:
- if w in graph.node[node]:
- data = graph.unique_id(prefix='data_')
- offset, size, in_port, precision = graph.node[node][w]
- if Node(graph, node).soft_get('type') == 'BinaryConvolution':
- precision = np.uint8
- value = np.frombuffer(buffer=bin_buff, dtype=precision, count=size, offset=offset)
- hashes[graph.node[node]['name']][w] = hashlib.sha512(value.tobytes()).hexdigest()
- graph.add_node(data, **{'kind': 'data', 'value': value, 'shape': value.shape})
- graph.add_edges_from([(data, node, {'in': in_port})])
- self.graph.graph['hashes'].update(hashes)
-
- def __load_bin_hashes(self):
- graph = self.graph
- bin_hash_map = {name: blob_map.item(0) for name, blob_map in dict(np.load(self.path_to_bin,
- allow_pickle=True)).items()}
-
- for node in graph.nodes():
- for w in ['weights', 'biases', 'custom']:
- if w in graph.node[node]:
- assert Node(graph, node).has_valid('name')
- node_name = Node(graph, node).name
- assert node_name in bin_hash_map and w in bin_hash_map[node_name]
- graph.node[node]['hashes'] = bin_hash_map[node_name][w]
-
- def __load_ir(self):
- self.__load_xml()
- if not self.path_to_bin:
- return
-
- if self.path_to_bin.endswith('.bin.hashes.npz'):
- self.__load_bin_hashes()
- else:
- self.__load_bin()
-
- def __load_layer(self, layer):
- """
- Layer example
-
-
-
-
-
- 1
- 3
- 32
- 32
-
-
-
-
- 1
- 32
- 32
- 32
-
-
-
-
-
-
-
-
- """
-
- layer_id = layer.attrib['id']
-
- layer_attrs = layer.attrib
- layer_attrs.update({'ports': {}, 'restored_input_ports': {}, 'kind': 'op'})
-
- inputs_counter = 0
-
- for attr in layer:
- if attr.tag == 'data':
- new_attrs = self.__normalize_attrs(attr.attrib)
- new_attrs['ir_data_attrs'] = attr.attrib
- if layer.attrib['type'] == 'Const':
- assert 'offset' in new_attrs and 'size' in new_attrs, \
- 'Incorrect attributes for Const layer, {} instead of {}!'.format(new_attrs.keys(), ['offset', 'size'])
- precision = ""
- for item in layer:
- if item.tag == "output":
- precision = item[0].attrib["precision"]
- break
- new_attrs.update(self.__prepare_bin_attrs(layer, 0, 'custom', new_attrs['offset'], new_attrs['size'], precision))
- layer_attrs.update(new_attrs)
- elif attr.tag == 'input':
- inputs_counter = len(attr)
-
- input = attr
- for port in input:
- port_id = int(port.attrib['id'])
- input_shape = []
- port_rt_info = {}
- for dim in port:
- if dim.tag == "dim":
- input_shape.append(int(dim.text))
- if dim.tag == 'rt_info':
- for attr in dim:
- port_rt_info.update(self.__read_rt_info_common(attr))
-
- input_shape = shape_array([d if d != -1 else dynamic_dimension_value for d in input_shape])
-
- in_tensor_names = None
- if 'names' in port.attrib:
- in_tensor_names = port.attrib['names']
-
- # special attribute to pass information about operation input ports
- layer_attrs['restored_input_ports'].update({port_id: (input_shape, in_tensor_names, port_rt_info)})
- elif attr.tag == 'output':
- output = attr
- for port in output:
- port_id = int(port.attrib['id'])
- output_shape = []
- port_rt_info = {}
- for dim in port:
- if dim.tag == "dim":
- output_shape.append(int(dim.text))
- if dim.tag == 'rt_info':
- for attr in dim:
- port_rt_info.update(self.__read_rt_info_common(attr))
-
- output_shape = shape_array([d if d != -1 else dynamic_dimension_value for d in output_shape])
-
- out_tensor_names = None
- if 'names' in port.attrib:
- out_tensor_names = port.attrib['names']
- # special attribute to pass information about operation input ports
- # NOTE: renaming or structure changing of this attribute may have big impact on tests
- layer_attrs['ports'].update({port_id: (output_shape, out_tensor_names, port_rt_info)})
- elif attr.tag == 'blobs':
- in_port = inputs_counter
- for blob_attr in attr:
- layer_attrs.update(self.__prepare_bin_attrs(layer, in_port, blob_attr.tag,
- blob_attr.attrib['offset'], blob_attr.attrib['size'],
- blob_attr.attrib.get('precision', None)))
- in_port += 1
- elif attr.tag == 'body':
- xml_body_child = list(layer.iterfind('body'))
- assert len(xml_body_child) == 1
-
- body_ir, input_port_map, output_port_map, input_layers = \
- self.__read_subgraph(layer, layer_attrs, xml_body_child, 'port_map')
-
- body_ir.input_node = input_layers[0]
- layer_attrs.update({'body': body_ir})
- layer_attrs.update({'input_port_map': input_port_map})
- layer_attrs.update({'output_port_map': output_port_map})
-
- xml_back_edges_map = list(layer.iterfind('back_edges'))
- if not len(xml_back_edges_map) == 1:
- log.warning("TensorIterator body won\'t be compared due to missing back_edges section!")
- continue
- xml_back_edges_map = xml_back_edges_map[0]
-
- back_edges = []
-
- for edge in xml_back_edges_map:
- back_edges.append(self.__normalize_attrs(edge.attrib))
-
- layer_attrs.update({'back_edges': back_edges})
-
- elif attr.tag == 'then_body' or attr.tag == 'else_body':
- assert layer.attrib['type'] == 'If', "Incorrect IR! The operation {0}" \
- " has sub-graphs for If operation"
- layer_attrs = self.__read_if(layer, layer_attrs)
- continue
-
- elif attr.tag == 'rt_info':
- layer_attrs = self.__read_rt_info(layer, layer_attrs)
- continue
-
- return layer_id, layer_attrs
-
- @staticmethod
- def __prepare_bin_attrs(xml_layer, in_port, tag, offset, size, precision):
- layer_attrs = dict()
- if precision is None:
- precision = xml_layer.attrib['precision']
- precision_map = {
- 'FP64': (8, np.float64),
- 'FP32': (4, np.float32),
- 'FP16': (2, np.float16),
- 'I64': (8, np.int64),
- 'I32': (4, np.int32),
- 'I8': (1, np.int8),
- 'U8': (1, np.uint8),
- 'U1': (1, np.uint8),
- 'U4': (1, np.uint8),
- 'I4': (1, np.uint8),
- 'BOOL': (1, bool),
- 'BIN': (1, np.uint8),
- 'U64': (8, np.uint64)
- }
- type_size, dtype = precision_map[precision]
- layer_attrs[tag] = (int(offset), int(size) // type_size, in_port, dtype)
- return layer_attrs
-
- @staticmethod
- def __normalize_attrs(attrs: dict):
- """
- Normalize attributes for type 'data'.
- Replace " from values (not used right now) and make list of value with int, float or other types values.
- Example: {'order': '1,0,2'} -> {'order': [1, 0, 2]}
- {'order': '1'} -> {'order': 1}
- """
- normalized_attrs = {}
- for attr, value in attrs.items():
- value = value.replace('\"', '').replace(' ', '')
- value = value.split(',')
- n_value = []
- for val in value:
- if IREngine.__isint(val):
- n_value.append(int(val))
- elif IREngine.__isfloat(val):
- n_value.append(float(val))
- elif val in ['True', 'False', 'true', 'false']:
- n_value.append(val in ['True', 'true'])
- else:
- n_value.append(val)
-
- if len(n_value) == 1:
- normalized_attrs.update({attr: n_value[0]})
- else:
- normalized_attrs.update({attr: n_value})
-
- return normalized_attrs
-
- @staticmethod
- def __isfloat(value):
- try:
- float(value)
- return True
- except ValueError:
- return False
-
- @staticmethod
- def __isint(value):
- is_signed = value.startswith('+') or value.startswith('-')
- other_chars_are_digits = value[1:].isdigit()
- all_chars_are_digits = value.isdigit()
- return all_chars_are_digits or (is_signed and other_chars_are_digits)
-
- @staticmethod
- def __find_input(graph):
- inputs = []
- for node in sorted(graph.nodes()):
- node = Node(graph, node)
- if node.has_valid('type') and node.type in ('Input', 'Parameter'):
- inputs.append(node)
-
- if len(inputs) < 1:
- raise RuntimeError("Graph {} has less than one input node".format(graph.name))
-
- return inputs
-
- def compare(self, ref_net):
- if not isinstance(ref_net, IREngine):
- ir_input = self.__find_input(self.graph)[0]
- ref_input = self.__find_input(ref_net)[0]
- ref_graph = ref_net
- else:
- ir_input = self.input_node or self.__find_input(self.graph)[0]
- ref_input = ref_net.input_node or ref_net.__find_input(ref_net.graph)[0]
- ref_graph = ref_net.graph
- # TODO check that ir_input[0].id and ref_input[0].id are the same
- result, stderr = compare_graphs(graph=self.graph, graph_ref=ref_graph, last_node=ir_input.id,
- last_node_ref=ref_input.id, check_op_attrs=True)
- return result, stderr
-
- def generate_bin_hashes_file(self, path_for_file=None):
- # This function creates file with extension '.bin.hashes.npz' where hashes of bin exists.
- # For creating this file in custom filder use attribute path_for_file.
- # Where directory for file should be existed
- graph = self.graph
- if path_for_file is None:
- path_for_file = str(Path(self.path_to_xml).with_suffix('.bin.hashes.npz'))
- assert 'hashes' in graph.graph, "Loaded IR graph doesn't contain `hashes`: {}".format(self.path_to_xml)
- np.savez_compressed(path_for_file, **graph.graph['hashes'])
- return path_for_file
-
- def get_inputs(self):
- # Function return input nodes in dictionary: {input_node_name: input_node_shape, ...}
- input_nodes = self.__find_input(self.graph)
- return {input_node.name: input_node.out_node().shape for input_node in input_nodes}
-
- def __eq__(self, other):
- # To call this function create two IREngine objects (IR1, IR2) and compare them IR1 == IR2
- if not isinstance(other, IREngine):
- raise AttributeError("IREngine can be compared only with IREngine object type")
- return self.compare(other)[0]
-
- def __read_subgraph(self, layer, layer_attrs, body_child, port_map_name):
- body_ir = IREngine(path_to_xml=None,
- path_to_bin=self.path_to_bin,
- xml_tree=ElementTree(body_child[0]))
-
- self.graph.graph['hashes'].update(body_ir.graph.graph['hashes'])
-
- xml_port_map = list(layer.iterfind(port_map_name))
- assert not len(xml_port_map) != 1, "If then_body won\'t be compared due to missing {1} section in node {0}! " \
- .format(layer_attrs['name'], port_map_name)
- xml_port_map = xml_port_map[0]
-
- input_layers = []
- input_port_map = []
- output_port_map = []
-
- for port in xml_port_map:
- if port.tag == 'input':
- if 'internal_layer_id' not in port.attrib:
- log.warning("internal_layer_id attrib not found in input section")
- else:
- input_layers.append(Node(body_ir.graph, port.attrib['internal_layer_id']))
- input_port_map.append(self.__normalize_attrs(port.attrib))
- elif port.tag == 'output':
- if 'internal_layer_id' not in port.attrib:
- log.warning("internal_layer_id attrib not found in output section")
- else:
- output_port_map.append(self.__normalize_attrs(port.attrib))
-
- return body_ir, input_port_map, output_port_map, input_layers
-
- def __read_if(self, layer, layer_attrs):
-
- xml_then_body_child = list(layer.iterfind('then_body'))
- xml_else_body_child = list(layer.iterfind('else_body'))
- assert len(xml_then_body_child) == 1 and len(xml_else_body_child) == 1, "If operation has only one subgraph"
-
- then_body_ir, then_input_port_map, then_output_port_map, _ = \
- self.__read_subgraph(layer, layer_attrs, xml_then_body_child, 'then_port_map')
- layer_attrs.update({'then_graph': then_body_ir})
- layer_attrs.update({'then_input_port_map': then_input_port_map})
- layer_attrs.update({'then_output_port_map': then_output_port_map})
-
- else_body_ir, else_input_port_map, else_output_port_map, _ = \
- self.__read_subgraph(layer, layer_attrs, xml_else_body_child, 'else_port_map')
- layer_attrs.update({'else_graph': else_body_ir})
- layer_attrs.update({'else_input_port_map': else_input_port_map})
- layer_attrs.update({'else_output_port_map': else_output_port_map})
-
- return layer_attrs
-
- def __read_rt_info(self, layer, layer_attrs):
- rt_info = RTInfo()
- xml_rt_info = list(layer.iterfind('rt_info'))[0]
-
- for attr in xml_rt_info:
- attr_name = attr.attrib['name']
- if attr_name == 'old_api_map_order':
- rt_info.info.update(self.__read_old_api_map_order(attr, layer.attrib['type']))
- elif attr_name == 'old_api_map_element_type':
- rt_info.info.update(self.__read_old_api_map_element_type(attr, layer.attrib['type']))
- else:
- rt_info.info.update((self.__read_rt_info_common(attr)))
-
- layer_attrs.update({'rt_info': rt_info})
- return layer_attrs
-
- @staticmethod
- def __read_old_api_map_order(attr, layer_type):
- version = int(attr.attrib['version'])
- order = list(map(int, attr.attrib['value'].split(',')))
- old_api_map = OldAPIMapOrder(version=version)
- if layer_type == 'Parameter':
- old_api_map.old_api_transpose_parameter(order)
- elif layer_type == 'Result':
- old_api_map.old_api_transpose_result(order)
- else:
- raise AttributeError("Cannot read old_api_map for layer of type: {}".format(layer_type))
-
- return {('old_api_map_order', version): old_api_map}
-
- @staticmethod
- def __read_old_api_map_element_type(attr, layer_type):
- version = int(attr.attrib['version'])
- element_type = destination_type_to_np_data_type(attr.attrib['value'])
- old_api_map = OldAPIMapElementType(version=version)
- old_api_map.set_legacy_type(element_type)
- return {('old_api_map_element_type', version): old_api_map}
-
- @staticmethod
- def __read_rt_info_common(attr):
- attr_name = attr.attrib['name']
- version = int(attr.attrib['version'])
- rt_info = OrderedDict()
- for key in attr.attrib:
- if key not in ('name', 'version'):
- rt_info[key] = attr.attrib[key]
- return {(attr_name, version): rt_info}
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/__init__.py b/tools/mo/openvino/tools/mo/utils/ir_reader/__init__.py
deleted file mode 100644
index 8ba81a92b19c53..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extender.py
deleted file mode 100644
index 579d6efc16cb2f..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extender.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils import class_registration
-from openvino.tools.mo.utils.graph import Node
-
-
-class Extender(object):
- registered_ops = {}
- registered_cls = []
- # Add the derived class to excluded_classes if one should not be registered in registered_ops
- excluded_classes = []
-
- @staticmethod
- def extend(op: Node):
- pass
-
- @staticmethod
- def get_extender_class_by_name(name: str):
- return __class__.registered_ops[name]
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.IR_READER_EXTENDER
-
- @staticmethod
- def attr_to_list(node: Node, attribute: str):
- if not node.has_valid(attribute):
- log.warning('Attribute {} missed in node {} with type {}!'.format(attribute, node.soft_get('name'),
- node.soft_get('type')))
- elif not isinstance(node[attribute], list):
- node[attribute] = [node[attribute]]
-
- @staticmethod
- def use_shapes_from_ir(node: Node):
- # This function used instead of operation shape inference function to set all output shapes the same as
- # restored from IR. Firstly, check equality of old (restored from IR) and
- # new (calculated while shape inference) input shapes
- node['new_input_shapes'] = list()
- for n in node.in_ports():
- # We use such condition to handle optional inputs
- if not node.in_port(n).disconnected():
- node.new_input_shapes.append(node.in_port(n).data.get_shape())
- assert len(node.new_input_shapes) == len(node.old_input_shapes), \
- 'Something wrong happened while {} node with type {} copy shape inference! {} != {}'.format(
- node.name, node.type, len(node.new_input_shapes), len(node.old_input_shapes))
- for new_input_shape, old_input_shape in zip(node.new_input_shapes, node.old_input_shapes):
- assert np.array_equal(new_input_shape, old_input_shape), \
- 'Something wrong happened while {} node with type {} copy shape inference! {} != {}'.format(
- node.name, node.type, new_input_shape, old_input_shape)
-
- # We need to use number of connected input ports to avoid errors with numbering
- # in node.ports dictionary, where used numbers of input nodes
- connected_input_ports = []
- for n in node.in_ports():
- if not node.in_port(n).disconnected():
- connected_input_ports.append(node.in_port(n))
- i = len(connected_input_ports)
-
- # Set all output shapes the same as restored from IR
- for num in node.out_ports():
- if i in node.ports:
- node.out_port(num).data.set_shape(int64_array(node.ports[i][0]))
- else:
- assert node.out_port(num).data.get_shape() is not None, "Newly added port does not have set shape"
- i += 1
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/ExtractImagePatches_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/ExtractImagePatches_extender.py
deleted file mode 100644
index 2ac87cfa44bcc8..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/ExtractImagePatches_extender.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class ExtractImagePatches(Extender):
- op = 'ExtractImagePatches'
-
- @staticmethod
- def extend(op: Node):
- op['sizes'] = int64_array([1, 1] + op.sizes)
- op['strides'] = int64_array([1, 1] + op.strides)
- op['rates'] = int64_array([1, 1] + op.rates)
-
- op['spatial_dims'] = int64_array([2, 3])
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/GRUCell_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/GRUCell_extender.py
deleted file mode 100644
index 3669f2d43e431a..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/GRUCell_extender.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import mark_input_bins
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class GRUCell_extender(Extender):
- op = 'GRUCell'
-
- @staticmethod
- def extend(op: Node):
- if not op.has_valid('activations'):
- op['activations'] = None
-
- mark_input_bins(op, start_port=2)
-
- op['need_copy_input_blobs'] = True
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/GRUSequence_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/GRUSequence_extender.py
deleted file mode 100644
index 3679d3e945ad0d..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/GRUSequence_extender.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class GRUSequence_extender(Extender):
- op = 'GRUSequence'
-
- @staticmethod
- def extend(op: Node):
- op['infer'] = Extender.use_shapes_from_ir
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/LSTMCell_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/LSTMCell_extender.py
deleted file mode 100644
index d1766ecbd205a6..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/LSTMCell_extender.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class LSTMCell_extender(Extender):
- op = 'LSTMCell'
-
- @staticmethod
- def extend(op: Node):
- if not op.has_valid('activations'):
- op['activations'] = None
- op['infer'] = Extender.use_shapes_from_ir
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/LSTMSequence_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/LSTMSequence_extender.py
deleted file mode 100644
index 168b82f6ba6694..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/LSTMSequence_extender.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class LSTMSequence_extender(Extender):
- op = 'LSTMSequence'
-
- @staticmethod
- def extend(op: Node):
- op['infer'] = Extender.use_shapes_from_ir
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/RNNCell_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/RNNCell_extender.py
deleted file mode 100644
index e11f6cede5d04c..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/RNNCell_extender.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class RNNCell_extender(Extender):
- op = 'RNNCell'
-
- @staticmethod
- def extend(op: Node):
- if not op.has_valid('activations'):
- op['activations'] = None
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/__init__.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/binary_convolution_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/binary_convolution_extender.py
deleted file mode 100644
index edf8b9a7744f17..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/binary_convolution_extender.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.extenders.conv_extender import Conv_extender
-
-
-class BinaryConv_extender(Extender):
- op = 'BinaryConvolution'
-
- @staticmethod
- def extend(op: Node):
- Conv_extender.extend(op)
- op['type_to_create'] = 'Convolution'
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/bucketize_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/bucketize_extender.py
deleted file mode 100644
index e76ed95967df30..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/bucketize_extender.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class BucketizeExtender(Extender):
- op = 'Bucketize'
-
- @staticmethod
- def extend(op: Node):
- if op.get_opset() != "extension":
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/conv_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/conv_extender.py
deleted file mode 100644
index 0c70874403b383..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/conv_extender.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class Conv_extender(Extender):
- op = 'Convolution'
-
- @staticmethod
- def extend(op: Node):
- for attr in ['strides', 'dilations', 'pads_begin', 'pads_end', 'output_padding']:
- Extender.attr_to_list(op, attr)
-
- op['stride'] = int64_array([1, 1] + op.strides)
- op['dilation'] = int64_array([1, 1] + op.dilations)
-
- op['batch_dims'] = int64_array([0])
- op['channel_dims'] = int64_array([1])
-
- if op.has_valid('output_padding'):
- op.output_padding = int64_array([0, 0] + op.output_padding)
-
- # Be VERY careful with these attributes!
- op['input_feature_channel'] = 1
- op['output_feature_channel'] = 0
-
- dim = len(op.pads_begin)
-
- assert dim in (1, 2, 3), '{}D Convolution not supported!'.format(dim)
-
- pad = [[0, 0], [0, 0]]
- pad.extend([[op.pads_begin[i], op.pads_end[i]] for i in range(dim)])
-
- op['pad'] = int64_array(pad)
-
- op['spatial_dims'] = [i + 2 for i in range(dim)]
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/convert_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/convert_extender.py
deleted file mode 100644
index 20ee8d0feb4f66..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/convert_extender.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class Convert_extender(Extender):
- op = 'Convert'
-
- @staticmethod
- def extend(op: Node):
- op['dst_type'] = destination_type_to_np_data_type(op.destination_type)
- # CompressQuantizeWeights generates IR with constant sub-graph, that should not be ConstFolded:
- # Const(u8) -> Convert(to fp) -> (some eltwise operations) -> FakeQuantize
- if op.in_node().in_node().soft_get('type') == 'Const':
- op['stop_value_propagation'] = True
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/ctc_greedy_decoder_seq_len_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/ctc_greedy_decoder_seq_len_extender.py
deleted file mode 100644
index 346bdfd85f0efa..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/ctc_greedy_decoder_seq_len_extender.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class CTCGreedyDecoderSeqLenExtender(Extender):
- op = 'CTCGreedyDecoderSeqLen'
-
- @staticmethod
- def extend(op: Node):
- if op.has_valid('classes_index_type'):
- op['classes_index_type'] = destination_type_to_np_data_type(op.classes_index_type)
- if op.has_valid('sequence_length_type'):
- op['sequence_length_type'] = destination_type_to_np_data_type(op.sequence_length_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/deconvolution_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/deconvolution_extender.py
deleted file mode 100644
index 6cce2a74c98e37..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/deconvolution_extender.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class ConvolutionBackpropData_extender(Extender):
- op = 'ConvolutionBackpropData'
-
- @staticmethod
- def extend(op: Node):
- common_backpropdata_extender(op)
-
-
-class GroupConvolutionBackpropData_extender(Extender):
- op = 'GroupConvolutionBackpropData'
-
- @staticmethod
- def extend(op: Node):
- common_backpropdata_extender(op)
-
-
-def common_backpropdata_extender(op: Node):
- for attr in ['strides', 'output_padding', 'pads_begin', 'pads_end', 'dilations']:
- Extender.attr_to_list(op, attr)
-
- if op.has_valid('output_padding'):
- op.output_padding = int64_array([0, 0] + op.output_padding)
-
- dim = len(op.strides)
-
- if op.has_valid('pads_begin') and op.has_valid('pads_end'):
- pad = [[0, 0], [0, 0]]
- pad.extend([[op.pads_begin[i], op.pads_end[i]] for i in range(dim)])
-
- op['pad'] = int64_array(pad)
-
- op['spatial_dims'] = [i + 2 for i in range(dim)]
-
- if not op.has_valid('dilations'):
- op['dilations'] = [1 for _ in range(dim)]
- if not op.has_valid('strides'):
- op['strides'] = [1 for _ in range(dim)]
-
- op['dilation'] = int64_array([1, 1] + op.dilations)
- op['stride'] = int64_array([1, 1] + op.strides)
-
- op['infer'] = backpropdata_infer
-
-
-def backpropdata_infer(op: Node):
- Extender.use_shapes_from_ir(op)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/deformable_convolution_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/deformable_convolution_extender.py
deleted file mode 100644
index e45df555c58ed3..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/deformable_convolution_extender.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.extenders.conv_extender import Conv_extender
-
-
-class DeformableConv_extender(Extender):
- op = 'DeformableConvolution'
-
- @staticmethod
- def extend(op: Node):
- Conv_extender.extend(op)
- op['bias_addable'] = False,
- op['bias_term'] = False,
- op['weights_index'] = 2
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/einsum_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/einsum_extender.py
deleted file mode 100644
index d04932bd5a15ed..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/einsum_extender.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class Einsum_extender(Extender):
- op = 'Einsum'
-
- @staticmethod
- def extend(op: Node):
- einsum_name = op.soft_get('name', op.id)
- if isinstance(op['equation'], list):
- op['equation'] = ','.join(op['equation'])
- elif not isinstance(op['equation'], str):
- assert False, "Equation of Einsum node {} has incorrect format.".format(einsum_name)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/experimental_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/experimental_extender.py
deleted file mode 100644
index 29125a79b311d3..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/experimental_extender.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class ExperimentalDetectronROIFeatureExtractor_extender(Extender):
- op = 'ExperimentalDetectronROIFeatureExtractor'
-
- @staticmethod
- def extend(op: Node):
- Extender.attr_to_list(op, 'pyramid_scales')
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/eye_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/eye_extender.py
deleted file mode 100644
index 7f25a4c8302507..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/eye_extender.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class EyeExtender(Extender):
- op = 'Eye'
-
- @staticmethod
- def extend(op: Node):
- if op.has_valid('output_type'):
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/fakequantize_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/fakequantize_extender.py
deleted file mode 100644
index e32df4d3b0acec..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/fakequantize_extender.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class FakeQuantize_extender(Extender):
- op = 'FakeQuantize'
-
- @staticmethod
- def extend(op: Node):
- op['stop_value_propagation'] = True
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/if_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/if_extender.py
deleted file mode 100644
index 15fc73b2a42cf0..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/if_extender.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.layer_to_class import copy_graph_with_ops
-
-
-class IfExtender(Extender):
- op = 'If'
-
- @staticmethod
- def set_input_output_id(subgraph, input_port_map, output_port_map, num_of_in_ports, num_of_out_ports):
- for node in subgraph.get_op_nodes():
- if not node.has_valid('id'):
- continue
- node_id = int(node.soft_get('id'))
- for if_input_mapping_elem in input_port_map:
- if node_id == if_input_mapping_elem['internal_layer_id']:
- node['input_id'] = if_input_mapping_elem['external_port_id']
- for if_out_mapping_elem in output_port_map:
- if node_id == if_out_mapping_elem['internal_layer_id']:
- # If external_point ID is counted with inputs
- if if_out_mapping_elem['external_port_id'] > num_of_out_ports:
- node['output_id'] = if_out_mapping_elem['external_port_id'] - num_of_in_ports
- # If external_point ID is counted from 0
- else:
- node['output_id'] = if_out_mapping_elem['external_port_id']
-
- @staticmethod
- def extend(op: Node):
- assert op.has('then_graph'), 'There is no "then_body" attribute in the If op {}.'.format(op.name)
- assert op.has('else_graph'), 'There is no "else_body" attribute in the If op {}.'.format(op.name)
- # Now op.body is an IREngine, we need to replace it with IREngine.graph
- op.then_graph.graph.graph['cmd_params'] = op.graph.graph['cmd_params']
- op.then_graph.graph.graph['ir_version'] = op.graph.graph['ir_version']
- op.then_graph.graph.name = op.name + '/then_body'
-
- op.else_graph.graph.graph['cmd_params'] = op.graph.graph['cmd_params']
- op.else_graph.graph.graph['ir_version'] = op.graph.graph['ir_version']
- op.else_graph.graph.name = op.name + '/else_body'
- op.then_graph = copy_graph_with_ops(op.then_graph.graph)
- op.else_graph = copy_graph_with_ops(op.else_graph.graph)
-
- num_of_in_ports = len(op.in_ports())
- num_of_out_ports = len(op.out_ports())
- IfExtender.set_input_output_id(op.then_graph, op.then_input_port_map, op.then_output_port_map, num_of_in_ports, num_of_out_ports)
- IfExtender.set_input_output_id(op.else_graph, op.else_input_port_map, op.else_output_port_map, num_of_in_ports, num_of_out_ports)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/interpolate_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/interpolate_extender.py
deleted file mode 100644
index ffd17d4528a33b..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/interpolate_extender.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class Interpolate_extender(Extender):
- op = 'Interpolate'
-
- @staticmethod
- def extend(op: Node):
- Extender.attr_to_list(op, 'axes')
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/loop_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/loop_extender.py
deleted file mode 100644
index 284df400f241c0..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/loop_extender.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.layer_to_class import copy_graph_with_ops
-
-
-class LoopExtender(Extender):
- op = 'Loop'
-
- @staticmethod
- def extend(op: Node):
- def normalize_port_map(port_map: dict):
- for port in port_map:
- for elem in ['axis', 'stride', 'part_size', 'start', 'end', 'purpose']:
- if port.get(elem) is None:
- port[elem] = None
-
- assert op.has('body'), 'There is no "body" attribute in the Loop op {}.'.format(op.name)
-
- # Now op.body is an IREngine, we need to replace it with IREngine.graph
- op.body.graph.graph['cmd_params'] = op.graph.graph['cmd_params']
- op.body.graph.graph['ir_version'] = op.graph.graph['ir_version']
- op.body.graph.name = op.name + '/body'
-
- for node in op.body.graph.get_op_nodes():
- node['internal_layer_id'] = int(node.id)
-
- op.body = copy_graph_with_ops(op.body.graph)
-
- normalize_port_map(op.input_port_map)
- normalize_port_map(op.output_port_map)
-
- # the 'external_port_id' uses end-to-end numbering of ports, but at this moment it is separate for input and
- # output ports so we need to decrease the output por_id with a number of input ports
- for record in op.output_port_map:
- if record['external_port_id'] != -1:
- record['external_port_id'] -= len(op.in_ports())
-
- for edge in op.back_edges:
- edge['from_layer'] = edge['from-layer']
- edge['to_layer'] = edge['to-layer']
-
- edge['to_port'] = 0
- edge['from_port'] = 0
-
- del(edge['from-layer'])
- del(edge['to-layer'])
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/non_max_suppression_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/non_max_suppression_extender.py
deleted file mode 100644
index 97effc754e8ced..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/non_max_suppression_extender.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class NonMaxSuppressionExtender(Extender):
- op = 'NonMaxSuppression'
-
- @staticmethod
- def extend(op: Node):
- if op.has_valid('output_type'):
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/non_zero_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/non_zero_extender.py
deleted file mode 100644
index 5b939dab2f60c8..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/non_zero_extender.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class NonZeroExtender(Extender):
- op = 'NonZero'
-
- @staticmethod
- def extend(op: Node):
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/pad_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/pad_extender.py
deleted file mode 100644
index 564818c18c2a49..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/pad_extender.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class Pad_extender(Extender):
- op = 'Pad'
-
- @staticmethod
- def extend(op: Node):
- op['mode'] = op['pad_mode']
- del op['pad_mode']
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/parameter_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/parameter_extender.py
deleted file mode 100644
index 12927bd142c5eb..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/parameter_extender.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.runtime import PartialShape, Dimension
-
-
-class Parameter_extender(Extender):
- op = 'Parameter'
-
- @staticmethod
- def extend(op: Node):
- assert op.has_valid('element_type'), 'Parameter node {} has missed element_type attr!'.format(op.name)
- op['data_type'] = destination_type_to_np_data_type(op.element_type)
- if op.shape == '':
- op.shape = int64_array([])
- else:
- Extender.attr_to_list(op, 'shape')
-
- # Remove brackets from shape splited by comma separator
- if isinstance(op.shape[0], str) and op.shape[0][0] == '[':
- op.shape[0] = op.shape[0][1:]
- if isinstance(op.shape[-1], str) and op.shape[-1][-1] == ']':
- op.shape[-1] = op.shape[-1][:-1]
-
- shape = op.shape.copy()
- has_shapes_with_boundaries = False
- for i, dim in enumerate(op.shape):
- if dim == -1 or (isinstance(dim, str) and ".." in dim):
- shape[i] = -1
- # Check only if dim is not int
- if not isinstance(dim, int) and '..' in dim:
- has_shapes_with_boundaries = True
- shape = shape_array([int(d) if d not in [-1, '?'] else dynamic_dimension_value for d in shape])
-
- if has_shapes_with_boundaries:
- shape_list = []
- for dim in op.shape:
- shape_list.append(Dimension(dim))
-
- # This value is used only for serialization of partial shapes with boundaries
- # for Parameter node.
- # 'user_shape' is not used in shape inference, as propagation of partial shapes with boundaries
- # is not implemented in MO.
- op['user_shape'] = PartialShape(shape_list)
-
- # If 'user_shape' is not set, 'shape' attribute is used for serialization.
- # 'shape' is also used for shape inference.
- op.shape = shape
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/pooling_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/pooling_extender.py
deleted file mode 100644
index 23220c465ebe41..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/pooling_extender.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class AvgPool_extender(Extender):
- op = 'AvgPool'
-
- @staticmethod
- def extend(op: Node):
- common_pool_extender(op)
-
- if 'exclude-pad' in op:
- op['exclude_pad'] = op['exclude-pad']
- del op['exclude-pad']
-
-
-class MaxPool_extender(Extender):
- op = 'MaxPool'
-
- @staticmethod
- def extend(op: Node):
- common_pool_extender(op)
-
-
-def common_pool_extender(op: Node):
- for attr in ['strides', 'pads_begin', 'pads_end', 'kernel', 'dilations']:
- Extender.attr_to_list(op, attr)
- op['stride'] = int64_array([1, 1] + op.strides)
- op['window'] = int64_array([1, 1] + op.kernel)
- op['kernel_spatial'] = op.kernel
- op['output_spatial_shape'] = None
-
- if op.has_valid('dilations'):
- op['dilation'] = int64_array([1, 1] + op.dilations)
- if op.has_valid('index_element_type'):
- op['index_element_type'] = destination_type_to_np_data_type(op.index_element_type)
-
- op['batch_dims'] = int64_array([0]),
- op['channel_dims'] = int64_array([1]),
-
- op['pool_method'] = 'max' if op.type == 'MaxPool' else 'avg'
-
- dim = len(op.pads_begin)
-
- assert dim in (1, 2, 3), '{}D {} not supported! Node name: {}'.format(dim, op.soft_get('type'), op.soft_get('name', op.id))
-
- pad = [[0, 0], [0, 0]]
- pad.extend([[op.pads_begin[i], op.pads_end[i]] for i in range(dim)])
-
- op['pad'] = int64_array(pad)
-
- op['spatial_dims'] = [i + 2 for i in range(dim)]
-
- if op.has_valid('rounding_type') and op.rounding_type == 'ceil':
- op['pooling_convention'] = 'full'
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/priorbox_clustered_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/priorbox_clustered_extender.py
deleted file mode 100644
index 72c147128af196..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/priorbox_clustered_extender.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.extenders.priorbox_extender import PriorBox_extender
-
-
-class PriorBoxClustered_extender(Extender):
- op = 'PriorBoxClustered'
-
- @staticmethod
- def extend(op: Node):
- op['V10_infer'] = True
-
- PriorBox_extender.attr_restore(op, 'width', value=1.0)
- PriorBox_extender.attr_restore(op, 'height', value=1.0)
- PriorBox_extender.attr_restore(op, 'variance')
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/priorbox_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/priorbox_extender.py
deleted file mode 100644
index ad301efeb3d865..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/priorbox_extender.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.multi_box_prior import multi_box_prior_infer_mxnet
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class PriorBox_extender(Extender):
- op = 'PriorBox'
-
- @staticmethod
- def extend(op: Node):
- op['V10_infer'] = True
-
- attrs = ['min_size', 'max_size', 'aspect_ratio', 'variance', 'fixed_ratio', 'fixed_size', 'density']
- for attr in attrs:
- PriorBox_extender.attr_restore(op, attr)
-
- @staticmethod
- def attr_restore(node: Node, attribute: str, value=None):
- # Function to restore some specific attr for PriorBox & PriorBoxClustered layers
- if not node.has_valid(attribute):
- node[attribute] = [] if value is None else [value]
- if isinstance(node[attribute], str):
- node[attribute] = []
- else:
- Extender.attr_to_list(node, attribute)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/random_uniform_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/random_uniform_extender.py
deleted file mode 100644
index 943049587d2187..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/random_uniform_extender.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class RandomUniformExtender(Extender):
- op = 'RandomUniform'
-
- @staticmethod
- def extend(op: Node):
- if op.has_valid('output_type'):
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/range_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/range_extender.py
deleted file mode 100644
index 7b337c17209266..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/range_extender.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class RangeExtender(Extender):
- op = 'Range'
-
- @staticmethod
- def extend(op: Node):
- if op.has_valid('output_type'):
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/reorg_yolo_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/reorg_yolo_extender.py
deleted file mode 100644
index f7b1da795ad9ac..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/reorg_yolo_extender.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class ReorgYolo_extender(Extender):
- op = 'ReorgYolo'
-
- @staticmethod
- def extend(op: Node):
- op['batch_dims'] = int64_array([0])
- op['channel_dims'] = int64_array([1])
- op['spatial_dims'] = [2, 3]
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/shape_of_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/shape_of_extender.py
deleted file mode 100644
index 7c3446fc505397..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/shape_of_extender.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class ShapeOfExtender(Extender):
- op = 'ShapeOf'
-
- @staticmethod
- def extend(op: Node):
- if op.has_valid('output_type'):
- op['output_type'] = destination_type_to_np_data_type(op.output_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/strided_slice_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/strided_slice_extender.py
deleted file mode 100644
index 609f3d97cf96da..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/strided_slice_extender.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class StridedSlice_extender(Extender):
- op = 'StridedSlice'
-
- @staticmethod
- def extend(op: Node):
- for attr in StridedSlice.get_mask_names():
- # We can not use op.has_and_set(attr) here as a condition, because it will return False if begin/end is
- # 1D tensor and begin_mask/end_mask is equal to 0
- if op.has(attr) and op[attr] != '':
- Extender.attr_to_list(op, attr)
- else:
- op[attr] = int64_array([])
-
- op.begin_mask = int64_array([1 - i for i in op.begin_mask])
- op.end_mask = int64_array([1 - i for i in op.end_mask])
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/tensoriterator_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/tensoriterator_extender.py
deleted file mode 100644
index 798603c8a998e1..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/tensoriterator_extender.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.layer_to_class import copy_graph_with_ops
-
-
-class TensorIterator_extender(Extender):
- op = 'TensorIterator'
-
- @staticmethod
- def extend(op: Node):
-
- def normalize_port_map(port_map: dict):
- for port in port_map:
- for elem in ['axis', 'stride', 'part_size', 'start', 'end']:
- if port.get(elem) is None:
- port[elem] = None
-
- assert op.has('body'), 'Something wrong with TensorIterator layer {}, please check!'.format(op.name)
-
- # Now op.body is an IREngine, we need to replace it with IREngine.graph
- op.body.graph.graph['cmd_params'] = op.graph.graph['cmd_params']
- op.body.graph.graph['ir_version'] = op.graph.graph['ir_version']
- op.body.graph.name = op.name + '/body'
-
- for node in op.body.graph.get_op_nodes():
- node['internal_layer_id'] = int(node.id)
-
- op.body = copy_graph_with_ops(op.body.graph)
-
- normalize_port_map(op.input_port_map)
- normalize_port_map(op.output_port_map)
-
- for edge in op.back_edges:
- edge['from_layer'] = edge['from-layer']
- edge['to_layer'] = edge['to-layer']
-
- del(edge['from-layer'])
- del(edge['to-layer'])
-
- op['infer'] = Extender.use_shapes_from_ir
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/topk_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/topk_extender.py
deleted file mode 100644
index 4b119288e7a4a3..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/topk_extender.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.passes.convert_data_type import destination_type_to_np_data_type
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class TopKExtender(Extender):
- op = 'TopK'
-
- @staticmethod
- def extend(op: Node):
- if op.out_port(0).disconnected():
- op['remove_values_output'] = True
- if op.has_valid('index_element_type'):
- op['index_element_type'] = destination_type_to_np_data_type(op.index_element_type)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/variadic_split_extender.py b/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/variadic_split_extender.py
deleted file mode 100644
index 541c8b0d8f2a1a..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/extenders/variadic_split_extender.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.utils.graph import Node
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-
-
-class VariadicSplit_extender(Extender):
- op = 'VariadicSplit'
-
- @staticmethod
- def extend(op: Node):
- op['out_ports_count'] = len(op.ports)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/scatter.py b/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/scatter.py
deleted file mode 100644
index 844b41189e4cdb..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/scatter.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.scatter import ScatterUpdate, Scatter
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value
-
-class ScatterUpdateInternal(ScatterUpdate):
- @staticmethod
- def infer(node: Node):
- updates_value = node.in_port(2).data.get_value()
- if updates_value is not None and isinstance(updates_value, np.ma.masked_array) and updates_value.ndim == 1:
- # we need to normalize masked_array so that the value infer works as expected
- value = [item if item is not np.ma.masked else dynamic_dimension_value for item in updates_value]
- updates_value = np.ma.masked_equal(value, dynamic_dimension_value).astype(dtype=updates_value.dtype)
- node.in_port(2).data.set_value(updates_value)
- ScatterUpdate.infer(node)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/squeeze.py b/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/squeeze.py
deleted file mode 100644
index 70effa1f6f12c2..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/squeeze.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, is_fully_defined
-
-
-class SqueezeInternal(Squeeze):
- @staticmethod
- def infer(node: Node):
- if node.is_in_port_connected(1):
- axis_value = node.in_port(1).data.get_value()
- Squeeze.infer(node)
- # preserve initial axis value
- node.in_port(1).data.set_value(axis_value)
- else:
- # Squeeze without axes provided
- node_name = node.soft_get('name', node.id)
- input_shape = node.in_port(0).data.get_shape()
- assert is_fully_defined(
- input_shape), 'Squeeze dimensions are not defined for op "{}"'.format(node_name)
- output_shape = [s for s in shape_array(input_shape).tolist() if s != 1]
- node.out_port(0).data.set_shape(shape_array(output_shape))
-
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/unique.py b/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/unique.py
deleted file mode 100644
index ebcc1021a486cf..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/unique.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.ops.op import Op
-
-
-class UniqueInternal(Op):
- op = 'Unique'
-
- def __init__(self, graph: Graph, attrs: dict):
- mandatory_props = {
- 'type': self.op,
- 'op': self.op,
- 'version': 'opset10',
- 'infer': self.infer,
- 'in_ports_count': 2,
- 'out_ports_count': 4
- }
- super().__init__(graph, mandatory_props, attrs)
-
- def supported_attrs(self):
- return [
- 'sorted',
- 'index_element_type',
- 'count_element_type',
- ]
-
- @staticmethod
- def infer(node: Node):
- input_shape = node.in_port(0).data.get_shape()
- if node.is_out_port_connected(0):
- if node.is_in_port_connected(1):
- axis = node.in_port(1).data.get_value()
- assert axis, "Unique must have constant axis."
- out_shape = input_shape.copy()
- out_shape[axis.item()] = dynamic_dimension
- node.out_port(0).data.set_shape(out_shape)
- else:
- # no axis, means flattening
- node.out_port(0).data.set_shape(
- shape_array([dynamic_dimension]))
- if node.is_out_port_connected(1):
- node.out_port(1).data.set_shape(shape_array([dynamic_dimension]))
- if node.is_out_port_connected(2):
- node.out_port(2).data.set_shape(shape_array([dynamic_dimension]))
- if node.is_out_port_connected(3):
- node.out_port(3).data.set_shape(shape_array([dynamic_dimension]))
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/unsqueeze.py b/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/unsqueeze.py
deleted file mode 100644
index 41e1fd2f3776d0..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/internal_ops/unsqueeze.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-
-
-class UnsqueezeInternal(Unsqueeze):
- @staticmethod
- def infer(node: Node):
- axis_value = node.in_port(1).data.get_value()
- Unsqueeze.infer(node)
- # preserve initial axis value
- node.in_port(1).data.set_value(axis_value)
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/layer_to_class.py b/tools/mo/openvino/tools/mo/utils/ir_reader/layer_to_class.py
deleted file mode 100644
index cfbd1c9b4c91e2..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/layer_to_class.py
+++ /dev/null
@@ -1,438 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import os
-
-import numpy as np
-
-from openvino.tools.mo.back.MaxPool import MaxPool
-from openvino.tools.mo.back.TopKNormalizer import TopKNormalizer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.GRU import GRU
-from openvino.tools.mo.ops.ReduceOps import ReduceOp
-from openvino.tools.mo.ops.activation_ops import Activation
-from openvino.tools.mo.ops.clamp import AttributedClamp
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.deconvolution import Deconvolution
-from openvino.tools.mo.ops.dft import FFTBase
-from openvino.tools.mo.ops.elementwise import Elementwise, UnaryElementwise, LogicalElementwise, BiasAdd, Div, Mul, Pow, \
- Sub
-from openvino.tools.mo.ops.embedding_bag import EmbeddingBagBase
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.pooling import Pooling
-from openvino.tools.mo.ops.psroipooling import DeformablePSROIPoolingOp
-from openvino.tools.mo.ops.scatter import Scatter
-from openvino.tools.mo.ops.scatternd import ScatterNDBase
-from openvino.tools.mo.ops.slice import OvSlice
-from openvino.tools.mo.ops.split import Split, VariadicSplit
-from openvino.tools.mo.utils.class_registration import update_registration
-from openvino.tools.mo.utils.import_extensions import import_by_path
-from openvino.tools.mo.utils.ir_reader.extender import Extender
-from openvino.tools.mo.utils.ir_reader.internal_ops.squeeze import SqueezeInternal
-from openvino.tools.mo.utils.ir_reader.internal_ops.unsqueeze import UnsqueezeInternal
-from openvino.tools.mo.utils.ir_reader.internal_ops.unique import UniqueInternal
-from openvino.tools.mo.utils.ir_reader.internal_ops.scatter import ScatterUpdateInternal
-
-# Operations not registered in collect_ops() function
-custom_ops = {
- 'AvgPool': Pooling,
- 'BiasAdd': BiasAdd,
- 'Convert': Cast,
- 'ConvolutionBackpropData': Deconvolution,
- 'DeformablePSROIPooling': DeformablePSROIPoolingOp,
- 'Divide': Div,
- 'GroupConvolution': Convolution,
- 'GroupConvolutionBackpropData': Deconvolution,
- 'GRUSequence': GRU,
- 'Loop': Loop,
- 'MaxPool': Pooling,
- 'Multiply': Mul,
- 'Power': Pow,
- 'ScatterUpdate': ScatterUpdateInternal,
- 'Slice': OvSlice,
- 'Split': Split,
- 'Squeeze': SqueezeInternal,
- 'Subtract': Sub,
- 'VariadicSplit': VariadicSplit,
- 'Clamp': AttributedClamp,
- 'Unique': UniqueInternal,
- 'Unsqueeze': UnsqueezeInternal,
-}
-
-
-def collect_ops(path: str):
- """
- A function to registrate all MO ops
- :param path: Path to Model Optimizer folder
- :return:
- """
- import_by_path(os.path.join(path, 'mo', 'ops'), ['mo', 'ops'], 'openvino.tools.')
- update_registration(classes=[Op, Activation, Elementwise, UnaryElementwise, LogicalElementwise,
- EmbeddingBagBase, ReduceOp, Scatter, ScatterNDBase, FFTBase],
- enabled_transforms=[], disabled_transforms=[], exclude_modules=set())
-
-
-def collect_extenders(path: str):
- """
- A function to registrate all MO IR Reader extenders
- :param path: Path to Model Optimizer folder
- :return:
- """
- import_by_path(os.path.join(path, 'mo', 'utils', 'ir_reader', 'extenders'),
- ['mo', 'utils', 'ir_reader', 'extenders'], 'openvino.tools.')
- update_registration(classes=[Extender], enabled_transforms=[], disabled_transforms=[], exclude_modules=set())
-
-
-def collect_node_outputs(node: Node) -> dict:
- """
- Function to collects output connections of node.
- :param node: node to collect connections
- :return: dictionary of the form {out_port: [(input_port, destination_node_id)]}
- """
- result = dict()
- for out_port_idx, out_port in node.out_ports().items():
- dest_info = []
- for d in out_port.get_destinations():
- dest_info.append((d.idx, d.node.id))
- result[out_port_idx] = dest_info
- return result
-
-
-def restore_correct_ports(graph: Graph):
- """
- Function renumbers from OV to MO port numbering and add ports to all nodes in graph.
- :param graph:
- :return:
- """
- for node_id, attrs in graph.nodes(data=True):
- if '_in_ports' not in attrs:
- attrs['_in_ports'] = set()
- if '_out_ports' not in attrs:
- attrs['_out_ports'] = set()
-
- for u, v, k, d in graph.edges(data=True, keys=True):
- from_node_attrs = graph.node[u]
- to_node_attrs = graph.node[v]
- is_control_flow = 'control_flow_edge' in d and d['control_flow_edge'] is True
-
- if 'in' in d:
- in_port_id = d['in'] if not is_control_flow else 'control_flow_' + str(d['in'])
- to_node_attrs['_in_ports'].update({in_port_id: {'control_flow': is_control_flow}})
- if 'out' in d:
- node = Node(graph, u)
- num_of_in_nodes = len(node.in_nodes())
- decremented_number = d['out'] - num_of_in_nodes
- # Initially Const operation in IR has output port with number 1. But later the behaviour was changed
- # so the output port become 0. This change was made to be consistent with the IR serializer in the OV which
- # generates Const with output port 0. For the backward compatibility reason we need to decrement the Const
- # output port number but for current version this number shouldn't be changed during reading the IR.
- if node.type == 'Const' and d['out'] == 0:
- decremented_number = d['out']
- out_port_id = decremented_number if not is_control_flow else 'control_flow_' + str(decremented_number)
- from_node_attrs['_out_ports'].update({out_port_id: {'control_flow': is_control_flow}})
- d['out'] = decremented_number
-
-
-def propagate_const_values(op: Node):
- """
- Function propagates const value from input data node and reshape it to correct shape.
- :param op:
- :return:
- """
- assert op.soft_get('type') == 'Const', 'Wrong operation type, {} instead of Const!' \
- ''.format(op.soft_get('type'))
- assert 0 in op.in_nodes(), 'Can\'t propagate restored value to Const operation with name: {}, check input ports' \
- ''.format(op.soft_get('name'))
- assert 0 in op.out_nodes(), 'Can\'t propagate restored value to Const operation with name: {}, check output ports' \
- ''.format(op.soft_get('name'))
-
- in_data_node = op.in_node()
- out_data_node = op.out_node()
-
- value = in_data_node.value
- assert len(op.out_node(0).out_nodes()) > 0, 'Const node {} have no consumers.'.format(op.soft_get('name'))
- if op.out_node(0).out_node(0).type == 'BinaryConvolution':
- # Unpack binary weights for binary convolution (revert PackBinaryWeights transformation)
- weights_rounded = np.unpackbits(value)
- weights_rounded.dtype = np.int8
- for elem in range(len(weights_rounded)):
- if weights_rounded[elem] == 0:
- weights_rounded[elem] -= 1 # pylint: disable=unsupported-assignment-operation
- assert len(weights_rounded) % 8 == 0
- weights_rounded = weights_rounded.reshape([len(weights_rounded) // 8, 8]) # pylint: disable=no-member
- weights_rounded = np.flip(weights_rounded, axis=1)
- value = weights_rounded.flatten()
-
- op['shape'] = out_data_node.shape
- # Reshape data node value for correct shape
- if op['element_type'] in ['u4', 'i4']:
- # Packed data types are custom from numpy perspective.
- # Shape from the IR is incompatible with numpy value we store.
- op['value'] = value
- op['force_type'] = op['element_type'].upper()
- op['force_shape'] = op.shape.copy()
- else:
- op['value'] = np.reshape(value, op.shape)
-
-
-def groupconv_to_conv(op: Node):
- """
- Function makes GroupConv op back to Conv op with weights reshaping
- :param op:
- :return:
- """
- assert op.soft_get('type') == 'GroupConvolution', \
- 'Wrong operation type, {} instead of GroupConvolution!'.format(op.soft_get('type'))
-
- weights_shape = op.in_port(1).data.get_shape()
- group = weights_shape[0]
- new_shape = [weights_shape[1] * group, *weights_shape[2:]]
-
- weights_node = op.in_port(1).get_source().node
- if weights_node.type == 'Const':
- weights_node.value = np.reshape(weights_node.value, new_shape)
- elif weights_node.type == 'Reshape':
- # We remove reshape node added in ConvolutionWithGroupsResolver pass
- assert strict_compare_tensors(weights_node.in_port(0).get_source().data.get_shape(), new_shape), \
- 'Weight shape and calculated shape mismatch in GroupConv node {}.'.format(op.name)
- op.in_port(1).disconnect()
- # We use add_destination method here to support case with multiple destinations of source port
- weights_node.in_port(0).get_source().get_connection().add_destination(op.in_port(1))
- weights_node.in_port(0).disconnect()
- op.graph.remove_node(weights_node.id)
- elif weights_node.type == 'Convert' and weights_node.destination_type == 'f32'\
- and weights_node.in_port(0).get_source().node.type == 'Const':
- # Support new FP16 IRs
- const_node = weights_node.in_port(0).get_source().node
- assert const_node.has_valid('value'), \
- 'Weights of GroupConv node {} have incorrect format'.format(op.name)
- const_node.value = np.reshape(const_node.value, new_shape)
-
- else:
- assert strict_compare_tensors(op.in_port(1).get_source().data.get_shape(), op.in_port(1).get_source().data.get_shape()), \
- 'Weight shape and calculated shape mismatch in GroupConv node {}.'.format(op.name)
- # We need to set this attrs for correct shape infer as convolution
- op['group'] = group
- # The only way GroupConvolution with 'group' = 1 appears in IR is by converting from TF DepthwiseConv2dNative.
- # In this case we need to specify 'op' parameter for the
- # extensions.back.ConvolutionNormalizer.ConvolutionWithGroupsResolver to work properly.
- # Otherwise there will be 'Convolution' instead 'GroupConvolution' in restored IR, since 'GroupConvolution' is
- # extended as node with 'type' = 'Convolution' by IR reader
- if group == 1:
- op['op'] = 'DepthwiseConv2dNative'
- op.type = 'Convolution'
-
-
-def backprop_to_deconv(op: Node):
- """
- Function changes BackpropData operations type to correct creation
- :param op:
- :return:
- """
- assert op.soft_get('type') in ('ConvolutionBackpropData', 'GroupConvolutionBackpropData'), \
- 'Wrong operation type, {} instead of ConvolutionBackpropData/GroupConvolutionBackpropData!' \
- ''.format(op.soft_get('type'))
-
- if op.has_valid('output_padding'):
- # In this case we need to create Deconvolution as Convolution
- op['type_to_create'] = 'Convolution'
-
-
-def ti_add_edge_attrs(op: Node):
- """
- Function adds necessary edge attrs in TensorIterator node
- :param op:
- :return:
- """
- assert op.soft_get('type') == 'TensorIterator', 'Wrong operation type, {} instead of TensorIterator!' \
- ''.format(op.soft_get('type'))
-
- i = 0
- for num in range(len(op.in_ports())):
- op.in_port(num).external_port_id = i
- i += 1
- for num in range(len(op.out_ports())):
- op.out_port(num).external_port_id = i
- i += 1
-
-
-def copy_input_blobs(op: Node, copy_op: Node):
- """
- Function copy input blob data nodes from restored graph to copied one
- :param op: Node from restored graph
- :param copy_op: Node from copied graph
- :return:
- """
- for u, d in op.get_sorted_inputs():
- if 'bin' in d:
- Op.create_and_connect_input_data_node(copy_op.graph, copy_op,
- {'value': op.in_node(d['in']).value,
- 'shape': op.in_node(d['in']).shape}, d)
-
-
-# Map with preprocessing functions
-preprocessing_op_nodes = {
- 'Const': propagate_const_values,
- 'GroupConvolution': groupconv_to_conv,
- 'ConvolutionBackpropData': backprop_to_deconv,
- 'GroupConvolutionBackpropData': backprop_to_deconv,
-}
-
-# Map with postprocessing functions for nodes
-postprocessing_op_nodes = {
- 'TensorIterator': ti_add_edge_attrs,
- 'TopK': TopKNormalizer.normalize_outputs,
- 'MaxPool': MaxPool.normalize_outputs,
-}
-
-
-def restore_tensor_names(op: Node):
- for out_port in op.ports:
- # op.ports is our internal attribute, dictionary, where keys are numbers of output ports
- # and values are tuples with shape and tensor name:
- # {out_port_idx_1: (out_port_idx_1_shape, out_port_idx_1_tensor_name, out_port_idx_1_rt_info),
- # out_port_idx_2: (out_port_idx_2_shape, out_port_idx_2_tensor_name, out_port_idx_2_rt_info)}
- out_tensor_names = op.ports[out_port][1]
-
- # handle Constant operations with old style output port numbering
- if op.soft_get('type') == 'Const':
- assert len(op.ports) == 1, 'Something wrong with Constant node: {}, wrong number ' \
- 'of output ports: {}!'.format(op.soft_get('name'), len(op.ports))
- out_port = 0
-
- out_port = out_port - len(op.in_nodes())
-
- if out_tensor_names is not None:
- # handle tensor names with commas and add them to dictionary as separate items
- if out_tensor_names.find(',') >= 0:
- str_to_replace = ''
- out_tensor_names = (out_tensor_names.replace('\\,', str_to_replace)).split(',')
- op.out_node(out_port)['fw_tensor_debug_info'] = []
- for out_tensor_name in out_tensor_names:
- out_tensor_name = out_tensor_name.replace(str_to_replace, ',')
- op.out_node(out_port)['fw_tensor_debug_info'].append((out_tensor_name, out_tensor_name))
- else:
- op.out_node(out_port)['fw_tensor_debug_info'] = [(out_tensor_names, out_tensor_names)]
-
-
-def copy_graph_with_ops(graph: Graph) -> Graph:
- """
- Function to copy graph and apply extenders to appropriate nodes
- :param graph: Graph to copy
- :return:Copied graph with applied extenders
- """
- new_graph = Graph()
- new_graph.stage = 'back'
- new_graph.graph = graph.graph
- new_graph.inputs_order = graph.inputs_order
- new_graph.outputs_order = graph.outputs_order
-
- node_connections = dict()
- mapping_of_old_idx_into_new = dict()
-
- restore_correct_ports(graph)
-
- # Nodes preprocessing stage in source graph
- # Firstly propagate values only for Const nodes, because other preprocessings
- # assumes Const nodes are already preprocessed.
- for op in graph.get_op_nodes(type='Const'):
- preprocessing_op_nodes[op.type](op)
-
- for op in graph.get_op_nodes():
- if op.soft_get('type') != 'Const' and op.soft_get('type') in preprocessing_op_nodes:
- preprocessing_op_nodes[op.type](op)
-
- # Create a new copy of graph with correct attributes (shape & type infer, backend attrs etc.)
- for op in graph.get_op_nodes():
-
- # Save input shapes restored from IR
- op['old_input_shapes'] = list()
- for n in op.in_nodes():
- op.old_input_shapes.append(int64_array(op.in_node(n).shape))
-
- # Apply extenders to nodes in source graph
- if op.type in Extender.registered_ops:
- Extender.get_extender_class_by_name(op.type).extend(op)
- else:
- log.debug('Extender for node {} with type={} not found, please note.'.format(op.name, op.type))
-
- # Add node with necessary type and extended attrs in new graph
- op_type = op.soft_get('type_to_create', op.type)
-
- if op_type in custom_ops:
- node = custom_ops[op_type](new_graph, op.attrs()).create_node()
- else:
- if op_type not in Op.registered_ops:
- log.warning('Operation {} is not found in MO operations, please check it! '
- 'Simple shape infer function is used'.format(op_type))
- node = Op(new_graph, op.attrs()).create_node()
- assert 'type' in node, 'Operation {} have no `type` attribute.'.format(node.soft_get('name'))
- node['op'] = node.type
- node['infer'] = Extender.use_shapes_from_ir
- if 'ir_data_attrs' in op:
- node['IE'] = [('layer',
- [('id', lambda node: node.node), 'name', 'type', 'version'],
- [('data',
- list(op.ir_data_attrs.keys()),
- []),
- '@ports',
- '@consts'])]
-
- else:
- node = Op.get_op_class_by_name(op_type)(new_graph, op.attrs()).create_node()
-
- # Fill out_ports_count attribute
- if 'out_ports_count' not in node and node.soft_get('type') != 'Result':
- node['out_ports_count'] = len(op.out_edges())
-
- # This attribute is no longer needed and we can delete it
- if 'ir_data_attrs' in node:
- del node['ir_data_attrs']
-
- if op.has_and_set('need_copy_input_blobs'):
- copy_input_blobs(op, node)
-
- # Collect node connections
- mapping_of_old_idx_into_new[op.id] = node.id
- node_connections[op.id] = collect_node_outputs(op)
-
- # Restore connections in new graph
- for input_node_idx, its_outputs in list(node_connections.items()):
- for out_port_idx, out_port_dest in its_outputs.items():
- for dest_in_port_idx, dest_node_idx in out_port_dest:
- src = Node(new_graph, mapping_of_old_idx_into_new[input_node_idx])
- dst = Node(new_graph, mapping_of_old_idx_into_new[dest_node_idx])
- src.out_port(out_port_idx).connect(dst.in_port(dest_in_port_idx))
-
- # Nodes postprocessing stage in new graph
- for op in new_graph.get_op_nodes():
- # Call normalize node outputs for restored operations to connect temporary Result operations for disconnected
- # output ports. We need to do that for correct shape inference. These Result operations will be removed during
- # IR emitting. For TopK operation outputs normalizing we should use specific
- # function TopKNormalizer.normalize_outputs.
- if op.soft_get('type') != 'TopK':
- Op.normalize_outputs(op)
-
- # Set correct_data_type attribute to Const data nodes to correct processing of restored values
- if op.soft_get('type') == 'Const':
- assert len(op.out_nodes()) == 1 and op.out_node(0).soft_get('kind') == 'data',\
- 'Const node {} not properly corrected to appropriate data node'.format(op.soft_get('name'))
- op.out_node(0)['correct_data_type'] = True
-
- if op.has_and_set('rt_info'):
- op.out_node(0)['rt_info'] = op.rt_info
-
- # operations postprocessing with some special types
- if op.soft_get('type') in postprocessing_op_nodes:
- postprocessing_op_nodes[op.type](op)
-
- restore_tensor_names(op)
-
- # clean up graph to shape inference
- new_graph.clean_up()
-
- return new_graph
diff --git a/tools/mo/openvino/tools/mo/utils/ir_reader/restore_graph.py b/tools/mo/openvino/tools/mo/utils/ir_reader/restore_graph.py
deleted file mode 100644
index 5752a94d3126b4..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/ir_reader/restore_graph.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-from copy import copy
-
-from openvino.tools.mo.back.ConvolutionNormalizer import ConvolutionNormalizer, ConvolutionWithGroupsResolver
-from openvino.tools.mo.back.ShapeOfConstFolding import ShapeOfConstFolding
-from openvino.tools.mo.back.MarkNodesWithShapeValues import MarkNodesWithShapeValues
-from openvino.tools.mo.back.PackBinaryWeights import PackBinaryWeights
-from openvino.tools.mo.back.SpecialNodesFinalization import RemoveConstOps, CreateConstNodesReplacement
-from openvino.tools.mo.back.StridedSliceMasksNormalizer import StridedSliceMasksNormalizer
-from openvino.tools.mo.back.blob_normalizer import BlobNormalizer
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.passes.convert_data_type import data_type_str_to_precision
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.pipeline.common import prepare_emit_ir
-from openvino.tools.mo.utils.class_registration import apply_replacements_list
-from openvino.tools.mo.utils.ir_engine.ir_engine import IREngine
-from openvino.tools.mo.utils.ir_reader.layer_to_class import copy_graph_with_ops, collect_extenders, collect_ops
-from openvino.tools.mo.utils.utils import get_mo_root_dir
-
-
-def restore_graph_from_ir(path_to_xml: str, path_to_bin: str = None) -> (Graph, dict):
- """
- Function to make valid graph and metadata for MO back stage from IR.
- :param path_to_xml:
- :param path_to_bin:
- :return: (restored graph, meta data)
- """
- ir = IREngine(path_to_xml, path_to_bin)
- assert ir.graph.graph.get('ir_version') >= 10, 'IR version {} is not supported, ' \
- 'please generate actual IR for your model and use it.'.format(ir.graph.graph.get('ir_version'))
-
- path = get_mo_root_dir()
- collect_ops(path)
- collect_extenders(path)
-
- # Create a new copy of graph with correct attributes (shape & type infer, backend attrs etc.)
- new_graph = copy_graph_with_ops(ir.graph)
-
- return new_graph, copy(ir.meta_data)
-
-
-def save_restored_graph(graph: Graph, path: str, meta_data, name=None, rename_results=True):
- """
- Function to apply all necessary transforms from back stage to prepare and save restored graph and metadata.
- :param graph: Graph to save
- :param path: Path to saved IR
- :param meta_data: Namespace with converting parameters restored from IR
- :param name: Name for saved IR
- :return:
- """
-
- if name is None:
- name = graph.name
-
- if 'data_type' not in meta_data:
- log.debug('Provided `meta_data` does not contain `data_type` parameter. Set `data_type`'
- ' parameter value to `FP32`.')
- # Set data_type to FP32. All restored constants will be saved in provided data type.
- data_type = 'FP32'
-
- # We need to specify this attribute to pass graph transformations. This information will not be saved into IR.
- # All constants and placeholders will be saved with same types as restored from IR
- graph.graph['cmd_params'].data_type = data_type
- else:
- data_type = data_type_str_to_precision(graph.graph['cmd_params'].data_type)
-
- assert data_type in ['FP16', 'FP32'], '`data_type` value {} is not supported by MO,' \
- ' cannot save graph'.format(data_type)
-
- # List items order matters, do not change it.
- transformation_list = [
- ConvolutionWithGroupsResolver,
- ShapeOfConstFolding,
- StridedSliceMasksNormalizer,
- PackBinaryWeights,
- BlobNormalizer,
- ConvolutionNormalizer,
- MarkNodesWithShapeValues,
- ]
-
- # We need to run some specific passes from MO back stage.
- apply_replacements_list(graph, transformation_list)
-
- # Transformations with enabled=False should be run manually.
- 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)
-
- prepare_emit_ir(graph, data_type, path, name, meta_info=meta_data, rename_results=rename_results)
diff --git a/tools/mo/openvino/tools/mo/utils/json_schema.py b/tools/mo/openvino/tools/mo/utils/json_schema.py
deleted file mode 100644
index bf3cc5e22c32d2..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/json_schema.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-schema_dict = {
- "definitions": {},
- "$schema": "http://json-schema.org/draft-07/schema#",
- "title": "Root",
- "type": "array",
- "default": [],
- "items": {
- "$id": "#root/items",
- "title": "Items",
- "type": "object",
- "required": [
- "id",
- "match_kind"
- ],
- "properties": {
- "custom_attributes": {
- "$id": "#root/items/custom_attributes",
- "title": "Custom_attributes",
- "type": "object",
- "properties": {
- }
- },
- "id": {
- "$id": "#root/items/id",
- "title": "Id",
- "type": "string",
- "pattern": "^.*$",
- "minLength": 1
- },
- "inputs": {
- "$id": "#root/items/inputs",
- "title": "Inputs",
- "type": "array",
- "default": [],
- "items": {
- "$id": "#root/items/inputs/items",
- "title": "Items",
- "type": "array",
- "default": [],
- "items": {
- "$id": "#root/items/inputs/items/items",
- "title": "Items",
- "type": "object",
- "properties": {
- "node": {
- "$id": "#root/items/inputs/items/items/node",
- "title": "Node",
- "type": "string",
- "default": "",
- "pattern": "^.*$"
- },
- "port": {
- "$id": "#root/items/inputs/items/items/port",
- "title": "Port",
- "type": "integer",
- "default": 0
- }
- },
- "required": ["node", "port"]
- }
-
- }
- },
- "instances": {
- "$id": "#root/items/instances",
- "title": "Instances",
- "type": ["array", "object"],
- "items": {
- "$id": "#root/items/instances/items",
- "title": "Items",
- "type": "string",
- "default": "",
- "pattern": "^.*$"
- }
- },
- "match_kind": {
- "$id": "#root/items/match_kind",
- "title": "Match_kind",
- "type": "string",
- "enum": ["points", "scope", "general"],
- "default": "points",
- "pattern": "^.*$"
- },
- "outputs": {
- "$id": "#root/items/outputs",
- "title": "Outputs",
- "type": "array",
- "default": [],
- "items": {
- "$id": "#root/items/outputs/items",
- "title": "Items",
- "type": "object",
- "properties": {
- "node": {
- "$id": "#root/items/outputs/items/node",
- "title": "Node",
- "type": "string",
- "default": "",
- "pattern": "^.*$"
- },
- "port": {
- "$id": "#root/items/outputs/items/port",
- "title": "Port",
- "type": "integer",
- "default": 0
- }
- },
- "required": ["node", "port"]
- }
-
- },
- "include_inputs_to_sub_graph": {
- "$id": "#root/items/include_inputs_to_sub_graph",
- "title": "Include_inputs_to_sub_graph",
- "type": "boolean",
- "default": False
- },
- "include_outputs_to_sub_graph": {
- "$id": "#root/items/include_outputs_to_sub_graph",
- "title": "Include_outputs_to_sub_graph",
- "type": "boolean",
- "default": False
- }
- }
- }
-}
diff --git a/tools/mo/openvino/tools/mo/utils/logger.py b/tools/mo/openvino/tools/mo/utils/logger.py
deleted file mode 100644
index c04a71dcf9ce62..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/logger.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import importlib.util
-import logging as log
-import os
-import re
-import sys
-from argparse import Namespace
-from copy import copy
-
-# WA for abseil bug that affects logging while importing TF starting 1.14 version
-# Link to original issue: https://github.com/abseil/abseil-py/issues/99
-if importlib.util.find_spec('absl') is not None:
- import absl.logging
-
- log.root.removeHandler(absl.logging._absl_handler) # pylint: disable=c-extension-no-member
-
-handler_num = 0
-
-
-class LvlFormatter(log.Formatter):
- format_dict = {
- log.DEBUG: "[ %(asctime)s ] [ %(levelname)s ] [ %(module)s:%(lineno)d ] %(msg)s",
- log.INFO: "[ %(levelname)s ] %(msg)s",
- log.WARNING: "[ WARNING ] %(msg)s",
- log.ERROR: "[ %(levelname)s ] %(msg)s",
- log.CRITICAL: "[ %(levelname)s ] %(msg)s",
- 'framework_error': "[ FRAMEWORK ERROR ] %(msg)s",
- 'analysis_info': "[ ANALYSIS INFO ] %(msg)s"
- }
-
- def __init__(self, lvl, fmt=None):
- log.Formatter.__init__(self, fmt)
- self.lvl = lvl
-
- def format(self, record: log.LogRecord):
- if self.lvl == 'DEBUG':
- self._style._fmt = self.format_dict[log.DEBUG]
- else:
- self._style._fmt = self.format_dict[record.levelno]
- if 'is_warning' in record.__dict__.keys():
- self._style._fmt = self.format_dict[log.WARNING]
- if 'framework_error' in record.__dict__.keys():
- self._style._fmt = self.format_dict['framework_error']
- if 'analysis_info' in record.__dict__.keys():
- self._style._fmt = self.format_dict['analysis_info']
- return log.Formatter.format(self, record)
-
-
-class TagFilter(log.Filter):
- def __init__(self, regex: str):
- self.regex = regex
-
- def filter(self, record: log.LogRecord):
- if record.__dict__['funcName'] == 'load_grammar': # for nx not to log into our logs
- return False
- if self.regex:
- if 'tag' in record.__dict__.keys():
- tag = record.__dict__['tag']
- return re.findall(self.regex, tag)
- else:
- return False
- return True # if regex wasn't set print all logs
-
-
-def init_logger(lvl: str, silent: bool):
- global handler_num
- log_exp = os.environ.get('MO_LOG_PATTERN')
- if silent:
- lvl = 'ERROR'
- fmt = LvlFormatter(lvl=lvl)
- handler = log.StreamHandler()
- handler.setFormatter(fmt)
- logger = log.getLogger()
- logger.setLevel(lvl)
- logger.addFilter(TagFilter(regex=log_exp))
- if handler_num == 0 and len(logger.handlers) == 0:
- logger.addHandler(handler)
- handler_num += 1
-
-def get_logger_state():
- logger = log.getLogger()
- return logger.level, copy(logger.filters), copy(logger.handlers)
-
-def restore_logger_state(state: tuple):
- level, filters, handlers = state
- logger = log.getLogger()
- logger.setLevel(level)
- logger.filters = filters
- logger.handlers = handlers
-
-
-def progress_bar(function: callable):
- """
- Decorator for model conversion pipeline progress display
- Works in combination with function: mo.utils.class_registration.apply_transform
- """
-
- def wrapper(*args, **kwargs):
- for arg in ['graph', 'curr_transform_num', 'num_transforms']:
- msg = 'Progress bar decorator is enabled for Model Conversion API transformation applying cycle only. ' \
- 'Argument `{}` {}'
-
- assert arg in kwargs, msg.format(arg, 'is missing')
- assert kwargs[arg] is not None, msg.format(arg, 'should not be None')
-
- if 'progress' in kwargs['graph'].graph['cmd_params'] and kwargs['graph'].graph['cmd_params'].progress:
- bar_len = 20
- total_replacers_count = kwargs['num_transforms']
-
- def progress(i):
- return int((i + 1) / total_replacers_count * bar_len)
-
- def percent(i):
- return (i + 1) / total_replacers_count * 100
-
- end = '' if not kwargs['graph'].graph['cmd_params'].stream_output else '\n'
- curr_i = kwargs['curr_transform_num']
- print('\rProgress: [{:{}}]{:>7.2f}% done'.format('.' * progress(curr_i), bar_len, percent(curr_i)), end=end)
-
- sys.stdout.flush()
-
- function(*args, **kwargs)
-
- return wrapper
-
-def progress_printer(argv: Namespace):
- """
- A higher-order factory function returning a configurable callback displaying a progress bar
- Depending on the configuration stored in 'argv' the progress bar can be one-line, multi-line, or silent.
- """
- def _progress_bar(progress, total, completed, endline):
- bar_len = 20
-
- def dots():
- return '.' * int(progress * bar_len)
-
- print('\rProgress: [{:{}}]{:>7.2f}% done'.format(dots(), bar_len, progress*100), end=endline)
- sys.stdout.flush()
-
- def no_progress_bar(progress, total, completed):
- """ A 'dummy' progressbar which doesn't print anything """
- pass
-
- def oneline_progress_bar(progress, total, completed):
- """ A callback that always prints the progress in the same line (mimics real GUI progress bar)"""
- _progress_bar(progress, total, completed, '')
-
- def newline_progress_bar(progress, total, completed):
- """ A callback that prints an updated progress bar in separate lines """
- _progress_bar(progress, total, completed, '\n')
-
- if "progress" in argv and argv.progress:
- if "stream_output" in argv and argv.stream_output:
- return newline_progress_bar
- else:
- return oneline_progress_bar
- else:
- return no_progress_bar
diff --git a/tools/mo/openvino/tools/mo/utils/model_analysis.py b/tools/mo/openvino/tools/mo/utils/model_analysis.py
deleted file mode 100644
index d76baf02d29ba1..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/model_analysis.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import sys
-
-from openvino.tools.mo.front.user_data_repack import UserDataRepack
-from openvino.tools.mo.load.loader import LoadFinish
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils import class_registration
-from openvino.tools.mo.utils.error import Error
-
-
-class AnalysisResults:
- _instance = None
-
- def __new__(cls, *args, **kwargs):
- if not cls._instance:
- cls._instance = super(AnalysisResults, cls).__new__(cls, *args, **kwargs)
- cls.results = {}
- cls.messages = []
- return cls._instance
-
- def __getattr__(self, item):
- return self.results[item]
-
- def __setattr__(self, key, value):
- self.results[key] = value
-
- @classmethod
- def get_result(cls, key=None):
- if key is not None:
- if key in cls.results and cls.results[key] is not None:
- return cls.results[key]
- else:
- return cls.results
-
- @classmethod
- def add_result(cls, result, key=None):
- if key is not None:
- cls.results[key] = result
- else:
- cls.results.update(result)
-
- @classmethod
- def get_messages(cls):
- return cls.messages
-
- @classmethod
- def add_message(cls, message):
- cls.messages.append(message)
-
-
-class AnalyzeAction(object):
- registered_cls = []
- registered_ops = {}
- excluded_replacers = []
- run_not_recursively = True
-
- def find_and_replace_pattern(self, graph: Graph):
- analysis_results = AnalysisResults()
- failed_analysers = []
-
- try:
- result, msg = self.analyze(graph) # pylint: disable=assignment-from-no-return
- except SystemExit:
- # the analysis transformation printing analysis results to the screen calls sys.exit(0) which in fact raises
- # SystemExit exception, so we handle it here
- sys.exit(0)
- except:
- failed_analysers.append(str(self.__class__))
- analysis_results.add_result(failed_analysers, 'failed_analysers')
- result = None
- msg = None
-
- if result is not None:
- analysis_results.add_result(result)
- if msg is not None:
- analysis_results.add_message(msg)
-
- def analyze(self, graph: Graph):
- raise Error('The method must be implemented in the sub-class')
-
- def run_before(self):
- """
- Returns list of replacer classes which this replacer must be run before.
- :return: list of classes
- """
- return [AnalysisCollectorAnchor, UserDataRepack]
-
- def run_after(self):
- """
- Returns list of replacer classes which this replacer must be run after.
- :return: list of classes
- """
- return [LoadFinish]
-
- @classmethod
- def class_type(cls):
- return class_registration.ClassType.FRONT_REPLACER
-
-
-class AnalysisCollectorAnchor(AnalyzeAction):
- """
- All analyzers should depend on this one which is an anchor analyzer to develop custom post-processor of all
- analyzers results.
- """
-
- def run_before(self):
- return []
-
- def analyze(self, graph: Graph):
- pass
-
-
-def graph_contains_scope(graph: Graph, scope: [str, tuple]):
- """
- Checks whether the graph contains node(s) which name includes "scope" string.
- :param graph: graph to check
- :param scope: string or tuple with strings defining the scope
- :return: the result of the check (True/False)
- """
- if type(scope) is str:
- return any([node.soft_get('name').find(scope) != -1 for node in graph.get_op_nodes()])
- else:
- return any([graph_contains_scope(graph, s) for s in scope])
diff --git a/tools/mo/openvino/tools/mo/utils/pipeline_config.py b/tools/mo/openvino/tools/mo/utils/pipeline_config.py
deleted file mode 100644
index 7ec54312c0b55e..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/pipeline_config.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import re
-
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.simple_proto_parser import SimpleProtoParser
-
-# The list of rules how to map the value from the pipeline.config file to the dictionary with attributes.
-# The rule is either a string or a tuple with two elements. In the first case the rule string is used as a key to
-# search in the parsed pipeline.config file attributes dictionary and a key to save found value. In the second case the
-# first element of the tuple is the key to save found value; the second element of the tuple is a string defining the
-# path to the value of the attribute in the pipeline.config file. The path consists of the regular expression strings
-# defining the dictionary key to look for separated with a '/' character.
-mapping_rules = [
- 'num_classes',
- # preprocessing block attributes
- ('resizer_image_height', 'image_resizer/fixed_shape_resizer/height'),
- ('resizer_image_width', 'image_resizer/fixed_shape_resizer/width'),
- ('resizer_min_dimension', 'image_resizer/keep_aspect_ratio_resizer/min_dimension'),
- ('resizer_max_dimension', 'image_resizer/keep_aspect_ratio_resizer/max_dimension'),
- ('pad_to_max_dimension', 'image_resizer/keep_aspect_ratio_resizer/pad_to_max_dimension', False),
- # anchor generator attributes
- ('anchor_generator_height', 'first_stage_anchor_generator/grid_anchor_generator/height$', 256),
- ('anchor_generator_width', 'first_stage_anchor_generator/grid_anchor_generator/width$', 256),
- ('anchor_generator_height_stride', 'first_stage_anchor_generator/grid_anchor_generator/height_stride', 16),
- ('anchor_generator_width_stride', 'first_stage_anchor_generator/grid_anchor_generator/width_stride', 16),
- ('anchor_generator_scales', 'first_stage_anchor_generator/grid_anchor_generator/scales'),
- ('anchor_generator_aspect_ratios', 'first_stage_anchor_generator/grid_anchor_generator/aspect_ratios'),
- ('multiscale_anchor_generator_min_level', 'anchor_generator/multiscale_anchor_generator/min_level'),
- ('multiscale_anchor_generator_max_level', 'anchor_generator/multiscale_anchor_generator/max_level'),
- ('multiscale_anchor_generator_anchor_scale', 'anchor_generator/multiscale_anchor_generator/anchor_scale'),
- ('multiscale_anchor_generator_aspect_ratios', 'anchor_generator/multiscale_anchor_generator/aspect_ratios'),
- ('multiscale_anchor_generator_scales_per_octave', 'anchor_generator/multiscale_anchor_generator/scales_per_octave'),
- # SSD anchor generator attributes
- ('ssd_anchor_generator_min_scale', 'anchor_generator/ssd_anchor_generator/min_scale', 0.2),
- ('ssd_anchor_generator_max_scale', 'anchor_generator/ssd_anchor_generator/max_scale', 0.95),
- ('ssd_anchor_generator_num_layers', 'anchor_generator/ssd_anchor_generator/num_layers'),
- ('ssd_anchor_generator_aspect_ratios', 'anchor_generator/ssd_anchor_generator/aspect_ratios'),
- ('ssd_anchor_generator_scales', 'anchor_generator/ssd_anchor_generator/scales'),
- ('ssd_anchor_generator_interpolated_scale_aspect_ratio',
- 'anchor_generator/ssd_anchor_generator/interpolated_scale_aspect_ratio', 1.0),
- ('ssd_anchor_generator_reduce_lowest', 'anchor_generator/ssd_anchor_generator/reduce_boxes_in_lowest_layer'),
- ('ssd_anchor_generator_base_anchor_height', 'anchor_generator/ssd_anchor_generator/base_anchor_height', 1.0),
- ('ssd_anchor_generator_base_anchor_width', 'anchor_generator/ssd_anchor_generator/base_anchor_width', 1.0),
- # Proposal and ROI Pooling layers attributes
- ('first_stage_nms_score_threshold', '.*_nms_score_threshold'),
- ('first_stage_nms_iou_threshold', '.*_nms_iou_threshold'),
- ('first_stage_max_proposals', '.*_max_proposals'),
- ('num_spatial_bins_height', '.*/rfcn_box_predictor/num_spatial_bins_height'),
- ('num_spatial_bins_width', '.*/rfcn_box_predictor/num_spatial_bins_width'),
- ('crop_height', '.*/rfcn_box_predictor/crop_height'),
- ('crop_width', '.*/rfcn_box_predictor/crop_width'),
- 'initial_crop_size',
- ('use_matmul_crop_and_resize', 'use_matmul_crop_and_resize', False),
- ('add_background_class', 'add_background_class', True),
- # Detection Output layer attributes
- ('postprocessing_score_converter', '.*/score_converter'),
- ('postprocessing_score_threshold', '.*/batch_non_max_suppression/score_threshold'),
- ('postprocessing_iou_threshold', '.*/batch_non_max_suppression/iou_threshold'),
- ('postprocessing_max_detections_per_class', '.*/batch_non_max_suppression/max_detections_per_class'),
- ('postprocessing_max_total_detections', '.*/batch_non_max_suppression/max_total_detections'),
- ('share_box_across_classes', 'second_stage_box_predictor/.*/share_box_across_classes$', False),
- # Variances for predicted bounding box deltas (tx, ty, tw, th)
- ('frcnn_variance_x', 'box_coder/faster_rcnn_box_coder/x_scale', 10.0),
- ('frcnn_variance_y', 'box_coder/faster_rcnn_box_coder/y_scale', 10.0),
- ('frcnn_variance_width', 'box_coder/faster_rcnn_box_coder/width_scale', 5.0),
- ('frcnn_variance_height', 'box_coder/faster_rcnn_box_coder/height_scale', 5.0)
-]
-
-
-class PipelineConfig:
- """
- The class that parses pipeline.config files used to generate TF models generated using Object Detection API.
- The class stores data read from the file in a plain dictionary for easier access using the get_param function.
- """
-
- def __init__(self, file_name: str):
- self._raw_data_dict = dict()
- self._model_params = dict()
- self._raw_data_dict = SimpleProtoParser().parse_file(file_name)
- if not self._raw_data_dict:
- raise Error('Failed to parse pipeline.config file {}'.format(file_name))
-
- self._initialize_model_params()
-
- @staticmethod
- def _get_value_by_path(params: dict, path: list):
- if not path or len(path) == 0:
- return None
- if not isinstance(params, dict):
- return None
- compiled_regexp = re.compile(path[0])
- for key in params.keys():
- if re.match(compiled_regexp, key):
- if len(path) == 1:
- return params[key]
- else:
- value = __class__._get_value_by_path(params[key], path[1:])
- if value is not None:
- return value
- return None
-
- def _update_param_using_rule(self, params: dict, rule: [str, tuple]):
- if isinstance(rule, str):
- if rule in params:
- self._model_params[rule] = params[rule]
- log.debug('Found value "{}" for path "{}"'.format(params[rule], rule))
- elif isinstance(rule, tuple):
- if len(rule) != 2 and len(rule) != 3:
- raise Error('Invalid rule length. Rule must be a tuple with two elements: key and path, or three '
- 'elements: key, path, default_value.')
- value = __class__._get_value_by_path(params, rule[1].split('/'))
- if value is not None:
- log.debug('Found value "{}" for path "{}"'.format(value, rule[1]))
- self._model_params[rule[0]] = value
- elif len(rule) == 3:
- self._model_params[rule[0]] = rule[2]
- log.debug('There is no value path "{}". Set default value "{}"'.format(value, rule[2]))
-
- else:
- raise Error('Invalid rule type. Rule can be either string or tuple')
-
- def _initialize_model_params(self):
- """
- Store global params in the dedicated dictionary self._model_params for easier use.
- :return: None
- """
-
- if 'model' not in self._raw_data_dict:
- raise Error('The "model" key is not found in the configuration file. Looks like the parsed file is not '
- 'Object Detection API model configuration file.')
- params = list(self._raw_data_dict['model'].values())[0]
- for rule in mapping_rules:
- self._update_param_using_rule(params, rule)
-
- def get_param(self, param: str):
- if param not in self._model_params:
- return None
- return self._model_params[param]
diff --git a/tools/mo/openvino/tools/mo/utils/replacement_pattern.py b/tools/mo/openvino/tools/mo/utils/replacement_pattern.py
deleted file mode 100644
index e9750e32d08f18..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/replacement_pattern.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.pattern_match import apply_pattern
-
-
-class ReplacementPattern(object):
- # List of classes that shouldn't be treated as standalone replacers
- # All intermediate infrastructure classes should be here
- excluded_replacers = []
-
- def find_and_replace_pattern(self, graph: Graph):
- apply_pattern(graph, **self.pattern(), action=self.replace_pattern) # pylint: disable=no-member
-
- def run_before(self):
- """
- Returns list of replacer classes which this replacer must be run before.
- :return: list of classes
- """
- return []
-
- def run_after(self):
- """
- Returns list of replacer classes which this replacer must be run after.
- :return: list of classes
- """
- return []
diff --git a/tools/mo/openvino/tools/mo/utils/runtime_info.py b/tools/mo/openvino/tools/mo/utils/runtime_info.py
deleted file mode 100644
index fdf2c4c48ef929..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/runtime_info.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import abc
-from collections import defaultdict
-from typing import Dict
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.passes.convert_data_type import np_data_type_to_destination_type
-
-
-class RTInfo:
- """
- Class that stores runtime information.
- """
-
- def __init__(self):
- """
- Dictionary with runtime information.
- Key is a tuple that contains name of runtime info attribute and version of the attribute.
- Value is an instance of a class derived from RTInfoElement that represents a particular runtime info attribute.
-
- Example of usage:
- rt_info = RTInfo()
- rt_info.info[('old_api_map_order', 0)] = OldAPIMapOrder()
-
- """
- self.info = defaultdict(dict)
-
- def contains(self, attribute_name: str):
- attr_count = [key[0] for key in list(self.info.keys())].count(attribute_name)
- assert attr_count <= 1, 'Incorrect rt_info attribute, got more than one {}.'.format(attribute_name)
- return attr_count > 0
-
- def get_attribute_version(self, attribute_name: str):
- for name, version in list(self.info.keys()):
- if name == attribute_name:
- return version
- raise Exception("rt_info does not contain attribute with name {}".format(attribute_name))
-
-
-class RTInfoElement:
- """
- Class that stores element of runtime information.
- """
-
- @abc.abstractmethod
- def serialize(self, node) -> Dict:
- """
- Serialize method for RTInfoElement.
- """
-
- @abc.abstractmethod
- def get_version(self):
- """
- Get version of RTInfoElement.
- """
-
- @abc.abstractmethod
- def get_name(self):
- """
- Get name of RTInfoElement.
- """
-
-
-class OldAPIMapOrder(RTInfoElement):
- """
- Class that stores transpose order required for obtaining IR in old API.
- """
-
- def __init__(self, version=0):
- self.info = defaultdict(dict)
- self.version = version
- self.name = "old_api_map_order"
-
- def old_api_transpose_parameter(self, inv: int64_array):
- self.info['inverse_order'] = inv
-
- def old_api_transpose_result(self, order: int64_array):
- self.info['order'] = order
-
- def serialize_old_api_map_for_parameter(self, node) -> Dict:
- if 'inverse_order' not in self.info:
- return {}
- return {'value': ','.join(map(str, self.info['inverse_order']))}
-
- def serialize_old_api_map_for_result(self, node) -> Dict:
- if 'order' not in self.info:
- return {}
- return {'value': ','.join(map(str, self.info['order']))}
-
- def serialize(self, node) -> Dict:
- result = {}
- if node.soft_get('type') == 'Parameter':
- result = self.serialize_old_api_map_for_parameter(node)
- elif node.soft_get('type') == 'Result':
- result = self.serialize_old_api_map_for_result(node)
- return result
-
- def get_version(self):
- return self.version
-
- def get_name(self):
- return self.name
-
-
-class OldAPIMapElementType(RTInfoElement):
- """
- Class that stores legacy type required for obtaining IR in old API.
- """
- def __init__(self, version=0):
- self.info = defaultdict(dict)
- self.version = version
- self.name = "old_api_map_element_type"
-
- def set_legacy_type(self, legacy_type: np.dtype):
- self.info['legacy_type'] = legacy_type
-
- def serialize(self, node) -> Dict:
- if 'legacy_type' not in self.info:
- return {}
- return {'value': np_data_type_to_destination_type(self.info['legacy_type'])}
-
- def get_version(self):
- return self.version
-
- def get_name(self):
- return self.name
diff --git a/tools/mo/openvino/tools/mo/utils/shape.py b/tools/mo/openvino/tools/mo/utils/shape.py
deleted file mode 100644
index 7240795b023e6f..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/shape.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.ops.elementwise import Add
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.graph_utils import create_op_node_with_second_input
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.graph.port import Port
-from openvino.tools.mo.ops.concat import Concat
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.ops.squeeze import Squeeze
-
-
-def get_canonical_axis_index_node(rank: Node, axis: int) -> Node:
- """
- Returns positive axis value
-
- :param rank: the node of 0D output shape to get rank of tensor from
- :param axis: integer value from [-rank; rank - 1]
- :return: node producing positive integer value of axis
- """
- graph = rank.graph
- name = rank.soft_get('name', rank.id)
- if axis < 0:
- axis = Const(graph, {'name': name + '/negative_axis', 'value': int64_array(axis)}).create_node()
- add = Add(graph, {'name': name + '/positive_axis'}).create_node()
- rank.out_port(0).connect(add.in_port(0))
- axis.out_port(0).connect(add.in_port(1))
- return add
- else:
- return Const(graph, {'name': name + '/positive_axis', 'value': int64_array(axis)}).create_node()
-
-
-def get_range_node_of_idxs(rank: Node, begin: int, end: int,
- include_begin: bool = True, include_end: bool = False) -> Node:
- """
- Returns node that produces 1D output of values of range from begin to end (ex)/(in)cluding begin or end point
-
- :param rank: the node of 0D output shape to get rank of tensor from
- :param begin: integer value from [-rank; rank - 1]
- :param end: integer value from [-rank; +rank]
- :param include_begin: boolean flag to include or exclude start point from range output
- :param include_end: boolean flag to include or exclude end point from range output
- :return: range node producing 1D output
- """
- graph = rank.graph
- name = rank.soft_get('name', rank.id)
-
- start_idx = get_canonical_axis_index_node(rank, begin)
- end_idx = get_canonical_axis_index_node(rank, end)
-
- if not include_begin:
- const = Const(graph, {'value': int64_array(1), 'name': name + '/exclude_begin/value'}).create_node()
- add = Add(graph, {'name': name + '/exclude_begin'}).create_node()
- start_idx.out_port(0).connect(add.in_port(0))
- const.out_port(0).connect(add.in_port(1))
- start_idx = add
-
- if include_end:
- const = Const(graph, {'value': int64_array(1), 'name': name + '/including_end/value'}).create_node()
- add = Add(graph, {'name': name + '/including_end'}).create_node()
- end_idx.out_port(0).connect(add.in_port(0))
- const.out_port(0).connect(add.in_port(1))
- end_idx = add
-
- delta = Const(graph, {'name': name + '/delta', 'value': int64_array(1)}).create_node()
- range_node = Range(graph, {'name': name + '/range_idxs'}).create_node()
-
- start_idx.out_port(0).connect(range_node.in_port(0))
- end_idx.out_port(0).connect(range_node.in_port(1))
- delta.out_port(0).connect(range_node.in_port(2))
-
- return range_node
-
-
-def get_shape_values_by_indices_node(shape_node: Node, indices_node: Node) -> Node:
- """
- The function returns a node that produces values of the specified indices node of the input node 'shape_node'
-
- :param shape_node: the node of 1D output shape to get elements from
- :param indices_node: the node of 1D output shape with the list of element indices to get
- :return: node producing required elements of the node
- """
- graph = shape_node.graph
- axis = Const(graph, {'value': int64_array(0), 'name': shape_node.name + '/Axis'}).create_node()
- gather_node = Gather(graph, {'name': shape_node.name + '/Gather'}).create_node()
-
- shape_node.out_port(0).connect(gather_node.in_port(0))
- indices_node.out_port(0).connect(gather_node.in_port(1))
- axis.out_port(0).connect(gather_node.in_port(2))
- return gather_node
-
-
-def node_to_get_shape_value_of_indices(shape_node: Node, indices: list) -> Node:
- """
- The function returns a node that produces values of the specified indices of the input node 'shape_node'
-
- :param shape_node: the node of 1D output shape to get elements from
- :param indices: the list of element indices to get
- :return: node producing required elements of the node
- """
- graph = shape_node.graph
- indices_node = Const(graph, {'value': int64_array(indices), 'name': shape_node.name + '/Indices'}).create_node()
-
- gather_node = get_shape_values_by_indices_node(shape_node, indices_node)
- return gather_node
-
-
-def get_shape_values_by_range_idxs(shape: Node, rank: Node, begin: int, end: int,
- include_begin: bool = True, include_end: bool = False):
- """
- Gathers shape values that are represented by range from begin to end (in)/(ex)cluding begin or end point
-
- :param shape: the node of 1D output shape to get elements from
- :param rank: the node of 0D output shape to get rank of tensor from
- :param begin: integer value from [-rank; rank - 1]
- :param end: integer value from [-rank; +rank]
- :param include_begin: boolean flag to include or exclude start point from range output
- :param include_end: boolean flag to include or exclude end point from range output
- :return: gather node producing 1D output
- """
- range_node = get_range_node_of_idxs(rank, begin, end, include_begin=include_begin, include_end=include_end)
- return get_shape_values_by_indices_node(shape, range_node)
-
-
-def node_to_get_batch_value(shape_node: Node) -> Node:
- """
- The function returns a node that produces the batch value which is usually the element of the shape with index 0
- :param shape_node: the node of 1D output shape to get batch from
- :return: the node producing batch value
- """
- return node_to_get_shape_value_of_indices(shape_node, [0])
-
-
-def node_to_get_features_dimension_value(shape_node: Node) -> Node:
- """
- The function returns a node that produces the feature dimension value
- :param shape_node: the node of 1D output shape to get the feature dimension value from
- :return: the node producing feature dimension value
- """
- layout = shape_node.graph.graph['layout']
- if layout == 'NCHW':
- return node_to_get_shape_value_of_indices(shape_node, [1])
- elif layout == 'NHWC':
- return node_to_get_shape_value_of_indices(shape_node, [-1])
- else:
- assert 'Unsupported layout "{}"'.format(layout)
-
-
-def node_to_get_spatial_dimensions_value(shape_node: Node) -> Node:
- """
- The function returns a node that produces the spatial dimension values
- :param shape_node: the node of 1D output shape to get the spatial dimension values from
- :return: the node producing the spatial dimension values
- """
- layout = shape_node.graph.graph['layout']
- shape = shape_node.in_port(0).get_connection().get_source().data.get_shape()
- assert shape is not None, 'The shape must be inferred before running this function'
-
- if layout == 'NCHW':
- return node_to_get_shape_value_of_indices(shape_node, list(range(2, len(shape))))
- elif layout == 'NHWC':
- return node_to_get_shape_value_of_indices(shape_node, list(range(1, len(shape) - 1)))
- else:
- assert 'Unsupported layout "{}"'.format(layout)
-
-
-def new_shape_node_from_shape_nodes(input_shape_nodes: list):
- """
- The function returns a node producing 1D tensor with concatenated shapes produced by nodes from "input_shape_nodes"
- :param input_shape_nodes: list of nodes producing 1D tensors
- :return: the node producing concatenated values of nodes from the "input_shape_nodes"
- """
- assert len(input_shape_nodes) > 0, 'The list of input shape nodes should be non-empty'
- new_shape_node = Concat(input_shape_nodes[0].graph,
- {'axis': 0,
- 'name': input_shape_nodes[0].soft_get('name', input_shape_nodes[0].id) + '/shapes_concat'}
- ).create_node()
-
- for ind, input_node in enumerate(input_shape_nodes):
- new_shape_node.add_input_port(ind)
- new_shape_node.in_port(ind).connect(input_node.out_port(0))
- return new_shape_node
-
-
-def get_shape_and_rank_nodes_by_port(port: Port, return_as_a_scalar: bool = True):
- """
- The function returns nodes producing shape and rank of the data from the desired port in order to use those
- operations on the middle/back phase
- :param port: Port object that specifies node output port
- :param return_as_a_scalar: boolean flag to return 1D or 0D rank
- :return: shape and rank nodes
- """
- input_node_name = port.node.soft_get('name', port.node.id)
- graph = port.node.graph
-
- shape = Shape(graph, dict(name=input_node_name + '/ShapeOf')).create_node()
- rank_1_d = Shape(graph, dict(name=input_node_name + '/1dRankOf')).create_node()
- rank_1_d.in_port(0).connect(shape.out_port(0))
- shape.in_port(0).connect(port)
- if not return_as_a_scalar:
- return shape, rank_1_d
-
- rank = create_op_node_with_second_input(graph, Squeeze, int64_array([0]), {'name': input_node_name + '/0dRankOf'},
- rank_1_d)
- return shape, rank
-
diff --git a/tools/mo/openvino/tools/mo/utils/simple_proto_parser.py b/tools/mo/openvino/tools/mo/utils/simple_proto_parser.py
deleted file mode 100644
index 79dd1a556aafd1..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/simple_proto_parser.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import ast
-import logging as log
-import os
-
-from openvino.tools.mo.utils.error import Error
-
-
-class SimpleProtoParser(object):
- """
- This is a simple Proto2 parser that has limited functionality and is intended to parse configuration files for the
- models created with Object Detection API only. The result of the parser is the dictionary.
- """
-
- _tokens = list()
- _result = dict()
-
- def __init__(self):
- self._tokens = list()
- self._result = dict()
-
- @staticmethod
- def _convert_value_to_correct_datatype(value: str):
- """
- Converts string representation of the token to a value with proper data type.
- :param value: string representation to be converted.
- :return: converted to a correct data type value.
- """
- if value == 'true':
- return True
- if value == 'false':
- return False
- try:
- result = ast.literal_eval(value)
- return result
- except Exception: # if it is not possible to evaluate the value then consider it as a string
- return value
-
- @staticmethod
- def _convert_values_to_correct_datatypes(d: dict):
- """
- Convert dictionary with values to correct data types.
- :param d: dictionary with values.
- :return: None
- """
- for key, value in d.items():
- if isinstance(value, dict):
- __class__._convert_values_to_correct_datatypes(value)
- elif isinstance(value, list):
- d[key] = [__class__._convert_value_to_correct_datatype(item) for item in value]
- else:
- d[key] = __class__._convert_value_to_correct_datatype(value)
-
- def _add_non_empty_token(self, token: str):
- """
- Add token to the list of tokens if it is non-empty.
- :param token: token to add
- :return: None
- """
- if token != "":
- self._tokens.append(token)
-
- def _parse_list(self, result: list, token_ind: int):
- prev_token = '['
- while token_ind < len(self._tokens):
- cur_token = self._tokens[token_ind]
- if cur_token == ']':
- return token_ind + 1
- if cur_token == ',':
- if prev_token == ',' or prev_token == '[':
- raise Error('Missing value in the list at position {}'.format(token_ind))
- else:
- result.append(cur_token)
- token_ind += 1
- prev_token = cur_token
- return token_ind
-
- def _parse_tokens(self, result: dict, token_ind: int, depth: int=0):
- """
- Internal function that parses tokens.
- :param result: current dictionary where to store parse result.
- :param token_ind: index of the token from the tokens list to start parsing from.
- :return: token index to continue parsing from.
- """
- while token_ind < len(self._tokens):
- cur_token = self._tokens[token_ind]
- if cur_token == ',': # redundant commas that we simply ignore everywhere except list "[x, y, z...]"
- token_ind += 1
- continue
- if cur_token == '}':
- return token_ind + 1
- next_token = self._tokens[token_ind + 1]
- if next_token == '{':
- result[cur_token] = dict()
- token_ind = self._parse_tokens(result[cur_token], token_ind + 2, depth + 1)
- elif next_token == ':':
- next_next_token = self._tokens[token_ind + 2]
- if next_next_token == '[':
- result[cur_token] = list()
- token_ind = self._parse_list(result[cur_token], token_ind + 3)
- else:
- if cur_token not in result:
- result[cur_token] = self._tokens[token_ind + 2]
- else:
- if not isinstance(result[cur_token], list):
- old_val = result[cur_token]
- result[cur_token] = [old_val]
- result[cur_token].append(self._tokens[token_ind + 2])
- token_ind += 3
- else:
- raise Error('Wrong character "{}" in position {}'.format(next_token, token_ind))
- if depth != 0:
- raise Error('Input/output braces mismatch.')
- return token_ind
-
- def _convert_tokens_to_dict(self):
- """
- Convert list of tokens into a dictionary with proper structure.
- Then converts values in the dictionary to values of correct data types. For example, 'false' -> False,
- 'true' -> true, '0.004' -> 0.004, etc.
- :return: True if conversion is successful.
- """
- try:
- self._parse_tokens(self._result, 0)
- except Exception as ex:
- log.error('Failed to convert tokens to dictionary: {}'.format(str(ex)))
- return False
- self._convert_values_to_correct_datatypes(self._result)
- return True
-
- def _split_to_tokens(self, file_content: str):
- """
- The function gets file content as string and converts it to the list of tokens (all tokens are still strings).
- :param file_content: file content as a string
- """
- cur_token = ''
- string_started = False
- for line in file_content.split('\n'):
- cur_token = ''
- line = line.strip()
- if line.startswith('#'): # skip comments
- continue
- for char in line:
- if string_started:
- if char == '"': # string ended
- self._add_non_empty_token(cur_token)
- cur_token = '' # start of a new string
- string_started = False
- else:
- cur_token += char
- elif char == '"':
- self._add_non_empty_token(cur_token)
- cur_token = '' # start of a new string
- string_started = True
- elif (char == " " and not string_started) or char == '\n':
- self._add_non_empty_token(cur_token)
- cur_token = ''
- elif char in [':', '{', '}', '[', ']', ',']:
- self._add_non_empty_token(cur_token)
- self._tokens.append(char)
- cur_token = ''
- else:
- cur_token += char
- self._add_non_empty_token(cur_token)
- self._add_non_empty_token(cur_token)
-
- def parse_from_string(self, file_content: str):
- """
- Parses the proto text file passed as a string.
- :param file_content: content of the file.
- :return: dictionary with file content or None if the file cannot be parsed.
- """
- self._split_to_tokens(file_content)
- if not self._convert_tokens_to_dict():
- log.error('Failed to generate dictionary representation of file.')
- return None
- return self._result
-
- def parse_file(self, file_name: str):
- """
- Parses the specified file and returns its representation as dictionary.
- :param file_name: file name to parse.
- :return: dictionary with file content or None if the file cannot be parsed.
- """
- if not os.path.exists(file_name):
- log.error('File {} does not exist'.format(file_name))
- return None
- try:
- with open(file_name) as file:
- file_content = file.readlines()
- except Exception as ex:
- log.error('Failed to read file {}: {}'.format(file_name, str(ex)))
- return None
- return self.parse_from_string(''.join(file_content))
diff --git a/tools/mo/openvino/tools/mo/utils/str_to.py b/tools/mo/openvino/tools/mo/utils/str_to.py
deleted file mode 100644
index 5c5f646497dee2..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/str_to.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-class StrTo(object):
- @staticmethod
- def tuple(type_of_elements: type, string: str):
- if type_of_elements == int:
- string = string.replace('L', '')
- return tuple(type_of_elements(x) for x in string[1:-1].split(',') if x != '')
-
- @staticmethod
- def list(string: str, type_of_elements: type, sep: str):
- result = string.split(sep)
- result = [type_of_elements(x) for x in result]
- return result
-
- @staticmethod
- def bool(val: str):
- if val.lower() == "false":
- return False
- elif val.lower() == "true":
- return True
- else:
- raise ValueError("Value is not boolean: " + val)
diff --git a/tools/mo/openvino/tools/mo/utils/summarize_graph.py b/tools/mo/openvino/tools/mo/utils/summarize_graph.py
deleted file mode 100644
index e9e87886c0356e..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/summarize_graph.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import sys
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-try:
- import tensorflow.compat.v1 as tf_v1
-except ImportError:
- import tensorflow as tf_v1
-
-#in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
-tf_v1.get_logger().setLevel("ERROR")
-
-unlikely_output_types = ['Const', 'Assign', 'NoOp', 'Parameter', 'Assert']
-
-
-def children(op_name: str, graph: tf_v1.Graph):
- op = graph.get_operation_by_name(op_name)
- return set(op for out in op.outputs for op in out.consumers())
-
-
-def summarize_graph(graph_def):
- placeholders = dict()
- outputs = list()
- graph = tf_v1.Graph()
- with graph.as_default(): # pylint: disable=not-context-manager
- tf_v1.import_graph_def(graph_def, name='')
- for node in graph.as_graph_def().node: # pylint: disable=no-member
- if node.op == 'Placeholder':
- node_dict = dict()
- node_dict['type'] = tf_v1.DType(node.attr['dtype'].type).name
- node_dict['shape'] = str(tf_v1.TensorShape(node.attr['shape'].shape)).replace(' ', '').replace('?', '-1')
- placeholders[node.name] = node_dict
- if len(children(node.name, graph)) == 0:
- if node.op not in unlikely_output_types and node.name.split('/')[-1] not in unlikely_output_types:
- outputs.append(node.name)
- result = dict()
- result['inputs'] = placeholders
- result['outputs'] = outputs
- return result
-
-
-def main():
- sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
- from openvino.tools.mo.front.tf.loader import load_tf_graph_def
-
- parser = argparse.ArgumentParser()
- parser.add_argument("--input_model", type=str, help="Path to tensorflow model", default="")
- parser.add_argument('--input_model_is_text', dest='text',
- help='TensorFlow*: treat the input model file as a text protobuf format. If not specified, '
- 'the Model Optimizer treats it as a binary file by default.', action='store_true',
- default=False)
- parser.add_argument('--input_meta', action='store_true',
- help='TensorFlow*: treat the input model file as a meta graph def format', default=False)
- parser.add_argument("--input_checkpoint", type=str, help='TensorFlow variables file to load.', default="")
- parser.add_argument('--saved_model_dir', type=str, default="", help="TensorFlow saved_model_dir")
- parser.add_argument('--saved_model_tags', type=str, default="",
- help="Group of tag(s) of the MetaGraphDef to load, in string \
- format, separated by ','. For tag-set contains multiple tags, all tags must be passed in.")
-
- argv = parser.parse_args()
- if not argv.input_model and not argv.saved_model_dir:
- print("[ ERROR ] Please, provide --input_model and --input_model_is_text if needed or --input_dir for saved "
- "model directory")
- sys.exit(1)
- if argv.input_model and argv.saved_model_dir:
- print("[ ERROR ] Both keys were provided --input_model and --input_dir. Please, provide only one of them")
- sys.exit(1)
- tags = argv.saved_model_tags.split(",")
- graph_def, _, _, _ = load_tf_graph_def(graph_file_name=argv.input_model, is_binary=not argv.text,
- checkpoint=argv.input_checkpoint,
- model_dir=argv.saved_model_dir, saved_model_tags=tags)
- summary = summarize_graph(graph_def)
- print("{} input(s) detected:".format(len(summary['inputs'])))
- for input in summary['inputs']:
- print("Name: {}, type: {}, shape: {}".format(input, summary['inputs'][input]['type'],
- summary['inputs'][input]['shape']))
- print("{} output(s) detected:".format(len(summary['outputs'])))
- print(*summary['outputs'], sep="\n")
-
-
-if __name__ == "__main__": # pragma: no cover
- main()
diff --git a/tools/mo/openvino/tools/mo/utils/telemetry_params.py b/tools/mo/openvino/tools/mo/utils/telemetry_params.py
deleted file mode 100644
index ea099ce2a873e6..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/telemetry_params.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-telemetry_params = {
- 'TID': "G-W5E9RNLD4H"
-}
diff --git a/tools/mo/openvino/tools/mo/utils/telemetry_stub.py b/tools/mo/openvino/tools/mo/utils/telemetry_stub.py
deleted file mode 100644
index 142ebf2abac760..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/telemetry_stub.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-class Telemetry(object):
- """
- Stab file for the Telemetry class which is used when Telemetry class is not available.
- """
-
- def __init__(self, *arg, **kwargs):
- pass
-
- def send_event(self, *arg, **kwargs):
- pass
-
- def send_error(self, *arg, **kwargs):
- pass
-
- def start_session(self, *arg, **kwargs):
- pass
-
- def end_session(self, *arg, **kwargs):
- pass
-
- def force_shutdown(self, *arg, **kwargs):
- pass
-
- def send_stack_trace(self, *arg, **kwargs):
- pass
diff --git a/tools/mo/openvino/tools/mo/utils/telemetry_utils.py b/tools/mo/openvino/tools/mo/utils/telemetry_utils.py
deleted file mode 100644
index a3e4c248d95979..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/telemetry_utils.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import argparse
-import numbers
-from collections import Counter
-
-import numpy as np
-from openvino.runtime import get_version as get_rt_version # pylint: disable=no-name-in-module,import-error
-
-from openvino.tools.mo.front.common.partial_infer.utils import is_fully_defined, unmask_shape, int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.utils.cli_parser import get_params_with_paths_list
-from openvino.tools.mo.utils.telemetry_params import telemetry_params
-from openvino.tools.mo.utils.utils import check_values_equal
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-def init_mo_telemetry(app_name='Model Optimizer'):
- return init_telemetry_class(tid=get_tid(),
- app_name=app_name,
- app_version=get_rt_version(),
- backend='ga4',
- enable_opt_in_dialog=False,
- disable_in_ci=True
- )
-
-
-def init_telemetry_class(tid,
- app_name,
- app_version,
- backend,
- enable_opt_in_dialog,
- disable_in_ci):
- # Init telemetry class
- telemetry = tm.Telemetry(tid=tid,
- app_name=app_name,
- app_version=app_version,
- backend=backend,
- enable_opt_in_dialog=enable_opt_in_dialog,
- disable_in_ci=disable_in_ci)
-
- # Telemetry is a singleton class and if it was already initialized in another tool
- # some parameters will be incorrect, including app_name.
- # In this case we need to force reinitialisation of telemetry.
- if hasattr(telemetry, "backend") and telemetry.backend.app_name != app_name:
- telemetry.init(tid=tid,
- app_name=app_name,
- app_version=app_version,
- backend=backend,
- enable_opt_in_dialog=enable_opt_in_dialog,
- disable_in_ci=disable_in_ci)
- return telemetry
-
-
-def send_framework_info(framework: str):
- """
- This function sends information about used framework.
- :param framework: framework name.
- """
- t = tm.Telemetry()
- t.send_event('mo', 'framework', framework)
-
-
-def get_tid():
- """
- This function returns the ID of the database to send telemetry.
- """
- return telemetry_params['TID']
-
-
-def send_conversion_result(conversion_result: str, need_shutdown=False):
- t = tm.Telemetry()
- t.send_event('mo', 'conversion_result', conversion_result)
- t.end_session('mo')
- if need_shutdown:
- t.force_shutdown(1.0)
-
-
-def arg_to_str(arg):
- # This method converts to string only known types, otherwise returns string with name of the type
- from openvino.runtime import PartialShape, Shape, Type, Layout # pylint: disable=no-name-in-module,import-error
- if isinstance(arg, (PartialShape, Shape, Type, Layout)):
- return str(arg)
- if isinstance(arg, (str, numbers.Number, bool)):
- return str(arg)
- return str(type(arg))
-
-
-def send_params_info(argv: argparse.Namespace, cli_parser: argparse.ArgumentParser):
- """
- This function sends information about used command line parameters.
- :param argv: command line parameters.
- :param cli_parser: command line parameters parser.
- """
- t = tm.Telemetry()
- params_with_paths = get_params_with_paths_list()
- for arg in vars(argv):
- arg_value = getattr(argv, arg)
- if not check_values_equal(arg_value, cli_parser.get_default(arg)):
- if arg in params_with_paths:
- # If command line argument value is a directory or a path to file it is not sent
- # as it may contain confidential information. "1" value is used instead.
- param_str = arg + ":" + str(1)
- else:
- param_str = arg + ":" + arg_to_str(arg_value)
-
- t.send_event('mo', 'cli_parameters', param_str)
-
-
-def send_op_names_info(framework: str, graph: Graph):
- """
- This function sends information about operations in model.
- :param framework: framework name.
- :param graph: model graph.
- """
- op_counter = Counter()
-
- def gather_op_statistics(g: Graph, op_c: Counter = op_counter):
- if hasattr(g, 'op_names_statistic'):
- op_c += g.op_names_statistic
-
- for_graph_and_each_sub_graph_recursively(graph, gather_op_statistics)
-
- t = tm.Telemetry()
- for op_name in op_counter:
- t.send_event('mo', 'op_count', "{}_{}".format(framework, op_name), op_counter[op_name])
-
-
-def send_shapes_info(framework: str, graph: Graph):
- """
- This function sends information about model input shapes.
- :param framework: framework name.
- :param graph: model graph.
- """
- shapes = []
- for node in graph.get_op_nodes():
- op_type = node.soft_get('type', None)
- if op_type == 'Parameter':
- if 'shape' in node:
- shapes.append(node['shape'])
- t = tm.Telemetry()
-
- if shapes:
- shape_str = ""
- is_partially_defined = "0"
- for shape in shapes:
- shape_str += (np.array2string(int64_array(unmask_shape(shape))) if shape is not None else "Undefined") + ","
- if not is_fully_defined(shape):
- is_partially_defined = "1"
- message_str = "{fw:" + framework + ",shape:\"" + shape_str[:-1] + "\"}"
- t.send_event('mo', 'input_shapes', message_str)
- t.send_event('mo', 'partially_defined_shape',
- "{partially_defined_shape:" + is_partially_defined + ",fw:" + framework + "}")
diff --git a/tools/mo/openvino/tools/mo/utils/tensorboard_util.py b/tools/mo/openvino/tools/mo/utils/tensorboard_util.py
deleted file mode 100644
index 4759daea2c3935..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/tensorboard_util.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-
-# do not print INFO and WARNING messages from TensorFlow
-os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
-try:
- import tensorflow.compat.v1 as tf_v1
-except ImportError:
- import tensorflow as tf_v1
-
-# in some environment suppressing through TF_CPP_MIN_LOG_LEVEL does not work
-tf_v1.get_logger().setLevel("ERROR")
-from tensorflow.python.eager.context import graph_mode # pylint: disable=no-name-in-module,import-error
-
-try:
- import tensorflow.contrib # pylint: disable=no-name-in-module,import-error
-except:
- pass # we try to import contrib for loading models that use contrib operations
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import refer_to_faq_msg
-
-
-def dump_for_tensorboard(graph_def: tf_v1.GraphDef, logdir: str):
- try:
- # TODO: graph_def is a deprecated argument, use graph instead
- print('Writing an event file for the tensorboard...')
- with graph_mode():
- with tf_v1.summary.FileWriter(logdir=logdir, graph_def=graph_def) as writer:
- writer.flush()
- print('Done writing an event file.')
- except Exception as err:
- raise Error('Cannot write an event file for the tensorboard to directory "{}". ' +
- refer_to_faq_msg(36), logdir) from err
diff --git a/tools/mo/openvino/tools/mo/utils/type_utils.py b/tools/mo/openvino/tools/mo/utils/type_utils.py
deleted file mode 100644
index 7cb082d2c05df2..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/type_utils.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.pipeline.common import convert_const_node_value_type
-from openvino.tools.mo.utils.error import Error
-
-np_map_cast = {bool: lambda x: bool_cast(x),
- np.int8: lambda x: np.int8(x),
- np.int16: lambda x: np.int16(x),
- np.int32: lambda x: np.int32(x),
- np.int64: lambda x: np.int64(x),
- np.uint8: lambda x: np.uint8(x),
- np.uint16: lambda x: np.uint16(x),
- np.uint32: lambda x: np.uint32(x),
- np.uint64: lambda x: np.uint64(x),
- np.float16: lambda x: np.float16(x),
- np.float32: lambda x: np.float32(x),
- np.double: lambda x: np.double(x),
- str: lambda x: str(x)}
-
-
-def bool_cast(x):
- if isinstance(x, str):
- return False if x.lower() in ['false', '0'] else True if x.lower() in ['true', '1'] else 'unknown_boolean_cast'
- else:
- return bool(x)
-
-
-def override_data_type_of_constant(node: Node, lhs_idx: int = 0, rhs_idx: int = 1):
- in_type_0 = node.in_port(lhs_idx).get_data_type()
- in_type_1 = node.in_port(rhs_idx).get_data_type()
- if in_type_0 != in_type_1:
- # in case of input values data type mismatch we try to change the type of the constant to match the type of
- # another input.
- in_node_0 = node.in_port(0).get_source().node
- in_node_1 = node.in_port(1).get_source().node
-
- if in_node_0.op == 'Const':
- node_to_convert, src_type, dst_type = in_node_0, in_type_0, in_type_1
- elif in_node_1.op == 'Const':
- node_to_convert, src_type, dst_type = in_node_1, in_type_1, in_type_0
- else:
- raise Error("{} operation '{}' has inputs of different data types: '{}' and '{}' "
- "that cannot be aligned".format(node.soft_get('op'),
- node.soft_get('name'),
- in_type_0,
- in_type_1))
- log.error("Changing Const node '{}' data type from {} to {} for {} operation".format(
- node_to_convert.soft_get('name', node_to_convert.id), src_type, dst_type, node.soft_get('op')),
- extra={'is_warning': True})
- convert_const_node_value_type(node_to_convert, dst_type)
diff --git a/tools/mo/openvino/tools/mo/utils/unsupported_ops.py b/tools/mo/openvino/tools/mo/utils/unsupported_ops.py
deleted file mode 100644
index ef189269c4e328..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/unsupported_ops.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import collections
-
-from openvino.tools.mo.graph.graph import Node, Graph
-
-
-class UnsupportedOps(object):
- def __init__(self, graph: Graph):
- self.graph = graph
- # map op to a list of node names
- self.unsupported = collections.defaultdict(list)
-
- def add(self, node: Node):
- op = node.op if node.has_valid('op') else ''
- name = node.name if node.has_valid('name') else ''
- self.unsupported[op].append(name)
-
- def report(self, reporter, header=None):
- if len(self.unsupported) > 0:
- if header:
- reporter(header)
- for k, v in self.unsupported.items():
- reporter(' ' * 4 + str(k) + ' (' + str(len(v)) + ')')
- for node_name in v:
- reporter(' ' * 8 + node_name)
diff --git a/tools/mo/openvino/tools/mo/utils/utils.py b/tools/mo/openvino/tools/mo/utils/utils.py
deleted file mode 100644
index 84301ff5d92d7f..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/utils.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import functools
-import os
-import re
-import warnings
-from typing import Callable
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-def refer_to_faq_msg(question_num: int):
- try:
- t = tm.Telemetry()
- t.send_event('mo', 'error_info', "faq:" + str(question_num))
- except Exception:
- # Telemetry can be not initialized if it is used in MO IR Reader
- pass
-
- return '\n For more information please refer to Model Conversion API FAQ, question #{0}. ' \
- '(https://docs.openvino.ai/2023.0/openvino_docs_MO_DG_prepare_model_Model_Optimizer_FAQ.html' \
- '?question={0}#question-{0})'.format(question_num)
-
-
-def check_values_equal(val1, val2):
- # This method is needed to check equality of values where some values can be None
- if val1 is None and val2 is None:
- return True
- if val1 is None:
- return False
- if val2 is None:
- return False
- return val1 == val2
-
-
-class NamedAttrsClass:
- def __init__(self, class_attrs: dict):
- for key, val in class_attrs.items():
- self.__setattr__(key, val)
-
-
-def match_shapes(pattern: np.array, shape: np.array):
- """ Check if shape matches shape pattern handling undefined dimension and 0 in the pattern. """
- # Elements with value 0 and undefined values in pattern are just ignored. Other elements should match.
- if pattern.size != shape.size:
- return False
- indices = [i for i, n in enumerate(pattern) if n != 0 and n is not dynamic_dimension]
- return np.ma.allequal(pattern[indices], shape[indices])
-
-
-def symm_match_shapes(shape1: np.array, shape2: np.array):
- """ Check if shape matches shape pattern handling -1 and 0 in the pattern. """
- # Elements with values -1 and 0 in both shapes are just ignored.
- # Other elements should match. Undefined elements can be one side only.
- return match_shapes(shape1, shape2) or match_shapes(shape2, shape1)
-
-
-def deprecated_api(class_name=None, new_method_name=None):
- def deprecated(func):
- @functools.wraps(func)
- def deprecation_message(*args, **kwargs):
- dep_msg = "Call to deprecated function {}. ".format(func.__name__)
- if class_name is not None:
- dep_msg += "Please use {}.{} method" \
- "".format(class_name.__name__ if not isinstance(class_name, str) else class_name,
- func.__name__ if new_method_name is None else new_method_name)
- warnings.warn(dep_msg, DeprecationWarning, stacklevel=2)
- return func(*args, **kwargs)
-
- return deprecation_message
-
- return deprecated
-
-
-def array_to_str(node, attr):
- if not node.has_valid(attr):
- return None
- else:
- return ','.join(map(str, node[attr]))
-
-
-def shrink_str_value(value: np.array, max_symbols=100):
- value = str(value)
- if len(value) > max_symbols:
- value = value.strip('\n')[:max_symbols - 3] + '...'
- return value
-
-
-def files_by_pattern(dir: str, pattern: str, files_only=True, add_prefix=False):
- """
- Return a list of files and directories (or only files if the files_only is set to True) in the directory dir that
- match pattern string pattern.
- :param dir: Directory to search for files
- :param pattern: string defining pattern name
- :param files_only: flag to include only files (not directories) to the result
- :param add_prefix: flag to include the prefix string to the file names
- :return: list of file and directory names
- """
- pattern_compiled = re.compile(pattern)
- matched_file_names = []
- for file_name in os.listdir(dir):
- if re.match(pattern_compiled, file_name) and (not files_only or os.path.isfile(os.path.join(dir, file_name))):
- matched_file_names.append(os.path.join(dir, file_name) if add_prefix else file_name)
- return matched_file_names
-
-
-def get_mo_root_dir():
- """
- Return the absolute path to the Model Optimizer root directory (where mo folder is located)
- :return: path to the MO root directory
- """
- return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(os.path.realpath(__file__))), os.pardir,
- os.pardir))
-
-
-def group_by_with_binary_predicate(xs: list, predicate: Callable) -> list:
- """
- It is an analogue of the function groupby from itertools, but with a binary predicate.
- In other words, group_by_with_binary_predicate generates a break or new group every time
- the value of the predicate function is False.
- :param xs: list of grouped value
- :param predicate: criterion of equality
- :return: grouped list
- """
- if not xs:
- return []
- prev = xs[0]
- sequence = [prev]
- result = []
- for x in xs[1:]:
- if predicate(prev, x):
- sequence.append(x)
- prev = x
- else:
- result.append(sequence)
- prev = x
- sequence = [prev]
- result.append(sequence)
- return result
-
-
-def unique_by(xs: list, predicate: Callable) -> list:
- """
- This function groups elements of the list xs using 'predicate', and then takes one element from each group.
- :param xs: input list
- :param predicate: grouping criterion which is some binary predicate
- :return: list with unique elements
- """
- groups = group_by_with_binary_predicate(xs, predicate)
- return [group[0] for group in groups]
diff --git a/tools/mo/openvino/tools/mo/utils/version.py b/tools/mo/openvino/tools/mo/utils/version.py
deleted file mode 100644
index 86bb346ac4bb18..00000000000000
--- a/tools/mo/openvino/tools/mo/utils/version.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import re
-import subprocess # nosec
-import sys
-
-from openvino.runtime import get_version as get_ie_version
-
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.find_ie_version import find_ie_version
-from openvino.tools.mo.utils.utils import get_mo_root_dir
-
-
-def extract_release_version(version: str):
- patterns = [
- # captures release version set by CI for example: '2021.1.0-1028-55e4d5673a8'
- r"^([0-9]+).([0-9]+)*",
- # captures release version generated by MO from release branch, for example: 'custom_releases/2021/1_55e4d567'
- r"_releases/([0-9]+)/([0-9]+)_*"
- ]
-
- for pattern in patterns:
- m = re.search(pattern, version)
- if m and len(m.groups()) == 2:
- return m.group(1), m.group(2)
- return None, None
-
-
-def simplify_version(version: str):
- release_version = extract_release_version(version)
- if release_version == (None, None):
- return "custom"
- return "{}.{}".format(*release_version)
-
-
-def extract_hash_from_version(full_version: str):
- res = re.findall(r'[-_]([a-f0-9]{7,40})', full_version)
- if len(res) > 0:
- return res[0]
- else:
- return None
-
-
-
-def get_version_file_path():
- return os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, "version.txt")
-
-
-def generate_mo_version():
- """
- Function generates version like in cmake
- custom_{branch_name}_{commit_hash}
- """
- try:
- mo_dir = get_mo_root_dir()
- branch_name = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=mo_dir).strip().decode()
- commit_hash = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=mo_dir).strip().decode()
- return "custom_{}_{}".format(branch_name, commit_hash)
- except Exception as e:
- return "unknown version"
-
-
-def get_version():
- version_txt = get_version_file_path()
- if not os.path.isfile(version_txt):
- return generate_mo_version()
- with open(version_txt) as f:
- return f.readline().replace('\n', '')
-
-
-def get_simplified_mo_version():
- return simplify_version(get_version())
-
-
-def get_simplified_ie_version(env=dict(), version=None):
- if version is None:
- try:
- version = subprocess.check_output([sys.executable, os.path.join(os.path.dirname(__file__), "ie_version.py")], timeout=2, env=env).strip().decode()
- except:
- return "ie not found"
-
- # To support legacy OV versions
- m = re.match(r"^([0-9]+).([0-9]+).(.*)", version)
- if m and len(m.groups()) == 3:
- return simplify_version(m.group(3))
- return simplify_version(version)
-
-
-class SingletonMetaClass(type):
- def __init__(self, cls_name, super_classes, dic):
- self.__single_instance = None
- super().__init__(cls_name, super_classes, dic)
-
- def __call__(cls, *args, **kwargs):
- if cls.__single_instance is None:
- cls.__single_instance = super(SingletonMetaClass, cls).__call__(*args, **kwargs)
- return cls.__single_instance
-
-
-class VersionChecker(metaclass=SingletonMetaClass):
- def __init__(self):
- self.runtime_checked = False
- self.mo_version = None
- self.ie_version = None
- self.mo_simplified_version = None
- self.ie_simplified_version = None
-
- def get_mo_version(self):
- if self.mo_version:
- return self.mo_version
- self.mo_version = get_version()
- return self.mo_version
-
- def get_ie_version(self):
- if self.ie_version:
- return self.ie_version
- self.ie_version = get_ie_version()
- return self.ie_version
-
- def get_mo_simplified_version(self):
- if self.mo_simplified_version:
- return self.mo_simplified_version
- self.mo_simplified_version = simplify_version(self.get_mo_version())
- return self.mo_simplified_version
-
- def get_ie_simplified_version(self):
- if self.ie_simplified_version:
- return self.ie_simplified_version
- self.ie_simplified_version = get_simplified_ie_version(env=os.environ)
- return self.ie_simplified_version
-
- def check_runtime_dependencies(self, silent=True):
- if not self.runtime_checked:
- def raise_ie_not_found():
- raise Error("Could not find the OpenVINO or Python API.\n"
- "Consider building the OpenVINO and Python APIs from sources or "
- "try to install OpenVINO (TM) Toolkit using pip \npip install openvino")
-
- try:
- if not find_ie_version(silent=silent):
- raise_ie_not_found()
- except Exception as e:
- import logging as log
- if log is not None:
- log.error(e)
- raise_ie_not_found()
- self.runtime_checked = True
diff --git a/tools/mo/requirements.txt b/tools/mo/requirements.txt
deleted file mode 100644
index fea66495f303ee..00000000000000
--- a/tools/mo/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
--c ../constraints.txt
-numpy>=1.16.6,<2.0.0
-networkx
-defusedxml
-openvino-telemetry
-packaging
diff --git a/tools/mo/requirements_caffe.txt b/tools/mo/requirements_caffe.txt
deleted file mode 100644
index 2806576890500c..00000000000000
--- a/tools/mo/requirements_caffe.txt
+++ /dev/null
@@ -1,7 +0,0 @@
--c ../constraints.txt
-numpy>=1.16.6,<1.27
-networkx
-protobuf
-defusedxml
-requests
-fastjsonschema
\ No newline at end of file
diff --git a/tools/mo/requirements_dev.txt b/tools/mo/requirements_dev.txt
deleted file mode 100644
index 5798a0ba9f7722..00000000000000
--- a/tools/mo/requirements_dev.txt
+++ /dev/null
@@ -1,9 +0,0 @@
--c ../constraints.txt
-coverage
-astroid
-pylint
-pyenchant
-defusedxml
-requests
-pytest
-fastjsonschema
\ No newline at end of file
diff --git a/tools/mo/requirements_kaldi.txt b/tools/mo/requirements_kaldi.txt
deleted file mode 100644
index 476ec8dab6535a..00000000000000
--- a/tools/mo/requirements_kaldi.txt
+++ /dev/null
@@ -1,8 +0,0 @@
--c ../constraints.txt
-# wa: conversion for stateful models is failed on higher numpy versions
-numpy>=1.16.6,<1.25; python_version<"3.12"
-numpy>=1.16.6,<1.27; python_version>="3.12"
-networkx
-defusedxml
-requests
-fastjsonschema
\ No newline at end of file
diff --git a/tools/mo/requirements_onnx.txt b/tools/mo/requirements_onnx.txt
deleted file mode 100644
index 28484f314a9d60..00000000000000
--- a/tools/mo/requirements_onnx.txt
+++ /dev/null
@@ -1,8 +0,0 @@
--c ../constraints.txt
-numpy>=1.16.6,<1.27
-onnx
-networkx
-defusedxml
-requests
-fastjsonschema
-protobuf
\ No newline at end of file
diff --git a/tools/mo/requirements_tf.txt b/tools/mo/requirements_tf.txt
deleted file mode 100644
index fb19c216e955ad..00000000000000
--- a/tools/mo/requirements_tf.txt
+++ /dev/null
@@ -1,8 +0,0 @@
--c ../constraints.txt
-h5py
-tensorflow>=1.15.5,<2.19.0
-numpy>=1.16.6,<1.27
-networkx
-defusedxml
-requests
-fastjsonschema
diff --git a/tools/mo/requirements_tf2.txt b/tools/mo/requirements_tf2.txt
deleted file mode 100644
index 50df4160c669d3..00000000000000
--- a/tools/mo/requirements_tf2.txt
+++ /dev/null
@@ -1,8 +0,0 @@
--c ../constraints.txt
-h5py
-tensorflow>=2.5,<2.19.0
-numpy>=1.16.6,<1.27
-networkx
-defusedxml
-requests
-fastjsonschema
diff --git a/tools/mo/setup.py b/tools/mo/setup.py
deleted file mode 100644
index c2b50ac656dfd2..00000000000000
--- a/tools/mo/setup.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python3
-
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-"""
-Use this script to create a wheel with Model Optimizer code:
-
-$ python setup.py sdist bdist_wheel
-"""
-
-import os
-import re
-from pathlib import Path
-from shutil import copyfile, copy
-
-from setuptools import setup, find_namespace_packages
-from setuptools.command.build_py import build_py
-from setuptools.command.install import install
-
-from typing import Dict, List
-
-prefix = 'openvino/tools/mo/'
-SETUP_DIR = Path(__file__).resolve().parent / Path(prefix)
-
-
-def read_constraints(path: str='../constraints.txt') -> Dict[str, List[str]]:
- """
- Read a constraints.txt file and return a dict
- of {package_name: [required_version_1, required_version_2]}.
- The dict values are a list because a package can be mentioned
- multiple times, for example:
- mxnet~=1.2.0; sys_platform == 'win32'
- mxnet>=1.7.0; sys_platform != 'win32'
- """
- constraints = {}
- with open(Path(__file__).resolve().parent / path) as f:
- raw_constraints = f.readlines()
- for line in raw_constraints:
- # skip comments
- if line.startswith('#'):
- continue
- line = line.replace('\n', '')
- # read constraints for that package
- package, delimiter, constraint = re.split('(~|=|<|>|;)', line, maxsplit=1)
- # if there is no entry for that package, add it
- if constraints.get(package) is None:
- constraints[package] = [delimiter + constraint]
- # else add another entry for that package
- else:
- constraints[package].extend([delimiter + constraint])
- return constraints
-
-
-def read_requirements(path: str) -> List[str]:
- """
- Read a requirements.txt file and return a list
- of requirements. Three cases are supported, the
- list corresponds to priority:
- 1. version specified in requirements.txt
- 2. version specified in constraints.txt
- 3. version unbound
-
- Putting environment markers into constraints.txt is prone to bugs.
- They should be specified in requirements.txt files.
- """
- requirements = []
- constraints = read_constraints()
- with open(Path(__file__).resolve().parent / path) as f:
- raw_requirements = f.readlines()
- for line in raw_requirements:
- # skip comments and constraints link
- if line.startswith(('#', '-c')):
- continue
- # get rid of newlines
- line = line.replace('\n', '')
- # if version is specified (non-word chars present)
- package_constraint = constraints.get(line.split(';')[0])
- if re.search('(~|=|<|>)', line) and len(line.split(';'))>1:
- if package_constraint: # both markers and versions specified
- marker_index = line.find(";")
- # insert package version between package name and environment markers
- line = line[:marker_index] \
- + ",".join([constraint for constraint in package_constraint]) \
- + line[marker_index:]
- requirements.append(line)
- # else get version from constraints
- else:
- constraint = constraints.get(line)
- # if version found in constraints.txt
- if constraint:
- for marker in constraint:
- requirements.append(line+marker)
- # else version is unbound
- else:
- requirements.append(line)
- return requirements
-
-
-# Detect all the framework specific requirements_*.txt files.
-requirements_txt = []
-py_modules = []
-for item in os.listdir():
- if re.match(r'requirements_?(tf|tf2|onnx|kaldi|caffe)?\.txt', item):
- requirements_txt.append(item)
-for item in os.listdir(prefix):
- if re.match(r'mo(.*)\.py|main(.*)\.py', item):
- py_modules.append(prefix.replace('/', '.') + item.split('.')[0])
-py_modules.append(prefix.replace('/', '.') + 'subprocess_main')
-py_modules.append(prefix.replace('/', '.') + 'convert')
-py_modules.append(prefix.replace('/', '.') + 'convert_impl')
-py_modules.append(prefix.replace('/', '.') + '__main__')
-
-class InstallCmd(install):
- def run(self):
- install.run(self)
- # copy requirements.txt files for all the frameworks
- for name in requirements_txt:
- copy(name, os.path.join(self.install_purelib, prefix))
-
- version_txt = 'version.txt'
- if os.path.exists(version_txt):
- copyfile(os.path.join(version_txt),
- os.path.join(self.install_purelib, prefix, version_txt))
-
-
-class BuildCmd(build_py):
- def find_package_modules(self, package, package_dir):
- modules = super().find_package_modules(package, package_dir)
- return [
- (pkg, module, filename)
- for (pkg, module, filename) in modules
- ]
-
-
-packages = find_namespace_packages(prefix[:-1])
-packages = [prefix.replace('/', '.') + p for p in packages]
-
-setup(
- name='openvino-mo',
- version='0.0.0',
- author='Intel Corporation',
- author_email='openvino_pushbot@intel.com',
- url='https://github.com/openvinotoolkit/openvino',
- packages=packages,
- py_modules=py_modules,
- cmdclass={
- 'install': InstallCmd,
- 'build_py': BuildCmd,
- },
- entry_points={
- 'console_scripts': [
- 'mo = openvino.tools.mo.__main__:main',
- ],
- },
- package_data={
- 'openvino.tools.mo.front.caffe.proto': ['*.proto'],
- 'openvino.tools.mo.front.onnx': ['*.json'],
- 'openvino.tools.mo.front.tf': ['*.json'],
- 'openvino.tools.mo.front.caffe': ['CustomLayersMapping.xml*']
- },
- extras_require={
- 'caffe': read_requirements('requirements_caffe.txt'),
- 'kaldi': read_requirements('requirements_kaldi.txt'),
- 'onnx': read_requirements('requirements_onnx.txt'),
- 'tensorflow': read_requirements('requirements_tf.txt'),
- 'tensorflow2': read_requirements('requirements_tf2.txt'),
- },
- classifiers=[
- "Programming Language :: Python :: 3",
- "License :: OSI Approved :: Apache Software License",
- "Operating System :: OS Independent",
- ],
- install_requires=read_requirements('requirements.txt'),
-)
diff --git a/tools/mo/unit_tests/__init__.py b/tools/mo/unit_tests/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/__init__.py b/tools/mo/unit_tests/mo/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/analysis/Iterator_get_next_test.py b/tools/mo/unit_tests/mo/analysis/Iterator_get_next_test.py
deleted file mode 100644
index 7662996680df4d..00000000000000
--- a/tools/mo/unit_tests/mo/analysis/Iterator_get_next_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.analysis.inputs import InputsAnalysis
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-class IteratorGetNextAnalysisTest(unittest.TestCase):
-
- def test_positive(self):
- graph = build_graph_with_edge_attrs(
- {
- 'iter_get_next': {'kind': 'op', 'op': 'IteratorGetNext', 'shapes': int64_array([[2, 2], [1, 1]]),
- 'types': [None, None]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'}
- },
- [
- ('iter_get_next', 'sub', {'out': 0, 'in': 0}),
- ('iter_get_next', 'add', {'out': 1, 'in': 0})
- ]
- )
- inputs_desc = {}
- message = InputsAnalysis.iterator_get_next_analysis(graph, inputs_desc)
- ref_message = 'It looks like there is IteratorGetNext as input\n' \
- 'Run the Model Optimizer without --input option \n' \
- 'Otherwise, try to run the Model Optimizer with:\n\t\t--input "iter_get_next:0[2 2],iter_get_next:1[1 1]"\n'
- self.assertEqual(message, ref_message)
-
- def test_negative(self):
- graph = build_graph_with_edge_attrs(
- {
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'}
- },
- [
- ('placeholder', 'sub', {'out': 0, 'in': 0}),
- ('placeholder', 'add', {'out': 0, 'in': 0})
- ]
- )
-
- inputs_desc = {}
- message = InputsAnalysis.iterator_get_next_analysis(graph, inputs_desc)
- self.assertEqual(message, None)
diff --git a/tools/mo/unit_tests/mo/analysis/__init__.py b/tools/mo/unit_tests/mo/analysis/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/back/ChangeOutputTypeAttributes_test.py b/tools/mo/unit_tests/mo/back/ChangeOutputTypeAttributes_test.py
deleted file mode 100644
index 830cf5c8eb8e95..00000000000000
--- a/tools/mo/unit_tests/mo/back/ChangeOutputTypeAttributes_test.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from copy import deepcopy
-
-import numpy as np
-
-from openvino.tools.mo.back.ChangeOutputTypeAttributes import ChangeOutputTypeAttributes
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.range import Range
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.middle.passes.convert_data_type import convert_blobs, data_type_str_to_np
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_empty_data, connect
-from unit_tests.utils.graph import valued_const_with_data
-
-
-class ChangeOutputTypeAttributesTests(unittest.TestCase):
-
- def test_range_correct_case(self):
- graph, graph_ref = build_range_test_graphs(start=0, limit=10, delta=1, dst_type_str='FP16')
- ChangeOutputTypeAttributes().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_range_correct_case_returns_shape_value(self):
- graph, graph_ref = build_range_test_graphs(start=0, limit=10, delta=1, dst_type_str='FP32',
- src_type_str='FP16', returns_shape_value=True)
- ChangeOutputTypeAttributes().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # starting from ~1000 FP16 absolute difference between neighbor values is more than 1
- # fails because of shape inconsistency
- def test_range_different_values(self):
- graph, graph_ref = build_range_test_graphs(start=0, limit=50000, delta=1, dst_type_str='FP16')
- self.assertRaises(Error, ChangeOutputTypeAttributes().find_and_replace_pattern, graph)
-
- def test_range_out_of_fp16_max(self):
- graph, graph_ref = build_range_test_graphs(start=0, limit=100000, delta=1, dst_type_str='FP16')
- self.assertRaises(Error, ChangeOutputTypeAttributes().find_and_replace_pattern, graph)
-
- def test_range_out_of_fp16_min(self):
- graph, graph_ref = build_range_test_graphs(start=0, limit=-100000, delta=-1, dst_type_str='FP16')
- self.assertRaises(Error, ChangeOutputTypeAttributes().find_and_replace_pattern, graph)
-
- def test_cast_correct_case(self):
- input_data = np.array([0, 1000, 4, 9, 0])
- graph, graph_ref = build_cast_test_graphs(input_data, dst_type_str='FP16')
- ChangeOutputTypeAttributes().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_cast_out_of_fp16_max(self):
- input_data = np.array([0, 100000, 4, 9, 0])
- graph, graph_ref = build_cast_test_graphs(input_data, dst_type_str='FP16')
- self.assertRaises(Error, ChangeOutputTypeAttributes().find_and_replace_pattern, graph)
-
- def test_cast_out_of_fp16_min(self):
- input_data = np.array([0, -100000, 4, 9, 0])
- graph, graph_ref = build_cast_test_graphs(input_data, dst_type_str='FP16')
- self.assertRaises(Error, ChangeOutputTypeAttributes().find_and_replace_pattern, graph)
-
- def test_cast_with_scalar(self):
- input_data = np.array(4)
- graph, graph_ref = build_cast_test_graphs(input_data, dst_type_str='FP16')
- ChangeOutputTypeAttributes().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-def build_range_test_graphs(start=0, limit=10, delta=1, dst_type_str='FP16',
- src_type_str='FP32', returns_shape_value=None):
- nodes = {
- **valued_const_with_data('start', float32_array(start)),
- **valued_const_with_data('limit', float32_array(limit)),
- **valued_const_with_data('delta', float32_array(delta)),
- **regular_op_with_empty_data('range', {'type': 'Range', 'op': 'Range',
- 'returns_shape_value': returns_shape_value,
- 'output_type': data_type_str_to_np(src_type_str),
- 'infer': Range.infer}),
- **result('res'),
- }
-
- nodes_ref = deepcopy(nodes)
- nodes_ref.update({
- **regular_op_with_empty_data('range', {'type': 'Range', 'op': 'Range',
- 'returns_shape_value': returns_shape_value,
- 'output_type': data_type_str_to_np(dst_type_str),
- 'infer': Range.infer}),
- })
-
- edges = [
- *connect('start', '0:range'),
- *connect('limit', '1:range'),
- *connect('delta', '2:range'),
- *connect('range', 'res'),
- ]
- graph = build_graph(nodes, edges)
- graph_ref = build_graph(nodes_ref, edges)
-
- graph = partial_infer(graph)
-
- graph.graph['cmd_params'].data_type = dst_type_str
- convert_blobs(graph, dst_type_str)
- return graph, graph_ref
-
-
-def build_cast_test_graphs(input_data, dst_type_str='FP16'):
- nodes = {
- **valued_const_with_data('input', float32_array(input_data)),
- **regular_op_with_empty_data('cast', {'type': 'Convert', 'op': 'Cast',
- 'dst_type': np.float32,
- 'infer': Cast.infer}),
- **result('res'),
- }
-
- nodes_ref = deepcopy(nodes)
- nodes_ref.update({
- **regular_op_with_empty_data('cast', {'type': 'Convert', 'op': 'Cast',
- 'dst_type': data_type_str_to_np(dst_type_str),
- 'infer': Cast.infer}),
- })
-
- edges = [
- *connect('input', 'cast'),
- *connect('cast', 'res'),
- ]
- graph = build_graph(nodes, edges)
- graph_ref = build_graph(nodes_ref, edges)
-
- graph = partial_infer(graph)
-
- graph.graph['cmd_params'].data_type = dst_type_str
- convert_blobs(graph, dst_type_str)
- return graph, graph_ref
diff --git a/tools/mo/unit_tests/mo/back/ChangeRandomUniformOutputType_test.py b/tools/mo/unit_tests/mo/back/ChangeRandomUniformOutputType_test.py
deleted file mode 100644
index df26df54713ca1..00000000000000
--- a/tools/mo/unit_tests/mo/back/ChangeRandomUniformOutputType_test.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from argparse import Namespace
-import pytest
-import numpy as np
-
-from openvino.tools.mo.back.ChangeRandomUniformOutputType import ChangeRandomUniformOutputType
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, regular_op_with_shaped_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder', [3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('random_uniform', [3, 4, 5], {'type': 'RandomUniform', 'op': 'RandomUniform'}),
- **regular_op_with_shaped_data('convert', [3, 4, 5], {'type': 'Convert'}),
- **result('result'),
-
- # new RandomUniform node and inputs
- **regular_op_with_shaped_data('min_val', [1], {'type': 'Const'}),
- **regular_op_with_shaped_data('max_val', [1], {'type': 'Const'}),
- **regular_op_with_shaped_data('shape', [3], {'type': 'Const'}),
-}
-
-edges = [*connect('placeholder', '0:random_uniform'), *connect('min_val', '1:random_uniform'),
- *connect('max_val', '2:random_uniform'), *connect('random_uniform', 'result')]
-edges_with_convert = [*connect('placeholder', '0:random_uniform'), *connect('min_val', '1:random_uniform'),
- *connect('max_val', '2:random_uniform'), *connect('random_uniform', 'convert'),
- *connect('convert', 'result'), ]
-
-
-class TestChangeRandomUniformOutputType():
- @pytest.mark.parametrize("ir_type, out_type, dst_type", [
- ("FP16", np.float32, np.float16),
- ("FP32", np.float16, np.float32),
- ("FP32", np.float32, None),
- ("FP32", np.int64, None)
-])
- def test_change_random_uniform_output_type(self,ir_type, out_type, dst_type):
- graph = build_graph(nodes, edges, cli=Namespace(data_type=ir_type))
- graph_ref = build_graph(nodes, edges if dst_type is None else edges_with_convert, {},
- nodes_with_edges_only=True)
- Node(graph, 'random_uniform')['output_type'] = out_type
-
- ChangeRandomUniformOutputType().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- assert flag, resp
-
- if dst_type is not None:
- convert_node = Node(graph, 'random_uniform').out_port(0).get_destination().node
- assert convert_node['dst_type'] == dst_type
diff --git a/tools/mo/unit_tests/mo/back/ClampNormalizer_test.py b/tools/mo/unit_tests/mo/back/ClampNormalizer_test.py
deleted file mode 100644
index 325471c1500718..00000000000000
--- a/tools/mo/unit_tests/mo/back/ClampNormalizer_test.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.ClampNormalizer import ClampNormalizer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect
-
-
-class AttributedClampNormalizerTests(unittest.TestCase):
-
- def test_2_inputs(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 20, 20], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('a_clamp', [1, 3, 20, 20], {'type': None, 'op': 'Clamp'}),
- **regular_op_with_shaped_data('clamp', [1, 3, 20, 20],
- {'type': 'Clamp', 'op': 'AttributedClamp', 'min': -3.5, 'max': 3.5}),
- **valued_const_with_data('min', np.array(-3.5)),
- **valued_const_with_data('max', np.array(3.5)),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:a_clamp'),
- *connect('min', '1:a_clamp'),
- *connect('max', '2:a_clamp'),
- *connect('a_clamp', 'result'),
- ]
- graph = build_graph(nodes, edges)
- ClampNormalizer().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, [*connect('placeholder', '0:clamp'), *connect('clamp', 'result')])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_all_dynamic_inputs(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 20, 20], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('min', [1, 3, 20, 20], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('max', [1, 3, 20, 20], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('a_clamp', [1, 3, 20, 20], {'type': None, 'op': 'Clamp'}),
- **regular_op_with_shaped_data('maximum', [1, 3, 20, 20], {'type': 'Maximum', 'op': 'Maximum'}),
- **regular_op_with_shaped_data('minimum', [1, 3, 20, 20], {'type': 'Minimum', 'op': 'Minimum'}),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:a_clamp'),
- *connect('min', '1:a_clamp'),
- *connect('max', '2:a_clamp'),
- *connect('a_clamp', 'result'),
- ]
- graph = build_graph(nodes, edges)
- ClampNormalizer().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, [*connect('placeholder', '0:maximum'),
- *connect('min', '1:maximum'),
- *connect('maximum', '0:minimum'),
- *connect('max', '1:minimum'),
- *connect('minimum', 'result')
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_no_max_input(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 20, 20], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('a_clamp', [1, 3, 20, 20], {'type': None, 'op': 'Clamp'}),
- **regular_op_with_shaped_data('maximum', [1, 3, 20, 20], {'type': 'Maximum', 'op': 'Maximum'}),
- **valued_const_with_data('min', np.array(-3.5)),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:a_clamp'),
- *connect('min', '1:a_clamp'),
- *connect('a_clamp', 'result'),
- ]
- graph = build_graph(nodes, edges)
- ClampNormalizer().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, [*connect('placeholder', '0:maximum'),
- *connect('min', '1:maximum'),
- *connect('maximum', 'result')
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_no_min_input(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 20, 20], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('a_clamp', [1, 3, 20, 20], {'type': None, 'op': 'Clamp'}),
- **regular_op_with_shaped_data('minimum', [1, 3, 20, 20], {'type': 'Minimum', 'op': 'Minimum'}),
- **valued_const_with_data('max', np.array(3.5)),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:a_clamp'),
- *connect('max', '2:a_clamp'),
- *connect('a_clamp', 'result'),
- ]
- graph = build_graph(nodes, edges)
- ClampNormalizer().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, [*connect('placeholder', '0:minimum'),
- *connect('max', '1:minimum'),
- *connect('minimum', 'result')
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/ConvolutionNormalizer_test.py b/tools/mo/unit_tests/mo/back/ConvolutionNormalizer_test.py
deleted file mode 100644
index e0902c9d53bd87..00000000000000
--- a/tools/mo/unit_tests/mo/back/ConvolutionNormalizer_test.py
+++ /dev/null
@@ -1,295 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.ConvolutionNormalizer import PullReshapeThroughFQ, V7ConvolutionWithGroupsResolver, \
- V10ConvolutionWithGroupsResolver
-from openvino.tools.mo.back.ShapeOfConstFolding import ShapeOfConstFolding
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.ops.fakequantize import FakeQuantize
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, regular_op_with_empty_data, \
- valued_const_with_data, connect
-
-
-def graph_template(weights_initial_shape, new_reshape_shape, limits_initial_shape, limits_new_shape=None):
- limits_new_shape = limits_initial_shape if limits_new_shape is None else limits_new_shape
-
- core_connections = [
- *connect('input:0', '0:convolution'),
- *connect('convolution:0', '0:output'),
- ]
-
- core_nodes = lambda weights_shape, limit_shape, reshape_shape: {
- **regular_op_with_shaped_data('input', None, {'type': 'Parameter', 'op': 'Parameter'}),
-
- **valued_const_with_data('weights', np.ones(weights_shape)),
-
- **valued_const_with_data('dim', int64_array(reshape_shape)),
- **regular_op_with_shaped_data('reshape', reshape_shape, {'type': 'Reshape', 'infer': Reshape.infer, 'op': 'Reshape'}),
-
- **valued_const_with_data('il', np.ones(limit_shape)),
- **valued_const_with_data('ih', np.ones(limit_shape)),
- **valued_const_with_data('ol', np.ones(limit_shape)),
- **valued_const_with_data('oh', np.ones(limit_shape)),
-
- **regular_op_with_shaped_data('FQ', weights_shape, {'type': 'FakeQuantize', 'infer': FakeQuantize.infer,
- 'stop_value_propagation': True, 'levels': 2, 'op': 'FakeQuantize'}),
-
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'op': 'Convolution'}),
-
- **result(),
- }
-
- nodes_before = core_nodes(weights_initial_shape, limits_initial_shape, new_reshape_shape)
- edges_before = [
-
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
-
- *connect('FQ:0', '0:reshape'),
- *connect('dim:0', '1:reshape'),
- *connect('reshape:0', '1:convolution'),
-
- *core_connections,
- ]
- graph = build_graph(nodes_attrs=nodes_before, edges=edges_before, nodes_with_edges_only=True)
-
- nodes_after = core_nodes(new_reshape_shape, limits_new_shape, [])
- edges_after = [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', '1:convolution'),
-
- *core_connections,
- ]
- graph_ref = build_graph(nodes_attrs=nodes_after, edges=edges_after, nodes_with_edges_only=True)
- return graph, graph_ref
-
-
-class TestPullReshapeThroughFQ(unittest.TestCase):
-
- def test_v7_weights_reshape(self):
- graph, graph_ref = graph_template([3, 8, 7, 7], [24, 1, 7, 7], [1, 1, 1, 1])
-
- PullReshapeThroughFQ().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_reshape_reducing_tensor_rank(self):
- graph, graph_ref = graph_template([3, 8, 7, 7], [24, 7, 7], [1, 1, 1])
-
- PullReshapeThroughFQ().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class TestV7ConvolutionWithGroupsResolver(unittest.TestCase):
- def test_v7_group_convolution_resolver(self):
- nodes = {
- **regular_op_with_shaped_data('input', [1, 3, 224, 224], {'type': 'Parameter'}),
-
- **valued_const_with_data('weights', np.ones([3, 8, 7, 7])),
-
- **valued_const_with_data('dim', int64_array([24, -1, 0, 0])),
- **regular_op_with_empty_data('reshape', {'type': 'Reshape'}),
-
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'group': 3, 'output': 24}),
-
- **result(),
- }
- graph = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- V7ConvolutionWithGroupsResolver().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '0:reshape'),
- *connect('dim', '1:reshape'),
- *connect('reshape', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_v7_group_convolution_resolver_weight_are_in_the_right_layout(self):
- nodes = {
- **regular_op_with_shaped_data('input', [1, 3, 224, 224], {'type': 'Parameter'}),
- **valued_const_with_data('weights', np.ones([24, 1, 7, 7])),
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'group': 3, 'output': 24}),
- **result(),
- }
- edges = [
- *connect('input', '0:convolution'),
- *connect('weights', '1:convolution'),
- *connect('convolution', 'output'),
- ]
- graph = build_graph(nodes, edges)
- V7ConvolutionWithGroupsResolver().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_v7_group_convolution_resolver_depthwise_conv2d(self):
- nodes = {
- **regular_op_with_shaped_data('input', [1, 1, 224, 224], {'type': 'Parameter'}),
-
- **valued_const_with_data('weights', np.ones([1, 8, 7, 7])),
-
- **valued_const_with_data('dim', int64_array([8, -1, 0, 0])),
- **regular_op_with_empty_data('reshape', {'type': 'Reshape'}),
-
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'group': 1, 'output': 8,
- 'op': 'DepthwiseConv2dNative'}),
-
- **result(),
- }
- graph = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- V7ConvolutionWithGroupsResolver().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '0:reshape'),
- *connect('dim', '1:reshape'),
- *connect('reshape', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class TestV10ConvolutionWithGroupsResolver(unittest.TestCase):
-
- @staticmethod
- def apply_transformation(graph):
- V10ConvolutionWithGroupsResolver().find_and_replace_pattern(graph)
- graph.clean_up()
- ShapeOfConstFolding().find_and_replace_pattern(graph)
- graph.clean_up()
-
- def test_v10_group_convolution_resolver(self):
- nodes = {
- **regular_op_with_shaped_data('input', [1, 3, 224, 224], {'type': 'Parameter'}),
-
- **valued_const_with_data('weights', np.ones([3, 8, 7, 7])),
-
- **valued_const_with_data('new_weights', np.ones([3, 8, 1, 7, 7])),
-
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'group': 3, 'output': 24}),
-
- **result(),
- }
- graph = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- TestV10ConvolutionWithGroupsResolver.apply_transformation(graph)
-
- nodes['convolution']['type'] = 'GroupConvolution'
- del nodes['convolution']['group']
-
- graph_ref = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('new_weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_v10_group_convolution_resolver_depthwise_conv2d(self):
- nodes = {
- **regular_op_with_shaped_data('input', [1, 1, 224, 224], {'type': 'Parameter'}),
-
- **valued_const_with_data('weights', np.ones([1, 8, 7, 7])),
-
- **valued_const_with_data('new_weights', np.ones([1, 8, 1, 7, 7])),
-
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'group': 1, 'output': 8,
- 'op': 'DepthwiseConv2dNative'}),
-
- **result(),
- }
- graph = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- TestV10ConvolutionWithGroupsResolver.apply_transformation(graph)
-
- nodes['convolution']['type'] = 'GroupConvolution'
- del nodes['convolution']['group']
-
- graph_ref = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('new_weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_v10_group_convolution_resolver_depthwise_conv2d_dynamic(self):
- nodes = {
- **regular_op_with_shaped_data('input', [-1, -1, -1, -1], {'type': 'Parameter'}),
-
- **valued_const_with_data('weights', np.ones([1, 8, 7, 7])),
-
- **valued_const_with_data('new_weights', np.ones([1, 8, 1, 7, 7])),
-
- **regular_op_with_shaped_data('convolution', None, {'type': 'Convolution', 'group': 1, 'output': 8,
- 'op': 'DepthwiseConv2dNative'}),
-
- **result(),
- }
- graph = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- TestV10ConvolutionWithGroupsResolver.apply_transformation(graph)
-
- nodes['convolution']['type'] = 'GroupConvolution'
- del nodes['convolution']['group']
-
- graph_ref = build_graph(nodes, [
- *connect('input', '0:convolution'),
- *connect('new_weights', '1:convolution'),
- *connect('convolution', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
diff --git a/tools/mo/unit_tests/mo/back/CutMemory_test.py b/tools/mo/unit_tests/mo/back/CutMemory_test.py
deleted file mode 100644
index 7a36c6fdd4bb68..00000000000000
--- a/tools/mo/unit_tests/mo/back/CutMemory_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.CutMemory import CutMemoryInput, CutMemoryOutput
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class CutMemoryTest(unittest.TestCase):
- def test_remove_memory(self):
- """Memory should be replaced by input and output"""
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op'},
- 'data_in': {'kind': 'data', 'shape': None, 'value': None},
- 'const_0': {'kind': 'op', 'op': 'Const'},
- 'const_0_data': {'kind': 'data'},
- 'memory_in': {'kind': 'op', 'op': 'ReadValue', 'variable_id': 'memory_'},
- 'data_mem': {'kind': 'data', 'shape': None, 'value': None},
- 'concat': {'kind': 'op', 'op': 'Concat', 'axis': 0},
- 'concat_data': {'kind': 'data', 'shape': None, 'value': None},
- 'some_op': {'kind': 'op'},
- 'some_op_data': {'kind': 'data', 'shape': None, 'value': None},
- 'memory_out': {'kind': 'op', 'op': 'Assign', 'variable_id': 'memory_'},
- 'data_mem_out': {'kind': 'data', 'shape': None, 'value': None},
- 'mem_out_result': {'kind': 'op', 'op': 'Result'}
- },
- edges=[
- ('input', 'data_in'),
- ('const_0', 'const_0_data'), ('const_0_data', 'memory_in'), ('memory_in', 'data_mem'),
- ('data_in', 'concat', {'in': 0}), ('data_mem', 'concat', {'in': 1}),
- ('concat', 'concat_data'), ('concat_data', 'some_op'),
- ('some_op', 'some_op_data'), ('some_op_data', 'memory_out'),
- ('memory_out', 'data_mem_out'), ('data_mem_out', 'mem_out_result')
- ]
- )
- graph_ref = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op'},
- 'data_in': {'kind': 'data', 'shape': None, 'value': None},
- 'new_input': {'kind': 'op', 'op': 'Parameter'},
- 'new_in_data': {'kind': 'data', 'shape': None, 'value': None},
- 'concat': {'kind': 'op', 'op': 'Concat', 'axis': 0},
- 'concat_data': {'kind': 'data', 'shape': None, 'value': None},
- 'some_op': {'kind': 'op'},
- 'some_op_data': {'kind': 'data', 'shape': None, 'value': None},
- 'crop': {'kind': 'op', 'op': 'Crop', 'axis': np.array([0])},
- 'crop_data': {'kind': 'data', 'shape': None, 'value': None},
- 'mem_out_result': {'kind': 'op', 'op': 'Result'},
- },
- edges=[
- ('input', 'data_in'), ('new_input', 'new_in_data'),
- ('data_in', 'concat', {'in': 0}), ('new_in_data', 'concat', {'in': 1}),
- ('concat', 'concat_data'), ('concat_data', 'some_op'),
- ('some_op', 'some_op_data'), ('some_op_data', 'crop'),
- ('crop', 'crop_data'), ('crop_data', 'mem_out_result')
- ],
- )
- CutMemoryInput().find_and_replace_pattern(graph)
- CutMemoryOutput().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='mem_out_result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/FakeOutputResolver_test.py b/tools/mo/unit_tests/mo/back/FakeOutputResolver_test.py
deleted file mode 100644
index d583d407f45cc7..00000000000000
--- a/tools/mo/unit_tests/mo/back/FakeOutputResolver_test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.FakeOutputResolver import FakeOutputResolver
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_empty_data, connect, empty_data, \
- valued_const_with_data
-
-
-class FakeOutputResolverTest(unittest.TestCase):
- def test_one(self):
- nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('some_op', {'type': 'SomeOp', 'name': 'some_op_name'}),
- **regular_op_with_empty_data('fake_output',
- {'type': None, 'kind': 'op', 'op': 'FakeOutput', 'name': 'my_output_name'}),
- **valued_const_with_data('const', int64_array(0)),
- **regular_op_with_empty_data('add', {'type': None, 'kind': 'op', 'op': 'Add', 'name': 'my_output_name'}),
- **result('result'),
- }
- edges = [*connect('input', 'some_op'),
- *connect('some_op', 'fake_output'),
- *connect('fake_output', 'result'),
- ]
- graph = build_graph(nodes, edges)
-
- edges_ref = [*connect('input', 'some_op'),
- *connect('some_op', '0:add'),
- *connect('const', '1:add'),
- *connect('add', 'result'),
- ]
-
- graph_ref = build_graph(nodes, edges_ref)
-
- FakeOutputResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_multi(self):
- nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('some_op', {'type': 'SomeOp', 'name': 'some_op_name'}),
- **empty_data('some_op_d2'),
- **regular_op_with_empty_data('fake_output1',
- {'type': None, 'kind': 'op', 'op': 'FakeOutput', 'name': 'my_output_name1'}),
- **regular_op_with_empty_data('fake_output2',
- {'type': None, 'kind': 'op', 'op': 'FakeOutput', 'name': 'my_output_name2'}),
-
- **valued_const_with_data('const1', int64_array(0)),
- **valued_const_with_data('const2', int64_array(0)),
- **regular_op_with_empty_data('add1', {'type': None, 'kind': 'op', 'op': 'Add', 'name': 'my_output_name1'}),
- **regular_op_with_empty_data('add2', {'type': None, 'kind': 'op', 'op': 'Add', 'name': 'my_output_name2'}),
- **result('result1'),
- **result('result2'),
- }
- edges = [*connect('input', 'some_op'),
- *connect('some_op', 'fake_output1'),
- ('some_op', 'some_op_d2'),
- ('some_op_d2', 'fake_output2'),
- *connect('fake_output1', 'result1'),
- *connect('fake_output2', 'result2'),
- ]
- graph = build_graph(nodes, edges)
-
- edges_ref = [*connect('input', 'some_op'),
- *connect('some_op', '0:add1'),
- *connect('const1', '1:add1'),
- ('some_op', 'some_op_d2'),
- ('some_op_d2', 'add2', {'in': 0}),
- *connect('const2', '1:add2'),
- *connect('add1', 'result1'),
- *connect('add2', 'result2'),
- ]
-
- graph_ref = build_graph(nodes, edges_ref)
-
- FakeOutputResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result1')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/FuseTransposesSequence_test.py b/tools/mo/unit_tests/mo/back/FuseTransposesSequence_test.py
deleted file mode 100644
index 1a24a12495449d..00000000000000
--- a/tools/mo/unit_tests/mo/back/FuseTransposesSequence_test.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.FuseTransposesSequence import FuseTransposesSequence
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-# 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_1': {'name': 'placeholder_1', 'value': None, 'shape': None, 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'placeholder_1_data': {'name': 'placeholder_1_data', 'value': None, 'shape': None, 'kind': 'data',
- 'data_type': None},
- # Transpose layers
- 'const_1': {'value': None, 'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'const_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'permute_1': {'type': 'Transpose', 'value': None, 'kind': 'op', 'op': 'Transpose'},
- 'permute_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'const_2': {'value': None, 'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'const_2_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'permute_2': {'type': 'Transpose', 'value': None, 'kind': 'op', 'op': 'Transpose'},
- 'permute_2_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'const_3': {'value': None, 'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'const_3_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'permute_3': {'type': 'Transpose', 'value': None, 'kind': 'op', 'op': 'Transpose'},
- 'permute_3_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': {'op': 'Result', 'kind': 'op'}
-}
-
-
-class FuseTransposesSequenceTest(unittest.TestCase):
- def test_1(self):
- #
- # NHWC NCHW NHWC
- # Input->DATA->Transpose->DATA->Transpose->DATA => Input->DATA
- #
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'permute_1'),
- ('permute_1', 'permute_1_data'),
- ('permute_1_data', 'permute_2'),
- ('permute_2', 'permute_2_data'),
- ('permute_2_data', 'op_output'),
-
- ('const_1', 'const_1_data'),
- ('const_1_data', 'permute_1', {'in': 1}),
-
- ('const_2', 'const_2_data'),
- ('const_2_data', 'permute_2', {'in': 1}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
-
- 'const_1_data': {'value': np.array([0, 3, 1, 2])},
- 'permute_1_data': {'shape': np.array([1, 3, 227, 227])},
-
- 'const_2_data': {'value': np.array([0, 2, 3, 1])},
- 'permute_2_data': {'shape': np.array([1, 227, 227, 3])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}},
- nodes_with_edges_only=True)
-
- pattern = FuseTransposesSequence()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_2(self):
- #
- # Input->DATA->Transpose->DATA->Transpose->DATA => Input->DATA->Transpose->DATA
- #
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'permute_1'),
- ('permute_1', 'permute_1_data'),
- ('permute_1_data', 'permute_2'),
- ('permute_2', 'permute_2_data'),
- ('permute_2_data', 'op_output'),
-
- ('const_1', 'const_1_data'),
- ('const_1_data', 'permute_1', {'in': 1}),
-
- ('const_2', 'const_2_data'),
- ('const_2_data', 'permute_2', {'in': 1}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_1': {'shape': np.array([4])},
- 'const_1_data': {'value': np.array([0, 3, 1, 2])},
- 'permute_1_data': {'shape': np.array([1, 3, 227, 227])},
-
- 'const_2': {'shape': np.array([4])},
- 'const_2_data': {'value': np.array([0, 1, 2, 3])},
- 'permute_2_data': {'shape': np.array([1, 3, 227, 227])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'permute_1'),
- ('permute_1', 'permute_1_data'),
- ('permute_1_data', 'op_output'),
-
- ('const_1', 'const_1_data'),
- ('const_1_data', 'permute_1', {'in': 1}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_1_data': {'value': np.array([0, 3, 1, 2])},
- 'permute_1_data': {'shape': np.array([1, 3, 227, 227])},
- }, nodes_with_edges_only=True)
-
- pattern = FuseTransposesSequence()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tools/mo/unit_tests/mo/back/GatherTreeNormalizer_test.py b/tools/mo/unit_tests/mo/back/GatherTreeNormalizer_test.py
deleted file mode 100644
index 358b26750f318f..00000000000000
--- a/tools/mo/unit_tests/mo/back/GatherTreeNormalizer_test.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.GatherNormalizer import GatherTreeNormalizer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.passes.eliminate import shape_inference
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect
-
-
-class GatherTreeNormalizerTests(unittest.TestCase):
- def test_gather_tree_normalizer(self):
- nodes = {
- **regular_op_with_shaped_data('data_0', [100, 1, 10], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('data_1', [100, 1, 10], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('data_2', [1], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('gather_tree', [1], {'type': 'GatherTree'}),
- **valued_const_with_data('const', np.array([2])),
- **result('result'),
- }
- edges = [*connect('data_0', '0:gather_tree'),
- *connect('data_1', '1:gather_tree'),
- *connect('data_2', '2:gather_tree'),
- *connect('const', '3:gather_tree'),
- *connect('gather_tree', 'result'),
- ]
- ref_edges = [*connect('data_0', '0:gather_tree'),
- *connect('data_1', '1:gather_tree'),
- *connect('data_2', '2:gather_tree'),
- *connect('const', '0:squeeze'),
- *connect('squeeze_axis', '1:squeeze'),
- *connect('squeeze', '3:gather_tree'),
- *connect('gather_tree', 'result'),]
- ref_nodes = nodes.copy()
- ref_nodes.update({**valued_const_with_data('squeeze_axis', int64_array([0])),
- **regular_op_with_shaped_data('squeeze', [], {'type': 'Squeeze'})})
- graph = build_graph(nodes, edges)
- GatherTreeNormalizer().find_and_replace_pattern(graph)
- # run shape inference to make sure that shape overriding happened
- shape_inference(graph)
-
- ref_graph = build_graph(ref_nodes, ref_edges)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/InterpolateReshape_test.py b/tools/mo/unit_tests/mo/back/InterpolateReshape_test.py
deleted file mode 100644
index 839d13edd04dca..00000000000000
--- a/tools/mo/unit_tests/mo/back/InterpolateReshape_test.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.InterpolateReshape import InterpolateReshapeWA, InterpolateConcat
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect, \
- connect_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 30, 40], {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('out_shape', np.array([60, 160])),
-
- **regular_op_with_shaped_data('interpolate', [1, 3, 60, 160], {'type': 'Interpolate', 'axes': [2, 3],
- 'op': 'Interpolate', 'version': 'opset1'}),
-
- **regular_op_with_shaped_data('shape', [4], {'type': 'ShapeOf', 'op': 'ShapeOf'}),
- **valued_const_with_data('indices', np.array([2, 3])),
- **valued_const_with_data('axis', np.array(0)),
- **regular_op_with_shaped_data('gather', [2], {'type': 'Gather', 'op': 'Gather'}),
-
- **valued_const_with_data('multiplier', np.array([2, 4])),
- **regular_op_with_shaped_data('mul', [2], {'type': 'Multiply', 'op': 'Mul'}),
-
- **regular_op_with_shaped_data('placeholder_1', [1, 3, 60, 160], {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('concat', [1, 7, 60, 160], {'type': 'Concat', 'axis': 1, 'op': 'Concat'}),
-
- **result(),
-}
-
-
-class TestInterpolateReshapeWA(unittest.TestCase):
- def test_interpolate_reshape_graph_comparison(self):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', 'output'),
- ], nodes_with_edges_only=True)
- InterpolateReshapeWA().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect_data('placeholder', 'shape'),
- *connect('shape', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', '0:mul'),
- *connect('multiplier', '1:mul'),
- *connect('mul', '1:interpolate'),
- *connect('interpolate', 'output'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class TestInterpolateConcat(unittest.TestCase):
- def test_interpolate_concat_reshape_graph_comparison(self):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect('placeholder_1', '1:concat'),
- *connect('concat', 'output'),
- ], nodes_with_edges_only=True)
-
- InterpolateConcat().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('placeholder_1', 'shape'),
- *connect('shape', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect_data('placeholder_1', '1:concat'),
- *connect('concat', 'output'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/LayoutChangeForGatherND_test.py b/tools/mo/unit_tests/mo/back/LayoutChangeForGatherND_test.py
deleted file mode 100644
index 19d7246cd2b649..00000000000000
--- a/tools/mo/unit_tests/mo/back/LayoutChangeForGatherND_test.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.LayoutChangeForGatherND import LayoutChangeForGatherND
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.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},
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # GatherND
- 'gathernd': {'type': 'GatherND', 'kind': 'op', 'op': 'GatherND'},
- 'gathernd_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Result layer
- 'result': {'type': 'Result', 'kind': 'op', 'op': 'Result'},
- # Transpose layers
- 'transpose_1': {'type': 'Transpose', 'kind': 'op', 'op': 'Transpose', 'need_shape_inference': True},
- 'transpose_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axis_1_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': None},
- 'axis_1_const_data': {'kind': 'data', 'value': None, 'shape': None},
- 'transpose_2': {'type': 'Transpose', 'kind': 'op', 'op': 'Transpose', 'need_shape_inference': True},
- 'transpose_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axis_2_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': None},
- 'axis_2_const_data': {'kind': 'data', 'value': None, 'shape': None},
- 'transpose_3': {'type': 'Transpose', 'kind': 'op', 'op': 'Transpose', 'need_shape_inference': True},
- 'transpose_3_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axis_3_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': None},
- 'axis_3_const_data': {'kind': 'data', 'value': None, 'shape': None},
-}
-
-
-class LayoutChangeForGatherNDTests(unittest.TestCase):
- def test_tf_all_ports(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'gathernd'),
- ('placeholder_2_data', 'gathernd'),
- ('gathernd', 'gathernd_data'),
- ('gathernd_data', 'result'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
- 'placeholder_2_data': {'shape': np.array([1, 3, 224, 224])},
- 'gathernd_data': {'shape': np.array([1, 3, 224, 224])},
- })
- graph.graph['fw'] = 'tf'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'transpose_1'),
- ('axis_1_const', 'axis_1_const_data'),
- ('axis_1_const_data', 'transpose_1'),
- ('transpose_1', 'transpose_1_data'),
- ('placeholder_2_data', 'transpose_2'),
- ('axis_2_const', 'axis_2_const_data'),
- ('axis_2_const_data', 'transpose_2'),
- ('transpose_2', 'transpose_2_data'),
- ('transpose_1_data', 'gathernd'),
- ('transpose_2_data', 'gathernd'),
- ('gathernd', 'gathernd_data'),
- ('gathernd_data', 'transpose_3'),
- ('axis_3_const', 'axis_3_const_data'),
- ('axis_3_const_data', 'transpose_3'),
- ('transpose_3', 'transpose_3_data'),
- ('transpose_3_data', 'result'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
- 'placeholder_2_data': {'shape': np.array([1, 3, 224, 224])},
- 'axis_1_const_data': {'value': int64_array([0, 2, 3, 1])},
- 'axis_2_const_data': {'value': int64_array([0, 2, 3, 1])},
- 'gathernd_data': {'shape': np.array([1, 3, 224, 224])},
- 'axis_3_const_data': {'value': int64_array([0, 3, 1, 2])},
- })
-
- pattern = LayoutChangeForGatherND()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_tf_one_ports(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'gathernd'),
- ('placeholder_2_data', 'gathernd'),
- ('gathernd', 'gathernd_data'),
- ('gathernd_data', 'result'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
- 'placeholder_2_data': {'shape': np.array([1, 3])},
- 'gathernd_data': {'shape': np.array([1, 3])},
- })
- graph.graph['fw'] = 'tf'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'transpose_1'),
- ('axis_1_const', 'axis_1_const_data'),
- ('axis_1_const_data', 'transpose_1'),
- ('transpose_1', 'transpose_1_data'),
- ('transpose_1_data', 'gathernd'),
- ('placeholder_2_data', 'gathernd'),
- ('gathernd', 'gathernd_data'),
- ('gathernd_data', 'result'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
- 'placeholder_2_data': {'shape': np.array([1, 3])},
- 'axis_1_const_data': {'value': int64_array([0, 2, 3, 1])},
- 'gathernd_data': {'shape': np.array([1, 3])}
- })
-
- pattern = LayoutChangeForGatherND()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/MarkNodesWithShapeValues_test.py b/tools/mo/unit_tests/mo/back/MarkNodesWithShapeValues_test.py
deleted file mode 100644
index 21dd0272dd0b4f..00000000000000
--- a/tools/mo/unit_tests/mo/back/MarkNodesWithShapeValues_test.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.MarkNodesWithShapeValues import MarkNodesWithShapeValues
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_empty_data, shaped_const_with_data, connect, \
- regular_op, regular_op_with_shaped_data
-
-
-class TestMarkDataTypeInShapeOfSubgraphs(unittest.TestCase):
-
- def test_run_with_shape_subgraph_input(self):
- inp_shape = (1, 3, 1000, 1000)
- dst_type = np.float32
-
- nodes = {
- **shaped_const_with_data('input', int64_array(inp_shape)),
- **regular_op_with_empty_data('shape', {'type': 'ShapeOf'}),
- **regular_op_with_empty_data('cast_to_float', {'type': 'Cast', 'dst_type': dst_type}),
- **regular_op('mul_const', {'op': 'Const'}),
- **{'mul_const_d': {'kind': 'data', 'value': float32_array([1., 1., 1., 100.])}},
- **regular_op_with_empty_data('mul', {'type': 'Mul'}),
- **regular_op_with_empty_data('cast_to_int', {'type': 'Cast', 'dst_type': np.int64}),
- **regular_op_with_empty_data('interpolate', {'type': 'Interpolate', 'shape_calculation_model': 'scales'}),
- **result('res'),
- }
-
- nodes_ref = {
- **shaped_const_with_data('input', int64_array(inp_shape)),
- **regular_op_with_empty_data('shape', {'type': 'ShapeOf'}),
- **regular_op_with_empty_data('cast_to_float', {'type': 'Cast', 'dst_type': dst_type,
- 'returns_shape_value': True}),
- **regular_op_with_empty_data('mul', {'type': 'Mul', 'returns_shape_value': True}),
- **regular_op('mul_const', {'op': 'Const', 'returns_shape_value': True}),
- **{'mul_const_d': {'kind': 'data', 'value': float32_array([1., 1., 1., 100.]),
- 'correct_data_type': True}},
- **regular_op_with_empty_data('cast_to_int', {'type': 'Cast', 'dst_type': np.int64,
- 'returns_shape_value': True}),
- **regular_op_with_empty_data('interpolate', {'type': 'Interpolate', 'shape_calculation_model': 'scales'}),
- **result('res'),
- }
-
- edges = [
- *connect('input', '0:interpolate'),
- *connect('input', '0:shape', skip_data=True),
- *connect('shape', '0:cast_to_float'),
- *connect('cast_to_float', '0:mul'),
- *connect('mul_const', '1:mul'),
- *connect('mul', '0:cast_to_int'),
- *connect('cast_to_int', '1:interpolate'),
- *connect('interpolate', 'res'),
- ]
- graph = build_graph(nodes, edges)
- interp_node = Node(graph, 'interpolate')
- interp_node.add_input_port(2)
-
- MarkNodesWithShapeValues().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_ref, edges)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_run_with_const_input(self):
- inp_shape = (1, 3, 1000, 1000)
-
- nodes = {
- **shaped_const_with_data('input', int64_array(inp_shape)),
- **regular_op('sizes_const', {'op': 'Const'}),
- **{'sizes_const_d': {'kind': 'data', 'value': float32_array([1., 1., 1., 100.])}},
- **regular_op_with_empty_data('interpolate', {'type': 'Interpolate', 'shape_calculation_model': 'scales'}),
- **result('res'),
- }
-
- nodes_ref = {
- **shaped_const_with_data('input', int64_array(inp_shape)),
- **regular_op('sizes_const', {'op': 'Const', 'returns_shape_value': True}),
- **{'sizes_const_d': {'kind': 'data', 'value': float32_array([1., 1., 1., 100.])}},
- **regular_op_with_empty_data('interpolate', {'type': 'Interpolate', 'shape_calculation_model': 'scales'}),
- **result('res'),
- }
-
- edges = [
- *connect('input', '0:interpolate'),
- *connect('sizes_const', '1:interpolate'),
- *connect('interpolate', 'res'),
- ]
- graph = build_graph(nodes, edges)
- interp_node = Node(graph, 'interpolate')
- interp_node.add_input_port(2)
-
- MarkNodesWithShapeValues().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_ref, edges)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_run_with_solitary_shapeof_in_shape_value_subgraph(self):
- # in this case MarkNodesWithShapeValues must leave graph unchanged
- # so reference nodes are exactly the same
-
- inp_shape_1 = int64_array((1, 3, 100, 100))
- inp_shape_2 = int64_array((1, 3, 100, 50)) # inp_2 and const will be concatenated to (1, 3, 200, 50)
- const_shape = int64_array((1, 3, 100, 50))
-
- nodes = {
- **regular_op_with_shaped_data('input_1', inp_shape_1, {'op': 'Parameter', 'type': 'Parameter'}),
- **regular_op_with_shaped_data('input_2', inp_shape_2, {'op': 'Parameter', 'type': 'Parameter',
- 'returns_shape_value': False}),
- **shaped_const_with_data('const', const_shape),
- **regular_op_with_empty_data('concat', {'op': 'Concat', 'type': 'Concat', 'axis': 2,
- 'returns_shape_value': False}),
- **regular_op_with_empty_data('shapeof', {'op': 'ShapeOf', 'type': 'ShapeOf'}),
- **regular_op_with_empty_data('reshape', {'op': 'Reshape', 'type': 'Reshape'}),
- **result('res'),
- }
-
- edges = [
- *connect('input_1', '0:reshape'),
- *connect('input_2', '0:concat'),
- *connect('const', '1:concat'),
- *connect('concat', 'shapeof'),
- *connect('shapeof', '1:reshape'),
- *connect('reshape', 'res'),
- ]
-
- graph = build_graph(nodes, edges)
-
- MarkNodesWithShapeValues().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, edges)
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- self.assertTrue(flag, "'returns_shape_value' should be False or unset for ShapeOf input nodes" + ': ' + str(resp))
diff --git a/tools/mo/unit_tests/mo/back/MatMulNormalizer_test.py b/tools/mo/unit_tests/mo/back/MatMulNormalizer_test.py
deleted file mode 100644
index aa0c5c7b4c11dd..00000000000000
--- a/tools/mo/unit_tests/mo/back/MatMulNormalizer_test.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from argparse import Namespace
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.back.MatMulNormalizer import SmartReshape_HC_Reshape_MatMul, PullTransposeThroughFQUp
-from openvino.tools.mo.ops.MatMul import MatMul
-from openvino.tools.mo.ops.fakequantize import FakeQuantize
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, \
- shaped_const_with_data, result, connect, connect_data
-from unit_tests.utils.graph import regular_op_with_empty_data as op_with_empty_data
-
-
-class TestSmartReshape_HC_Reshape_MatMulTest():
- @pytest.mark.parametrize("in1_shape, in2_shape, reshape_pattern, transpose_a, transpose_b, updated_pattern",
- [
- ([1, 20, 30], [30, 40], [20, -1], False, False, [-1, 30]),
- ([1, 20, 30], [40, 30], [20, -1], False, True, [-1, 30]),
- ([1, 30, 20], [30, 40], [-1, 20], True, False, [30, -1]),
- ([1, 30, 20], [40, 30], [-1, 20], True, True, [30, -1]),
- ]
- )
- def test_reshape_on_the_A_input(self,
- in1_shape, in2_shape, reshape_pattern, transpose_a, transpose_b, updated_pattern):
- nodes = {
- **regular_op_with_shaped_data('in_1', in1_shape, dict(type='Parameter', op='Parameter')),
- **regular_op_with_shaped_data('in_2', in2_shape, dict(type='Parameter', op='Parameter')),
- **valued_const_with_data('dim', int64_array(reshape_pattern)),
- **op_with_empty_data('reshape',
- dict(type='Reshape', op='Reshape', infer=Reshape.infer, need_shape_inference=True)),
- **op_with_empty_data('matmul',
- dict(type='MatMul', op='MatMul', infer=MatMul.infer, need_shape_inference=True,
- transpose_a=transpose_a, transpose_b=transpose_b, dim_attrs={})),
- **result(),
- }
- edges = [
- *connect('in_1:0', '0:reshape'),
- *connect('dim:0', '1:reshape'),
- *connect('reshape:0', '0:matmul'),
- *connect('in_2:0', '1:matmul'),
- *connect('matmul:0', 'output'),
- ]
- graph = build_graph(nodes_attrs=nodes, edges=edges, cli=Namespace(static_shape=True))
- graph.clean_up()
- SmartReshape_HC_Reshape_MatMul().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(nodes_attrs=nodes, edges=edges, update_attributes={
- 'dim': {'value': int64_array(updated_pattern)}, 'dim_d': {'value': int64_array(updated_pattern)}})
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- @pytest.mark.parametrize("in1_shape, in2_shape, reshape_pattern, transpose_a, transpose_b, updated_pattern",[
- ([20, 30], [1, 30, 40], [-1, 40], False, False, [30, -1]),
- ([20, 30], [1, 40, 30], [40, -1], False, True, [-1, 30]),
- ([30, 20], [1, 30, 40], [-1, 40], True, False, [30, -1]),
- ([30, 20], [1, 40, 30], [40, -1], True, True, [-1, 30]),
- ])
- def test_reshape_on_the_B_input(self,
- in1_shape, in2_shape, reshape_pattern, transpose_a, transpose_b, updated_pattern):
- nodes = {
- **regular_op_with_shaped_data('in_1', in1_shape, dict(type='Parameter', op='Parameter')),
- **regular_op_with_shaped_data('in_2', in2_shape, dict(type='Parameter', op='Parameter')),
- **valued_const_with_data('dim', int64_array(reshape_pattern)),
- **op_with_empty_data('reshape',
- dict(type='Reshape', op='Reshape', infer=Reshape.infer, need_shape_inference=True)),
- **op_with_empty_data('matmul',
- dict(type='MatMul', op='MatMul', infer=MatMul.infer, need_shape_inference=True,
- transpose_a=transpose_a, transpose_b=transpose_b, dim_attrs={})),
- **result(),
- }
- edges = [
- *connect('in_1:0', '0:matmul'),
- *connect('in_2:0', '0:reshape'),
- *connect('dim:0', '1:reshape'),
- *connect('reshape:0', '1:matmul'),
- *connect('matmul:0', 'output'),
- ]
- graph = build_graph(nodes_attrs=nodes, edges=edges, cli=Namespace(static_shape=True))
- graph.clean_up()
- SmartReshape_HC_Reshape_MatMul().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(nodes_attrs=nodes, edges=edges, update_attributes={
- 'dim': {'value': int64_array(updated_pattern)}, 'dim_d': {'value': int64_array(updated_pattern)}})
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
-
-class FQTransposePullerTest(unittest.TestCase):
- def nodes(self, input_shape, transpose_shape, fq_shape, is_input_const):
- nodes = {
- **valued_const_with_data('il', np.array([[[[0]]]])),
- **valued_const_with_data('ih', np.array([[[[255]]]])),
- **valued_const_with_data('ol', np.array([[[[0]]]])),
- **valued_const_with_data('oh', np.array([[[[255]]]])),
- **regular_op_with_shaped_data('FQ', fq_shape, dict(type='FakeQuantize', op='FakeQuantize', infer=FakeQuantize.infer)),
- **valued_const_with_data('order', int64_array([0, 2, 3, 1])),
- **regular_op_with_shaped_data('transpose', transpose_shape, dict(type='Transpose', op='Transpose', infer=Transpose.infer)),
- **regular_op_with_shaped_data('relu', fq_shape, dict(type='Relu', op='Relu')),
-
- **result(),
- }
-
- if is_input_const:
- input_node = shaped_const_with_data('input', input_shape)
- else:
- input_node = regular_op_with_shaped_data('input', input_shape, dict(type='Parameter', op='Parameter'))
-
- nodes.update(input_node)
- return nodes
-
- def test_positive(self):
- nodes = self.nodes([1, 3, 224, 224], [1, 224, 224, 3], [1, 3, 224, 224], True)
- edges = [
- *connect('input', '0:FQ'),
- *connect('il', '1:FQ'),
- *connect('ih', '2:FQ'),
- *connect('ol', '3:FQ'),
- *connect('oh', '4:FQ'),
- *connect('FQ:0', '0:transpose'),
- *connect('order:0', '1:transpose'),
- *connect('transpose:0', 'output'),
- ]
- graph = build_graph(nodes_attrs=nodes, edges=edges, nodes_with_edges_only=True)
- PullTransposeThroughFQUp().find_and_replace_pattern(graph)
- graph.clean_up()
-
- nodes = self.nodes([1, 3, 224, 224], [1, 224, 224, 3], [1, 224, 224, 3], True)
- edges = [
- *connect('input', '0:transpose'),
- *connect('order:0', '1:transpose'),
- *connect('transpose', '0:FQ'),
- *connect('il', '1:FQ'),
- *connect('ih', '2:FQ'),
- *connect('ol', '3:FQ'),
- *connect('oh', '4:FQ'),
- *connect('FQ:0', 'output'),
- ]
- graph_ref = build_graph(nodes_attrs=nodes, edges=edges, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_negative_1(self):
- nodes = self.nodes([1, 3, 224, 224], [1, 224, 224, 3], [1, 3, 224, 224], True)
- edges = [
- *connect('input', '0:FQ'),
- *connect('il', '1:FQ'),
- *connect('ih', '2:FQ'),
- *connect('ol', '3:FQ'),
- *connect('oh', '4:FQ'),
- *connect('FQ:0', '0:transpose'),
- *connect_data('FQ:0', 'relu'),
- *connect('order:0', '1:transpose'),
- *connect('transpose:0', 'output'),
- ]
- graph = build_graph(nodes_attrs=nodes, edges=edges, nodes_with_edges_only=True)
- graph_ref = graph.copy()
- PullTransposeThroughFQUp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_negative_2(self):
- nodes = self.nodes([1, 3, 224, 224], [1, 224, 224, 3], [1, 3, 224, 224], False)
- edges = [
- *connect('input', '0:FQ'),
- *connect('il', '1:FQ'),
- *connect('ih', '2:FQ'),
- *connect('ol', '3:FQ'),
- *connect('oh', '4:FQ'),
- *connect('FQ:0', '0:transpose'),
- *connect('order:0', '1:transpose'),
- *connect('transpose:0', 'output'),
- ]
- graph = build_graph(nodes_attrs=nodes, edges=edges, nodes_with_edges_only=True)
- graph_ref = graph.copy()
- PullTransposeThroughFQUp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/MaxPoolTest.py b/tools/mo/unit_tests/mo/back/MaxPoolTest.py
deleted file mode 100644
index 47d3291690b58f..00000000000000
--- a/tools/mo/unit_tests/mo/back/MaxPoolTest.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.MaxPool import MaxPool
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class TestMaxPool(unittest.TestCase):
-
- def test_no_out_normalization(self):
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node'},
- 'input_data': {'kind': 'data'},
- 'pool': {'kind': 'op', 'name': 'node', 'type': 'Pooling', 'pool_method': 'max'},
- 'pool_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result', 'name': 'node'}
- },
- edges=[
- ('input', 'input_data'),
- ('input_data', 'pool'),
- ('pool', 'pool_data'),
- ('pool_data', 'result')
- ]
- )
-
- graph_ref = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node'},
- 'input_data': {'kind': 'data'},
- 'pool': {'kind': 'op', 'name': 'node', 'type': 'MaxPool'},
- 'pool_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result', 'name': 'node'},
- },
- edges=[
- ('input', 'input_data'),
- ('input_data', 'pool'),
- ('pool', 'pool_data'),
- ('pool_data', 'result'),
- ]
- )
-
- MaxPool().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_out_normalization(self):
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node'},
- 'input_data': {'kind': 'data'},
- 'pool': {'kind': 'op', 'name': 'node', 'type': 'Pooling', 'pool_method': 'max'},
- 'pool_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result', 'name': 'node'}
- },
- edges=[
- ('input', 'input_data'),
- ('input_data', 'pool'),
- ('pool', 'pool_data'),
- ('pool_data', 'result')
- ]
- )
-
- graph_ref = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node'},
- 'input_data': {'kind': 'data'},
- 'pool': {'kind': 'op', 'name': 'node', 'type': 'MaxPool'},
- 'pool_data': {'kind': 'data'},
- 'pool_data_added': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result', 'name': 'node'},
- 'result_added': {'kind': 'op', 'op': 'Result', 'name': 'node'}
- },
- edges=[
- ('input', 'input_data'),
- ('input_data', 'pool'),
- ('pool', 'pool_data'),
- ('pool_data', 'result'),
- ('pool', 'pool_data_added'),
- ('pool_data_added', 'result_added')
- ]
- )
-
- pool_op = Node(graph, 'pool')
- pool_op.add_output_port(1) # add disconnected output port to check normalization
-
- MaxPool().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/OptimizeTransposeReshapeSequence_test.py b/tools/mo/unit_tests/mo/back/OptimizeTransposeReshapeSequence_test.py
deleted file mode 100644
index 8dbe232db1292b..00000000000000
--- a/tools/mo/unit_tests/mo/back/OptimizeTransposeReshapeSequence_test.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.OptimizeTransposeReshapeSequence import match_shapes, split_input_permute_dimension, \
- split_dims_indices, split_output_permute_dimension
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-
-
-class SplitDimsIndicesTest(unittest.TestCase):
- def test_1(self):
- self.assertListEqual(list(split_dims_indices(int64_array([1, 32, 64, 60]), int64_array([1, 8, 4, 64, 3, 20]))), [1, 3])
-
- def test_2(self):
- self.assertListEqual(list(split_dims_indices(int64_array([8, 4, 64, 3, 20]), int64_array([1, 8, 4, 64, 3, 20, 1, 1]))), [0, 4, 4])
-
- def test_3(self):
- self.assertListEqual(list(split_dims_indices(int64_array([120]), int64_array([2, 3, 4, 1, 5]))), [0, 0, 0, 0])
-
- def test_4(self):
- self.assertListEqual(list(split_dims_indices(int64_array([120, 1]), int64_array([2, 3, 4, 5, 1]))), [0, 0, 0])
-
- def test_5(self):
- self.assertListEqual(list(split_dims_indices(int64_array([1, 4, 1, 1]), int64_array([1, 2, 1, 1, 2, 1, 1]))), [1, 1, 1])
-
- def test_6(self):
- self.assertListEqual(list(split_dims_indices(int64_array([1, 20, 64]), int64_array([1, 1, 20, 64]))), [1])
-
-
-class SplitOutputTransposeDimensionTest(unittest.TestCase):
- def test_1(self):
- self.assertListEqual(list(split_output_permute_dimension(3, int64_array([0, 2, 3, 1]))), [0, 3, 4, 1, 2])
-
- def test_2(self):
- self.assertListEqual(list(split_output_permute_dimension(0, int64_array([0, 1, 3, 2]))), [0, 1, 2, 4, 3])
-
- def test_3(self):
- self.assertListEqual(list(split_output_permute_dimension(1, int64_array([0, 3, 1, 2]))), [0, 3, 4, 1, 2])
-
-
-class SplitInputTransposeDimensionTest(unittest.TestCase):
- def test_1(self):
- self.assertListEqual(list(split_input_permute_dimension(1, int64_array([0, 2, 3, 1]))), [0, 3, 4, 1, 2])
-
- def test_2(self):
- self.assertListEqual(list(split_input_permute_dimension(0, int64_array([0, 1, 3, 2]))), [0, 1, 2, 4, 3])
-
- def test_3(self):
- self.assertListEqual(list(split_input_permute_dimension(3, int64_array([0, 3, 1, 2]))), [0, 3, 4, 1, 2])
-
- def test_4(self):
- self.assertListEqual(list(split_input_permute_dimension(0, int64_array([0, 1, 2, 3]))), [0, 1, 2, 3, 4])
-
- def test_5(self):
- self.assertListEqual(list(split_input_permute_dimension(3, int64_array([0, 1, 2, 3]))), [0, 1, 2, 3, 4])
-
-
-class MatchShapesTest(unittest.TestCase):
- def test_basic(self):
- self.assertListEqual(list(match_shapes(int64_array([1, 32, 64, 60]), int64_array([8, 4, 64, 3, 20]))), [1, 8, 4, 64, 3, 20])
-
- def test_ones_in_the_middle(self):
- self.assertListEqual(list(match_shapes(int64_array([32, 1, 2, 3, 1, 8]), int64_array([4, 2, 1, 4, 6, 1, 1, 8]))), [4, 2, 1, 4, 1, 2, 3, 1, 1, 8])
-
- def test_trailing_one(self):
- self.assertListEqual(list(match_shapes(int64_array([1, 32, 64, 60, 1]), int64_array([8, 4, 64, 3, 20]))), [1, 8, 4, 64, 3, 20, 1])
-
- def test_one_to_many(self):
- self.assertListEqual(list(match_shapes(int64_array([120]), int64_array([2, 3, 4, 5]))), [2, 3, 4, 5])
-
- def test_many_to_one(self):
- self.assertListEqual(list(match_shapes(int64_array([2, 3, 4, 5]), int64_array([120]))), [2, 3, 4, 5])
-
- def test_many_to_one_with_trailing(self):
- self.assertListEqual(list(match_shapes(int64_array([2, 3, 4, 5]), int64_array([120, 1, 1]))), [2, 3, 4, 5, 1, 1])
-
- def test_equal_shapes(self):
- self.assertListEqual(list(match_shapes(int64_array([2, 3, 4, 5]), int64_array([2, 3, 4, 5]))), [2, 3, 4, 5])
-
- def test_one(self):
- self.assertListEqual(list(match_shapes(int64_array([1]), int64_array([1]))), [1])
-
- def test_ones_equal_lengths(self):
- self.assertListEqual(list(match_shapes(int64_array([1, 1, 1]), int64_array([1, 1, 1]))), [1, 1, 1])
-
- def test_ones_different_lengths(self):
- self.assertListEqual(list(match_shapes(int64_array([1]), int64_array([1, 1, 1]))), [1, 1, 1])
-
- def test_intersection_of_input_output_dimensions(self): # is this test correct? Looks like yes...
- self.assertListEqual(list(match_shapes(int64_array([10, 20, 7]), int64_array([5, 4, 1, 70]))), [5, 2, 2, 1, 10, 7])
-
- def test_trailing_ones(self):
- self.assertListEqual(list(match_shapes(int64_array([1, 1, 10]), int64_array([1, 5, 1, 1, 2, 1]))), [1, 1, 5, 1, 1, 2, 1])
-
- def test_not_matchabale_shapes(self):
- self.assertIsNone(match_shapes(int64_array([5, 7]), int64_array([7, 5])))
diff --git a/tools/mo/unit_tests/mo/back/ReduceTransposeDimensions_test.py b/tools/mo/unit_tests/mo/back/ReduceTransposeDimensions_test.py
deleted file mode 100644
index d82eb539784048..00000000000000
--- a/tools/mo/unit_tests/mo/back/ReduceTransposeDimensions_test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.ReduceTransposeDimensions import sequential_dims, merge_permute_order_dimensions, merge_dims
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-
-
-class SequentialDimsTest(unittest.TestCase):
- def test_returns_first_instance(self):
- self.assertListEqual(sequential_dims(int64_array([0, 3, 4, 1, 2])), [1, 2])
-
- def test_returns_last_indices(self):
- self.assertListEqual(sequential_dims(int64_array([4, 0, 3, 1, 2])), [3, 4])
-
- def test_returns_full_list(self):
- self.assertListEqual(sequential_dims(int64_array([0, 1, 2, 3, 4])), [0, 1, 2, 3, 4])
-
- def test_returns_from_the_beginning(self):
- self.assertListEqual(sequential_dims(int64_array([1, 2, 3, 0, 4])), [0, 1, 2])
-
- def test_no_sequential_dims(self):
- self.assertIsNone(sequential_dims(int64_array([2, 1, 3, 0, 4])))
-
- def test_2d_input_with_sequential_dims(self):
- self.assertListEqual(sequential_dims(int64_array([0, 1])), [0, 1])
-
- def test_2d_input_without_sequential_dims(self):
- self.assertIsNone(sequential_dims(int64_array([1, 0])))
-
-
-class MergeTransposeOrderDimensionsTest(unittest.TestCase):
- def test_merge_last_dims(self):
- self.assertListEqual(list(merge_permute_order_dimensions([1, 2], int64_array([0, 3, 4, 1, 2]))), [0, 3, 1, 2])
-
- def test_merge_last_indices(self):
- self.assertListEqual(list(merge_permute_order_dimensions([3, 4], int64_array([0, 3, 4, 1, 2]))), [0, 2, 3, 1])
-
- def test_merge_start_indices(self):
- self.assertListEqual(list(merge_permute_order_dimensions([0, 1], int64_array([1, 2, 4, 3, 0]))), [1, 3, 2, 0])
-
- def test_merge_all_dims(self):
- self.assertListEqual(list(merge_permute_order_dimensions([0, 1, 2], int64_array([0, 1, 2]))), [0])
-
- def test_merge_3_dims(self):
- self.assertListEqual(list(merge_permute_order_dimensions([1, 2, 3], int64_array([3, 0, 1, 2, 4]))), [1, 0, 2])
-
-
-class MergeDimsTest(unittest.TestCase):
- def test_merge_middle_dims(self):
- self.assertListEqual(list(merge_dims([1, 2], int64_array([3, 2, 5, 7]))), [3, 10, 7])
-
- def test_merge_first_dim(self):
- self.assertListEqual(list(merge_dims([0, 1], int64_array([3, 2, 5, 7]))), [6, 5, 7])
-
- def test_merge_last_dim(self):
- self.assertListEqual(list(merge_dims([2, 3], int64_array([3, 2, 5, 7]))), [3, 2, 35])
-
- def test_merge_all_dims(self):
- self.assertListEqual(list(merge_dims([0, 1, 2, 3], int64_array([3, 2, 5, 7]))), [210])
-
- def test_reduce_with_minus_one(self):
- self.assertListEqual(list(merge_dims([1, 2], int64_array([3, -1, 5, 7]))), [3, -1, 7])
-
- def test_merge_with_0_being_merged(self):
- with self.assertRaisesRegex(AssertionError, ".*The value 0 is not supported.*"):
- merge_dims([1, 2], int64_array([3, 0, 5, 7]))
-
- def test_merge_with_0_not_merged(self):
- with self.assertRaisesRegex(AssertionError, ".*The value 0 is not supported.*"):
- merge_dims([2, 3], int64_array([3, 0, 5, 7]))
diff --git a/tools/mo/unit_tests/mo/back/ResultRename_test.py b/tools/mo/unit_tests/mo/back/ResultRename_test.py
deleted file mode 100644
index 6b8a6c5ddee481..00000000000000
--- a/tools/mo/unit_tests/mo/back/ResultRename_test.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.ResultRename import ResultRename
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result
-
-nodes = {
- 'Op1': {'type': 'Op1', 'kind': 'op', 'op': 'Op1'},
- 'Op2': {'type': 'Op2', 'kind': 'op', 'op': 'Op2'},
- 'Op1_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op1', 'Op1_tensor')]},
- 'Op2_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op2', 'Op2_tensor')]},
- **result('result1'),
- **result('result2'),
-}
-
-
-class ResultRenameTest(unittest.TestCase):
- def test_case1(self):
- graph = build_graph(nodes, [('Op1', 'Op1_data'), ('Op1_data', 'result1')])
- ResultRename().find_and_replace_pattern(graph)
- res_node = Node(graph, 'result1')
- self.assertTrue(res_node['name'] == 'Op1_tensor')
-
- def test_case2(self):
- graph = build_graph(nodes, [])
- graph_ref = build_graph(nodes, [])
-
- ResultRename().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'result1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_case3(self):
- graph = build_graph(nodes, [('Op1', 'Op1_data'), ('Op1_data', 'result1')])
- res_node_graph = Node(graph, 'Op1')
- res_node_graph['name'] = 'Op1_tensor'
- ResultRename().find_and_replace_pattern(graph)
- res_node = Node(graph, 'result1')
- self.assertTrue(res_node['name'] == 'Op1_tensor/sink_port_0')
-
- def test_case4(self):
- graph = build_graph(nodes, [('Op1', 'Op1_data'), ('Op1_data', 'result1'),
- ('Op1_data', 'Op2'), ('Op2', 'Op2_data'),
- ('Op2_data', 'result2')])
- graph.outputs_order = ['result1', 'result2']
-
- ResultRename().find_and_replace_pattern(graph)
- res1_node = Node(graph, 'result1')
- res2_node = Node(graph, 'result2')
- self.assertTrue(res1_node['name'] == 'Op1_tensor')
- self.assertTrue(res2_node['name'] == 'Op2_tensor')
-
- self.assertTrue(graph.outputs_order == ['Op1_tensor', 'Op2_tensor'])
-
- def test_case5(self):
- graph = build_graph(nodes, [('Op1', 'Op1_data'), ('Op1_data', 'result1'),
- ('Op1_data', 'Op2'), ('Op2', 'Op2_data'),
- ('Op2_data', 'result2')])
-
- res_node_graph = Node(graph, 'result1')
- res_node_graph['name'] = 'Op1_tensor'
- ResultRename().find_and_replace_pattern(graph)
- res1_node = Node(graph, 'result1')
- res2_node = Node(graph, 'result2')
- self.assertTrue(res1_node['name'] == 'Op1_tensor')
- self.assertTrue(res2_node['name'] == 'Op2_tensor')
-
- def test_case6(self):
- _nodes = nodes.copy()
- _nodes.update({
- 'Op3': {'type': 'Op3', 'kind': 'op', 'op': 'Op3'},
- 'Op4': {'type': 'Op4', 'kind': 'op', 'op': 'Op4'},
- 'Op3_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op3', 'Op3_tensor')]},
- 'Op4_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op4', 'Op4_tensor')]},
- **result('result3'),
- **result('result4'),
- })
- graph = build_graph(_nodes, [('Op1', 'Op1_data'), ('Op1_data', 'result1'), ('Op1_data', 'Op2'),
- ('Op2', 'Op2_data'), ('Op2_data', 'result2'), ('Op2_data', 'Op3'),
- ('Op3', 'Op3_data'), ('Op3_data', 'result3'), ('Op3_data', 'Op4'),
- ('Op4', 'Op4_data'), ('Op4_data', 'result4')])
- graph.outputs_order = ['result1', 'result3', 'result4', 'result2']
-
- ResultRename().find_and_replace_pattern(graph)
- self.assertTrue(Node(graph, 'result1')['name'] == 'Op1_tensor')
- self.assertTrue(Node(graph, 'result2')['name'] == 'Op2_tensor')
- self.assertTrue(Node(graph, 'result3')['name'] == 'Op3_tensor')
- self.assertTrue(Node(graph, 'result4')['name'] == 'Op4_tensor')
-
- self.assertTrue(graph.outputs_order == ['Op1_tensor', 'Op3_tensor', 'Op4_tensor', 'Op2_tensor'])
diff --git a/tools/mo/unit_tests/mo/back/ReverseInputChannels_test.py b/tools/mo/unit_tests/mo/back/ReverseInputChannels_test.py
deleted file mode 100644
index 1ea0eaf1cc8b9f..00000000000000
--- a/tools/mo/unit_tests/mo/back/ReverseInputChannels_test.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from argparse import Namespace
-
-import numpy as np
-
-from openvino.tools.mo.back.ReverseInputChannels import ReverseChannelsPropagationUp, ReverseChannelsPropagationDown
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from openvino.tools.mo.utils.runtime_info import OldAPIMapOrder, RTInfo
-from unit_tests.utils.graph import build_graph, result, connect, regular_op_with_shaped_data, valued_const_with_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder1', [1, 3, 10, 10], {'type': 'Parameter', 'rt_info': RTInfo()}),
- **regular_op_with_shaped_data('placeholder2', [1, 1, 1, 1], {'type': 'Parameter'}),
-
- **regular_op_with_shaped_data('mul', [1, 3, 10, 10], {'type': 'Multiply'}),
- **regular_op_with_shaped_data('reverse_channels', [1, 3, 10, 10],
- {'type': 'ReverseChannels', 'axis': int64_array(1)}),
-
- **regular_op_with_shaped_data('pad', [1, 3, 10, 10], {'type': 'Pad'}),
-
- **result('result'),
-}
-
-nodes2 = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 10, 10], {'type': 'Parameter'}),
-
- **valued_const_with_data('mul_const', float32_array([-127.5, -127.5, -127.5])),
- **regular_op_with_shaped_data('mul', [1, 3, 10, 10], {'type': 'Multiply'}),
- **valued_const_with_data('pad_const_1', int64_array([0, 0, 0, 0])),
- **valued_const_with_data('pad_const_2', int64_array([0, 0, 1, 1])),
- **regular_op_with_shaped_data('pad', [1, 3, 10, 10], {'type': 'Pad'}),
- **regular_op_with_shaped_data('reverse_channels', [1, 3, 10, 10],
- {'type': 'ReverseChannels', 'axis': int64_array(1)}),
- **result('result'),
- **result('result2'),
-}
-
-nodes3 = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 10, 10], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('transpose', [1, 3, 10, 10], {'type': 'Transpose'}),
- **valued_const_with_data('transpose_order', int64_array([0, 3, 1, 2])),
- **regular_op_with_shaped_data('reverse_channels_up', [1, 3, 10, 10],
- {'type': 'ReverseChannels', 'axis': int64_array(3)}),
- **regular_op_with_shaped_data('reverse_channels_down', [1, 3, 10, 10],
- {'type': 'ReverseChannels', 'axis': int64_array(1)}),
- **result('result'),
- **result('result2'),
-}
-
-
-def get_nodes(shape, axis=1):
- return {
- **regular_op_with_shaped_data('placeholder1', shape,
- {'type': 'Parameter', 'shape': shape, 'rt_info': RTInfo()}),
- **regular_op_with_shaped_data('placeholder2', [1, 1, 1, 1], {'type': 'Parameter', 'shape': [1, 1, 1, 1]}),
-
- **regular_op_with_shaped_data('mul', shape, {'type': 'Multiply'}),
- **regular_op_with_shaped_data('reverse_channels', shape,
- {'op': 'ReverseChannels', 'type': None, 'axis': int64_array(axis)}),
-
- **regular_op_with_shaped_data('pad', shape, {'type': 'Pad'}),
-
- **result('result'),
- }
-
-
-class ReverseInputChannelsTest(unittest.TestCase):
- def check_graph_attrs(self, graph: Graph, parameter_node_names: list):
- for node in graph.get_op_nodes():
- if node.soft_get('name') in parameter_node_names:
- self.assertTrue(node.soft_get('type') == 'Parameter')
- out_node = node.out_node(0)
- self.assertTrue(out_node['fw_tensor_debug_info'] == ['fw_name', 0])
- else:
- for idx in node.out_nodes():
- out_node = node.out_node(idx)
- self.assertFalse('fw_tensor_debug_info' in out_node)
-
- def set_graph_attrs(self, graph: Graph, parameter_node_names: list):
- for node in graph.get_op_nodes():
- if node.soft_get('name') in parameter_node_names:
- self.assertTrue(node.soft_get('type') == 'Parameter')
- out_node = node.out_node(0)
- out_node['fw_tensor_debug_info'] = ['fw_name', 0]
-
- def test_lift_up_through_eltwise(self):
- graph = build_graph(nodes, [*connect('placeholder1', '0:mul'), *connect('placeholder2', '1:mul'),
- *connect('mul', 'reverse_channels'), *connect('reverse_channels', 'result')])
- self.set_graph_attrs(graph, ['placeholder1', 'placeholder2'])
-
- node = Node(graph, 'mul')
- reverse_channels = Node(graph, 'reverse_channels')
-
- ReverseChannelsPropagationUp.lift_up_through_eltwise(node, reverse_channels)
- self.check_graph_attrs(graph, ['placeholder1', 'placeholder2'])
-
- def test_lift_up_through_eltwise_broadcast(self):
- graph = build_graph(nodes, [*connect('placeholder1', '0:mul'), *connect('placeholder2', '1:mul'),
- *connect('mul', 'reverse_channels'), *connect('reverse_channels', 'result')])
- self.set_graph_attrs(graph, ['placeholder1', 'placeholder2'])
- placeholder_node = Node(graph, 'placeholder2')
- placeholder_node.out_port(0).data.set_shape([])
-
- node = Node(graph, 'mul')
- reverse_channels = Node(graph, 'reverse_channels')
-
- ReverseChannelsPropagationUp.lift_up_through_eltwise(node, reverse_channels)
- self.check_graph_attrs(graph, ['placeholder1', 'placeholder2'])
-
- def test_lift_up_through_pad(self):
- graph = build_graph(nodes2, [*connect('placeholder', '0:mul'), *connect('mul_const', '1:mul'),
- *connect('mul', '0:pad'), *connect('pad_const_1', '1:pad'),
- *connect('pad_const_2', '2:pad'), *connect('pad', 'reverse_channels'),
- *connect('reverse_channels', 'result')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'pad')
- reverse_channels = Node(graph, 'reverse_channels')
-
- keep_moving_up, new_reverses = ReverseChannelsPropagationUp.lift_up_through_zero_port_only(node,
- reverse_channels)
- self.assertTrue(keep_moving_up is True)
- self.assertTrue(len(new_reverses) == 1)
- self.check_graph_attrs(graph, ['placeholder'])
-
- def test_lift_up_through_pad2(self):
- graph = build_graph(nodes2, [*connect('placeholder', '0:mul'), *connect('mul_const', '1:mul'),
- *connect('mul', '0:pad'), *connect('pad_const_1', '1:pad'),
- *connect('pad_const_2', '2:pad'), *connect('pad', 'reverse_channels'),
- *connect('reverse_channels:0', '0:result'),
- *connect('reverse_channels:0', '0:result2')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'pad')
- reverse_channels = Node(graph, 'reverse_channels')
-
- keep_moving_up, new_reverses = ReverseChannelsPropagationUp.lift_up_through_zero_port_only(node,
- reverse_channels)
- self.assertTrue(keep_moving_up is True)
- self.assertTrue(len(new_reverses) == 1)
- self.check_graph_attrs(graph, ['placeholder'])
-
- def test_pass_rc_through(self):
- graph = build_graph(nodes2, [*connect('placeholder', '0:mul'), *connect('mul_const', '1:mul'),
- *connect('mul', 'reverse_channels'), *connect('reverse_channels', '0:pad'),
- *connect('pad_const_1', '1:pad'), *connect('pad_const_2', '2:pad'),
- *connect('pad', 'result')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'pad')
- reverse_channels = Node(graph, 'reverse_channels')
-
- ReverseChannelsPropagationDown.pass_rc_through_zero_port_only(node, reverse_channels)
- self.check_graph_attrs(graph, ['placeholder'])
-
- def test_lift_up_through_transpose(self):
- graph = build_graph(nodes3, [*connect('placeholder', '0:transpose'), *connect('transpose_order', '1:transpose'),
- *connect('transpose', 'reverse_channels_down'),
- *connect('reverse_channels_down', 'result')])
- graph_ref = build_graph(nodes3, [*connect('placeholder', 'reverse_channels_down'),
- *connect('transpose_order', '1:transpose'),
- *connect('reverse_channels_down', 'transpose'),
- *connect('transpose', 'result')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'transpose')
- reverse_channels = Node(graph, 'reverse_channels_down')
-
- keep_moving_up, new_reverses = ReverseChannelsPropagationUp.lift_up_through_transpose(node, reverse_channels)
- self.assertTrue(keep_moving_up is True)
- self.assertTrue(len(new_reverses) == 1)
- self.check_graph_attrs(graph, ['placeholder'])
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- reverse_channels = Node(graph, 'reverse_channels_down')
- self.assertTrue(reverse_channels.axis == 3)
- self.assertTrue(type(reverse_channels.axis) == np.ndarray)
-
- def test_lift_down_through_transpose(self):
- graph = build_graph(nodes3, [*connect('placeholder', 'reverse_channels_up'),
- *connect('transpose_order', '1:transpose'),
- *connect('reverse_channels_up', '0:transpose'),
- *connect('transpose', 'result')])
- graph_ref = build_graph(nodes3, [*connect('placeholder', '0:transpose'),
- *connect('transpose_order', '1:transpose'),
- *connect('transpose', 'reverse_channels_up'),
- *connect('reverse_channels_up', '0:result')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'transpose')
- reverse_channels = Node(graph, 'reverse_channels_up')
-
- keep_moving_down = ReverseChannelsPropagationDown.pass_rc_through_transpose(node, reverse_channels)
-
- self.assertTrue(keep_moving_down is True)
- self.check_graph_attrs(graph, ['placeholder'])
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- reverse_channels = Node(graph, 'reverse_channels_down')
- self.assertTrue(reverse_channels.axis == 1)
- self.assertTrue(type(reverse_channels.axis) == np.ndarray)
-
- def test_lift_up_through_transpose_negative_axis(self):
- graph = build_graph(nodes3, [*connect('placeholder', '0:transpose'), *connect('transpose_order', '1:transpose'),
- *connect('transpose', 'reverse_channels_down'),
- *connect('reverse_channels_down', 'result')])
- graph_ref = build_graph(nodes3, [*connect('placeholder', 'reverse_channels_down'),
- *connect('transpose_order', '1:transpose'),
- *connect('reverse_channels_down', 'transpose'),
- *connect('transpose', 'result')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'transpose')
- reverse_channels = Node(graph, 'reverse_channels_down')
- reverse_channels.axis = int64_array(-3)
-
- keep_moving_up, new_reverses = ReverseChannelsPropagationUp.lift_up_through_transpose(node, reverse_channels)
- self.assertTrue(keep_moving_up is True)
- self.assertTrue(len(new_reverses) == 1)
- self.check_graph_attrs(graph, ['placeholder'])
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- reverse_channels = Node(graph, 'reverse_channels_down')
- self.assertTrue(reverse_channels.axis == 3)
- self.assertTrue(type(reverse_channels.axis) == np.ndarray)
-
- def test_lift_down_through_transpose_negative_axis(self):
- graph = build_graph(nodes3, [*connect('placeholder', 'reverse_channels_up'),
- *connect('transpose_order', '1:transpose'),
- *connect('reverse_channels_up', '0:transpose'),
- *connect('transpose', 'result')])
- graph_ref = build_graph(nodes3, [*connect('placeholder', '0:transpose'),
- *connect('transpose_order', '1:transpose'),
- *connect('transpose', 'reverse_channels_up'),
- *connect('reverse_channels_up', '0:result')])
- self.set_graph_attrs(graph, ['placeholder'])
-
- node = Node(graph, 'transpose')
- reverse_channels = Node(graph, 'reverse_channels_up')
- reverse_channels.axis = int64_array(-1)
-
- keep_moving_down = ReverseChannelsPropagationDown.pass_rc_through_transpose(node, reverse_channels)
-
- self.assertTrue(keep_moving_down is True)
- self.check_graph_attrs(graph, ['placeholder'])
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- reverse_channels = Node(graph, 'reverse_channels_down')
- self.assertTrue(reverse_channels.axis == 1)
- self.assertTrue(type(reverse_channels.axis) == np.ndarray)
diff --git a/tools/mo/unit_tests/mo/back/ShapeOfConstFolding_test.py b/tools/mo/unit_tests/mo/back/ShapeOfConstFolding_test.py
deleted file mode 100644
index 41313c40422dae..00000000000000
--- a/tools/mo/unit_tests/mo/back/ShapeOfConstFolding_test.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.ShapeOfConstFolding import ShapeOfConstFolding
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-const_value = np.random.rand(1, 3, 30, 30)
-nodes_attributes = {'input': {'shape': int64_array([1, 3, 30, 30]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_data': {'value': None, 'shape': int64_array([1, 3, 30, 30]), 'kind': 'data'},
- 'const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': const_value},
- 'const_data': {'kind': 'data', 'value': const_value},
- 'shapeof_input': {'kind': 'op', 'op': 'ShapeOf', 'value': int64_array([1, 3, 30, 30])},
- 'shapeof_input_data': {'value': None, 'shape': None, 'kind': 'data',
- 'value': int64_array([1, 3, 30, 30])},
-
- 'shapeof_const': {'kind': 'op', 'op': 'ShapeOf', 'value': int64_array([1, 3, 30, 30])},
- 'shapeof_const_data': {'value': None, 'shape': None, 'kind': 'data',
- 'value': int64_array([1, 3, 30, 30])},
-
- 'mul': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_data': {'kind': 'data', 'value': np.array([1, 9, 900, 900])},
- 'last': {'kind': 'op', 'op': 'Result'},
-
- # new nodes
- 'new_const_shapeof': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': int64_array([1, 3, 30, 30])}
- }
-
-const_value2 = np.random.rand(30, 30)
-nodes_attributes2 = {'input': {'shape': int64_array([1, 3, 30, 30]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_data': {'value': None, 'shape': int64_array([1, 3, 30, 30]), 'kind': 'data'},
-
- 'const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': const_value2},
- 'const_data': {'kind': 'data', 'value': const_value2},
-
- 'shapeof_const': {'kind': 'op', 'op': 'ShapeOf', 'value': int64_array([2700, 30])},
- 'shapeof_const_data': {'value': int64_array([2700, 30]), 'shape': None, 'kind': 'data'},
-
- 'gather': {'kind': 'op', 'op': 'Gather', 'batch_dims': 0},
- 'gather_data': {'kind': 'data'},
-
- 'const_concat': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': [1]},
- 'const_concat_data': {'kind': 'data', 'value': [1]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data'},
-
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'reshape_data': {'kind': 'data'},
-
- 'matmul': {'kind': 'op', 'op': 'MatMul'},
- 'matmul_data': {'kind': 'data'},
- 'last': {'kind': 'op', 'op': 'Result'},
-
- # new nodes
- 'new_const_shapeof': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': int64_array([2700, 30])},
- }
-
-
-class ShapeOfConstFoldingTests(unittest.TestCase):
- def test_const_with_one_output(self):
- graph = build_graph(nodes_attributes,
- [('input', 'input_data'),
- ('input_data', 'shapeof_input'),
- ('shapeof_input', 'shapeof_input_data'),
- ('shapeof_input_data', 'mul'),
- ('const', 'const_data'),
- ('const_data', 'shapeof_const'),
- ('shapeof_const', 'shapeof_const_data'),
- ('shapeof_const_data', 'mul'),
- ('mul', 'mul_data'),
- ('mul_data', 'last')],
- {
- 'input': {'shape': int64_array([1, 3, 30, 30])},
- 'input_data': {'shape': int64_array([1, 3, 30, 30])},
- 'shapeof_input': {'value': int64_array([1, 3, 30, 30])},
- 'shapeof_input_data': {'value': int64_array([1, 3, 30, 30])},
- 'const': {'value': const_value},
- 'const_data': {'value': const_value},
- 'shapeof_const': {'value': int64_array([1, 3, 30, 30])},
- 'shapeof_const_data': {'value': int64_array([1, 3, 30, 30])},
- 'mul_data': {'value': int64_array([1, 9, 900, 900])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('input', 'input_data'),
- ('input_data', 'shapeof_input'),
- ('shapeof_input', 'shapeof_input_data'),
- ('shapeof_input_data', 'mul'),
- ('new_const_shapeof', 'shapeof_const_data'),
- ('shapeof_const_data', 'mul'),
- ('mul', 'mul_data'),
- ('mul_data', 'last')],
- {
- 'input': {'shape': int64_array([1, 3, 30, 30])},
- 'input_data': {'shape': int64_array([1, 3, 30, 30])},
- 'shapeof_input': {'value': int64_array([1, 3, 30, 30])},
- 'shapeof_input_data': {'value': int64_array([1, 3, 30, 30])},
- 'new_const_shapeof': {'value': int64_array([1, 3, 30, 30])},
- 'shapeof_const_data': {'value': int64_array([1, 3, 30, 30])},
- 'mul_data': {'value': int64_array([1, 9, 900, 900])},
- },
- nodes_with_edges_only=True)
- ShapeOfConstFolding().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- def test_const_with_two_outputs(self):
- graph = build_graph(nodes_attributes2,
- [('input', 'input_data'),
- ('input_data', 'reshape'),
- ('const', 'const_data'),
- ('const_data', 'shapeof_const'),
- ('shapeof_const', 'shapeof_const_data'),
- ('shapeof_const_data', 'gather'),
- ('gather', 'gather_data'),
- ('const_concat', 'const_concat_data'),
- ('const_concat_data', 'concat'),
- ('gather_data', 'concat'),
- ('concat', 'reshape'),
- ('reshape', 'reshape_data'),
- ('reshape_data', 'matmul'),
- ('const_data', 'matmul'),
- ('matmul', 'matmul_data'),
- ('matmul_data', 'last')
- ],
- {
- 'input': {'shape': int64_array([1, 3, 30, 30])},
- 'input_data': {'shape': int64_array([1, 3, 30, 30])},
- 'shapeof_const': {'value': int64_array([2700, 30])},
- 'shapeof_const_data': {'value': int64_array([2700, 30])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes2,
- [('input', 'input_data'),
- ('input_data', 'reshape'),
- ('new_const_shapeof', 'shapeof_const_data'),
- ('shapeof_const_data', 'gather'),
- ('gather', 'gather_data'),
- ('const_concat', 'const_concat_data'),
- ('const_concat_data', 'concat'),
- ('gather_data', 'concat'),
- ('concat', 'reshape'),
- ('reshape', 'reshape_data'),
- ('reshape_data', 'matmul'),
- ('const', 'const_data'),
- ('const_data', 'matmul'),
- ('matmul', 'matmul_data'),
- ('matmul_data', 'last')],
- {
- 'input': {'shape': int64_array([1, 3, 30, 30])},
- 'input_data': {'shape': int64_array([1, 3, 30, 30])},
- 'new_const_shapeof': {'value': int64_array([2700, 30])},
- 'shapeof_const_data': {'value': int64_array([2700, 30])},
- },
- nodes_with_edges_only=True)
- ShapeOfConstFolding().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/ShuffleChannelPatternOptimization_test.py b/tools/mo/unit_tests/mo/back/ShuffleChannelPatternOptimization_test.py
deleted file mode 100644
index 546080c0af083b..00000000000000
--- a/tools/mo/unit_tests/mo/back/ShuffleChannelPatternOptimization_test.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from argparse import Namespace
-import pytest
-
-from openvino.tools.mo.back.ShuffleChannelPatternOptimization import ShuffleChannelFusion, DepthToSpaceFusion
-from openvino.tools.mo.ops.depth_to_space import DepthToSpaceOp
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.ops.shufflechannel import ShuffleChannels
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.ops.reshape import Reshape
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, \
- valued_const_with_data, connect, regular_op_with_empty_data
-
-
-class TestShuffleChannelFusionTest():
- @staticmethod
- def get_graphs(input_shape, reshape_0_pattern, order, reshape_1_pattern, group):
- nodes = {
- **regular_op_with_shaped_data('input', input_shape, {'type': 'Parameter', 'shape': int64_array(input_shape),
- 'infer': Parameter.infer}),
-
- **valued_const_with_data('reshape_0_pattern', int64_array(reshape_0_pattern)),
- **regular_op_with_empty_data('reshape_0', {'type': 'Reshape', 'infer': Reshape.infer}),
-
- **valued_const_with_data('order', int64_array(order)),
- **regular_op_with_empty_data('transpose', {'type': 'Transpose', 'infer': Transpose.infer}),
-
- **valued_const_with_data('reshape_1_pattern', int64_array(reshape_1_pattern)),
- **regular_op_with_empty_data('reshape_1', {'type': 'Reshape', 'infer': Reshape.infer,
- 'name': 'final_reshape'}),
-
- **result(),
- }
- edges = [
- *connect('input', '0:reshape_0'),
- *connect('reshape_0_pattern', '1:reshape_0'),
- *connect('reshape_0', '0:transpose'),
- *connect('order', '1:transpose'),
- *connect('transpose', '0:reshape_1'),
- *connect('reshape_1_pattern', '1:reshape_1'),
- *connect('reshape_1', 'output'),
- ]
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- for node in graph.get_op_nodes():
- node['op'] = node['type']
- graph.clean_up()
-
- ref_nodes = {
- **regular_op_with_shaped_data('input', input_shape, {'type': 'Parameter', 'shape': int64_array(input_shape),
- 'infer': Parameter.infer}),
- **regular_op_with_empty_data('shuffle_channel', {'type': 'ShuffleChannels', 'infer': ShuffleChannels.infer,
- 'name': 'final_reshape', 'group': group}),
- **result()
- }
- ref_edges = [*connect('input', 'shuffle_channel'), *connect('shuffle_channel', 'output')]
- graph_ref = build_graph(ref_nodes, ref_edges, nodes_with_edges_only=True)
- for node in graph_ref.get_op_nodes():
- node['op'] = node['type']
- graph_ref.clean_up()
-
- return graph, graph_ref
-
- @pytest.mark.parametrize("input_shape, reshape_0_pattern, order, reshape_1_pattern, group",[
- ([1, 512, 7, 6], [1, 2, 256, 7, 6], [0, 2, 1, 3, 4], [1, 512, 7, 6], 2),
- ([2, 512, 7, 6], [2, 2, 256, 7, 6], [0, 2, 1, 3, 4], [2, 512, 7, 6], 2),
- ([1, 200, 200, 200], [1, 50, 4, 200, 200], [0, 2, 1, 3, 4], [1, 200, 200, 200], 50),
- ])
- def test_fusion(self, input_shape, reshape_0_pattern, order, reshape_1_pattern, group):
- graph, graph_ref = self.get_graphs(input_shape, reshape_0_pattern, order, reshape_1_pattern, group)
- ShuffleChannelFusion().find_and_replace_pattern(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'output')
- assert flag, resp
- assert len(graph.get_op_nodes(name='final_reshape')) == 1 and \
- graph.get_op_nodes(name='final_reshape')[0].op == 'ShuffleChannels'
-
- @pytest.mark.parametrize("input_shape, reshape_0_pattern, order, reshape_1_pattern, group",[
- ([1, 512, 7, 6], [0, 2, 256, 7, 6], [0, 2, 1, 3, 4], [1, 512, 7, 6], 2),
- ([1, 512, 7, 6], [1, 2, 256, 7, 6], [0, 2, 1, 4, 3], [1, 512, 7, 6], 2),
- ([1, 512, 7, 6], [1, 2, 256, 7, 6], [0, 2, 1, 3, 4], [-1, 512, 7, 6], 2),
- ])
- def test_negative(self, input_shape, reshape_0_pattern, order, reshape_1_pattern, group):
- graph, _ = self.get_graphs(input_shape, reshape_0_pattern, order, reshape_1_pattern, group)
- graph_ref = graph.copy()
- ShuffleChannelFusion().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output')
- assert flag, resp
-
-
-class TestDepthToSpaceFusionTest():
- @staticmethod
- def get_graphs(input_shape, reshape_0_pattern, order, reshape_1_pattern, block_size):
- nodes = {
- **regular_op_with_shaped_data('input', input_shape, {'type': 'Parameter', 'shape': int64_array(input_shape),
- 'infer': Parameter.infer}),
-
- **valued_const_with_data('reshape_0_pattern', int64_array(reshape_0_pattern)),
- **regular_op_with_empty_data('reshape_0', {'type': 'Reshape', 'infer': Reshape.infer}),
-
- **valued_const_with_data('order', int64_array(order)),
- **regular_op_with_empty_data('transpose', {'type': 'Transpose', 'infer': Transpose.infer}),
-
- **valued_const_with_data('reshape_1_pattern', int64_array(reshape_1_pattern)),
- **regular_op_with_empty_data('reshape_1', {'type': 'Reshape', 'infer': Reshape.infer,
- 'name': 'final_reshape'}),
-
- **result(),
- }
- edges = [
- *connect('input', '0:reshape_0'),
- *connect('reshape_0_pattern', '1:reshape_0'),
- *connect('reshape_0', '0:transpose'),
- *connect('order', '1:transpose'),
- *connect('transpose', '0:reshape_1'),
- *connect('reshape_1_pattern', '1:reshape_1'),
- *connect('reshape_1', 'output'),
- ]
- graph = build_graph(nodes, edges, nodes_with_edges_only=True, cli=Namespace())
- for node in graph.get_op_nodes():
- node['op'] = node['type']
- graph.clean_up()
-
- ref_nodes = {
- **regular_op_with_shaped_data('input', input_shape, {'type': 'Parameter', 'shape': int64_array(input_shape),
- 'infer': Parameter.infer}),
- **regular_op_with_empty_data('depth_to_space', {'type': 'DepthToSpace', 'infer': DepthToSpaceOp.infer,
- 'name': 'final_reshape', 'block_size': block_size}),
- **result()
- }
- ref_edges = [*connect('input', 'depth_to_space'), *connect('depth_to_space', 'output')]
- graph_ref = build_graph(ref_nodes, ref_edges, nodes_with_edges_only=True)
- for node in graph_ref.get_op_nodes():
- node['op'] = node['type']
- graph_ref.clean_up()
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- return graph, graph_ref
-
- @pytest.mark.parametrize("input_shape, reshape_0_pattern, order, reshape_1_pattern, block_size",[
- ([1, 512, 7, 6], [1, 2, 2, 128, 7, 6], [0, 1, 4, 2, 5, 3], [1, 128, 14, 12], 2),
- ([2, 512, 7, 6], [2, 2, 2, 128, 7, 6], [0, 1, 4, 2, 5, 3], [2, 128, 14, 12], 2),
- ([1, 200, 200, 200], [1, 2, 2, 50, 200, 200], [0, 1, 4, 2, 5, 3], [1, 50, 400, 400], 2),
- ])
- def test_fusion(self, input_shape, reshape_0_pattern, order, reshape_1_pattern, block_size):
- graph, graph_ref = self.get_graphs(input_shape, reshape_0_pattern, order, reshape_1_pattern, block_size)
- DepthToSpaceFusion().find_and_replace_pattern(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'output')
- assert flag, resp
- assert len(graph.get_op_nodes(name='final_reshape')) == 1 and \
- graph.get_op_nodes(name='final_reshape')[0].op == 'DepthToSpace'
-
- @pytest.mark.parametrize("input_shape, reshape_0_pattern, order, reshape_1_pattern, group",[
- ([1, 512, 7, 6], [0, 2, 2, 128, 7, 6], [0, 1, 4, 2, 5, 3], [1, 128, 14, 12], 2),
- ([2, 512, 7, 6], [2, 2, 2, 128, 7, 6], [0, 1, 4, 2, 5, 3], [-1, 128, 14, 12], 2),
- ([1, 200, 200, 200], [1, 2, 2, 50, 200, 200], [0, 1, 4, 2, 3, 5], [1, 50, 400, 400], 2),
- ])
- def test_negative(self, input_shape, reshape_0_pattern, order, reshape_1_pattern, group):
- graph, _ = self.get_graphs(input_shape, reshape_0_pattern, order, reshape_1_pattern, group)
- graph_ref = graph.copy()
- DepthToSpaceFusion().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output')
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/back/SpecialNodesFinalization_test.py b/tools/mo/unit_tests/mo/back/SpecialNodesFinalization_test.py
deleted file mode 100644
index a288c411bacf21..00000000000000
--- a/tools/mo/unit_tests/mo/back/SpecialNodesFinalization_test.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.SpecialNodesFinalization import CreateConstNodesReplacement
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class CreateConstNodesReplacementTest(unittest.TestCase):
- nodes = [
- ('data_node', {'kind': 'data', 'shape': None, 'value': None}),
- ('next_node', {'kind': 'op'}),
- ]
- edges = [
- ('data_node', 'next_node')
- ]
-
- new_nodes = [
- ('const', {'kind': 'op', 'op': 'Const'}),
- ('const_data', {'kind': 'data'})
- ]
- new_edges = [
- ('const', 'data_node'),
- ('const_data', 'const')
- ]
-
- def test_one_node(self):
- """We should add Const node and data node."""
- shape = np.array([2, 3, 4])
- data = np.zeros(shape)
- graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[('data_node', {'shape': shape, 'value': data})]
- )
- graph_ref = build_graph_with_attrs(
- nodes_with_attrs=self.nodes + self.new_nodes,
- edges_with_attrs=self.edges + self.new_edges,
- update_nodes_attributes=[('data_node', {'shape': shape, 'value': data}),
- ('const_data', {'shape': shape, 'value': data})]
- )
- tested_pattern = CreateConstNodesReplacement()
- tested_pattern.find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='next_node')
- self.assertTrue(flag, resp)
-
- def test_one_bin_node(self):
- """Nothing should happen."""
- shape = np.array([2, 3, 4])
- data = np.zeros(shape)
- graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[('data_node', {'shape': shape, 'value': data})],
- update_edge_attrs={('data_node', 'next_node', 0): {'bin': 0}},
- )
- tested_pattern = CreateConstNodesReplacement()
- tested_pattern.find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph, last_node='next_node')
- self.assertTrue(flag, resp)
-
- def test_two_nodes_with_bin(self):
- """Test case for data node with 2 consumers with bin edge attr.
- Nothing should happened."""
- shape = np.array([2, 3, 4])
- data = np.zeros(shape)
- graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes + [('next_node_2', {'kind': 'op'})],
- edges_with_attrs=self.edges + [('data_node', 'next_node_2')],
- update_nodes_attributes=[('data_node', {'shape': shape, 'value': data})],
- update_edge_attrs={('data_node', 'next_node', 0): {'bin': 0}, ('data_node', 'next_node_2', 0): {'bin': 0}},
- )
- tested_pattern = CreateConstNodesReplacement()
- tested_pattern.find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph, last_node='next_node')
- self.assertTrue(flag, resp)
-
- def test_two_nodes_one_bin(self):
- """Test case for two output nodes, one with 'bin' parameter, other without."""
- shape = np.array([2, 3, 4])
- data = np.zeros(shape)
- graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes + [('next_node_2', {'kind': 'op'})],
- edges_with_attrs=self.edges + [('data_node', 'next_node_2')],
- update_nodes_attributes=[('data_node', {'shape': shape, 'value': data})],
- update_edge_attrs={('data_node', 'next_node', 0): {'bin': 0}},
- )
- graph_ref = build_graph_with_attrs(
- nodes_with_attrs=self.nodes + self.new_nodes + [('next_node_2', {'kind': 'op'})],
- edges_with_attrs=self.edges + self.new_edges + [('data_node', 'next_node_2')],
- update_nodes_attributes=[('data_node', {'shape': shape, 'value': data}),
- ('const_data', {'shape': shape, 'value': data})]
- )
- tested_pattern = CreateConstNodesReplacement()
- tested_pattern.find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='next_node')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/TransposeDFT_test.py b/tools/mo/unit_tests/mo/back/TransposeDFT_test.py
deleted file mode 100644
index 85e20268caeedf..00000000000000
--- a/tools/mo/unit_tests/mo/back/TransposeDFT_test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.TransposeDFT import TransposeDFT
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect, \
- regular_op_with_empty_data
-
-dft_graph_node_attrs = {
- **regular_op_with_shaped_data('placeholder', [8, 2, 40, 56], {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('axes', int64_array([-2, -1])),
- **regular_op_with_shaped_data('dft', [8, 2, 40, 56], {'op': 'DFT', 'need_insert_transposes_for_dft': True}),
- **regular_op_with_shaped_data('abs', [8, 2, 40, 56], {'type': 'Abs', 'op': 'Abs'}),
- **result(),
-}
-
-dft_graph_edges = [
- *connect('placeholder', '0:dft'),
- *connect('axes', '1:dft'),
- *connect('dft', 'abs'),
- *connect('abs', 'output'),
-]
-
-
-transposed_dft_graph_node_attrs = {
- **regular_op_with_shaped_data('placeholder', [8, 2, 40, 56], {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_empty_data('transpose_before',
- {'type': 'Transpose', 'op': 'Transpose', 'need_shape_inference': True}),
- **valued_const_with_data('transpose_before_axis_const', int64_array([0, 2, 3, 1])),
- **regular_op_with_empty_data('transpose_after',
- {'type': 'Transpose', 'op': 'Transpose', 'need_shape_inference': True}),
- **valued_const_with_data('transpose_after_axis_const', int64_array([0, 3, 1, 2])),
- **valued_const_with_data('dft_axes', int64_array([-2, -1])),
- **regular_op_with_shaped_data('dft', [8, 2, 40, 56], {'op': 'DFT', 'need_insert_transposes_for_dft': True}),
- **regular_op_with_shaped_data('abs', [8, 2, 40, 56], {'type': 'Abs', 'op': 'Abs'}),
- **result(),
-}
-
-transposed_dft_graph_edges = [
- *connect('placeholder', '0:transpose_before'),
- *connect('transpose_before_axis_const', '1:transpose_before'),
- *connect('transpose_before', '0:dft'),
- *connect('dft_axes', '1:dft'),
- *connect('dft', '0:transpose_after'),
- *connect('transpose_after_axis_const', '1:transpose_after'),
- *connect('transpose_after', 'abs'),
- *connect('abs', 'output'),
-]
-
-
-nontransposed_dft_graph_node_attrs = {
- **regular_op_with_shaped_data('placeholder', [8, 2, 40, 56], {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('axes', int64_array([-2, -1])),
- **regular_op_with_shaped_data('dft', [8, 2, 40, 56], {'op': 'DFT'}),
- **regular_op_with_shaped_data('abs', [8, 2, 40, 56], {'type': 'Abs', 'op': 'Abs'}),
- **result(),
-}
-
-nontransposed_dft_graph_edges = [
- *connect('placeholder', '0:dft'),
- *connect('axes', '1:dft'),
- *connect('dft', 'abs'),
- *connect('abs', 'output'),
-]
-
-
-class TransposeDFTTest(unittest.TestCase):
- def test_dft_transpose(self):
- graph = build_graph(nodes_attrs=dft_graph_node_attrs, edges=dft_graph_edges)
- ref_graph = build_graph(nodes_attrs=transposed_dft_graph_node_attrs, edges=transposed_dft_graph_edges)
- graph.graph['fw'] = 'tf'
- TransposeDFT().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_dft_nontranspose(self):
- graph = build_graph(nodes_attrs=nontransposed_dft_graph_node_attrs, edges=nontransposed_dft_graph_edges)
- ref_graph = build_graph(nodes_attrs=nontransposed_dft_graph_node_attrs, edges=nontransposed_dft_graph_edges)
- TransposeDFT().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/TransposeReduceFusing_test.py b/tools/mo/unit_tests/mo/back/TransposeReduceFusing_test.py
deleted file mode 100644
index 70fdaa3bd84a00..00000000000000
--- a/tools/mo/unit_tests/mo/back/TransposeReduceFusing_test.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.TransposeReduceFusing import TransposeReduce
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- # op
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- 'transpose': {'kind': 'op', 'type': 'Transpose'},
- 'reduceMean': {'kind': 'op', 'type': 'ReduceMean', 'keep_dims': False},
- 'transpose_const': {'kind': 'op', 'type': 'Const'},
- 'reduceMeanConst': {'kind': 'op', 'type': 'Const'},
- 'convolution': {'kind': 'op', 'op': 'Convolution'},
- 'gather': {'kind': 'op', 'op': 'Gather'},
- 'gather_const': {'kind': 'op', 'op': 'Const'},
-
- # data
- 'placeholder_data': {'kind': 'data'},
- 'transpose_data': {'kind': 'data'},
- 'reduceMean_data': {'kind': 'data'},
- 'transpose_const_data': {'kind': 'data'},
- 'reduceMeanConst_data': {'kind': 'data'},
- 'gather_data': {'kind': 'data'},
- 'gather_const_data': {'kind': 'data'}
-}
-
-
-class TestTransposeReduceFusing(unittest.TestCase):
-
- def test_positive(self):
- graph = build_graph(nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'transpose', {'in': 0}),
- ('transpose_const', 'transpose_const_data'),
- ('transpose_const_data', 'transpose', {'in': 1}),
- ('transpose', 'transpose_data'),
- ('transpose_data', 'reduceMean', {'in': 0}),
- ('reduceMeanConst', 'reduceMeanConst_data'),
- ('reduceMeanConst_data', 'reduceMean', {'in': 1}),
- ('reduceMean', 'reduceMean_data'),
- ('reduceMean_data', 'convolution')
- ],
- {
- 'transpose_const': {'value': int64_array([0, 2, 3, 1])},
- 'transpose_const_data': {'value': int64_array([0, 2, 3, 1])},
- 'reduceMeanConst': {'value': int64_array([1, 2])},
- 'reduceMeanConst_data': {'value': int64_array([1, 2])}
- },
- nodes_with_edges_only=True)
- ref_graph = build_graph(nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'reduceMean', {'in': 0}),
- ('transpose_const', 'transpose_const_data'),
- ('transpose_const_data', 'gather', {'in': 0}),
- ('reduceMeanConst', 'reduceMeanConst_data'),
- ('reduceMeanConst_data', 'gather', {'in': 1}),
- ('gather_const', 'gather_const_data'),
- ('gather_const_data', 'gather', {'in': 2}),
- ('gather', 'gather_data'),
- ('gather_data', 'reduceMean', {'in': 1}),
- ('reduceMean', 'reduceMean_data'),
- ('reduceMean_data', 'convolution')
- ],
- {
- 'transpose_const_data': {'value': int64_array([0, 2, 3, 1])},
- 'reduceMeanConst_data': {'value': int64_array([1, 2])},
- },
- nodes_with_edges_only=True)
- TransposeReduce().find_and_replace_pattern(graph)
- flag, resp = compare_graphs(graph, ref_graph, 'convolution', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_negative_values(self):
- graph = build_graph(nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'transpose', {'in': 0}),
- ('transpose_const', 'transpose_const_data'),
- ('transpose_const_data', 'transpose', {'in': 1}),
- ('transpose', 'transpose_data'),
- ('transpose_data', 'reduceMean', {'in': 0}),
- ('reduceMeanConst', 'reduceMeanConst_data'),
- ('reduceMeanConst_data', 'reduceMean', {'in': 1}),
- ('reduceMean', 'reduceMean_data'),
- ('reduceMean_data', 'convolution')
- ],
- {
- 'transpose_const': {'value': int64_array([0, 1, 3, 2])},
- 'transpose_const_data': {'value': int64_array([0, 1, 3, 2])},
- 'reduceMeanConst': {'value': int64_array([1])},
- 'reduceMeanConst_data': {'value': int64_array([1])}
- },
- nodes_with_edges_only=True)
- ref_graph = build_graph(nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'transpose', {'in': 0}),
- ('transpose_const', 'transpose_const_data'),
- ('transpose_const_data', 'transpose', {'in': 1}),
- ('transpose', 'transpose_data'),
- ('transpose_data', 'reduceMean', {'in': 0}),
- ('reduceMeanConst', 'reduceMeanConst_data'),
- ('reduceMeanConst_data', 'reduceMean', {'in': 1}),
- ('reduceMean', 'reduceMean_data'),
- ('reduceMean_data', 'convolution')
- ],
- {
- 'transpose_const': {'value': int64_array([0, 1, 3, 2])},
- 'transpose_const_data': {'value': int64_array([0, 1, 3, 2])},
- 'reduceMeanConst': {'value': int64_array([1])},
- 'reduceMeanConst_data': {'value': int64_array([1])}
- },
- nodes_with_edges_only=True)
- TransposeReduce().find_and_replace_pattern(graph)
- flag, resp = compare_graphs(graph, ref_graph, 'convolution', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_negative(self):
- graph = build_graph(nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'reduceMean', {'in': 0}),
- ('reduceMeanConst', 'reduceMeanConst_data'),
- ('reduceMeanConst_data', 'reduceMean', {'in': 1}),
- ('reduceMean', 'reduceMean_data'),
- ('reduceMean_data', 'convolution')
- ],
- nodes_with_edges_only=True)
- ref_graph = build_graph(nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'reduceMean', {'in': 0}),
- ('reduceMeanConst', 'reduceMeanConst_data'),
- ('reduceMeanConst_data', 'reduceMean', {'in': 1}),
- ('reduceMean', 'reduceMean_data'),
- ('reduceMean_data', 'convolution')
- ],
- nodes_with_edges_only=True)
-
- TransposeReduce().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'convolution', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/back/__init__.py b/tools/mo/unit_tests/mo/back/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/back/add_outputs_recursive_test.py b/tools/mo/unit_tests/mo/back/add_outputs_recursive_test.py
deleted file mode 100644
index c3ea17b67238ec..00000000000000
--- a/tools/mo/unit_tests/mo/back/add_outputs_recursive_test.py
+++ /dev/null
@@ -1,602 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import numpy as np
-import unittest
-
-from openvino.tools.mo.back.add_outputs_recursive import AddOutputRecursive
-from openvino.tools.mo.ops.If import If
-from openvino.tools.mo.ops.loop import Loop
-from openvino.tools.mo.ops.tensor_iterator import TensorIterator
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension_value, shape_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, shaped_parameter, \
- valued_const_with_data, shaped_const_with_data, regular_op_with_shaped_data
-
-# test for Loop
-main_graph_nodes = {
- **shaped_parameter("IN_1", [1, 4, 64, 54]),
- **shaped_parameter("IN_2", [1, 4, 64, 54]),
- **valued_const_with_data("M", int64_array([5])),
- **valued_const_with_data("cond", int64_array([1])),
- **regular_op_with_empty_data("Loop", {'op': "Loop", 'type': 'Loop', 'sub_graphs': ['body'], "body": None,
- 'input_port_map': [{'external_port_id': 1, 'internal_layer_id': 2,
- 'axis': None},
- {'external_port_id': 2, 'internal_layer_id': 0,
- 'axis': None},
- {'external_port_id': 3, 'internal_layer_id': 1,
- 'axis': None}],
- 'output_port_map': [{'external_port_id': 0, 'internal_layer_id': 4,
- 'axis': None},
- {'external_port_id': -1, 'internal_layer_id': 5,
- 'axis': None, 'purpose': "execution_condition"}],
- 'back_edges': [{'from_layer': 8, 'to_layer': 7},
- {'from_layer': 10, 'to_layer': 9}],
- 'infer': Loop.infer}),
- **result("OUT_1")
-}
-
-sub_graph_1_nodes = {
- **shaped_parameter("IN_2", int64_array([1, 4, 64, 54]), {'internal_layer_id': 0}),
- **valued_const_with_data("M_2", int64_array([10])),
- **valued_const_with_data("cond_2", int64_array([1])),
- **regular_op_with_empty_data("Loop_2", {'op': "Loop", 'type': 'Loop', 'sub_graphs': ['body'], "body": None,
- 'input_port_map': [{'external_port_id': 1, 'internal_layer_id': 0,
- 'axis': None},
- {'external_port_id': 2, 'internal_layer_id': 2,
- 'axis': None}],
- 'output_port_map': [{'external_port_id': 0, 'internal_layer_id': 7,
- 'axis': None},
- {'external_port_id': -1, 'internal_layer_id': 6,
- 'axis': None,
- 'purpose': "execution_condition"}],
- 'back_edges': [{'from_layer': 1, 'to_layer': 0},
- {'from_layer': 8, 'to_layer': 2}],
- 'infer': Loop.infer}),
- **regular_op_with_empty_data('Loop_2_out', {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 3}),
- **shaped_parameter("in_1_int", int64_array([1, 4, 64, 54]), {'internal_layer_id': 1}),
- **regular_op_with_empty_data("in_1_int_out",
- {'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 4}),
- **shaped_parameter("cond_1_int", int64_array([1]), {'internal_layer_id': 2}),
- **regular_op_with_empty_data("cond_1_int_out", {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 5}),
-}
-
-sub_graph_2_nodes = {
- **shaped_parameter('cond_2_int', [1, 4, 64, 54], {'internal_layer_id': 0}),
- **regular_op_with_empty_data("cond_2_int_out",
- {'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 8}),
- **shaped_parameter('in_2_int', [1, 4, 64, 54], {'internal_layer_id': 1}),
- **shaped_const_with_data('ones', int64_array([1, 4, 64, 54]), {'internal_layer_id': 9}),
- **regular_op_with_shaped_data('OUT_2', int64_array([1, 4, 64, 54]), {'op': "Add", 'infer': copy_shape_infer}),
- **regular_op_with_empty_data('OUT_2_out',
- {'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 7}),
- **regular_op_with_shaped_data('in_2_int_out', int64_array([1, 4, 64, 54]),
- {'op': 'Result', 'type': 'Result', 'infer': lambda x: None, 'internal_layer_id': 6})
-}
-
-
-def ti_create_main_graph(body):
- main_graph = build_graph(nodes_attrs=ti_main_graph_nodes,
- edges=[*connect('M', '0:Loop'),
- *connect('cond', '1:Loop'),
- *connect('IN_2', '2:Loop'),
- *connect('IN_1', "3:Loop"),
- *connect('Loop:0', 'OUT_1')],
- nodes_with_edges_only=True)
- loop_node = Node(main_graph, 'Loop')
- loop_node.body = body
- loop_node.in_edge(0)['external_port_id'] = 0
- loop_node.in_edge(1)['external_port_id'] = 1
- loop_node.in_edge(2)['external_port_id'] = 2
- loop_node.in_edge(3)['external_port_id'] = 3
- loop_node.out_edge(0)['external_port_id'] = 4
-
- return main_graph
-
-
-def if_create_main_graph():
- sub_graph_2 = build_graph(nodes_attrs=if_sub_graph_2_then_nodes,
- edges=[*connect('in_2_int', 'OUT_2'),
- *connect('ones', 'OUT_2'),
- *connect('OUT_2', 'OUT_2_out')],
- nodes_with_edges_only=True)
-
- sub_graph_2_else = build_graph(nodes_attrs=if_sub_graph_2_else_nodes,
- edges=[*connect('in_2_int_else', 'OUT_2_else'),
- *connect('ones_else', 'OUT_2_else'),
- *connect('OUT_2_else', 'OUT_2_out_else')],
- nodes_with_edges_only=True)
-
- sub_graph_1 = build_graph(nodes_attrs=if_sub_graph_1_then_nodes,
- edges=[*connect('cond_2', '0:If_2'),
- *connect('IN_2', '1:If_2'),
- *connect('If_2:0', 'If_2_out'),
- *connect('in_1_int', 'in_1_int_out')],
- nodes_with_edges_only=True)
- if_node_1 = Node(sub_graph_1, 'If_2')
- if_node_1.then_graph = sub_graph_2
- if_node_1.else_graph = sub_graph_2_else
-
- return sub_graph_1
-
-
-class AddOutputRecursiveTest(unittest.TestCase):
-
- def test_add_output_1(self):
- sub_graph_2 = build_graph(nodes_attrs=sub_graph_2_nodes,
- edges=[*connect('cond_2_int', 'cond_2_int_out'),
- *connect('in_2_int', 'OUT_2'),
- *connect('ones', 'OUT_2'),
- *connect('OUT_2', 'OUT_2_out'),
- *connect('in_2_int', 'in_2_int_out')],
- nodes_with_edges_only=True)
-
- sub_graph_1 = build_graph(nodes_attrs=sub_graph_1_nodes,
- edges=[*connect('M_2', '0:Loop_2'),
- *connect('cond_2', '1:Loop_2'),
- *connect('IN_2', '2:Loop_2'),
- *connect('Loop_2:0', 'Loop_2_out'),
- *connect('in_1_int', 'in_1_int_out'),
- *connect('cond_1_int', 'cond_1_int_out')],
- nodes_with_edges_only=True)
- loop_node_1 = Node(sub_graph_1, 'Loop_2')
- loop_node_1.body = sub_graph_2
-
- main_graph = build_graph(nodes_attrs=main_graph_nodes,
- edges=[*connect('M', '0:Loop'),
- *connect('cond', '1:Loop'),
- *connect('IN_2', '2:Loop'),
- *connect('IN_1', "3:Loop"),
- *connect('Loop:0', 'OUT_1')],
- nodes_with_edges_only=True)
- loop_node = Node(main_graph, 'Loop')
- loop_node.body = sub_graph_1
- main_graph.graph['additional_outputs'] = ['Loop', 'Loop_2']
- loop_node_1['out_ports_count'] = 2
- loop_node_1.add_output_port(1)
- loop_node_1['output_port_map'].append({'external_port_id': 1, 'internal_layer_id': 8, 'axis': None})
-
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_2_out_ports_len = len(loop_node_1.out_ports())
- max_layer_id = 5
-
- results = AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.assertEqual(len(results), 2)
- loop_node = Node(main_graph, 'Loop')
- self.assertEqual(len(loop_node.output_port_map), loop_node_output_port_map_len + 2)
- self.assertEqual(len(loop_node.out_ports()), loop_node_out_ports_len + 2)
- self.assertEqual(loop_node.out_port(1).get_destination().node.op, 'Result')
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == int64_array([5, 10, 4, 64, 54])))
- last_node = Node(sub_graph_1, 'Loop_2')
- self.assertEqual(len(last_node.out_ports()), loop_2_out_ports_len)
- unsq_node = last_node.out_port(0).get_destinations()[1].node
- self.assertEqual(unsq_node.op, 'Unsqueeze')
- self.assertEqual(unsq_node.out_port(0).get_destination().node.op, 'Result')
- self.assertEqual(unsq_node.out_port(0).get_destination().node.internal_layer_id, max_layer_id + 3)
- self.assertTrue(np.all(unsq_node.out_port(0).data.get_shape() == int64_array([1, 10, 4, 64, 54])))
-
-
-# test for TensorIterator
-ti_main_graph_nodes = {
- **shaped_parameter("IN_1", [1, 4, 64, 54]),
- **shaped_parameter("IN_2", [1, 4, 64, 54]),
- **valued_const_with_data("M", int64_array([5])),
- **valued_const_with_data("cond", int64_array([1])),
- **regular_op_with_empty_data("Loop", {'op': "TensorIterator", 'type': 'TensorIterator',
- 'sub_graphs': ['body'], "body": None,
- 'input_port_map': [{'external_port_id': 1, 'internal_layer_id': 2, 'axis': None},
- {'external_port_id': 2, 'internal_layer_id': 0, 'axis': None},
- {'external_port_id': 3, 'internal_layer_id': 1, 'axis': None}],
- 'output_port_map': [{'external_port_id': 4, 'internal_layer_id': 4, 'axis': None}],
- 'back_edges': [{'from_layer': 8, 'to_layer': 7},
- {'from_layer': 10, 'to_layer': 9}],
- 'infer': TensorIterator.infer}),
- **result("OUT_1")
-}
-
-ti_sub_graph_1_nodes = {
- **shaped_parameter("IN_2", int64_array([1, 4, 64, 54]), {'internal_layer_id': 0}),
- **valued_const_with_data("cond_2", int64_array([1])),
- **regular_op_with_empty_data("Loop_2", {'op': "TensorIterator", 'type': 'TensorIterator',
- 'sub_graphs': ['body'], "body": None,
- 'input_port_map': [{'external_port_id': 1, 'internal_layer_id': 0, 'axis': None},
- {'external_port_id': 0, 'internal_layer_id': 1, 'axis': 0}],
- 'output_port_map': [{'external_port_id': 2, 'internal_layer_id': 7,
- 'axis': None},
- ],
- 'back_edges': [{'from_layer': 1, 'to_layer': 0},
- {'from_layer': 8, 'to_layer': 2}],
- 'infer': TensorIterator.infer}),
- **regular_op_with_empty_data('Loop_2_out', {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 3}),
- **shaped_parameter("in_1_int", int64_array([1, 4, 64, 54]), {'internal_layer_id': 1}),
- **regular_op_with_empty_data("in_1_int_out", {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 4}),
- **shaped_parameter("cond_1_int", int64_array([1]), {'internal_layer_id': 2}),
- **regular_op_with_empty_data("cond_1_int_out", {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 5}),
-}
-
-ti_sub_graph_2_nodes = {
- **shaped_parameter('cond_2_int', [1, 4, 64, 54], {'internal_layer_id': 0}),
- **result("cond_2_int_out"),
- **shaped_parameter('in_2_int', [1, 4, 64, 54], {'internal_layer_id': 1}),
- **shaped_const_with_data('ones', int64_array([1, 4, 64, 54])),
- **regular_op_with_shaped_data('OUT_2', int64_array([1, 4, 64, 54]),
- {'op': "Add", 'infer': copy_shape_infer}),
- **regular_op_with_empty_data('OUT_2_out', {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 7}),
- **regular_op_with_empty_data('in_2_int_out', {'op': 'Result', 'type': 'Result', 'infer': lambda x: None,
- 'internal_layer_id': 6})
-}
-
-
-class TI_AddOutputRecursiveTest(unittest.TestCase):
- @staticmethod
- def create_graph():
- sub_graph_2 = build_graph(nodes_attrs=ti_sub_graph_2_nodes,
- edges=[*connect('cond_2_int', 'cond_2_int_out'),
- *connect('in_2_int', 'OUT_2'),
- *connect('ones', 'OUT_2'),
- *connect('OUT_2', 'OUT_2_out'),
- *connect('in_2_int', 'in_2_int_out')],
- nodes_with_edges_only=True)
-
- sub_graph_1 = build_graph(nodes_attrs=ti_sub_graph_1_nodes,
- edges=[*connect('cond_2', '1:Loop_2'),
- *connect('IN_2', '0:Loop_2'),
- *connect('Loop_2:0', 'Loop_2_out'),
- *connect('in_1_int', 'in_1_int_out'),
- *connect('cond_1_int', 'cond_1_int_out')],
- nodes_with_edges_only=True)
- loop_node_1 = Node(sub_graph_1, 'Loop_2')
- loop_node_1.body = sub_graph_2
- loop_node_1.in_edge(0)['external_port_id'] = 0
- loop_node_1.in_edge(1)['external_port_id'] = 1
- loop_node_1.out_edge(0)['external_port_id'] = 2
-
- main_graph = ti_create_main_graph(sub_graph_1)
- main_graph.graph['additional_outputs'] = ['Loop', 'Loop_2']
-
- return main_graph, sub_graph_1
-
- def check_body_last_node(self, body, node_id, loop_2_node_out_ports_len):
- last_node = Node(body, node_id)
- max_layer_id = 5
- self.assertEqual(len(last_node.out_ports()), loop_2_node_out_ports_len)
- unsq_node = last_node.out_port(0).get_destinations()[1].node
- self.assertEqual(unsq_node.op, 'Unsqueeze')
- self.assertEqual(unsq_node.out_port(0).get_destination().node.op, 'Result')
- self.assertEqual(unsq_node.out_port(0).get_destination().node.internal_layer_id, max_layer_id + 3)
- self.assertTrue(np.all(unsq_node.out_port(0).data.get_shape() == int64_array([1, 1, 4, 64, 54])))
-
- def check_loop_node(self, graph, node_id, port_map_len, out_ports_len):
- loop_node = Node(graph, node_id)
- self.assertEqual(len(loop_node.output_port_map), port_map_len + 1)
- self.assertEqual(len(loop_node.out_ports()), out_ports_len + 1)
- self.assertEqual(loop_node.out_port(1).get_destination().node.op, 'Result')
-
- def test_add_output_1(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == int64_array([1, 1, 4, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_dynamic(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['start'] = 0
- loop_node.input_port_map[2]['end'] = -1
- loop_node.input_port_map[2]['stride'] = 1
- in_1_node = Node(main_graph, 'IN_1')
- in_1_node['shape'] = shape_array([1, dynamic_dimension_value, 64, 54])
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() ==
- shape_array([dynamic_dimension_value, 1, 4, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_several_iterations(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['start'] = 0
- loop_node.input_port_map[2]['end'] = -1
- loop_node.input_port_map[2]['stride'] = 1
- loop_node.output_port_map[0]['axis'] = 1
- loop_node.output_port_map[0]['start'] = 0
- loop_node.output_port_map[0]['end'] = 10
- loop_node.output_port_map[0]['stride'] = 2
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == shape_array([4, 1, 4, 64, 54])))
- self.assertTrue(np.all(loop_node.out_port(0).data.get_shape() == shape_array([1, 5, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_several_iterations_wo_start_end(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['stride'] = 1
-
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == shape_array([4, 1, 4, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_several_iterations_negative_end(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['start'] = 0
- loop_node.input_port_map[2]['end'] = -3
- loop_node.input_port_map[2]['stride'] = 1
- loop_node.output_port_map[0]['axis'] = 1
- loop_node.output_port_map[0]['start'] = 0
- loop_node.output_port_map[0]['end'] = -1
- loop_node.output_port_map[0]['stride'] = 2
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == shape_array([2, 1, 4, 64, 54])))
- self.assertTrue(np.all(loop_node.out_port(0).data.get_shape() == shape_array([1, 2, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_several_iterations_negative_stride(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
-
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['start'] = -1
- loop_node.input_port_map[2]['end'] = 0
- loop_node.input_port_map[2]['stride'] = -2
- loop_node.output_port_map[0]['axis'] = 1
- loop_node.output_port_map[0]['start'] = 0
- loop_node.output_port_map[0]['end'] = -1
- loop_node.output_port_map[0]['stride'] = 2
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == shape_array([2, 1, 4, 64, 54])))
- self.assertTrue(np.all(loop_node.out_port(0).data.get_shape() == shape_array([1, 2, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_several_iterations_negative_start_end_input(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['start'] = -1
- loop_node.input_port_map[2]['end'] = -4
- loop_node.input_port_map[2]['stride'] = -2
- loop_node.output_port_map[0]['axis'] = 1
- loop_node.output_port_map[0]['start'] = 0
- loop_node.output_port_map[0]['end'] = -1
- loop_node.output_port_map[0]['stride'] = 2
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == shape_array([2, 1, 4, 64, 54])))
- self.assertTrue(np.all(loop_node.out_port(0).data.get_shape() == shape_array([1, 2, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
- def test_add_output_several_iterations_negative_start_end_output(self):
- main_graph, sub_graph_1 = self.create_graph()
-
- loop_node = Node(main_graph, 'Loop')
- loop_node_output_port_map_len = len(loop_node.output_port_map)
- loop_node_out_ports_len = len(loop_node.out_ports())
- loop_node_2 = Node(sub_graph_1, 'Loop_2')
- loop_2_node_out_ports_len = len(loop_node_2.out_ports())
-
- loop_node.input_port_map[2]['axis'] = 1
- loop_node.input_port_map[2]['start'] = -1
- loop_node.input_port_map[2]['end'] = -4
- loop_node.input_port_map[2]['stride'] = -2
- loop_node.output_port_map[0]['axis'] = 1
- loop_node.output_port_map[0]['start'] = -4
- loop_node.output_port_map[0]['end'] = -1
- loop_node.output_port_map[0]['stride'] = 1
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
-
- self.check_loop_node(main_graph, 'Loop', loop_node_output_port_map_len, loop_node_out_ports_len)
- self.assertTrue(np.all(loop_node.out_port(1).data.get_shape() == shape_array([2, 1, 4, 64, 54])))
- self.assertTrue(np.all(loop_node.out_port(0).data.get_shape() == shape_array([1, 3, 64, 54])))
- self.check_body_last_node(sub_graph_1, 'Loop_2', loop_2_node_out_ports_len)
-
-
-# test for If
-if_main_graph_nodes = {
- **shaped_parameter("IN_1", [1, 4, 64, 54]),
- **shaped_parameter("IN_2", [1, 4, 64, 54]),
- **valued_const_with_data("cond", int64_array([1])),
- **regular_op_with_empty_data("If", {'op': "If", 'type': 'If', 'sub_graphs': ['then_graph', 'else_graph'],
- "then_graph": None, 'else_graph': None, 'infer': If.infer}),
- **result("OUT_1")
-}
-
-if_sub_graph_1_then_nodes = {
- **shaped_parameter("IN_2", int64_array([1, 4, 64, 54]), {'input_id': 2}),
- **valued_const_with_data("cond_2", int64_array([1])),
- **regular_op_with_empty_data("If_2", {'op': "If", 'type': 'If', 'sub_graphs': ['then_graph', 'else_graph'],
- "then_graph": None, 'else_graph': None, 'infer': If.infer}),
- **regular_op_with_empty_data('If_2_out', {'op': 'Result', 'type': 'Result', 'infer': lambda x: None}),
- **shaped_parameter("in_1_int", int64_array([1, 4, 64, 54]), {'input_id': 1}),
- **regular_op_with_empty_data("in_1_int_out", {'op': 'Result', 'type': 'Result', 'output_id': 0})
-}
-
-if_sub_graph_1_else_nodes = {
- **shaped_parameter("in_1_int", int64_array([1, 4, 64, 54]), {'input_id': 1}),
- **regular_op_with_empty_data("in_1_int_out", {'op': 'Result', 'type': 'Result', 'output_id': 0})
-}
-
-if_sub_graph_2_then_nodes = {
- **shaped_parameter('in_2_int', [1, 4, 64, 54], {'input_id': 1}),
- **shaped_const_with_data('ones', int64_array([1, 4, 64, 54])),
- **regular_op_with_shaped_data('OUT_2', int64_array([1, 4, 64, 54]), {'op': "Add"}),
- **regular_op_with_empty_data('OUT_2_out', {'op': 'Result', 'type': 'Result', 'output_id': 0}),
-}
-
-if_sub_graph_2_else_nodes = {
- **shaped_parameter('in_2_int_else', [1, 4, 64, 54], {'input_id': 1}),
- **shaped_const_with_data('ones_else', int64_array([1, 4, 64, 54])),
- **regular_op_with_shaped_data('OUT_2_else', int64_array([1, 4, 64, 54]), {'op': "Sub"}),
- **regular_op_with_empty_data('OUT_2_out_else', {'op': 'Result', 'type': 'Result', 'output_id': 0}),
-}
-
-
-class IF_AddOutputRecursiveTest(unittest.TestCase):
- def test_add_output_1(self):
- sub_graph_1 = if_create_main_graph()
- if_node_1 = Node(sub_graph_1, 'If_2')
-
- sub_graph_1_else = build_graph(nodes_attrs=if_sub_graph_1_else_nodes,
- edges=[*connect('in_1_int', 'in_1_int_out')],
- nodes_with_edges_only=True)
-
- main_graph = build_graph(nodes_attrs=if_main_graph_nodes,
- edges=[*connect('cond', '0:If'),
- *connect('IN_1', '1:If'),
- *connect('IN_2', "2:If"),
- *connect('If:0', 'OUT_1')],
- nodes_with_edges_only=True)
- if_node = Node(main_graph, 'If')
- if_node.then_graph = sub_graph_1
- if_node.else_graph = sub_graph_1_else
- if_node_out_ports_len = len(if_node.out_ports())
- if_2_node_out_ports_len = len(if_node_1.out_ports())
-
- main_graph.graph['additional_outputs'] = ['If', ['If_2', 'in_1_int']]
-
- AddOutputRecursive().find_and_replace_pattern(main_graph)
- if_node = Node(main_graph, 'If')
- self.assertEqual(len(if_node.out_ports()), if_node_out_ports_len + 1)
- self.assertEqual(if_node.out_port(1).get_destination().node.op, 'Result')
- self.assertTrue(np.all(if_node.out_port(1).data.get_shape() == int64_array([1, 4, 64, 54])))
- last_node = Node(sub_graph_1, 'If_2')
- self.assertEqual(len(last_node.out_ports()), if_2_node_out_ports_len)
- self.assertEqual(last_node.out_port(0).get_destinations()[1].node.op, 'Result')
- self.assertTrue(np.all(last_node.out_port(0).data.get_shape() == int64_array([1, 4, 64, 54])))
-
-
-class SplitUserPathTest(unittest.TestCase):
-
- @staticmethod
- def create_graph():
- sub_graph_1 = if_create_main_graph()
- out_node = Node(sub_graph_1, 'If_2_out')
- out_node['internal_layer_id'] = 4
-
- main_graph = ti_create_main_graph(sub_graph_1)
-
- return main_graph
-
- def test_linear_graph_change(self):
- graph = self.create_graph()
- path = ['Loop', 'in_1_int']
- ref_path = []
- loop_node = Node(graph, 'Loop')
- ref_path.append({'node': loop_node, 'graph': graph})
- ref_path.append({'node': Node(loop_node.body, 'in_1_int'), 'graph': loop_node.body})
-
- tracks = AddOutputRecursive().split_path_to_simple_tracks(graph, path)
-
- self.assertTrue(np.all(tracks[0] == ref_path))
-
- def test_1_if_graph_change(self):
- graph = self.create_graph()
- path = ['Loop', 'If_2', ['OUT_2', 'OUT_2_else']]
- ref_path = [[]]
- loop_node = Node(graph, 'Loop')
- ref_path[0].append({'node': loop_node, 'graph': graph})
- if_node = Node(loop_node.body, 'If_2')
- ref_path[0].append({'node': if_node, 'graph': loop_node.body})
- ref_path.append([])
- ref_path[1] = ref_path[0][:]
- ref_path[0].append({'node': Node(if_node.then_graph, 'OUT_2'), 'graph': if_node.then_graph})
- ref_path[1].append({'node': Node(if_node.else_graph, 'OUT_2_else'), 'graph': if_node.else_graph})
-
- tracks = AddOutputRecursive().split_path_to_simple_tracks(graph, path)
-
- self.assertTrue(np.all(tracks[0] == ref_path[0]))
- self.assertTrue(np.all(tracks[1] == ref_path[1]))
-
- def test_1_if_graph_change_add_output(self):
- graph = self.create_graph()
- graph.graph['additional_outputs'] = ['Loop', 'If_2', ['OUT_2', 'OUT_2_else']]
-
- AddOutputRecursive().find_and_replace_pattern(graph)
-
- loop_node = Node(graph, 'Loop')
- if_node = Node(loop_node.body, 'If_2')
- left_node = Node(if_node.then_graph, 'OUT_2')
- right_node = Node(if_node.else_graph, 'OUT_2_else')
- self.assertEqual(len(left_node.out_port(0).get_destinations()), 2)
- self.assertEqual(left_node.out_port(0).get_destinations()[1].node.op, 'Result')
-
- self.assertEqual(len(right_node.out_port(0).get_destinations()), 2)
- self.assertEqual(right_node.out_port(0).get_destinations()[1].node.op, 'Result')
-
- self.assertTrue(len(if_node.out_ports()), 2)
- self.assertTrue(if_node.out_port(1).get_destination().node.op, 'Result')
-
- self.assertTrue(len(loop_node.out_ports()), 2)
- self.assertTrue(loop_node.out_port(1).get_destination().node.op, 'Result')
diff --git a/tools/mo/unit_tests/mo/back/compress_quantized_weights_test.py b/tools/mo/unit_tests/mo/back/compress_quantized_weights_test.py
deleted file mode 100644
index 451f3e96cc17f1..00000000000000
--- a/tools/mo/unit_tests/mo/back/compress_quantized_weights_test.py
+++ /dev/null
@@ -1,438 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from argparse import Namespace
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.back.compress_quantized_weights import CompressQuantizeWeights, ZeroPointOptimizer
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.ops.elementwise import Sub, Mul
-from openvino.tools.mo.ops.fakequantize import FakeQuantize
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from openvino.tools.mo.middle.passes.infer import type_infer
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect, \
- shaped_const_with_data
-
-
-def nodes_dict(original, transformed=None, levels=255, data=None,
- il=[-127], ih=[127], ol=[-127], oh=[127],
- scale=np.array([1]), zp=np.array([0]), int_data=None):
- shape = [1, 2, 3, 4] if data is None else np.array(data).shape
- data = np.ones(shape, dtype=original) if data is None else np.array(data, dtype=original)
- if int_data is None:
- int_data = data.astype(dtype=np.int8)
- transformed = transformed if transformed is not None else original
-
- return {
- **valued_const_with_data('weights', data),
- **valued_const_with_data('int_weights', int_data),
-
- **regular_op_with_shaped_data(
- 'weights_cast', shape, {'type': 'Convert', 'op': 'Cast', 'infer': Cast.infer, 'dst_type': np.float32}),
-
- **regular_op_with_shaped_data(
- 'cast', shape, {'type': 'Convert', 'op': 'Cast', 'infer': Cast.infer, 'dst_type': transformed}),
-
- **valued_const_with_data('il', np.array(il)),
- **valued_const_with_data('ih', np.array(ih)),
- **valued_const_with_data('ol', np.array(ol)),
- **valued_const_with_data('oh', np.array(oh)),
-
- **regular_op_with_shaped_data(
- 'FQ', shape, {'type': 'FakeQuantize', 'infer': FakeQuantize.infer, 'stop_value_propagation': True,
- 'levels': levels, 'op': 'FakeQuantize'}),
-
- **valued_const_with_data('zp', zp),
- **valued_const_with_data('scale', scale),
-
- **regular_op_with_shaped_data(
- 'sub', shape, {'type': 'Subtract', 'op': 'Sub', 'infer': lambda node: eltwise_infer(node, Sub.operation)}),
-
- **regular_op_with_shaped_data(
- 'mul', shape, {'type': 'Multiply', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, Mul.operation)}),
-
- **result()
- }
-
-
-class CompressionQuantizeDequantizeSeparateTest(unittest.TestCase):
- def test_quantize(self):
- original_type = np.float32
- nodes = nodes_dict(original_type)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
-
- error_message = 'Unexpected number of FakeQuantize nodes {} CompressQuantizeWeights.quantize_data call `{}`'
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- self.assertEqual(len(fq_nodes), 1, error_message.format('before', len(fq_nodes)))
- fake_quantize = fq_nodes[0]
-
- CompressQuantizeWeights.quantize_data(fake_quantize, original_type, np.int8, "signed")
- graph.clean_up()
-
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- self.assertEqual(len(fq_nodes), 1, error_message.format('after', len(fq_nodes)))
- self.assertEqual(fq_nodes[0].in_port(0).get_source().node.soft_get('type'), 'Const')
- self.assertEqual(fq_nodes[0].in_port(0).get_source().node.data_type, np.int8)
-
- graph_ref = build_graph(nodes, [
- *connect('int_weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_dequantize(self):
- original_type = np.float32
- nodes = nodes_dict(original_type, np.int8)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:cast'),
- *connect('cast:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
-
- error_message = 'Unexpected number of {} nodes {} CompressQuantizeWeights.dequantize_data call `{}`'
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- cast_nodes = graph.get_op_nodes(name='cast')
- self.assertEqual(len(fq_nodes), 1, error_message.format('FakeQuantize', 'before', len(fq_nodes)))
- self.assertEqual(len(cast_nodes), 1, error_message.format('Convert', 'before', len(cast_nodes)))
- cast_nodes[0]['need_shape_inference'] = True
-
- CompressQuantizeWeights.dequantize_data(fq_nodes[0], original_type, np.int8)
- graph.clean_up()
-
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- self.assertEqual(len(fq_nodes), 0, error_message.format('FakeQuantize', 'after', len(fq_nodes)))
-
- graph_ref = build_graph(nodes, [
- *connect('int_weights:0', '0:cast'),
- *connect('cast:0', '0:sub'),
- *connect('zp:0', '1:sub'),
- *connect('sub:0', '0:mul'),
- *connect('scale:0', '1:mul'),
- *connect('mul:0', 'output'),
- ], {'cast': {'dst_type': original_type}}, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_quantize_new_fp16(self):
- original_type = np.float16
- nodes = nodes_dict(original_type)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
-
- error_message = 'Unexpected number of FakeQuantize nodes {} CompressQuantizeWeights.quantize_data call `{}`'
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- self.assertEqual(len(fq_nodes), 1, error_message.format('before', len(fq_nodes)))
- fake_quantize = fq_nodes[0]
-
- CompressQuantizeWeights.quantize_data(fake_quantize, original_type, np.int8, "signed")
- graph.clean_up()
-
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- self.assertEqual(len(fq_nodes), 1, error_message.format('after', len(fq_nodes)))
- self.assertEqual(fq_nodes[0].in_port(0).get_source().node.soft_get('type'), 'Const')
- self.assertEqual(fq_nodes[0].in_port(0).get_source().node.data_type, np.int8)
-
- graph_ref = build_graph(nodes, [
- *connect('int_weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class TestCompressionDataTypeTest():
- @pytest.mark.parametrize("original",[np.int64,
- np.int32,
- np.float64,
- np.float32,
- np.float16])
- def test_data_type(self, original):
- nodes = nodes_dict(original)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True, cli=Namespace(static_shape=True))
-
- CompressQuantizeWeights().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(nodes, [
- *connect('int_weights:0', '0:cast'),
- *connect('cast:0', '0:sub'),
- *connect('zp:0', '1:sub'),
- *connect('sub:0', '0:mul'),
- *connect('scale:0', '1:mul'),
- *connect('mul:0', 'output'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- def test_data_type_new_fp16(self):
- nodes = nodes_dict(np.float16)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:weights_cast'),
- *connect('weights_cast:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True, cli=Namespace(data_type='FP16', static_shape=True))
-
- CompressQuantizeWeights().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(nodes, [
- *connect('int_weights:0', '0:weights_cast'),
- *connect('weights_cast:0', '0:sub'),
- *connect('zp:0', '1:sub'),
- *connect('sub:0', '0:mul'),
- *connect('scale:0', '1:mul'),
- *connect('mul:0', 'output'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
-
- def test_fp16_fake_quantize(self):
- original_type = np.float16
- input_low = np.array([-0.59033203125, -1.4833984375, -1.2900390625], dtype=np.float16)
- input_high = np.array([0.59033203125, 1.4833984375, 1.2900390625], dtype=np.float16)
- output_low = np.array([0.295166015625, 0.74169921875, 0.64501953125], dtype=np.float16)
- output_high = np.array([-0.295166015625, -0.74169921875, -0.64501953125], dtype=np.float16)
- scale = np.array([-0.002325, -0.00584, -0.005077], dtype=np.float16)
- int_data = np.array([43, 103, 118], dtype=np.int8)
- nodes = nodes_dict(original_type, transformed=np.int8,
- levels=255, data=np.array([0.2, 1.2, 1.2], dtype=np.float16),
- il=input_low, ih=input_high, ol=output_low, oh=output_high, scale=scale, int_data=int_data)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
- type_infer(graph)
-
- error_message = 'Unexpected number of {} nodes {} CompressQuantizeWeights.dequantize_data call `{}`'
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- assert len(fq_nodes) == 1, error_message.format('FakeQuantize', 'before', len(fq_nodes))
-
- CompressQuantizeWeights().find_and_replace_pattern(graph)
- graph.clean_up()
- ZeroPointOptimizer().find_and_replace_pattern(graph)
- graph.clean_up()
-
- fq_nodes = graph.get_op_nodes(type='FakeQuantize')
- assert len(fq_nodes) == 0, error_message.format('FakeQuantize', 'after', len(fq_nodes))
-
- graph_ref = build_graph(nodes, [
- *connect('int_weights:0', '0:cast'),
- *connect('cast:0', '0:mul'),
- *connect('scale:0', '1:mul'),
- *connect('mul:0', 'output'),
- ], {'cast': {'dst_type': original_type}}, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
-
-class TestAccuracyCheckFP32Test():
- eps = np.finfo(np.float32).eps
-
- @pytest.mark.parametrize("data, in_low, in_high, out_low, out_high, levels, add_cast" ,[
- ([-2.586, -1.338, 2.773, 4.414], [-2.586], [4.414], [-2.586], [4.414], 256, False),
- ([-1.5, -0.32, 0.167, 2.8], [-1.5], [2.8], [-1.5], [2.8], 256, False),
- ([1, 1 + eps, 1 + 2 * eps, 1 + 3 * eps], [1], [1 + 3 * eps], [1], [1 + 3 * eps], 256, False),
- ([1.0, 2.0, 3.0, 4.0], [1], [4], [1], [4], 256, False),
- ([-2.586, -1.338, 2.773, 4.414], [-2.586], [4.414], [-2.586], [4.414], 256, True),
- ([-1.5, -0.32, 0.167, 2.8], [-1.5], [2.8], [-1.5], [2.8], 256, True),
- ([1, 1 + eps, 1 + 2 * eps, 1 + 3 * eps], [1], [1 + 3 * eps], [1], [1 + 3 * eps], 256, True),
- ([1.0, 2.0, 3.0, 4.0], [1], [4], [1], [4], 256, True),
- ])
- def test_accuracy(self, data, in_low, in_high, out_low, out_high, levels, add_cast):
- if not add_cast:
- nodes = nodes_dict(np.float32, None, levels, data, in_low, in_high, out_low, out_high)
- graph = build_graph(nodes, [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
- else:
- nodes = nodes_dict(np.float16, None, levels, data, in_low, in_high, out_low, out_high)
- graph = build_graph(nodes, [
- *connect('weights:0', '0:weights_cast'),
- *connect('weights_cast:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
- graph_ref = graph.copy()
-
- CompressQuantizeWeights().find_and_replace_pattern(graph)
-
- for node in graph.get_op_nodes() + graph_ref.get_op_nodes():
- node['stop_value_propagation'] = False
- node['need_shape_inference'] = node.soft_get('need_shape_inference', True)
-
- graph.clean_up()
- graph_ref.clean_up()
-
- const_result_graph = build_graph({**shaped_const_with_data('weights', np.array(data).shape), **result()},
- [*connect('weights', 'output')], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, const_result_graph, 'output', check_op_attrs=True)
- assert flag, resp
-
- (flag, resp) = compare_graphs(graph_ref, const_result_graph, 'output', check_op_attrs=True)
- assert flag, resp
-
- # as this two graphs calculated the same data through different constant folding functions, they resulted in
- # constants of different data type since FakeQuantize always have f32 output dtype, but eltwises use numpy
- # for folding which doesn't have such restriction
- const_node = graph.get_op_nodes(type='Const')
- assert len(const_node) == 1
- if const_node[0].data_type == np.float64:
- const_node[0].data_type = np.float32
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- # I would like to leave this commented code here to quickly check the actual output value:
- # print(result_node.in_port(0).data.get_value()) # actual calculated value
-
-
-class TestNegativeCompressionTestLevels():
- @pytest.mark.parametrize("levels" , [(2), (257), (None), (0), (-5)])
- def test_negative_fq_unacceptable_levels(self, levels):
- nodes = nodes_dict(np.float32, None, levels)
-
- graph = build_graph(nodes, [
- *connect('weights:0', '0:FQ'),
- *connect('il:0', '1:FQ'),
- *connect('ih:0', '2:FQ'),
- *connect('ol:0', '3:FQ'),
- *connect('oh:0', '4:FQ'),
- *connect('FQ:0', 'output'),
- ], nodes_with_edges_only=True)
- graph_ref = graph.copy()
- CompressQuantizeWeights().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
-
-
-class TestZeroPointOptimizerTestClass():
- @pytest.mark.parametrize("weights, zero_point, adj_weights, adj_zero_point" ,[
- ([-10, 7], [-1], [-9, 8], [0]),
- ([-10, 7], [-0.99999999], [-9, 8], [0]),
- ])
- def test_zero_point_optimization(self, weights, zero_point, adj_weights, adj_zero_point):
- nodes = lambda w, zp: {
- **valued_const_with_data('weights', np.array(w, dtype=np.int8)),
- **regular_op_with_shaped_data(
- 'cast', [len(w)], {'type': 'Convert', 'op': 'Cast', 'infer': Cast.infer, 'dst_type': np.float32}),
- **valued_const_with_data('zp', np.array(zp, dtype=np.float32)),
- **regular_op_with_shaped_data(
- 'sub', [len(w)],
- {'type': 'Subtract', 'op': 'Sub', 'infer': lambda node: eltwise_infer(node, Sub.operation)}),
- **result()
- }
- edges = [
- *connect("weights:0", "0:cast"),
- *connect("cast:0", "0:sub"),
- *connect("zp:0", "1:sub"),
- *connect("sub:0", "0:output"),
- ]
- graph = build_graph(nodes(weights, zero_point), edges, nodes_with_edges_only=True)
- ZeroPointOptimizer().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(nodes(adj_weights, adj_zero_point), [
- *connect("weights:0", "0:cast"),
- *connect("cast:0", "0:output"),
- ], nodes_with_edges_only=True)
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- @pytest.mark.parametrize("weights, zero_point, adj_weights, adj_zero_point" ,[
- ([-128, 7], [1], [-128, 7], [1]),
- ([127, 7], [-1], [127, 7], [-1]),
- ])
- def test_negative_zero_point_optimization(self, weights, zero_point, adj_weights, adj_zero_point):
- nodes = lambda w, zp: {
- **valued_const_with_data('weights', np.array(w, dtype=np.int8)),
- **regular_op_with_shaped_data(
- 'cast', [len(w)], {'type': 'Convert', 'op': 'Cast', 'infer': Cast.infer, 'dst_type': np.float32}),
- **valued_const_with_data('zp', np.array(zp, dtype=np.float32)),
- **regular_op_with_shaped_data(
- 'sub', [len(w)],
- {'type': 'Subtract', 'op': 'Sub', 'infer': lambda node: eltwise_infer(node, Sub.operation)}),
- **result()
- }
- edges = [
- *connect("weights:0", "0:cast"),
- *connect("cast:0", "0:sub"),
- *connect("zp:0", "1:sub"),
- *connect("sub:0", "0:output"),
- ]
- graph = build_graph(nodes(weights, zero_point), edges, nodes_with_edges_only=True)
- ZeroPointOptimizer().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(nodes(adj_weights, adj_zero_point), edges, nodes_with_edges_only=True)
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/back/ie_ir_ver_2/__init__.py b/tools/mo/unit_tests/mo/back/ie_ir_ver_2/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/back/ie_ir_ver_2/emitter_test.py b/tools/mo/unit_tests/mo/back/ie_ir_ver_2/emitter_test.py
deleted file mode 100644
index 7f781f0536efa6..00000000000000
--- a/tools/mo/unit_tests/mo/back/ie_ir_ver_2/emitter_test.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import MagicMock
-
-import defusedxml.ElementTree as ET
-import numpy as np
-from defusedxml import defuse_stdlib
-
-from openvino.tools.mo.back.ie_ir_ver_2.emitter import soft_get, xml_shape, serialize_runtime_info, serialize_network, \
- port_renumber
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer, type_infer
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.ops.pooling import Pooling
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.runtime_info import RTInfo, OldAPIMapOrder, OldAPIMapElementType
-from openvino.tools.mo.utils.unsupported_ops import UnsupportedOps
-from unit_tests.utils.graph import valued_const_with_data, result, regular_op_with_empty_data, connect, \
- shaped_parameter, build_graph, regular_op
-
-# defuse_stdlib provide patched version of xml.etree.ElementTree which allows to use objects from xml.etree.ElementTree
-# in a safe manner without including unsafe xml.etree.ElementTree
-ET_defused = defuse_stdlib()[ET]
-Element = ET_defused.Element
-tostring = ET_defused.tostring
-
-expected_result = b'2 10 50 50 '
-
-
-class TestEmitter(unittest.TestCase):
- def test_xml_shape(self):
- net = Element('net')
- xml_shape(np.array([2, 10, 50, 50], dtype=np.int64), net)
- self.assertEqual(tostring(net), expected_result)
-
- def test_xml_shape_float_values(self):
- net = Element('net')
- xml_shape(np.array([2.0, 10.0, 50.0, 50.0], dtype=np.float32), net)
- self.assertEqual(tostring(net), expected_result)
-
- def test_xml_shape_non_integer_values(self):
- net = Element('net')
- with self.assertRaises(Error):
- xml_shape(np.array([2.0, 10.0, 50.0, 50.5], dtype=np.float32), net)
-
- def test_xml_shape_negative_values(self):
- net = Element('net')
- with self.assertRaises(Error):
- xml_shape(np.array([2, 10, 50, -50], dtype=np.int64), net)
-
-
-class TestSoftGet(unittest.TestCase):
-
- def test_node(self):
- node = MagicMock()
- node.soft_get = lambda attr: attr
- self.assertEqual(soft_get(node, 'string'), 'string')
-
- def test_not_callable(self):
- node = MagicMock()
- node.soft_get = 'foo'
- self.assertEqual(soft_get(node, 'string'), '')
-
- def test_not_node_1(self):
- node = {'soft_get': lambda attr: attr}
- self.assertEqual(soft_get(node, 'string'), '')
-
- def test_not_node_2(self):
- node = 'something-else'
- self.assertEqual(soft_get(node, 'string'), '')
-
-
-class TestSerializeRTInfo(unittest.TestCase):
- def test_serialize_old_api_map_parameter(self):
- graph = build_graph({**regular_op('placeholder', {'type': 'Parameter', 'rt_info': RTInfo()}),
- **result('result')},
- [('placeholder', 'result')], {}, nodes_with_edges_only=True)
- param_node = Node(graph, 'placeholder')
- param_node.rt_info.info[('old_api_map_order', 0)] = OldAPIMapOrder()
- param_node.rt_info.info[('old_api_map_order', 0)].old_api_transpose_parameter([0, 2, 3, 1])
- param_node.rt_info.info[('old_api_map_element_type', 0)] = OldAPIMapElementType()
- param_node.rt_info.info[('old_api_map_element_type', 0)].set_legacy_type(np.float32)
-
- net = Element('net')
- serialize_runtime_info(param_node, net)
- serialize_res = str(tostring(net))
- self.assertTrue("name=\"old_api_map_order\"" in serialize_res)
- self.assertTrue("name=\"old_api_map_element_type\"" in serialize_res)
- self.assertTrue("version=\"0\"" in serialize_res)
- self.assertTrue("value=\"0,2,3,1\"" in serialize_res)
- self.assertTrue("value=\"f32\"" in serialize_res)
- self.assertTrue(serialize_res.startswith("b'"))
- self.assertTrue(serialize_res.endswith(" '"))
-
- del param_node.rt_info.info[('old_api_map_order', 0)]
- param_node.rt_info.info[('old_api_map_element_type', 0)] = OldAPIMapElementType()
- param_node.rt_info.info[('old_api_map_element_type', 0)].set_legacy_type(np.float16)
-
- net = Element('net')
- serialize_runtime_info(param_node, net)
- serialize_res = str(tostring(net))
- self.assertTrue("name=\"old_api_map_element_type\"" in serialize_res)
- self.assertTrue("version=\"0\"" in serialize_res)
- self.assertTrue("value=\"f16\"" in serialize_res)
- self.assertTrue(serialize_res.startswith("b'"))
- self.assertTrue(serialize_res.endswith(" '"))
-
- def test_serialize_old_api_map_result(self):
- graph = build_graph({**regular_op('placeholder', {'type': 'Parameter', 'rt_info': RTInfo()}),
- **regular_op('result', {'type': 'Result', 'rt_info': RTInfo()})},
- [('placeholder', 'result')], {}, nodes_with_edges_only=True)
- result_node = Node(graph, 'result')
- result_node.rt_info.info[('old_api_map_order', 0)] = OldAPIMapOrder()
- result_node.rt_info.info[('old_api_map_order', 0)].old_api_transpose_result([0, 3, 1, 2])
-
- net = Element('net')
- serialize_runtime_info(result_node, net)
- serialize_res = str(tostring(net))
- self.assertTrue("name=\"old_api_map_order\"" in serialize_res)
- self.assertTrue("version=\"0\"" in serialize_res)
- self.assertTrue("value=\"0,3,1,2\"" in serialize_res)
- self.assertTrue(serialize_res.startswith("b'"))
- self.assertTrue(serialize_res.endswith(" '"))
-
-
-class TestSerialize(unittest.TestCase):
- @staticmethod
- def build_graph_with_gather():
- nodes = {
- **shaped_parameter('data', int64_array([3, 3]), {'data_type': np.float32, 'type': Parameter.op}),
- **shaped_parameter('indices', int64_array([1, 2]), {'data_type': np.float32, 'type': Parameter.op}),
- **valued_const_with_data('axis', int64_array(1)),
- **regular_op_with_empty_data('gather', {'op': 'Gather', 'batch_dims': 0, 'infer': Gather.infer,
- 'type': Gather.op}),
- **result('res'),
- }
-
- edges = [
- *connect('data', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', 'res'),
- ]
-
- graph = build_graph(nodes, edges)
-
- data_node = Node(graph, 'data')
- Parameter.update_node_stat(data_node, {})
- indices_node = Node(graph, 'indices')
- Parameter.update_node_stat(indices_node, {})
-
- gather_node = Node(graph, 'gather')
- Gather.update_node_stat(gather_node, {})
-
- res_node = Node(graph, 'res')
- Result.update_node_stat(res_node, {})
-
- partial_infer(graph)
- type_infer(graph)
-
- return graph
-
- @staticmethod
- def build_graph_with_maxpool():
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node', 'infer': Parameter.infer,
- 'shape': [1, 3, 10, 10]},
- 'input_data': {'kind': 'data', 'value': None, 'shape': None},
-
- 'pool': {'kind': 'op', 'type': 'MaxPool', 'infer': Pooling.infer,
- 'window': np.array([1, 1, 2, 2]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [0, 0], [1, 1]]),
- 'pad_spatial_shape': np.array([[0, 0], [1, 1]]),
- 'pool_method': 'max', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([2, 2]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full', 'dilation': np.array([1, 1, 2, 2]),
- 'auto_pad': 'valid'},
-
- 'pool_data': {'kind': 'data', 'value': None, 'shape': None},
- 'pool_data_added': {'kind': 'data', 'value': None, 'shape': None},
- 'result': {'kind': 'op', 'op': 'Result'},
- 'result_added': {'kind': 'op', 'op': 'Result'}
- },
- edges=[
- ('input', 'input_data'),
- ('input_data', 'pool'),
- ('pool', 'pool_data', {'out': 0}),
- ('pool_data', 'result'),
- ('pool', 'pool_data_added', {'out': 1}),
- ('pool_data_added', 'result_added')
- ]
- )
-
- input_node = Node(graph, 'input')
- Parameter.update_node_stat(input_node, {})
-
- pool_node = Node(graph, 'pool')
- Pooling.update_node_stat(pool_node, {'pool_method': 'max'})
-
- result_node = Node(graph, 'result')
- Result.update_node_stat(result_node, {})
- result_added_node = Node(graph, 'result_added')
- Result.update_node_stat(result_added_node, {})
-
- partial_infer(graph)
- type_infer(graph)
- return graph
-
- def test_gather(self):
- graph = self.build_graph_with_gather()
-
- net = Element('net')
- graph.outputs_order = ['gather']
- unsupported = UnsupportedOps(graph)
- port_renumber(graph)
-
- serialize_network(graph, net, unsupported)
- xml_string = str(tostring(net))
- self.assertTrue("type=\"Parameter\"" in xml_string)
- self.assertTrue("type=\"Result\"" in xml_string)
- self.assertTrue("type=\"Gather\"" in xml_string)
-
- def test_maxpool(self):
- graph = self.build_graph_with_maxpool()
-
- net = Element('net')
- graph.outputs_order = ['pool']
- unsupported = UnsupportedOps(graph)
- port_renumber(graph)
- serialize_network(graph, net, unsupported)
- xml_string = str(tostring(net))
- self.assertTrue("type=\"Parameter\"" in xml_string)
- self.assertTrue("type=\"Result\"" in xml_string)
- self.assertTrue("type=\"Pooling\"" in xml_string)
-
- def test_maxpool_raises(self):
- graph = self.build_graph_with_maxpool()
-
- pool_node = Node(graph, 'pool')
- result_node = Node(graph, 'result')
- result_added_node = Node(graph, 'result_added')
- pool_out_1 = Node(graph, 'pool_data')
- pool_out_2 = Node(graph, 'pool_data_added')
-
- # when operation does not have output data nodes Exception should be raised
- graph.remove_edge(pool_node.id, pool_out_1.id)
- graph.remove_edge(pool_node.id, pool_out_2.id)
- graph.remove_edge(pool_out_1.id, result_node.id)
- graph.remove_edge(pool_out_2.id, result_added_node.id)
-
- graph.remove_node(result_node.id)
- graph.remove_node(result_added_node.id)
-
- net = Element('net')
- graph.outputs_order = ['pool']
- unsupported = UnsupportedOps(graph)
- port_renumber(graph)
-
- with self.assertRaisesRegex(AssertionError, "Incorrect graph. Non-Result node.*"):
- serialize_network(graph, net, unsupported)
diff --git a/tools/mo/unit_tests/mo/back/insert_compatibility_l2normalization_test.py b/tools/mo/unit_tests/mo/back/insert_compatibility_l2normalization_test.py
deleted file mode 100644
index 19bbeeba8bad7c..00000000000000
--- a/tools/mo/unit_tests/mo/back/insert_compatibility_l2normalization_test.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.back.insert_compatibility_l2normalization import CompatibilityL2NormalizationPattern
-from unit_tests.utils.graph import build_graph
-
-
-class CompatibilityL2NormalizationPatternTest(unittest.TestCase):
- nodes = {
- 'input_node': {
- 'kind': 'data'
- },
- 'l2norm_node': {
- 'op': 'Normalize',
- 'kind': 'op',
- 'type': 'Normalize',
- },
- 'output_node': {
- 'kind': 'data'
- }
- }
-
- def test_insert_data(self):
- graph = build_graph(self.nodes, [('input_node', 'l2norm_node'), ('l2norm_node', 'output_node')],
- {'input_node': {'shape': np.array([1, 10])},
- })
- CompatibilityL2NormalizationPattern().find_and_replace_pattern(graph)
- self.assertEqual(len(graph.nodes()), 5)
- self.assertEqual(graph.node['l2norm_node_weights']['name'], 'l2norm_node_weights')
- self.assertEqual(len(graph.node['l2norm_node_weights']['value']), 10)
-
- expect_value = np.full([10], 1.0, np.float32)
-
- for i, val in enumerate(expect_value):
- self.assertEqual(graph.node['l2norm_node_weights']['value'][i], val)
diff --git a/tools/mo/unit_tests/mo/back/kaldi_remove_memory_output_test.py b/tools/mo/unit_tests/mo/back/kaldi_remove_memory_output_test.py
deleted file mode 100644
index c57d0e5d0886f5..00000000000000
--- a/tools/mo/unit_tests/mo/back/kaldi_remove_memory_output_test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.kaldi_remove_memory_output import KaldiRemoveMemoryOutputBackReplacementPattern
-from unit_tests.utils.graph import build_graph
-
-
-class KaldiRemoveMemoryOutputTest(unittest.TestCase):
- nodes = {
- 'input_node': {
- 'kind': 'data'
- },
- 'memory_node': {
- 'op': 'Assign',
- 'kind': 'op'
- },
- 'output_node': {
- 'kind': 'data'
- },
- 'op_output': {
- 'kind': 'data',
- 'op': 'Result',
- }
- }
-
- def test_remove_out_data_for_memory(self):
- graph = build_graph(self.nodes,
- [
- ('input_node', 'memory_node'),
- ('memory_node', 'output_node'),
- ('output_node', 'op_output')
- ])
- KaldiRemoveMemoryOutputBackReplacementPattern().find_and_replace_pattern(graph)
- self.assertNotIn('output_node', graph.node)
-
- def test_do_not_remove_out_data_for_memory(self):
- graph = build_graph(self.nodes,
- [
- ('input_node', 'memory_node'),
- ('memory_node', 'output_node'),
- ])
- KaldiRemoveMemoryOutputBackReplacementPattern().find_and_replace_pattern(graph)
- self.assertIn('output_node', graph.node)
diff --git a/tools/mo/unit_tests/mo/back/moc_preprocessing_test_actual.py b/tools/mo/unit_tests/mo/back/moc_preprocessing_test_actual.py
deleted file mode 100644
index 39d4913a26a103..00000000000000
--- a/tools/mo/unit_tests/mo/back/moc_preprocessing_test_actual.py
+++ /dev/null
@@ -1,731 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from argparse import Namespace
-
-import numpy as np
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-
-try:
- # pylint: disable=no-name-in-module,import-error
- from openvino.tools.mo.back.preprocessing import apply_preprocessing
-
- # pylint: disable=no-name-in-module,import-error
- import openvino.runtime.opset8 as ops
- from openvino.runtime import Model, Layout, PartialShape
-
-except Exception:
- print("No OpenVINO API available,"
- "ensure to set correct PYTHONPATH when running these tests")
- raise
-
-
-def create_function3(shape1=[2, 2]):
- input1 = ops.parameter(shape1, dtype=np.float32, name="input1")
- input1.get_output_tensor(0).set_names({'a_input', 'b_input', 'c_input'})
- relu1 = ops.relu(input1)
- res1 = ops.result(relu1, "res")
- res1.get_output_tensor(0).set_names({'res'})
- function = Model(results=[res1], parameters=[input1], name="TestFunction")
- return function
-
-
-def create_function2(shape1=[2, 2], shape2=[2, 2], dtype1=np.float32, dtype2=np.float32):
- input1 = ops.parameter(shape1, dtype=dtype1, name="input1")
- input1.get_output_tensor(0).set_names({'input1', 'input1a'})
- relu1 = ops.relu(input1)
- res1 = ops.result(relu1, "res1")
- res1.get_output_tensor(0).set_names({'res1', 'res1a'})
- input2 = ops.parameter(shape2, dtype=dtype2, name="input2")
- input2.get_output_tensor(0).set_names({'input2', 'input2a'})
- relu2 = ops.relu(input2)
- res2 = ops.result(relu2, "res2")
- res2.get_output_tensor(0).set_names({'res2', 'res2a'})
- function = Model(results=[res1, res2], parameters=[input1, input2], name="TestFunction")
- return function
-
-
-def create_function1(shape1=[2, 2]):
- input1 = ops.parameter(shape1, dtype=np.float32, name="input1")
- input1.get_output_tensor(0).set_names({'input1a', 'input1b'})
- relu1 = ops.relu(input1)
- res1 = ops.result(relu1, "res1")
- res1.get_output_tensor(0).set_names({'res1', 'res1a'})
- function = Model(results=[res1], parameters=[input1], name="TestFunction")
- return function
-
-
-def process_function(ov_function: Model, argv: Namespace):
- apply_preprocessing(ov_function=ov_function, argv=argv)
-
-
-class TestPreprocessingMOC(UnitTestWithMockedTelemetry):
- def setUp(self):
- super(TestPreprocessingMOC, self).setUp()
- pass
-
- def check_constant(self, const_node, expected, shape=None):
- self.assertEqual(const_node.get_type_name(), 'Constant')
- self.assertTrue(np.allclose(const_node.get_vector(), expected))
- if shape is not None:
- assert const_node.shape == PartialShape(shape)
-
- def check_scale_constant(self, node, expected, shape=None):
- const_node = node.input(1).get_source_output().get_node()
- if node.get_type_name() != 'Divide':
- expected = 1. / expected
- self.check_constant(const_node, expected, shape)
-
- def check_mean_constant(self, node, expected, shape=None):
- const_node = node.input(1).get_source_output().get_node()
- if node.get_type_name() != 'Subtract':
- expected = -expected.toList()
- self.check_constant(const_node, expected, shape)
-
- def test_scale_single_value(self):
- argv = Namespace(mean_scale_values=None, scale=2.0)
- function = create_function2()
- process_function(ov_function=function, argv=argv)
-
- for param in function.get_parameters():
- op_node = list(param.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, [2.0])
-
- def test_scale_single_value_fp64(self):
- argv = Namespace(mean_scale_values=None, scale=2.0)
- function = create_function2(dtype1=np.float64)
- process_function(ov_function=function, argv=argv)
-
- for ov_input in function.inputs:
- op_node = list(ov_input.get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, [2.0])
-
- def test_scale_single_value_fp16(self):
- argv = Namespace(mean_scale_values=None, scale=2.0)
- function = create_function2(dtype1=np.float16)
- process_function(ov_function=function, argv=argv)
-
- for ov_input in function.inputs:
- op_node = list(ov_input.get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
-
- def test_scale_vector(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([4.]), 'mean': None}}, scale=None)
- function = create_function2()
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, [4.0], shape=None)
- # Verify that input2 is not affected
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- def test_scale_vector3(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([2., 4., 8.]), 'mean': None}}, scale=None)
- function = create_function2(shape1=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- # Verify that input2 is not affected
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that guessed layout (?C??) is not appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout())
-
- def test_scale_vector4_layout(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([2., 4., 8., 9.]), 'mean': None}},
- layout_values={'input1': {'source_layout': 'nhwc'}},
- scale=None)
- function = create_function2(shape1=[1, 3, 3, 4]) # Use layout to determine channels dim
-
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8., 9.], shape=[1, 1, 1, 4])
-
- # Verify that input2 is not affected
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that layout (NHWC) is appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout('nhwc'))
-
- def test_mean_single(self):
- argv = Namespace(mean_scale_values={'input1': {'mean': np.array([4.]), 'scale': None}}, scale=None)
- function = create_function2()
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, [4.0], shape=None)
- # Verify that input2 is not affected
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- def test_mean_single_fp64(self):
- argv = Namespace(mean_scale_values={'input1': {'mean': np.array([4.]), 'scale': None}}, scale=None)
- function = create_function2(dtype1=np.float64)
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, [4.0], shape=None)
- # Verify that input2 is not affected
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- def test_mean_single_fp16(self):
- argv = Namespace(mean_scale_values={'input1': {'mean': np.array([4.]), 'scale': None}}, scale=None)
- function = create_function2(dtype1=np.float16)
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- # Verify that input2 is not affected
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- def test_mean_vector3(self):
- argv = Namespace(mean_scale_values={'input2': {'mean': np.array([2., 4., 8.]), 'scale': None}}, scale=None)
- function = create_function2(shape2=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- # Verify that input1 is not affected
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that guessed layout (?C??) is not appeared in input2
- self.assertEqual(function.get_parameters()[1].layout, Layout())
-
- def test_mean_scale(self):
- argv = Namespace(mean_scale_values={'input2a': {'mean': np.array([1., 2., 3.]),
- 'scale': np.array([2., 4., 8.])}},
- scale=None)
- function = create_function2(shape2=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- # Verify that first is 'subtract mean', then 'scale'
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[1., 2., 3.], shape=[1, 3, 1, 1])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- # Verify that input1 is not affected
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that guessed layout (?C??) is not appeared in input2
- self.assertEqual(function.get_parameters()[1].layout, Layout())
-
- def test_mean_scale_with_layout(self):
- argv = Namespace(mean_scale_values={'input2a': {'mean': np.array([1., 2., 3., 4.]),
- 'scale': np.array([2., 4., 8., 9.])}},
- scale=None)
- function = create_function2(shape2=[1, 3, 3, 4])
- function.get_parameters()[1].layout = Layout("NHWC")
- process_function(ov_function=function, argv=argv)
- # Verify that first is 'subtract mean', then 'scale'
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[1., 2., 3., 4.], shape=[1, 1, 1, 4])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8., 9.], shape=[1, 1, 1, 4])
-
- # Verify that input1 is not affected
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that layout presents in function after preprocessing
- self.assertEqual(function.get_parameters()[1].layout, Layout("NHWC"))
-
- def test_mean_scale_with_layout_dynamic(self):
- argv = Namespace(mean_scale_values={'input2a': {'mean': np.array([1., 2., 3., 4.]),
- 'scale': np.array([2., 4., 8., 9.])}},
- scale=None)
- function = create_function2(shape2=[-1, -1, -1, -1])
- function.get_parameters()[1].layout = Layout("NHWC")
- process_function(ov_function=function, argv=argv)
- # Verify that first is 'subtract mean', then 'scale'
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[1., 2., 3., 4.], shape=[1, 1, 1, 4])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8., 9.], shape=[1, 1, 1, 4])
-
- # Verify that input1 is not affected
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that layout presents in function after preprocessing
- self.assertEqual(function.get_parameters()[1].layout, Layout("NHWC"))
-
- def test_no_param_name(self):
- argv = Namespace(mean_scale_values=list(np.array([(np.array([1., 2., 3.]), np.array([2., 4., 6.])),
- (np.array([7., 8., 9.]), None)],
- dtype='object')), scale=None)
- function = create_function2(shape1=[1, 3, 224, 224], shape2=[1, 224, 224, 3])
- process_function(ov_function=function, argv=argv)
-
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[1., 2., 3.], shape=[1, 3, 1, 1])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 6.], shape=[1, 3, 1, 1])
-
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[7., 8., 9.], shape=[1, 1, 1, 3])
-
- # Verify that guessed layouts are not appeared in inputs
- self.assertEqual(function.get_parameters()[0].layout, Layout())
- self.assertEqual(function.get_parameters()[1].layout, Layout())
-
- def test_no_param_name_single_value(self):
- argv = Namespace(mean_scale_values=list(np.array([(np.array([1.]), None),
- (np.array([2., 3., 4.]), np.array([5.]))],
- dtype='object')), scale=None)
- function = create_function2(shape1=[1, 3, 224, 224], shape2=[1, 224, 224, 3])
- process_function(ov_function=function, argv=argv)
-
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[1.], shape=None)
-
- op_node = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[2., 3., 4.], shape=[1, 1, 1, 3])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[5.], shape=None)
-
- # Two inputs, but 'mean_scale_value' has only one array
- def test_error_no_param_name_number_not_match(self):
- argv = Namespace(mean_scale_values=[(np.array([2., 3.]), np.array([4.]))], scale=None)
- function = create_function2(shape1=[1, 3, 224, 224], shape2=[1, 2, 224, 224])
- with self.assertRaisesRegex(Error, '.*question.*61.*'):
- process_function(ov_function=function, argv=argv)
-
- def test_mean_scale_error_no_node_name_found(self):
- argv = Namespace(mean_scale_values={'not_found': {'scale': np.array([1.]), 'mean': np.array([1.])}},
- scale=None)
- function = create_function2(shape1=[1, 3, 224, 224], shape2=[1, 2, 224, 224])
- with self.assertRaisesRegex(Error, '.*question.*83.*'):
- process_function(ov_function=function, argv=argv)
-
- def test_layout_error_no_node_name_found(self):
- argv = Namespace(layout_values={'not_found': {'source_layout': 'nhwc'}},
- scale=None)
- function = create_function2(shape1=[1, 3, 224, 224], shape2=[1, 2, 224, 224])
- with self.assertRaisesRegex(Error, '.*question.*83.*'):
- process_function(ov_function=function, argv=argv)
-
- def test_error_dimension_mismatch(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3., 4.]), 'mean': None}},
- scale=None)
- function = create_function2(shape1=[1, 3, 224, 224])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_dimension_not_clear(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3.]), 'mean': None}},
- scale=None)
- function = create_function2(shape1=[1, 3, 3, 3]) # Not clear to which 3 should scale be applied
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_dimension_mismatch_with_scale(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3., 4.]),
- 'mean': np.array([1., 2., 3.])}},
- scale=None)
- function = create_function2(shape1=[1, 3, 4, 224])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_guess_c_wrong_position_3d(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3.]),
- 'mean': np.array([1., 2., 3.])}},
- scale=None)
- function = create_function2(shape1=[2, 3, 4])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_guess_c_wrong_position_4d(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3.]),
- 'mean': np.array([1., 2., 3.])}},
- scale=None)
- function = create_function2(shape1=[1, 2, 3, 4])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_guess_c_wrong_position_5d(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3.]),
- 'mean': np.array([1., 2., 3.])}},
- scale=None)
- function = create_function2(shape1=[1, 2, 3, 4, 5])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_guess_c_wrong_position_6d(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3.]),
- 'mean': np.array([1., 2., 3.])}},
- scale=None)
- function = create_function2(shape1=[1, 2, 4, 5, 6, 3])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_2_names_to_same_input(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([1., 2., 3.])},
- 'input1a': {'scale': np.array([1., 2., 3.])}},
- scale=None)
- function = create_function2(shape1=[1, 3, 224, 224])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_error_2_names_to_same_input_single_value(self):
- argv = Namespace(mean_scale_values={'input1': {'scale': np.array([2.])},
- 'input1a': {'scale': np.array([3.])}},
- scale=None)
- function = create_function2(shape1=[1, 3, 224, 224])
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_reverse_input_channels(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[1, 224, 224, 3], shape2=[1, 3, 224, 224])
- process_function(ov_function=function,
- argv=argv)
- # Verify that some operations are inserted.
- # In future, consider using mock PrePostProcessor to verify that 'reverse_channels' was called
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
-
- # Verify that guessed layouts are not appeared in input1,input2
- self.assertEqual(function.get_parameters()[0].layout, Layout())
- self.assertEqual(function.get_parameters()[1].layout, Layout())
-
- def test_reverse_input_channels_func_layout(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[1, 3, 3, 3], shape2=[1, 3, 3, 3])
- function.get_parameters()[0].layout = Layout("NCHW")
- function.get_parameters()[1].layout = Layout("NHWC")
- process_function(ov_function=function,
- argv=argv)
- # Verify that some operations are inserted.
- # In future, consider using mock PrePostProcessor to verify that 'reverse_channels' was called
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
-
- # Verify that guessed layouts are not appeared in input1,input2
- self.assertEqual(function.get_parameters()[0].layout, Layout("NCHW"))
- self.assertEqual(function.get_parameters()[1].layout, Layout("NHWC"))
-
- def test_reverse_input_channels_layout(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values={'input1a': { 'source_layout': 'nhwc' },
- 'input2a': { 'source_layout': 'nchw' }
- })
- function = create_function2(shape1=[1, 224, 224, 4], shape2=[1, 4, 224, 224])
- # no suitable inputs
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_reverse_input_channels_3d(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values=None)
- function = create_function2(shape1=[224, 224, 3], shape2=[3, 224, 224])
- process_function(ov_function=function, argv=argv)
- # Verify that reverse_channels are applied.
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
-
- def test_reverse_input_channels_6d(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values=None)
- function = create_function2(shape1=[4, 4, 4, 4, 4, 3], shape2=[4, 3, 4, 4, 4, 4])
- # no suitable inputs
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_reverse_input_channels_dynamic(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values=None)
- function = create_function2(shape1=[1, -1, 5, 5], shape2=[-1, -1, -1, -1])
- # no suitable inputs
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_reverse_input_channels_dynamic_layout(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values={'input1a': {'source_layout': 'nchw'},
- 'input2a': {'source_layout': 'nhwc'}
- })
- function = create_function2(shape1=[1, -1, 5, 5], shape2=[-1, -1, -1, -1])
- process_function(ov_function=function, argv=argv)
- # Verify that reverse_channels are applied.
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
-
- def test_reverse_input_channels_layout_change(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values={'input1a': {'source_layout': 'nchw', 'target_layout': 'nhwc'},
- 'input2a': {'source_layout': 'nhwc', 'target_layout': 'nchw'}
- })
- function = create_function2(shape1=[1, 3, 5, 5], shape2=[1, 5, 5, 3])
- process_function(ov_function=function, argv=argv)
- # Verify that reverse_channels are applied.
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
-
- def test_reverse_input_channels_2_channels(self):
- argv = Namespace(reverse_input_channels=True,
- mean_scale_values=None,
- scale=None)
- function = create_function2(shape1=[1, 224, 224, 2], shape2=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- # Verify that some operations are inserted to input2.
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() == 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
-
- # Verify that guessed layouts are not appeared in input1,input2
- self.assertEqual(function.get_parameters()[0].layout, Layout())
- self.assertEqual(function.get_parameters()[1].layout, Layout())
-
- # When input name for layout is empty for model with one input - it is applied to this input
- def test_scale_vector3_layout_empty_input_name(self):
- argv = Namespace(mean_scale_values=list(np.array([(None, np.array([2., 4., 8.]))],
- dtype='object')),
- layout_values={'': {'source_layout': 'nchw'}},
- scale=None)
- function = create_function1(shape1=[1, 3, 3, 3]) # Use layout to determine channels dim
-
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- # Verify that layout (nchw) is appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout('nchw'))
-
- def test_layout_output(self):
- argv = Namespace(mean_scale_values=None,
- layout_values={
- 'res1': {
- 'source_layout': 'nchw',
- 'target_layout': 'nhwc'
- },
- 'res2a': {
- 'source_layout': 'ncdhw'
- }
- },
- scale=None)
- function = create_function2(shape1=[1, 3, 3, 3], shape2=[1, 3, 3, 3, 3])
-
- process_function(ov_function=function, argv=argv)
- op_node = function.get_results()[0].input(0).get_source_output().get_node()
- self.assertEqual(op_node.get_type_name(), 'Transpose')
-
- self.assertEqual(function.get_results()[0].layout, Layout('nhwc'))
- self.assertEqual(function.get_results()[1].layout, Layout('ncdhw'))
-
- def test_error_layout_empty_input_name_2_inputs(self):
- argv = Namespace(mean_scale_values=None,
- layout_values={'': {'source_layout': 'nchw'}},
- scale=None)
- function = create_function2(shape1=[1, 3, 3, 3])
-
- # Verify user friendly error message contains number of inputs and their names
- with self.assertRaisesRegex(Error, '.*2.*inputs.*input1.*input2.*'):
- process_function(ov_function=function, argv=argv)
-
- def test_incompatible_layout(self):
- function = create_function2(shape1=[1, 224, 224, 3], shape2=[1, 4, 224, 224])
- with self.assertRaisesRegex(Exception, '.*input1.*'):
- function.get_parameters()[0].layout = Layout("NDHWC")
-
- def test_guess_layout_reverse_channels_dont_apply_to_4(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[1, 224, 224, 3], shape2=[1, 4, 224, 224])
- process_function(ov_function=function, argv=argv)
-
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() == 'Relu')
-
- def test_error_guess_layout_reverse_channels_multi_3(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[1, 224, 224, 3], shape2=[1, 3, 3, 224])
- process_function(ov_function=function, argv=argv)
- # Applied to only input1
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() == 'Relu')
-
-
- def test_no_guess_layout_reverse_channels_has_layout_no_c(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[1, 224, 224, 3], shape2=[1, 3, 224, 224])
- function.get_parameters()[0].layout = Layout("NHW?")
- function.get_parameters()[1].layout = Layout("N?HW")
- # no suitable inputs
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_guess_layout_reverse_channels_incorrect_pos(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[1, 4, 224, 224], shape2=[1, 224, 224, 2])
- function.get_parameters()[0].layout = Layout("NCHW")
- function.get_parameters()[1].layout = Layout("NHWC")
- # no suitable inputs
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_no_reverse_channels_even_with_layout(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None)
- function = create_function2(shape1=[3, 4, 224, 224], shape2=[1, 224, 3, 224])
- # no suitable inputs
- with self.assertRaises(Exception):
- process_function(ov_function=function, argv=argv)
-
- def test_reverse_channels_and_mean_scale(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values={
- 'input2a': {
- 'mean': np.array([1., 2., 3.]),
- 'scale': np.array([2., 4., 8.])}},
- scale=None)
- function = create_function2(shape2=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
-
- # Verify that first is gather, then subtract 'mean', then 'scale'
- gather = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(gather.get_type_name() == 'Gather')
- range_node = gather.input(1).get_source_output().get_node()
- self.assertTrue(range_node.get_type_name() == 'Range')
- start = range_node.input(0).get_source_output().get_node()
- end = range_node.input(1).get_source_output().get_node()
- step = range_node.input(2).get_source_output().get_node()
- self.check_constant(start, expected=[2], shape=[])
- self.check_constant(end, expected=[-1], shape=[])
- self.check_constant(step, expected=[-1], shape=[])
- axes = gather.input(2).get_source_output().get_node()
- self.check_constant(axes, expected=[1], shape=[1])
-
- op_node = list(gather.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[1., 2., 3.], shape=[1, 3, 1, 1])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- # Verify that input1 is not affected
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertEqual(op_node.get_type_name(), 'Relu')
-
- # Verify that guessed layout (?C??) is not appeared in input2
- self.assertEqual(function.get_parameters()[1].layout, Layout())
-
- def test_friendly_name(self):
- argv = Namespace(mean_scale_values={'input1': {'mean': np.array([2., 4., 8.]), 'scale': None}},
- layout_values={'input1': {'source_layout': 'nchw'}},
- scale=None)
- function = create_function1(shape1=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- # Verify that layout (nchw) is appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout('nchw'))
-
- def test_sorting_tensor_names(self):
- argv = Namespace(mean_scale_values={'c_input': {'mean': np.array([2., 4., 8.]), 'scale': None}},
- layout_values={'c_input': {'source_layout': 'nchw'}},
- scale=127.5)
- function = create_function3(shape1=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=127.5, shape=[1])
-
- # Verify that layout (nchw) is appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout('nchw'))
-
- def test_sorting_tensor_names_friendly_name_case(self):
- argv = Namespace(mean_scale_values={'input1': {'mean': np.array([2., 4., 8.]), 'scale': None}},
- layout_values={'input1': {'source_layout': 'nchw'}},
- scale=127.5)
- function = create_function3(shape1=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=127.5, shape=[1])
-
- # Verify that layout (nchw) is appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout('nchw'))
-
- def test_sorting_tensor_names_unnamed_layout(self):
- argv = Namespace(mean_scale_values={'input1': {'mean': np.array([2., 4., 8.]), 'scale': None}},
- layout_values={'': {'source_layout': 'nchw'}},
- scale=127.5)
- function = create_function3(shape1=[1, 3, 224, 224])
- process_function(ov_function=function, argv=argv)
- op_node = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Subtract' or op_node.get_type_name() == 'Add')
- self.check_mean_constant(op_node, expected=[2., 4., 8.], shape=[1, 3, 1, 1])
-
- op_node = list(op_node.output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node.get_type_name() == 'Divide' or op_node.get_type_name() == 'Multiply')
- self.check_scale_constant(op_node, expected=127.5, shape=[1])
-
- # Verify that layout (nchw) is appeared in input1
- self.assertEqual(function.get_parameters()[0].layout, Layout('nchw'))
-
- def test_sorting_tensor_names_unnamed_layout_list(self):
- argv = Namespace(reverse_input_channels=True, mean_scale_values=None, scale=None,
- layout_values=[{'source_layout': 'nchw', 'target_layout': 'nhwc'},
- {'source_layout': 'nhwc', 'target_layout': 'nchw'}])
-
- function = create_function2(shape1=[1, 3, 5, 5], shape2=[1, 5, 5, 3])
- process_function(ov_function=function, argv=argv)
- # Verify that reverse_channels are applied.
- op_node0 = list(function.get_parameters()[0].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node0.get_type_name() != 'Relu')
- op_node1 = list(function.get_parameters()[1].output(0).get_target_inputs())[0].get_node()
- self.assertTrue(op_node1.get_type_name() != 'Relu')
diff --git a/tools/mo/unit_tests/mo/back/names_uniqueness_check_test.py b/tools/mo/unit_tests/mo/back/names_uniqueness_check_test.py
deleted file mode 100644
index 7623c19d39a67f..00000000000000
--- a/tools/mo/unit_tests/mo/back/names_uniqueness_check_test.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.names_uniqueness_check import NamesUniquenessCheck
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-class TestNamesUniquenessCheck(unittest.TestCase):
-
- def test_1(self):
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node'},
- 'cast': {'kind': 'op', 'op': 'Cast', 'name': 'node'},
- 'result': {'kind': 'op', 'op': 'Result', 'name': 'node'}
- },
- edges=[
- ('input', 'cast'),
- ('cast', 'result')
- ]
- )
-
- NamesUniquenessCheck().find_and_replace_pattern(graph)
- names = [node.name for node in graph.get_op_nodes()]
- result_name = Node(graph, 'result').name
-
- self.assertTrue(len(set(names)) == 3)
- self.assertTrue(result_name == 'node')
-
- def test_2(self):
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node'},
- 'cast': {'kind': 'op', 'op': 'Cast', 'name': 'node_0'},
- 'result': {'kind': 'op', 'op': 'Result', 'name': 'node'}
- },
- edges=[
- ('input', 'cast'),
- ('cast', 'result')
- ]
- )
-
- NamesUniquenessCheck().find_and_replace_pattern(graph)
- names = [node.name for node in graph.get_op_nodes()]
- result_name = Node(graph, 'result').name
-
- self.assertTrue(len(set(names)) == 3)
- self.assertTrue(result_name == 'node')
-
- def test_3(self):
- graph = build_graph(
- nodes_attrs={
- 'input': {'kind': 'op', 'op': 'Parameter', 'name': 'node_0'},
- 'cast': {'kind': 'op', 'op': 'Cast', 'name': 'node_1'},
- 'result_1': {'kind': 'op', 'op': 'Result', 'name': 'node'},
- 'result_2': {'kind': 'op', 'op': 'Result', 'name': 'node'}
- },
- edges=[
- ('input', 'cast'),
- ('cast', 'result_1'),
- ('cast', 'result_2'),
- ]
- )
- NamesUniquenessCheck().find_and_replace_pattern(graph)
- names = [node.name for node in graph.get_op_nodes()]
-
- self.assertTrue('node' in names)
- self.assertTrue(len(set(names)) == 4)
diff --git a/tools/mo/unit_tests/mo/back/remove_last_softmax_test.py b/tools/mo/unit_tests/mo/back/remove_last_softmax_test.py
deleted file mode 100644
index d9b278f51c88bd..00000000000000
--- a/tools/mo/unit_tests/mo/back/remove_last_softmax_test.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.back.remove_last_softmax_pattern import RemoveLastSoftMaxPattern, RemoveLastLogSoftMaxPattern
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class KaldiRemoveLastSoftMaxTest(unittest.TestCase):
- nodes = {
- 'input_node': {
- 'kind': 'data'
- },
- 'softmax_node': {
- 'op': 'SoftMax',
- 'kind': 'op'
- },
- 'output_node': {
- 'kind': 'data'
- },
- 'op_output': {
- 'kind': 'op',
- 'op': 'Result'
- },
- 'log_node': {
- 'op': 'Log',
- 'kind': 'op'
- },
- 'log_data': {
- 'kind': 'data'
- },
- }
-
- nodes_for_logsoftmax = {
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'input_data': {'kind': 'data'},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'reduce_max_node': {'kind': 'op', 'op': 'ReduceMax'},
- 'reduce_max_node_data': {'kind': 'data'},
- 'reduce_max_axis': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'reduce_max_axis_data': {
- 'kind': 'data',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'sub_data': {'kind': 'data'},
- 'exp': {'kind': 'op', 'op': 'Exp'},
- 'exp_data': {'kind': 'data'},
- 'reduce_sum_node': {'kind': 'op', 'op': 'ReduceSum'},
- 'reduce_sum_node_data': {'kind': 'data'},
- 'reduce_sum_axis': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'reduce_sum_axis_data': {
- 'kind': 'data',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'log': {'kind': 'op', 'op': 'Log'},
- 'log_data': {'kind': 'data'},
- 'last_sub': {'kind': 'op', 'op': 'Sub'},
- 'last_sub_data': {'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
- edges_for_logsoftmax = [
- ('input', 'input_data'),
- ('input_data', 'sub', {'in': 0}),
- ('input_data', 'reduce_max_node', {'in': 0}),
- ('reduce_max_node', 'reduce_max_node_data'),
- ('reduce_max_node_data', 'sub', {'in': 1}),
- ('reduce_max_axis', 'reduce_max_axis_data'),
- ('reduce_max_axis_data', 'reduce_max_node', {'in': 1}),
- ('sub', 'sub_data'),
- ('sub_data', 'exp', {'out': 0, 'in': 0}),
- ('exp', 'exp_data'),
- ('exp_data', 'reduce_sum_node', {'in': 0}),
- ('reduce_sum_node', 'reduce_sum_node_data'),
- ('reduce_sum_axis', 'reduce_sum_axis_data'),
- ('reduce_sum_axis_data', 'reduce_sum_node', {'in': 1}),
- ('reduce_sum_node_data', 'log'),
- ('log', 'log_data'),
- ('log_data', 'last_sub', {'in': 1}),
- ('last_sub', 'last_sub_data'),
- ('sub_data', 'last_sub', {'out': 0, 'in': 0}),
- ('last_sub_data', 'op_output'),
- ]
-
- def test_remove_last_SoftMax(self):
- graph = build_graph(self.nodes, [
- ('input_node', 'softmax_node'),
- ('softmax_node', 'output_node'),
- ('output_node', 'op_output')
- ], nodes_with_edges_only=True)
- RemoveLastSoftMaxPattern().find_and_replace_pattern(graph)
- self.assertNotIn('softmax_node', graph.node)
-
- def test_remove_last_LogSoftMax(self):
- graph = build_graph(nodes_attrs=self.nodes_for_logsoftmax, edges=self.edges_for_logsoftmax)
- RemoveLastLogSoftMaxPattern().find_and_replace_pattern(graph)
- graph.clean_up()
-
- ref_graph_nodes_attributes = {
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'input_data': {'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
- ref_graph_edges = [('input', 'input_data'), ('input_data', 'op_output')]
- ref_graph = build_graph(ref_graph_nodes_attributes, ref_graph_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'op_output')
- self.assertTrue(flag, resp)
-
- def test_do_not_remove_not_last_SoftMax(self):
- graph = build_graph(self.nodes, [
- ('input_node', 'softmax_node'),
- ('softmax_node', 'output_node')
- ])
- RemoveLastSoftMaxPattern().find_and_replace_pattern(graph)
- self.assertIn('softmax_node', graph.node)
diff --git a/tools/mo/unit_tests/mo/bom_test.py b/tools/mo/unit_tests/mo/bom_test.py
deleted file mode 100644
index b836eefc888f2b..00000000000000
--- a/tools/mo/unit_tests/mo/bom_test.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import platform
-import re
-import unittest
-from itertools import islice
-
-from openvino.tools.mo.utils.utils import get_mo_root_dir
-
-dir_patterns_to_skip = ['.*__pycache__.*']
-file_patterns_to_skip = ['.*\\.DS_Store$',
- '.*\\.swp',
- '.*\\.pyc$',
- 'requirements.*\.txt',
- 'version.txt']
-full_name_patterns_to_skip = ['^openvino/tools/mo/utils/convert.py$',
- '^openvino/tools/mo/front/caffe/CustomLayersMapping.xml$',
- ]
-if platform.system() == 'Windows':
- full_name_patterns_to_skip = [i.replace('/', '\\\\') for i in full_name_patterns_to_skip]
-
-
-def is_match(name: str, patterns: ()):
- return any((re.match(pattern, name) for pattern in patterns))
-
-
-class TestBOMFile(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- cls.existing_files = []
- cur_path = os.path.join(os.path.realpath(__file__), os.pardir)
- mo_path = os.path.abspath(os.path.join(cur_path, os.pardir, os.pardir))
- with open(os.path.join(mo_path, 'automation', 'package_BOM.txt'), 'r') as bom_file:
- if platform.system() == 'Windows':
- cls.existing_files = [name.rstrip().replace('/', '\\') for name in bom_file.readlines()]
- else:
- cls.existing_files = [name.rstrip() for name in bom_file.readlines()]
-
- # dirs_to_search is the root directory where MO is located, 'openvino_project_root/tools/mo/openvino/tools'
- cls.dirs_to_search = os.path.normpath(get_mo_root_dir() + '/mo/')
- cls.prefix = os.path.normpath(get_mo_root_dir() + '../../../') # prefix which is used in BOM file
- cls.expected_header = [re.compile(pattern) for pattern in [
- r'^# Copyright \([cC]\) [0-9\-]+ Intel Corporation$',
- r'^# SPDX-License-Identifier: Apache-2.0$',
- ]]
-
- def test_bom_file(self):
- missing_files = list()
- for src_dir in [self.dirs_to_search]:
- if not os.path.isdir(src_dir):
- continue
- for root, dirs, files in os.walk(src_dir):
- if is_match(root, dir_patterns_to_skip):
- continue
- for f in files:
- full_name = os.path.join(root, f)
- full_name = full_name[len(self.prefix) + 1:]
- if is_match(f, file_patterns_to_skip):
- continue
- if is_match(full_name, full_name_patterns_to_skip):
- continue
- if full_name not in self.existing_files:
- missing_files.append(full_name)
-
- if len(missing_files) != 0:
- print("Missing files:")
- for f in missing_files:
- print(f.replace('\\', '/'))
- self.assertTrue(not len(missing_files), '{} files missed in BOM'.format(len(missing_files)))
-
- def test_bom_does_not_contain_unittest_files(self):
- for file_name in self.existing_files:
- self.assertFalse(file_name.endswith('_test.py'), 'BOM file contains test file {}'.format(file_name))
-
- def test_deleted_files_still_stored_in_bom(self):
- deleted = list()
- for file in self.existing_files:
- if not os.path.isfile(os.path.join(self.prefix, file)):
- deleted.append(file)
- if len(deleted) != 0:
- print("Deleted files still stored in BOM file:")
- for f in deleted:
- print(f)
- self.assertTrue(not len(deleted), '{} files deleted but still stored in BOM'.format(len(deleted)))
-
- def test_alphabetical_order_and_duplicates(self):
- sorted_bom = sorted([x for x in self.existing_files if self.existing_files.count(x) == 1], key=str.lower)
- if self.existing_files != sorted_bom:
- print("Wrong order. Alphabetical order of BOM is:")
- print(*sorted_bom, sep='\n')
- self.assertTrue(False)
-
- def test_missed_intel_header(self):
- missing_files = list()
- for src_dir in [self.dirs_to_search]:
- if not os.path.isdir(src_dir):
- continue
- for root, dirs, files in os.walk(src_dir):
- if is_match(root, dir_patterns_to_skip):
- continue
- for f in files:
- ignores = [
- '^__init__.py$',
- '^caffe_pb2.py$',
- '^.*.pyc$',
- '^generate_caffe_pb2.py$'
- ]
- if not is_match(f, ['.*.py$']) or is_match(f, ignores):
- continue
- full_name = os.path.join(root, f)
- with open(full_name, 'r') as source_f:
- # read two more lines from the file because it can contain shebang and empty lines
- s = [x.strip() for x in islice(source_f, len(self.expected_header) + 2)]
- # skip shebang and empty lines in the beginning of the file
- try:
- while s[0] in ('', '#!/usr/bin/env python3'):
- s = s[1:]
- for str_ind in range(0, len(self.expected_header)):
- if not re.match(self.expected_header[str_ind], s[str_ind]):
- missing_files.append(full_name)
- break
- except:
- pass
- self.assertTrue(not len(missing_files),
- '{} files with missed header: \n{}'.format(len(missing_files), '\n'.join(missing_files)))
diff --git a/tools/mo/unit_tests/mo/convert/import_from_mo_test.py b/tools/mo/unit_tests/mo/convert/import_from_mo_test.py
deleted file mode 100644
index 03f523fe57f372..00000000000000
--- a/tools/mo/unit_tests/mo/convert/import_from_mo_test.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import tempfile
-from pathlib import Path
-
-import pytest
-from openvino.runtime import serialize
-
-from openvino.tools.mo import InputCutInfo, LayoutMap
-from openvino.tools.mo.utils.ir_engine.ir_engine import IREngine
-from unit_tests.utils.graph import build_graph
-from utils import create_onnx_model, save_to_onnx
-
-
-class TestConvertImportMOTest():
- test_directory = os.path.dirname(os.path.realpath(__file__))
-
- @staticmethod
- def create_onnx_model():
- #
- # Create ONNX model
- #
-
- import onnx
- from onnx import helper
- from onnx import TensorProto
-
- shape = [1, 2, 3]
-
- input = helper.make_tensor_value_info('input', TensorProto.FLOAT, shape)
- output = helper.make_tensor_value_info('output', TensorProto.FLOAT, shape)
-
- node_def = onnx.helper.make_node(
- 'Relu',
- inputs=['input'],
- outputs=['Relu_out'],
- )
- node_def2 = onnx.helper.make_node(
- 'Sigmoid',
- inputs=['Relu_out'],
- outputs=['output'],
- )
-
- # Create the graph (GraphProto)
- graph_def = helper.make_graph(
- [node_def, node_def2],
- 'test_model',
- [input],
- [output],
- )
-
- # Create the model (ModelProto)
- onnx_net = helper.make_model(graph_def, producer_name='test_model')
- return onnx_net
-
- @staticmethod
- def create_model_ref():
- nodes_attributes = {
- 'input': {'kind': 'op', 'type': 'Parameter'},
- 'input_data': {'shape': [1, 2, 3], 'kind': 'data'},
- 'relu': {'kind': 'op', 'type': 'ReLU'},
- 'relu_data': {'shape': [1, 2, 3], 'kind': 'data'},
- 'sigmoid': {'kind': 'op', 'type': 'Sigmoid'},
- 'sigmoid_data': {'shape': [1, 2, 3], 'kind': 'data'},
- 'result': {'kind': 'op', 'type': 'Result'}
- }
-
- ref_graph = build_graph(nodes_attributes,
- [('input', 'input_data'),
- ('input_data', 'relu'),
- ('relu', 'relu_data'),
- ('relu_data', 'sigmoid'),
- ('sigmoid', 'sigmoid_data'),
- ('sigmoid_data', 'result'),
- ])
- return ref_graph
-
- @pytest.mark.parametrize("params",[
- ({}),
- ({'input': InputCutInfo(name='LeakyRelu_out', shape=None, type=None, value=None)}),
- ({'layout': {'input': LayoutMap(source_layout='NCHW', target_layout='NHWC')}}),
- ])
- # Checks convert import from openvino.tools.mo
- def test_import(self, params):
- from openvino.tools.mo import convert_model
-
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmpdir:
- model = create_onnx_model()
- model_path = save_to_onnx(model, tmpdir)
- out_xml = os.path.join(tmpdir, "model.xml")
-
- ov_model = convert_model(input_model=model_path, **params)
- serialize(ov_model, out_xml.encode('utf-8'), out_xml.replace('.xml', '.bin').encode('utf-8'))
- assert os.path.exists(out_xml)
-
- def test_input_model_path(self):
- from openvino.tools.mo import convert_model
-
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmpdir:
- model = self.create_onnx_model()
- model_path = save_to_onnx(model, tmpdir)
- out_xml = os.path.join(tmpdir, "model.xml")
-
- ov_model = convert_model(Path(model_path))
- serialize(ov_model, out_xml.encode('utf-8'), out_xml.replace('.xml', '.bin').encode('utf-8'))
-
- ir = IREngine(out_xml, out_xml.replace('.xml', '.bin'))
- ref_graph = self.create_model_ref()
- flag, resp = ir.compare(ref_graph)
- assert flag, '\n'.join(resp)
-
- def test_unnamed_input_model(self):
- from openvino.tools.mo import convert_model
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmpdir:
- model = self.create_onnx_model()
- model_path = save_to_onnx(model, tmpdir)
- out_xml = os.path.join(tmpdir, "model.xml")
-
- ov_model = convert_model(model_path)
- serialize(ov_model, out_xml.encode('utf-8'), out_xml.replace('.xml', '.bin').encode('utf-8'))
-
- ir = IREngine(out_xml, out_xml.replace('.xml', '.bin'))
- ref_graph = self.create_model_ref()
- flag, resp = ir.compare(ref_graph)
- assert flag, '\n'.join(resp)
diff --git a/tools/mo/unit_tests/mo/convert/logger_test_actual.py b/tools/mo/unit_tests/mo/convert/logger_test_actual.py
deleted file mode 100644
index 6e384a71bb6596..00000000000000
--- a/tools/mo/unit_tests/mo/convert/logger_test_actual.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import os
-import sys
-import tempfile
-
-
-def create_tf_model(out_dir):
- import tensorflow as tf
-
- tf.compat.v1.reset_default_graph()
-
- with tf.compat.v1.Session() as sess:
- inp1 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input')
- inp2 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input')
- relu = tf.nn.relu(inp1 + inp2, name='Relu')
-
- output = tf.nn.sigmoid(relu, name='Sigmoid')
-
- tf.compat.v1.global_variables_initializer()
- tf_net = sess.graph_def
- tf.io.write_graph(tf_net, out_dir + os.sep, 'model_bool.pb', as_text=False)
- return out_dir + os.sep + 'model_bool.pb'
-
-
-def run_main():
- from openvino.tools.mo import convert_model
-
- log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
- test_directory = os.path.dirname(os.path.realpath(__file__))
-
- with tempfile.TemporaryDirectory(dir=test_directory) as tmpdir:
- tf_model = create_tf_model(test_directory)
- _ = convert_model(tf_model)
-
- log.info("test message 1")
-
- logger = log.getLogger()
- assert logger.level == 20
- assert len(logger.handlers) == 1
- assert len(logger.filters) == 0
-
- _ = convert_model(tf_model, log_level="DEBUG", silent=False)
-
- log.info("test message 2")
-
- logger = log.getLogger()
- assert logger.level == 20
- assert len(logger.handlers) == 1
- assert len(logger.filters) == 0
-
- _ = convert_model(tf_model, log_level="CRITICAL", silent=False)
-
- log.info("test message 3")
-
- logger = log.getLogger()
- assert logger.level == 20
- assert len(logger.handlers) == 1
- assert len(logger.filters) == 0
-
-
-if __name__ == "__main__":
- run_main()
diff --git a/tools/mo/unit_tests/mo/convert/meta_data_test.py b/tools/mo/unit_tests/mo/convert/meta_data_test.py
deleted file mode 100644
index 6493737533b60a..00000000000000
--- a/tools/mo/unit_tests/mo/convert/meta_data_test.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import tempfile
-from pathlib import Path
-
-from openvino.runtime import get_version as get_rt_version
-from openvino.runtime import serialize
-
-from openvino.tools.mo import convert_model
-from openvino.tools.mo.utils import import_extensions
-from openvino.tools.mo.utils.version import get_version
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from utils import save_to_onnx
-
-from openvino.tools.mo.utils.ir_reader.restore_graph import restore_graph_from_ir, save_restored_graph
-
-
-class MetaDataTest(UnitTestWithMockedTelemetry):
- test_directory = os.path.dirname(os.path.realpath(__file__))
-
- def test_meta_data(self):
- def create_onnx_model():
- #
- # Create ONNX model
- #
-
- import onnx
- from onnx import helper
- from onnx import TensorProto
-
- shape = [1, 2, 3]
-
- input = helper.make_tensor_value_info('input', TensorProto.FLOAT, shape)
- output = helper.make_tensor_value_info('output', TensorProto.FLOAT, shape)
-
- node_def = onnx.helper.make_node(
- 'Relu',
- inputs=['input'],
- outputs=['Relu_out'],
- )
- node_def2 = onnx.helper.make_node(
- 'Sigmoid',
- inputs=['Relu_out'],
- outputs=['output'],
- )
-
- # Create the graph (GraphProto)
- graph_def = helper.make_graph(
- [node_def, node_def2],
- 'test_model',
- [input],
- [output],
- )
-
- # Create the model (ModelProto)
- onnx_net = helper.make_model(graph_def, producer_name='test_model')
- return onnx_net
-
- def ref_meta_data():
- return {
- 'MO_version': get_version(),
- 'Runtime_version': get_rt_version(),
- 'legacy_frontend': "False",
- 'conversion_parameters': {
- 'input_model': Path.joinpath(Path("DIR"), Path("model.onnx")),
- }
-
- }
-
- def check_meta_data(ov_model):
- ref_meta = ref_meta_data()
- for key, value in ref_meta.items():
- if key == 'conversion_parameters':
- for param_name, param_value in value.items():
- val = ov_model.get_rt_info([key, param_name]).astype(str)
- if param_name in ['extensions', 'caffe_parser_path', 'input_model', 'k', 'output_dir']:
- val = Path(val)
- assert val == param_value, \
- "Runtime info attribute with name {} does not match. Expected: {}, " \
- "got {}".format(param_name, param_value, val)
- continue
- assert ov_model.get_rt_info(key).astype(str) == value, \
- "Runtime info attribute with name {} does not match. Expected: {}, " \
- "got {}".format(key, value, ov_model.get_rt_info(key).astype(str))
-
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmpdir:
-
- model = create_onnx_model()
- model_path = save_to_onnx(model, tmpdir)
- out_xml = os.path.join(tmpdir, "model.xml")
-
- ov_model = convert_model(model_path)
- check_meta_data(ov_model)
-
- serialize(ov_model, out_xml.encode('utf-8'), out_xml.replace('.xml', '.bin').encode('utf-8'))
-
- from openvino.runtime import Core
- core = Core()
- serialized_model = core.read_model(out_xml)
- check_meta_data(serialized_model)
-
- restored_graph, meta_data = restore_graph_from_ir(out_xml, out_xml.replace('.xml', '.bin'))
- save_restored_graph(restored_graph, tmpdir, meta_data, "mo_ir_reader_test_model")
-
- mo_ir_reader_test_model = core.read_model(os.path.join(tmpdir, "mo_ir_reader_test_model.xml"))
- check_meta_data(mo_ir_reader_test_model)
diff --git a/tools/mo/unit_tests/mo/convert/meta_data_test_actual.py b/tools/mo/unit_tests/mo/convert/meta_data_test_actual.py
deleted file mode 100644
index 9d012bc43dc616..00000000000000
--- a/tools/mo/unit_tests/mo/convert/meta_data_test_actual.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import tempfile
-import unittest
-from pathlib import Path
-
-from openvino.runtime import get_version as get_rt_version
-from openvino.runtime import serialize
-from openvino.tools.mo import convert_model
-from openvino.tools.mo.utils.ir_reader.restore_graph import restore_graph_from_ir, save_restored_graph
-from openvino.tools.mo.utils.version import get_version
-
-
-class MetaDataTestTF(unittest.TestCase):
- test_directory = os.path.dirname(os.path.realpath(__file__))
-
- @staticmethod
- def check_meta_data(ov_model, ref_meta):
- ignore_attrs = ['version', 'optimization']
- for key, value in ref_meta.items():
- if key == 'conversion_parameters':
- for param_name, param_value in value.items():
- val = ov_model.get_rt_info([key, param_name]).astype(str)
- if param_name in ['extensions', 'caffe_parser_path', 'input_model', 'k', 'output_dir']:
- val = Path(val)
- assert val == param_value, \
- "Runtime info attribute with name {} does not match. Expected: {}, " \
- "got {}".format(param_name, param_value, val)
- continue
- assert ov_model.get_rt_info(key).astype(str) == value, \
- "Runtime info attribute with name {} does not match. Expected: {}, " \
- "got {}".format(key, value, ov_model.get_rt_info(key).astype(str))
-
- for key, value in ov_model.get_rt_info().items():
- if key in ignore_attrs:
- continue
- assert key in ref_meta, "Unexpected runtime info attribute: {}".format(key)
-
- def test_meta_data_tf(self):
- def create_tf_model(out_dir):
- import tensorflow as tf
-
- tf.compat.v1.reset_default_graph()
-
- with tf.compat.v1.Session() as sess:
- inp1 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input')
- inp2 = tf.compat.v1.placeholder(tf.float32, [1, 2, 3], 'Input')
- relu = tf.nn.relu(inp1 + inp2, name='Relu')
-
- output = tf.nn.sigmoid(relu, name='Sigmoid')
-
- tf.compat.v1.global_variables_initializer()
- tf_net = sess.graph_def
- tf.io.write_graph(tf_net, out_dir + os.sep, 'model_bool.pb', as_text=False)
- return out_dir + os.sep + 'model_bool.pb'
-
- def ref_meta_data():
- return {
- 'MO_version': get_version(),
- 'Runtime_version': get_rt_version(),
- 'legacy_frontend': "False",
- 'conversion_parameters': {
- 'scale': "1.5",
- 'batch': "1"
- }
- }
-
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmpdir:
- model = create_tf_model(tmpdir)
- out_xml = os.path.join(tmpdir, "model.xml")
- ref_meta = ref_meta_data()
-
- ov_model = convert_model(model, scale=1.5, batch=1)
- self.check_meta_data(ov_model, ref_meta)
-
- serialize(ov_model, out_xml.encode('utf-8'), out_xml.replace('.xml', '.bin').encode('utf-8'))
-
- from openvino.runtime import Core
- core = Core()
- deserialized_model = core.read_model(out_xml)
- self.check_meta_data(deserialized_model, ref_meta)
-
- restored_graph, meta_data = restore_graph_from_ir(out_xml, out_xml.replace('.xml', '.bin'))
- save_restored_graph(restored_graph, tmpdir, meta_data, "mo_ir_reader_test_model")
-
- mo_ir_reader_test_model = core.read_model(os.path.join(tmpdir, "mo_ir_reader_test_model.xml"))
- self.check_meta_data(mo_ir_reader_test_model, ref_meta)
diff --git a/tools/mo/unit_tests/mo/convert/utils.py b/tools/mo/unit_tests/mo/convert/utils.py
deleted file mode 100644
index 66970cab8e597c..00000000000000
--- a/tools/mo/unit_tests/mo/convert/utils.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-
-
-def create_onnx_model():
- #
- # Create ONNX model
- #
-
- import onnx
- from onnx import helper
- from onnx import TensorProto
-
- shape = [1, 3, 2, 2]
-
- input = helper.make_tensor_value_info('input', TensorProto.FLOAT, shape)
- output = helper.make_tensor_value_info('output', TensorProto.FLOAT, shape)
-
- node_def = onnx.helper.make_node(
- 'LeakyRelu',
- inputs=['input'],
- outputs=['LeakyRelu_out'],
- alpha=0.1
- )
- node_def2 = onnx.helper.make_node(
- 'Elu',
- inputs=['LeakyRelu_out'],
- outputs=['output'],
- alpha=0.1
- )
-
- # Create the graph (GraphProto)
- graph_def = helper.make_graph(
- [node_def, node_def2],
- 'test_model',
- [input],
- [output],
- )
-
- # Create the model (ModelProto)
- onnx_net = helper.make_model(graph_def, producer_name='test_model')
- return onnx_net
-
-
-def save_to_onnx(onnx_model, path_to_saved_onnx_model):
- import onnx
- path = os.path.join(path_to_saved_onnx_model, 'model.onnx')
- onnx.save(onnx_model, path)
- assert os.path.isfile(path), "model.onnx haven't been saved here: {}".format(path_to_saved_onnx_model)
- return path
diff --git a/tools/mo/unit_tests/mo/convert/version_checker_test_actual.py b/tools/mo/unit_tests/mo/convert/version_checker_test_actual.py
deleted file mode 100644
index 663f1f207a2bde..00000000000000
--- a/tools/mo/unit_tests/mo/convert/version_checker_test_actual.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.runtime import get_version as get_ie_version
-
-from openvino.tools.mo.utils.version import get_version, get_simplified_ie_version, \
- get_simplified_mo_version, VersionChecker
-
-
-class VersionCheckerTest(unittest.TestCase):
- def test_version_checker(self):
- import datetime
- import os
- ref_mo_version = get_version()
- ref_ie_version = get_ie_version()
- ref_mo_simplified_version = get_simplified_mo_version()
- ref_ie_simplified_version = get_simplified_ie_version(env=os.environ)
-
- # first init of VersionChecker
- start_time = datetime.datetime.now()
- VersionChecker().check_runtime_dependencies()
- VersionChecker().get_mo_version()
- VersionChecker().get_ie_version()
- VersionChecker().get_mo_simplified_version()
- VersionChecker().get_ie_simplified_version()
- first_init_time = (datetime.datetime.now() - start_time).total_seconds()
-
- # Loop with multiple usages of VersionChecker
- start_time = datetime.datetime.now()
- for _ in range(100):
- VersionChecker().check_runtime_dependencies()
- assert VersionChecker().get_mo_version() == ref_mo_version
- assert VersionChecker().get_ie_version() == ref_ie_version
- assert VersionChecker().get_mo_simplified_version() == ref_mo_simplified_version
- assert VersionChecker().get_ie_simplified_version() == ref_ie_simplified_version
- loop_time = (datetime.datetime.now() - start_time).total_seconds()
-
- # Check that time of loop is less than first init, so no actual initialization happens
- assert loop_time < first_init_time
diff --git a/tools/mo/unit_tests/mo/extensions_test_actual.py b/tools/mo/unit_tests/mo/extensions_test_actual.py
deleted file mode 100644
index df9dc8c7688e9f..00000000000000
--- a/tools/mo/unit_tests/mo/extensions_test_actual.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright (C) 2022 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-import unittest
-from unittest.mock import Mock
-import onnx
-from onnx.helper import make_graph, make_model, make_tensor_value_info
-import os
-from os import path
-import json
-import argparse
-from pathlib import Path
-from itertools import chain
-from openvino.tools.mo.convert_impl import prepare_ir
-from openvino.frontend import (
- FrontEndManager,
-) # pylint: disable=no-name-in-module,import-error
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-def base_args_config():
- args = argparse.Namespace()
- args.feManager = FrontEndManager()
- args.extensions = None
- args.use_legacy_frontend = False
- args.use_new_frontend = True
- args.framework = "onnx"
- args.model_name = None
- args.input_model = None
- args.silent = True
- args.transform = []
- args.legacy_ir_generation = False
- args.scale = None
- args.output = None
- args.input = None
- args.input_shape = None
- args.batch = None
- args.mean_values = None
- args.scale_values = None
- args.output_dir = os.getcwd()
- args.freeze_placeholder_with_value = None
- args.transformations_config = None
- args.disable_gfusing = None
- args.static_shape = None
- args.reverse_input_channels = None
- args.data_type = None
- args.layout = None
- args.source_layout = None
- args.target_layout = None
- return args
-
-
-def get_builtin_extensions_path():
- win_folder_path = Path(__file__).parent.parent.parent.parent
- linux_folder_path = win_folder_path.joinpath("lib")
- for lib_path in chain(
- win_folder_path.glob("*.dll"), linux_folder_path.glob("*.so")
- ):
- if "libtest_builtin_extensions" in lib_path.name:
- return str(lib_path)
- return ""
-
-
-class TestMoFallback(unittest.TestCase):
- def setUp(self):
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
-
- self.models = {}
- relu = onnx.helper.make_node("Relu", inputs=["in"], outputs=["out"])
- input_tensors = [
- make_tensor_value_info("in", onnx.TensorProto.FLOAT, (1, 2)),
- ]
- output_tensors = [
- make_tensor_value_info("out", onnx.TensorProto.FLOAT, (1, 2)),
- ]
- graph = make_graph([relu], "test_graph", input_tensors, output_tensors)
- model = make_model(
- graph,
- producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)],
- )
- self.models["test_model.onnx"] = model
- for name, model in self.models.items():
- onnx.save(model, name)
-
- def tearDown(self):
- for name in self.models.keys():
- os.remove(name)
-
- @pytest.mark.skipif(
- len(get_builtin_extensions_path()) == 0,
- reason="The extension library path was not found",
- )
- def test_conersion_if_extensions_is_used(self):
- args = base_args_config()
- args.input_model = "test_model.onnx"
- args.extensions = [get_builtin_extensions_path()]
-
- graph, model = prepare_ir(args)
-
- assert any(op.get_type_name() == "Swish" for op in model.get_ops())
- assert all(op.get_type_name() != "Relu" for op in model.get_ops())
diff --git a/tools/mo/unit_tests/mo/front/ATenToEmbeddingBag_test.py b/tools/mo/unit_tests/mo/front/ATenToEmbeddingBag_test.py
deleted file mode 100644
index 2dba32302a4dc5..00000000000000
--- a/tools/mo/unit_tests/mo/front/ATenToEmbeddingBag_test.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.ATenToEmbeddingBag import AtenToEmbeddingBag
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op, const
-
-
-class AtenToEmbeddingBagTest(unittest.TestCase):
- def test(self):
- nodes = {
- **const('weights_inp', np.random.randn(100, 2)),
- **regular_op('indices_inp', {'type': 'Parameter'}),
- **regular_op('offsets_inp', {'type': 'Parameter'}),
- **regular_op('aten', {'type': None, 'kind': 'op', 'op': 'ATen', 'operator': 'embedding_bag', 'mode': 0,
- 'name': 'my_aten'}),
-
- **regular_op('emb_bag', {'type': 'EmbeddingBagOffsetsSum', 'kind': 'op', 'op': 'EmbeddingBagOffsetsSum'}),
- **result('result'),
- }
- edges = [('weights_inp', 'aten'),
- ('indices_inp', 'aten'),
- ('offsets_inp', 'aten'),
- ('aten', 'result'),
- ]
- graph = build_graph(nodes, edges)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- edges_ref = [('weights_inp', 'emb_bag'),
- ('indices_inp', 'emb_bag'),
- ('offsets_inp', 'emb_bag'),
- ('emb_bag', 'result'),
- ]
-
- graph_ref = build_graph(nodes, edges_ref)
-
- AtenToEmbeddingBag().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_packed(self):
- nodes = {
- **const('weights_inp', np.random.randn(100, 4)),
- **regular_op('indices_inp', {'type': 'Parameter'}),
- **regular_op('aten', {'type': None, 'kind': 'op', 'op': 'ATen', 'operator': 'embedding_bag', 'mode': 0,
- 'name': 'my_aten'}),
-
- **regular_op('emb_bag', {'type': 'EmbeddingBagPackedSum', 'kind': 'op',
- 'op': 'EmbeddingBagPackedSum'}),
- **result('result'),
- }
- edges = [('weights_inp', 'aten'),
- ('indices_inp', 'aten'),
- ('aten', 'result'),
- ]
- graph = build_graph(nodes, edges)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- edges_ref = [('weights_inp', 'emb_bag'),
- ('indices_inp', 'emb_bag'),
- ('emb_bag', 'result'),
- ]
-
- graph_ref = build_graph(nodes, edges_ref)
-
- AtenToEmbeddingBag().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_per_sample_weights(self):
- nodes = {
- **const('weights_inp', np.random.randn(100, 2)),
- **regular_op('indices_inp', {'type': 'Parameter'}),
- **regular_op('offsets_inp', {'type': 'Parameter'}),
- **regular_op('per_sample_weights', {'type': 'Parameter'}),
- **regular_op('aten', {'type': None, 'kind': 'op', 'op': 'ATen', 'operator': 'embedding_bag', 'mode': 0,
- 'name': 'my_aten'}),
-
- **regular_op('emb_bag', {'type': 'EmbeddingBagOffsetsSum', 'kind': 'op',
- 'op': 'EmbeddingBagOffsetsSum'}),
- **regular_op('WeightsRank', {'type': None, 'kind': 'op', 'op': 'Rank'}),
- **regular_op('WeightsRank/axis', {'type': 'Add', 'kind': 'op', 'op': 'Add'}),
- **regular_op('gather1', {'type': 'Gather', 'kind': 'op', 'op': 'Gather'}),
- **regular_op('gather2', {'type': 'Gather', 'kind': 'op', 'op': 'Gather'}),
- **regular_op('WeightsShape', {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'}),
- **regular_op('Broadcast', {'type': 'Broadcast', 'kind': 'op', 'op': 'Broadcast'}),
- **regular_op('Unsqueeze', {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'}),
- **const('WeightsShape/Axis', int64_array(0)),
- **const('zero1', int64_array(0)),
- **const('zero2', int64_array(0)),
- **const('Unsqueeze/value', int64_array(0)),
- **const('Broadcast/value', int64_array(0)),
- **const('neg', int64_array(-1)),
- **regular_op('Concat', {'type': 'Concat', 'kind': 'op', 'op': 'Concat'}),
- **result('result'),
- }
- edges = [('weights_inp', 'aten'),
- ('indices_inp', 'aten'),
- ('offsets_inp', 'aten'),
- ('per_sample_weights', 'aten'),
- ('aten', 'result'),
- ]
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- edges_ref = [('weights_inp', 'Concat', {'in': 0, 'out': 0}),
- ('weights_inp', 'WeightsShape', {'in': 0, 'out': 0}),
- ('weights_inp', 'WeightsRank', {'in': 0, 'out': 0}),
- ('WeightsRank', 'WeightsRank/axis'),
- ('neg', 'WeightsRank/axis'),
- ('WeightsShape', 'gather1', {'in': 0, 'out': 0}),
- ('WeightsRank/axis', 'gather1'),
- ('WeightsShape/Axis', 'gather1'),
- ('WeightsShape', 'gather2', {'in': 0, 'out': 0}),
- ('zero1', 'gather2'),
- ('zero2', 'gather2'),
- ('Broadcast/value', 'Broadcast'),
- ('gather1', 'Broadcast'),
- ('Broadcast', 'Unsqueeze'),
- ('Unsqueeze/value', 'Unsqueeze'),
- ('Unsqueeze', 'Concat'),
- ('Concat', 'emb_bag'),
- ('indices_inp', 'emb_bag'),
- ('offsets_inp', 'emb_bag'),
- ('gather2', 'emb_bag'),
- ('per_sample_weights', 'emb_bag'),
- ('emb_bag', 'result'),
- ]
-
- graph_ref = build_graph(nodes, edges_ref, nodes_with_edges_only=True)
-
- AtenToEmbeddingBag().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/AttributedClampNormalizer_test.py b/tools/mo/unit_tests/mo/front/AttributedClampNormalizer_test.py
deleted file mode 100644
index d447ed72849620..00000000000000
--- a/tools/mo/unit_tests/mo/front/AttributedClampNormalizer_test.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.AttributedClampNormalizer import AttributedClampNormalizer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-nodes_attributes = {
- 'placeholder': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'attr_clamp': {'type': 'Clamp', 'kind': 'op', 'op': 'AttributedClamp', 'name': 'attr_clamp',
- 'min': np.array(-3.5, dtype=np.float32), 'max': np.array(3.5, dtype=np.float32)},
- 'result': {'type': 'Result', 'value': None, 'kind': 'op', 'op': 'Result'},
-
- # new Clamp layer and inputs
- 'clamp': {'type': None, 'kind': 'op', 'op': 'Clamp'},
- **const('min', np.array(-3.5, dtype=np.float32)),
- **const('max', np.array(3.5, dtype=np.float32)),
-}
-
-
-class AttributedClampNormalizerTest(unittest.TestCase):
- def test_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'attr_clamp', {'in': 0, 'out': 0}),
- ('attr_clamp', 'result', {'in': 0, 'out': 0}),
- ],
- {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'clamp', {'in': 0, 'out': 0}),
- ('min', 'clamp', {'in': 1, 'out': 0}),
- ('max', 'clamp', {'in': 2, 'out': 0}),
- ('clamp', 'result')
- ],
- {}, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = AttributedClampNormalizer()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Clamp')[0]]['name'] == 'attr_clamp')
diff --git a/tools/mo/unit_tests/mo/front/AttributedPadToPad_test.py b/tools/mo/unit_tests/mo/front/AttributedPadToPad_test.py
deleted file mode 100644
index 212967a92a64b8..00000000000000
--- a/tools/mo/unit_tests/mo/front/AttributedPadToPad_test.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.AttributedPadToPad import AttributedPadToPad
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-nodes_attributes = {
- 'placeholder': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'attr_pad': {'type': None, 'kind': 'op', 'op': 'AttributedPad', 'mode': 'constant', 'name': 'attr_pad',
- 'pads': int64_array([1, 2, 3, 4, 5, 6]).reshape([3, 2]), 'fill_value': 0.75},
- 'result': {'type': 'Result', 'value': None, 'kind': 'op', 'op': 'Result'},
-
- # new Pad layer and inputs
- 'pad': {'type': 'Pad', 'kind': 'op', 'op': 'Pad', 'mode': 'constant'},
- 'convert_like': {'type': 'ConvertLike', 'kind': 'op', 'op': 'ConvertLike'},
- **const('pad_begin', int64_array([1, 3, 5])),
- **const('pad_end', int64_array([2, 4, 6])),
- **const('pad_fill', np.array(0.75)),
-}
-
-
-class AttributedPadToPadTest(unittest.TestCase):
- def test_mode_constant(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'attr_pad', {'in': 0, 'out': 0}),
- ('attr_pad', 'result', {'in': 0, 'out': 0}),
- ],
- {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'pad', {'in': 0, 'out': 0}),
- ('pad_begin', 'pad', {'in': 1, 'out': 0}),
- ('pad_end', 'pad', {'in': 2, 'out': 0}),
- ('pad_fill', 'convert_like', {'in': 0, 'out': 0}),
- ('placeholder', 'convert_like', {'in': 1, 'out': 0}),
- ('convert_like', 'pad', {'in': 3, 'out': 0}),
- ('pad', 'result')
- ],
- {}, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = AttributedPadToPad()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Pad')[0]]['name'] == 'attr_pad')
-
- def test_mode_non_constant(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'attr_pad', {'in': 0, 'out': 0}),
- ('attr_pad', 'result', {'in': 0, 'out': 0}),
- ],
- {'attr_pad': {'mode': 'reflect'}}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'pad', {'in': 0, 'out': 0}),
- ('pad_begin', 'pad', {'in': 1, 'out': 0}),
- ('pad_end', 'pad', {'in': 2, 'out': 0}),
- ('pad', 'result')
- ],
- {'pad': {'mode': 'reflect'}}, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = AttributedPadToPad()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Pad')[0]]['name'] == 'attr_pad')
diff --git a/tools/mo/unit_tests/mo/front/AttributedRandomUniformToRandomUniform_test.py b/tools/mo/unit_tests/mo/front/AttributedRandomUniformToRandomUniform_test.py
deleted file mode 100644
index 00beab5a624fa7..00000000000000
--- a/tools/mo/unit_tests/mo/front/AttributedRandomUniformToRandomUniform_test.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.AttributedRandomUniformToRandomUniform import AttributedRandomUniformToRandomUniform
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const, result, regular_op
-
-nodes = {
- **regular_op('placeholder', {'type': 'Parameter'}),
- **regular_op('attr_random_uniform', {'type': 'AttributedRandomUniform', 'op': 'AttributedRandomUniform',
- 'output_type': np.float32,
- 'min_val': float32_array([-1.5]), 'max_val': float32_array([10.7]),
- 'shape': int64_array([5, 4, 3])}),
- **result('result'),
-
- # new RandomUniform node and inputs
- **regular_op('random_uniform', {'type': 'RandomUniform'}),
- **const('min_val', float32_array([-1.5])),
- **const('max_val', float32_array([10.7])),
- **const('shape', int64_array([5, 4, 3])),
-}
-
-
-class AttributedRandomUniformToRandomUniformTest(unittest.TestCase):
- def test_min_max(self):
- graph = build_graph(nodes,
- [('placeholder', 'attr_random_uniform', {'in': 0, 'out': 0}),
- ('attr_random_uniform', 'result', {'in': 0, 'out': 0})], {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes,
- [('placeholder', 'random_uniform', {'in': 0, 'out': 0}),
- ('min_val', 'random_uniform', {'in': 1, 'out': 0}),
- ('max_val', 'random_uniform', {'in': 2, 'out': 0}),
- ('random_uniform', 'result')], {}, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- AttributedRandomUniformToRandomUniform().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(
- graph.node[graph.get_nodes_with_attributes(op='RandomUniform')[0]]['name'] == 'attr_random_uniform')
-
- def test_min_max_shape(self):
- graph = build_graph(nodes,
- [('attr_random_uniform', 'result', {'in': 0, 'out': 0})], {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes,
- [('shape', 'random_uniform', {'in': 0, 'out': 0}),
- ('min_val', 'random_uniform', {'in': 1, 'out': 0}),
- ('max_val', 'random_uniform', {'in': 2, 'out': 0}),
- ('random_uniform', 'result')], {}, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- AttributedRandomUniformToRandomUniform().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(
- graph.node[graph.get_nodes_with_attributes(op='RandomUniform')[0]]['name'] == 'attr_random_uniform')
diff --git a/tools/mo/unit_tests/mo/front/AttributedRollToRoll_test.py b/tools/mo/unit_tests/mo/front/AttributedRollToRoll_test.py
deleted file mode 100644
index b6518cc00b1315..00000000000000
--- a/tools/mo/unit_tests/mo/front/AttributedRollToRoll_test.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.AttributedRollToRoll import AttributedRollToRoll
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const, result, regular_op
-
-nodes_attributes = {
- **regular_op('placeholder', {'type': 'Parameter'}),
- **regular_op('attr_roll', {'type': 'AttributedRoll', 'op': 'AttributedRoll', 'axes': int64_array([-1, 2, 3]),
- 'shift': int64_array([5, -2, 3])}),
- **result('result'),
-
- # new Roll node and inputs
- **regular_op('roll', {'type': 'Roll'}),
- **const('roll_axes', int64_array([-1, 2, 3])),
- **const('roll_shift', int64_array([5, -2, 3]))
-}
-
-
-class AttributedRollToRollTest(unittest.TestCase):
- def test_axes_shift(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'attr_roll', {'in': 0, 'out': 0}),
- ('attr_roll', 'result', {'in': 0, 'out': 0})], {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'roll', {'in': 0, 'out': 0}),
- ('roll_shift', 'roll', {'in': 1, 'out': 0}),
- ('roll_axes', 'roll', {'in': 2, 'out': 0}),
- ('roll', 'result')], {}, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- AttributedRollToRoll().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Roll')[0]]['name'] == 'attr_roll')
-
- def test_axes(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'attr_roll', {'in': 0, 'out': 0}),
- ('attr_roll', 'result', {'in': 0, 'out': 0})], {}, nodes_with_edges_only=True)
- Node(graph, 'attr_roll')['axes'] = None
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'roll', {'in': 0, 'out': 0}),
- ('roll_shift', 'roll', {'in': 1, 'out': 0}),
- ('roll', 'result')], {}, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- AttributedRollToRoll().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Roll')[0]]['name'] == 'attr_roll')
diff --git a/tools/mo/unit_tests/mo/front/GeLUMerger_Erf_test.py b/tools/mo/unit_tests/mo/front/GeLUMerger_Erf_test.py
deleted file mode 100644
index 43dca0a506b28f..00000000000000
--- a/tools/mo/unit_tests/mo/front/GeLUMerger_Erf_test.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from math import sqrt
-
-from openvino.tools.mo.front.GeLUMerger_Erf import GeLUMergerErf
-from openvino.tools.mo.front.common.partial_infer.utils import float_array, int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import const, regular_op, result, build_graph
-
-ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
- **regular_op('gelu', {'type': 'Gelu', 'approximation_mode': 'erf', 'name': 'final_mul'}),
- **result('result')
- }
-ref_edges = [('input', 'gelu'), ('gelu', 'result')]
-
-
-class GeLUMergerErfTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'op': 'Parameter', 'type': 'Parameter'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul0', {'op': 'Mul', 'name': 'final_mul'}),
- **regular_op('div', {'op': 'Div'}),
- **regular_op('erf', {'op': 'Erf'}),
- **regular_op('add', {'op': 'Add'}),
- **const('mul_param', float_array([0.5])),
- **const('div_param', float_array([sqrt(2.)])),
- **const('add_param', int64_array([1])),
- **result('result'),
- }
-
- def test_gelu_p1(self):
- edges = [('input', 'mul'),
- ('mul', 'mul0'),
- ('input', 'div'),
- ('div', 'erf'),
- ('erf', 'add'),
- ('add', 'mul0'),
- ('mul_param', 'mul'),
- ('div_param', 'div'),
- ('add_param', 'add'),
- ('mul0', 'result')]
-
- graph = build_graph(self.nodes, edges)
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- GeLUMergerErf().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(graph.get_op_nodes(op='Gelu')[0].approximation_mode == 'erf')
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'Gelu')
-
- def test_gelu_p2(self):
- edges = [('input', 'mul'),
- ('div', 'erf'),
- ('erf', 'add'),
- ('add', 'mul'),
- ('mul', 'mul0'),
- ('mul_param', 'mul0'),
- ('div_param', 'div'),
- ('add_param', 'add'),
- ('mul0', 'result')]
-
- graph = build_graph(self.nodes, edges)
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- GeLUMergerErf().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(graph.get_op_nodes(op='Gelu')[0].approximation_mode == 'erf')
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'Gelu')
-
- def test_gelu_p3(self):
- edges = [('input', 'mul'),
- ('div', 'erf'),
- ('erf', 'add'),
- ('add', 'mul'),
- ('mul', 'mul0'),
- ('mul_param', 'mul'),
- ('div_param', 'div'),
- ('add_param', 'add'),
- ('mul0', 'result')]
-
- graph = build_graph(self.nodes, edges)
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- GeLUMergerErf().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(graph.get_op_nodes(op='Gelu')[0].approximation_mode == 'erf')
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'Gelu')
diff --git a/tools/mo/unit_tests/mo/front/GeLUMerger_Tanh_test.py b/tools/mo/unit_tests/mo/front/GeLUMerger_Tanh_test.py
deleted file mode 100644
index 7b8570e91a72b1..00000000000000
--- a/tools/mo/unit_tests/mo/front/GeLUMerger_Tanh_test.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from math import sqrt
-
-import numpy as np
-
-from openvino.tools.mo.front.GeLUMerger_Tanh import GeLUMergerTanh
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes_erf = {
- 'inp': {'kind': 'op', 'op': 'AnyOp'},
- 'mul': {'kind': 'op', 'op': 'Mul'},
- 'mul0': {'kind': 'op', 'op': 'Mul'},
- 'div': {'kind': 'op', 'op': 'Div'},
- 'erf': {'kind': 'op', 'op': 'Erf'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'mul_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'div_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'add_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
-}
-
-nodes_attributes_tanh = {
- 'inp': {'kind': 'op', 'op': 'AnyOp'},
- 'pow': {'kind': 'op', 'op': 'Pow'},
- 'mul': {'kind': 'op', 'op': 'Mul'},
- 'mul0': {'kind': 'op', 'op': 'Mul'},
- 'mul1': {'kind': 'op', 'op': 'Mul'},
- 'mul2': {'kind': 'op', 'op': 'Mul'},
- 'tanh': {'kind': 'op', 'op': 'Tanh'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'add0': {'kind': 'op', 'op': 'Add'},
- 'mul_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'mul0_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'mul1_param': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
-}
-
-nodes_attributes_ref = {
- 'inp': {'kind': 'op', 'op': 'AnyOp'},
- 'gelu': {'kind': 'op', 'op': 'Gelu', 'approximation_mode': 'tanh'},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
-}
-
-
-class TestGeLUMergerReplacement(unittest.TestCase):
- def test_GeLUMergerTanh(self):
- graph = build_graph(nodes_attributes_tanh,
- [('inp', 'mul2', {'out': 0}),
- ('inp', 'add', {'out': 0}),
- ('inp', 'pow', {'out': 0}),
- ('pow', 'mul'),
- ('mul', 'add'),
- ('add', 'mul0'),
- ('mul0', 'tanh'),
- ('tanh', 'add0'),
- ('add0', 'mul1'),
- ('mul1', 'mul2'),
- ('mul_param', 'mul'),
- ('mul0_param', 'mul0'),
- ('mul1_param', 'mul1'),
- ('mul2', 'out'),
- ],
- {'mul0_param': {'shape': np.array([1]), 'value': np.array(sqrt(2.0/3.1415926))},
- 'mul1_param': {'shape': np.array([1]), 'value': np.array(0.5)},
- 'mul_param': {'shape': np.array([1]), 'value': np.array(0.044715)}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_attributes_ref,
- [('inp', 'gelu'),
- ('gelu', 'out')],
- {}, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- replacer = GeLUMergerTanh()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/GlobalPoolingToReduce_test.py b/tools/mo/unit_tests/mo/front/GlobalPoolingToReduce_test.py
deleted file mode 100644
index c12e1e14920a8a..00000000000000
--- a/tools/mo/unit_tests/mo/front/GlobalPoolingToReduce_test.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.global_pooling_to_reduce import GlobalPoolingToReduce
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op, result, build_graph_with_edge_attrs, const
-
-nodes = {**regular_op('input', {'type': 'Parameter'}),
-
- **regular_op('relu', {'type': 'Relu'}),
- **regular_op('pooling', {'type': 'Pooling', 'global_pool': True, 'pool_method': 'avg'}),
-
- **result('result'),
-
- **regular_op('rank', {'type': 'Rank'}),
- **regular_op('reduce_mean', {'type': 'ReduceMean'}),
- **regular_op('range', {'type': 'Range'}),
- **const('const_1', int64_array(2)),
- **const('const_2', int64_array(1)),
-
- }
-edges = [('input', 'relu', {'in': 0, 'out': 0}), ('relu', 'pooling', {'in': 0, 'out': 0}),
- ('pooling', 'result', {'in': 0, 'out': 0})]
-ref_edges = [('input', 'relu', {'in': 0, 'out': 0}), ('relu', 'rank', {'in': 0, 'out': 0}),
- ('rank', 'range', {'in': 1, 'out': 0}),
- ('relu', 'reduce_mean', {'in': 0, 'out': 0}),
- ('const_1', 'range', {'in': 0, 'out': 0}), ('const_2', 'range', {'in': 2, 'out': 0}),
- ('range', 'reduce_mean', {'in': 1, 'out': 0}),
- ('reduce_mean', 'result', {'in': 0, 'out': 0})]
-
-
-class GlobalPoolingToReduceTest(unittest.TestCase):
- def test_global_pooling_to_reduce(self):
- graph = build_graph_with_edge_attrs(nodes, edges)
-
- graph_ref = build_graph(nodes, ref_edges)
- graph.stage = 'front'
- graph.graph['layout'] = 'NCHW'
- node = Node(graph, 'relu')
- node.out_edge(0)['fw_tensor_debug_info'] = [('Relu_0', 'Relu_tensor')]
-
- GlobalPoolingToReduce().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- node = Node(graph, 'relu')
- edge_attrs = node.out_port(0).get_destinations()[0].get_in_edge_attrs()
- self.assertTrue('fw_tensor_debug_info' in edge_attrs)
- self.assertTrue(edge_attrs['fw_tensor_debug_info'] == [('Relu_0', 'Relu_tensor')])
diff --git a/tools/mo/unit_tests/mo/front/HSigmoid_fusion_test.py b/tools/mo/unit_tests/mo/front/HSigmoid_fusion_test.py
deleted file mode 100644
index 02e39f1b720912..00000000000000
--- a/tools/mo/unit_tests/mo/front/HSigmoid_fusion_test.py
+++ /dev/null
@@ -1,342 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.HSigmoid_fusion import HSigmoidWithClamp, HSigmoidWithMinMax, HSigmoidWithReluDiv, \
- HSigmoidWithReluMul
-from openvino.tools.mo.front.common.partial_infer.utils import float_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const, regular_op, result, build_graph_with_edge_attrs
-
-ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
- **regular_op('hsigmoid', {'type': 'HSigmoid', 'name': 'final_mul'}),
- **result('result')
- }
-ref_edges = [('input', 'hsigmoid'), ('hsigmoid', 'result')]
-
-
-class HSigmoidWithClampTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('relu6', {'op': 'Clamp'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }
-
- edges = [('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'relu6', {'in': 0, 'out': 0}),
- ('const_0', 'relu6', {'in': 1, 'out': 0}),
- ('const_6', 'relu6', {'in': 2, 'out': 0}),
- ('relu6', 'mul_2', {'in': 1, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})]
-
- def test_hsigmoid_with_clamp(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- HSigmoidWithClamp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'HSigmoid')
-
- def test_hsigmoid_with_clamp_wrong_constant(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'const_0': {'value': float_array([0.00001])}})
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithClamp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_hsigmoid_with_clamp_different_tensors(self):
- graph = build_graph_with_edge_attrs({
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('input_2', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('relu6', {'op': 'Clamp'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }, [('input', 'mul', {'in': 0, 'out': 0}),
- ('input_2', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'relu6', {'in': 0, 'out': 0}),
- ('const_0', 'relu6', {'in': 1, 'out': 0}),
- ('const_6', 'relu6', {'in': 2, 'out': 0}),
- ('relu6', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})])
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithClamp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
-
-class HSigmoidWithMinMaxTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('max', {'op': 'Maximum'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }
-
- edges = [('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'max', {'in': 0, 'out': 0}),
- ('const_0', 'max', {'in': 1, 'out': 0}),
- ('max', 'min', {'in': 0, 'out': 0}),
- ('const_6', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})]
-
- def test_hsigmoid_with_min_max(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- HSigmoidWithMinMax().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'HSigmoid')
-
- def test_hsigmoid_with_min_max_wrong_constant(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'const_0': {'value': float_array([0.00001])}})
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithMinMax().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_hsigmoid_with_min_max_different_tensors(self):
- graph = build_graph_with_edge_attrs({
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('input_2', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('max', {'op': 'Maximum'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }, [('input_2', 'mul', {'in': 1, 'out': 0}),
- ('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'max', {'in': 0, 'out': 0}),
- ('const_0', 'max', {'in': 1, 'out': 0}),
- ('max', 'min', {'in': 0, 'out': 0}),
- ('const_6', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul', {'in': 0, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})])
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithMinMax().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
-
-class HSigmoidWithReluDivTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('relu', {'op': 'ReLU'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('div', {'op': 'Div', 'name': 'final_div'}),
- **const('add_const', float_array([3.0])),
- **const('min_const', float_array([6.0])),
- **const('div_const', float_array([6.0])),
- **result('result'),
- }
-
- edges = [('input', 'add', {'in': 0, 'out': 0}),
- ('add_const', 'add', {'in': 1, 'out': 0}),
- ('add', 'relu', {'in': 0, 'out': 0}),
- ('relu', 'min', {'in': 0, 'out': 0}),
- ('min_const', 'min', {'in': 1, 'out': 0}),
- ('min', 'div', {'in': 0, 'out': 0}),
- ('div_const', 'div', {'in': 1, 'out': 0}),
- ('div', 'result', {'in': 0, 'out': 0})]
-
- def test_hsigmoid_with_relu_div(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- HSigmoidWithReluDiv().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_div')) == 1 and
- graph.get_op_nodes(name='final_div')[0].op == 'HSigmoid')
- self.assertTrue(graph.get_op_nodes(name='final_div')[0].out_nodes()[0].node == 'result')
-
- def test_hsigmoid_with_relu_div_wrong_constant(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'add_const': {'value': float_array([0.00001])}})
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithReluDiv().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_hsigmoid_with_relu_div_different_tensors(self):
- graph = build_graph_with_edge_attrs({
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('input_2', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('max', {'op': 'Maximum'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }, [('input_2', 'mul', {'in': 1, 'out': 0}),
- ('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'max', {'in': 0, 'out': 0}),
- ('const_0', 'max', {'in': 1, 'out': 0}),
- ('max', 'min', {'in': 0, 'out': 0}),
- ('const_6', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul', {'in': 0, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})])
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithReluDiv().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
-
-class HSigmoidWithReluMulTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('relu', {'op': 'ReLU'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul', {'op': 'Mul', 'name': 'final_mul'}),
- **const('add_const', float_array([3.0])),
- **const('min_const', float_array([6.0])),
- **const('mul_const', float_array([1.0/6.0])),
- **result('result'),
- }
-
- edges = [('input', 'add', {'in': 0, 'out': 0}),
- ('add_const', 'add', {'in': 1, 'out': 0}),
- ('add', 'relu', {'in': 0, 'out': 0}),
- ('relu', 'min', {'in': 0, 'out': 0}),
- ('min_const', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul', {'in': 0, 'out': 0}),
- ('mul_const', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'result', {'in': 0, 'out': 0})]
-
- def test_hsigmoid_with_relu_mul(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- HSigmoidWithReluMul().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'HSigmoid')
- self.assertTrue(graph.get_op_nodes(name='final_mul')[0].out_nodes()[0].node == 'result')
-
- def test_hsigmoid_with_relu_mul_wrong_constant(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'add_const': {'value': float_array([0.00001])}})
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithReluMul().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_hsigmoid_with_relu_mul_different_tensors(self):
- graph = build_graph_with_edge_attrs({
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('input_2', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('max', {'op': 'Maximum'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }, [('input_2', 'mul', {'in': 1, 'out': 0}),
- ('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'max', {'in': 0, 'out': 0}),
- ('const_0', 'max', {'in': 1, 'out': 0}),
- ('max', 'min', {'in': 0, 'out': 0}),
- ('const_6', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul', {'in': 0, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})])
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSigmoidWithReluMul().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/HSwish_fusing_test.py b/tools/mo/unit_tests/mo/front/HSwish_fusing_test.py
deleted file mode 100644
index 4415d438904256..00000000000000
--- a/tools/mo/unit_tests/mo/front/HSwish_fusing_test.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.HSwish_fusion import HSwishWithClamp, HSwishWithMinMax
-from openvino.tools.mo.front.common.partial_infer.utils import float_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const, regular_op, result, build_graph_with_edge_attrs
-
-ref_nodes = {**regular_op('input', {'type': 'Parameter'}),
- **regular_op('hswish', {'type': 'HSwish', 'name': 'final_mul'}),
- **result('result')
- }
-ref_edges = [('input', 'hswish'), ('hswish', 'result')]
-
-
-class HSwishWithClampTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('relu6', {'op': 'Clamp'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }
-
- edges = [('input', 'mul', {'in': 0, 'out': 0}),
- ('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'relu6', {'in': 0, 'out': 0}),
- ('const_0', 'relu6', {'in': 1, 'out': 0}),
- ('const_6', 'relu6', {'in': 2, 'out': 0}),
- ('relu6', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})]
-
- def test_hswish_with_clamp(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- HSwishWithClamp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'HSwish')
-
- def test_hswish_with_clamp_wrong_constant(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'const_0': {'value': float_array([0.00001])}})
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSwishWithClamp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_hswish_with_clamp_different_tensors(self):
- graph = build_graph_with_edge_attrs({
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('input_2', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('relu6', {'op': 'Clamp'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }, [('input', 'mul', {'in': 0, 'out': 0}),
- ('input_2', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'relu6', {'in': 0, 'out': 0}),
- ('const_0', 'relu6', {'in': 1, 'out': 0}),
- ('const_6', 'relu6', {'in': 2, 'out': 0}),
- ('relu6', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})])
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSwishWithClamp().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
-
-class HSwishWithMinMaxTest(unittest.TestCase):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('max', {'op': 'Maximum'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }
-
- edges = [('input', 'mul', {'in': 1, 'out': 0}),
- ('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'max', {'in': 0, 'out': 0}),
- ('const_0', 'max', {'in': 1, 'out': 0}),
- ('max', 'min', {'in': 0, 'out': 0}),
- ('const_6', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul', {'in': 0, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})]
-
- def test_hswish_with_min_max(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {})
-
- graph_ref = build_graph(ref_nodes, ref_edges)
- graph.stage = 'front'
-
- HSwishWithMinMax().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_mul')) == 1 and
- graph.get_op_nodes(name='final_mul')[0].op == 'HSwish')
-
- def test_hswish_with_min_max_wrong_constant(self):
- graph = build_graph_with_edge_attrs(self.nodes, self.edges, {'const_0': {'value': float_array([0.00001])}})
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSwishWithMinMax().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_hswish_with_min_max_different_tensors(self):
- graph = build_graph_with_edge_attrs({
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('input_2', {'type': 'Parameter'}),
- **regular_op('add', {'op': 'Add'}),
- **regular_op('max', {'op': 'Maximum'}),
- **regular_op('min', {'op': 'Minimum'}),
- **regular_op('mul', {'op': 'Mul'}),
- **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}),
- **const('const_0', float_array([0.0])),
- **const('const_3', float_array([3.0])),
- **const('const_6', float_array([6.0])),
- **const('const_1_6', float_array([1.0 / 6.0])),
- **result('result'),
- }, [('input_2', 'mul', {'in': 1, 'out': 0}),
- ('input', 'add', {'in': 0, 'out': 0}),
- ('const_3', 'add', {'in': 1, 'out': 0}),
- ('add', 'max', {'in': 0, 'out': 0}),
- ('const_0', 'max', {'in': 1, 'out': 0}),
- ('max', 'min', {'in': 0, 'out': 0}),
- ('const_6', 'min', {'in': 1, 'out': 0}),
- ('min', 'mul', {'in': 0, 'out': 0}),
- ('mul', 'mul_2', {'in': 0, 'out': 0}),
- ('const_1_6', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2', 'result', {'in': 0, 'out': 0})])
-
- graph_ref = graph.copy()
- graph.stage = 'front'
-
- HSwishWithMinMax().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/LayerNorm_test.py b/tools/mo/unit_tests/mo/front/LayerNorm_test.py
deleted file mode 100644
index 2bb15c95aea616..00000000000000
--- a/tools/mo/unit_tests/mo/front/LayerNorm_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.LayerNorm import LayerNorm
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class TestMVNPatternReplacement(unittest.TestCase):
- nodes_attributes_mvn = {
- 'inp': {'kind': 'op', 'op': 'AnyOp'},
- 'pool0': {'kind': 'op', 'op': 'ReduceMean'},
- 'pool1': {'kind': 'op', 'op': 'ReduceMean'},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'pow': {'kind': 'op', 'op': 'Pow'},
- 'div': {'kind': 'op', 'op': 'Div'},
- 'sqrt': {'kind': 'op', 'op': 'Pow'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add_param': {'kind': 'op', 'op': 'Const', 'shape': np.array([1]), 'value': np.array(1e-06, dtype=np.float32)},
- 'pow_param': {'kind': 'op', 'op': 'Const', 'shape': np.array([1]), 'value': np.array(0.5, dtype=np.float32)},
- 'pool0_param': {'kind': 'op', 'op': 'Const', 'shape': np.array([1]), 'value': np.array(-1, dtype=np.int32)},
- 'pool1_param': {'kind': 'op', 'op': 'Const', 'shape': np.array([1]), 'value': np.array(-1, dtype=np.int32)},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
- }
-
- nodes_attributes_ref = {
- 'inp': {'kind': 'op', 'op': 'AnyOp'},
- 'mvn': {'kind': 'op', 'op': 'MVN', 'eps': 1e-6, 'normalize_variance': 1, 'eps_mode': 'inside_sqrt'},
- 'mvn_param': {'kind': 'op', 'op': 'Const', 'shape': np.array([]), 'value': np.array(-1, dtype=np.int32)},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
- }
-
- def test_MVNPatternReplacement_test_1(self):
- graph = build_graph(self.nodes_attributes_mvn,
- [('inp', 'pool0', {'out': 0}),
- ('inp', 'sub', {'out': 0}),
- ('pool0', 'sub'),
- ('sub', 'pow'),
- ('pow', 'pool1'),
- ('pool1', 'add'),
- ('add', 'sqrt'),
- ('sqrt', 'div'),
- ('sub', 'div'),
- ('div', 'out'),
- ('pow_param', 'sqrt'),
- ('add_param', 'add'),
- ('pool0_param', 'pool0'),
- ('pool1_param', 'pool1'),
- ],
- nodes_with_edges_only=True)
- graph_ref = build_graph(self.nodes_attributes_ref,
- [('inp', 'mvn'),
- ('mvn_param', 'mvn'),
- ('mvn', 'out')],
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- replacer = LayerNorm()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_MVNPatternReplacement_test_2(self):
- graph = build_graph(self.nodes_attributes_mvn,
- [('inp', 'pool0', {'out': 0}),
- ('inp', 'sub', {'out': 0}),
- ('pool0', 'sub'),
- ('sub', 'cast'),
- ('cast', 'pow'),
- ('pow', 'pool1'),
- ('pool1', 'add'),
- ('add', 'sqrt'),
- ('sqrt', 'div'),
- ('sub', 'div'),
- ('div', 'out'),
- ('pow_param', 'sqrt'),
- ('add_param', 'add'),
- ('pool0_param', 'pool0'),
- ('pool1_param', 'pool1'),
- ],
- nodes_with_edges_only=True)
- graph_ref = build_graph(self.nodes_attributes_ref,
- [('inp', 'mvn'),
- ('mvn_param', 'mvn'),
- ('mvn', 'out')],
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- replacer = LayerNorm()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/Log1p_test.py b/tools/mo/unit_tests/mo/front/Log1p_test.py
deleted file mode 100644
index da114f9620dcf9..00000000000000
--- a/tools/mo/unit_tests/mo/front/Log1p_test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.Log1p import Log1p
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder': {'shape': np.array([4, 5, 6]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- # Log1p operation
- 'Log1p': {'kind': 'op', 'op': 'Log1p'},
- # Test operation
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None},
- # Add and Log operations
- 'const': {'kind': 'op', 'op': 'Const', 'value': np.ones([1], dtype=np.float32)},
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'log': {'type': 'Log', 'kind': 'op', 'op': 'Log'},
-}
-
-
-class TestLog1p(unittest.TestCase):
- def test_log1p_test(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'Log1p'),
- ('Log1p', 'last')
- ], nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('const', 'add'),
- ('placeholder', 'add'),
- ('add', 'log'),
- ('log', 'last'),
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- tested_class = Log1p()
- tested_class.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/OneHotDepthNormalizer_test.py b/tools/mo/unit_tests/mo/front/OneHotDepthNormalizer_test.py
deleted file mode 100644
index 71708303e3597c..00000000000000
--- a/tools/mo/unit_tests/mo/front/OneHotDepthNormalizer_test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.OneHotDepthNormalizer import OneHotDepthNormalizer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, \
- regular_op, const
-
-
-class OneHotDepthNormalizerTest(unittest.TestCase):
- def test(self):
- nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **const('depth', int64_array([2])),
- **regular_op('onehot', {'type': 'OneHot', 'kind': 'op', 'op': 'OneHot'}),
-
- **regular_op('reshape', {'type': 'Reshape', 'kind': 'op', 'op': 'Reshape'}),
- **const('reshape_dims', int64_array([])),
- **result('result'),
- }
- edges = [('input', 'onehot'),
- ('depth', 'onehot'),
- ('onehot', 'result'),
- ]
- graph = build_graph(nodes, edges)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- edges_ref = [('input', 'onehot'),
- ('depth', 'reshape'),
- ('reshape_dims', 'reshape'),
- ('reshape', 'onehot'),
- ('onehot', 'result'),
- ]
-
- graph_ref = build_graph(nodes, edges_ref)
-
- OneHotDepthNormalizer().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/Pack_test.py b/tools/mo/unit_tests/mo/front/Pack_test.py
deleted file mode 100644
index b4c0dcf42535c7..00000000000000
--- a/tools/mo/unit_tests/mo/front/Pack_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.front.Pack import Pack
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder_0': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- # Pack operation
- 'pack': {'axis': None, 'type': None, 'kind': 'op', 'op': 'Pack'},
- # Test operation
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None},
- # Unsqueeze, Concat and Const operations
- 'const_1': {'value': None, 'type': None, 'kind': 'op', 'op': 'Const'},
- 'Unsqueeze_0': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- 'Unsqueeze_1': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- 'Unsqueeze_2': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- 'Unsqueeze_3': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- 'Unsqueeze_0_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None},
- 'Unsqueeze_1_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None},
- 'Unsqueeze_2_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None},
- 'Unsqueeze_3_axis': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None},
- 'concat_1': {'axis': None, 'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
-}
-
-
-class TestPackTest():
-
- @pytest.mark.parametrize("num_inputs, num_placeholders, axis", [(2, 2, 0), (3, 3, 0), (4, 4, 0),
- (4, 4, 1), (4, 1, 0), (4, 1, 1)])
- def test_pack_test_all(self, num_inputs: int, num_placeholders: int, axis: list):
-
- graph_edges = []
- for i in range(num_inputs - num_placeholders + 1):
- for j in range(num_placeholders):
- graph_edges.append(('placeholder_{}'.format(j), 'pack'))
- graph_edges.append(('pack', 'last'))
-
- update_graph_attributes = {}
- for i in range(num_placeholders):
- update_graph_attributes['placeholder_{}'.format(i)] = {'shape': np.array([1, 227, 227, 3])}
- update_graph_attributes['pack'] = {'axis': axis}
-
- graph = build_graph(nodes_attributes, graph_edges, update_graph_attributes,
- nodes_with_edges_only=True)
-
- graph_ref_edges = []
- for i in range(num_inputs - num_placeholders + 1):
- for j in range(num_placeholders):
- graph_ref_edges.append(('placeholder_{}'.format(j), 'Unsqueeze_{}'.format(i + j)))
- graph_ref_edges.append(('Unsqueeze_{}'.format(i + j), 'concat_1'))
- graph_ref_edges.append(('concat_1', 'last'))
-
- update_graph_ref_attributes = {}
- for i in range(num_placeholders):
- update_graph_ref_attributes['placeholder_{}'.format(i)] = {'shape': np.array([1, 227, 227, 3])}
- for i in range(num_inputs):
- graph_ref_edges.append(('Unsqueeze_{}_axis'.format(i), 'Unsqueeze_{}'.format(i)))
- update_graph_ref_attributes['Unsqueeze_{}_axis'.format(i)] = {'shape': int64_array([1]),
- 'value': int64_array([axis])}
- update_graph_ref_attributes['concat_1'] = {'axis': axis}
-
- graph_ref = build_graph(nodes_attributes, graph_ref_edges, update_graph_ref_attributes,
- nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- replacer = Pack()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/front/RollWithEmptyAxesReplacer_test.py b/tools/mo/unit_tests/mo/front/RollWithEmptyAxesReplacer_test.py
deleted file mode 100644
index 636718983f2b3c..00000000000000
--- a/tools/mo/unit_tests/mo/front/RollWithEmptyAxesReplacer_test.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.RollWithEmptyAxesReplacer import RollWithEmptyAxesReplacer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const, result, regular_op
-
-nodes_attributes = {
- **regular_op('placeholder', {'type': 'Parameter'}),
- **regular_op('roll', {'type': 'Roll', 'op': 'Roll', 'axes': int64_array([-1, 2, 3]), 'shift': int64_array([5, -2, 3])}),
- **const('roll_shift', int64_array([5, -2, 3])),
- **result('result'),
-
- **regular_op('shape_of', {'type': 'ShapeOf'}),
- **regular_op('reshape1', {'type': 'Reshape'}),
- **regular_op('new_roll', {'type': 'Roll'}),
- **regular_op('reshape2', {'type': 'Reshape'}),
-
- **const('min_one_const', int64_array([-1])),
- **const('zero_const', int64_array([0]))
-}
-
-
-class RollWithEmptyAxesReplacerTest(unittest.TestCase):
- def test_transform(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'roll', {'in': 0, 'out': 0}),
- ('roll_shift', 'roll', {'in': 1, 'out': 0}),
- ('roll', 'result', {'in': 0, 'out': 0})], {}, nodes_with_edges_only=True)
- Node(graph, 'roll').add_input_port(2)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'reshape1', {'in': 0, 'out': 0}),
- ('min_one_const', 'reshape1', {'in': 1, 'out': 0}),
- ('reshape1', 'new_roll', {'in': 0, 'out': 0}),
- ('roll_shift', 'new_roll', {'in': 1, 'out': 0}),
- ('zero_const', 'new_roll', {'in': 2, 'out': 0}),
- ('new_roll', 'reshape2', {'in': 0, 'out': 0}),
- ('placeholder', 'shape_of', {'in': 0, 'out': 0}),
- ('shape_of', 'reshape2', {'in': 1, 'out': 0}),
- ('reshape2', 'result', {'in': 0, 'out': 0})], {}, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- RollWithEmptyAxesReplacer().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- shape_of_nodes = graph.get_op_nodes(type='ShapeOf')
- self.assertTrue(len(shape_of_nodes) == 1)
- shape_of = shape_of_nodes[0]
- self.assertTrue(shape_of.in_node().soft_get('name') == 'placeholder')
diff --git a/tools/mo/unit_tests/mo/front/ThresholdedReluDecomposition_test.py b/tools/mo/unit_tests/mo/front/ThresholdedReluDecomposition_test.py
deleted file mode 100644
index 8c506f7ead613d..00000000000000
--- a/tools/mo/unit_tests/mo/front/ThresholdedReluDecomposition_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.ThresholdedReluDecomposition import ThresholdedReluDecomposition
-from openvino.tools.mo.front.common.partial_infer.utils import float_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-nodes_attributes = {
- 'parameter': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'trelu': {'type': None, 'kind': 'op', 'op': 'ThresholdedRelu', 'alpha': 0.75, 'name': 'my_trelu'},
- 'result': {'type': 'Result', 'value': None, 'kind': 'op', 'op': 'Result'},
-
- 'cast': {'type': 'Convert', 'kind': 'op', 'op': 'Cast'},
- 'greater': {'type': 'Greater', 'kind': 'op', 'op': 'Greater'},
- 'mul': {'type': 'Multiply', 'kind': 'op', 'op': 'Mul', 'name': 'my_trelu'},
- 'squeeze2': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- **const('alpha', float_array([0.75])),
-}
-
-
-class ThresholdedReluDecompositionTest(unittest.TestCase):
- def test_trelu(self):
- graph = build_graph(nodes_attributes,
- [('parameter', 'trelu', {'in': 0, 'out': 0}),
- ('trelu', 'result', {'in': 0, 'out': 0}),
- ], nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('parameter', 'greater', {'in': 0, 'out': 0}),
- ('alpha', 'greater', {'in': 1, 'out': 0}),
- ('greater', 'cast', {'in': 0, 'out': 0}),
- ('parameter', 'mul', {'in': 0, 'out': 0}),
- ('cast', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'result', {'in': 0, 'out': 0}),
- ], nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- ThresholdedReluDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='my_trelu')) == 1 and
- graph.get_op_nodes(name='my_trelu')[0].op == 'Mul')
diff --git a/tools/mo/unit_tests/mo/front/__init__.py b/tools/mo/unit_tests/mo/front/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/binary_quantize_normalization_test.py b/tools/mo/unit_tests/mo/front/binary_quantize_normalization_test.py
deleted file mode 100644
index d60fac14b60f04..00000000000000
--- a/tools/mo/unit_tests/mo/front/binary_quantize_normalization_test.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.binary_quantize_normalization import BinaryFakeQuantizeNormalization
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-graph_nodes = {
- '0': {'name': 'input', 'kind': 'op', 'op': 'Parameter'},
- '1': {'name': 'mi_i', 'kind': 'op', 'op': 'Const'},
- '2': {'name': 'ma_i', 'kind': 'op', 'op': 'Const'},
- '3': {'name': 'mi_o', 'kind': 'op', 'op': 'Const'},
- '4': {'name': 'mi_o', 'kind': 'op', 'op': 'Const'},
-
- 'add': {'kind': 'op', 'op': 'Add'},
- 'const': {'kind': 'op', 'op': 'Const', 'value': np.array(0.5)},
- 'mul': {'kind': 'op', 'op': 'Mul'},
-
- 'quantize': {'name': 'quantize', 'levels': 2, 'kind': 'op', 'op': 'FakeQuantize'},
-
- 'output': {'name': 'output1', 'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-graph_edges = [
- ('0', 'quantize', {'in': 0}),
- ('1', 'quantize', {'in': 1}),
- ('2', 'quantize', {'in': 2}),
- ('3', 'quantize', {'in': 3}),
- ('4', 'quantize', {'in': 4}),
- ('quantize', 'output'),
-]
-
-graph_ref_edges = [
- ('0', 'quantize', {'in': 0}),
- ('1', 'add'),
- ('2', 'add'),
- ('add', 'mul'),
- ('const', 'mul'),
- ('mul', 'quantize', {'in': 1, 'out': 0}),
- ('mul', 'quantize', {'in': 2, 'out': 0}),
- ('3', 'quantize', {'in': 3}),
- ('4', 'quantize', {'in': 4}),
- ('quantize', 'output'),
-]
-
-
-class TestBinaryQuantizeNormalization(unittest.TestCase):
- def test_binary_quantize_normalizer(self):
- graph = build_graph(graph_nodes, graph_edges, nodes_with_edges_only=True)
- graph.stage = 'front'
- BinaryFakeQuantizeNormalization().find_and_replace_pattern(graph)
- graph.clean_up()
-
- graph_ref = build_graph(graph_nodes, graph_ref_edges)
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/broadcast_with_range_test.py b/tools/mo/unit_tests/mo/front/broadcast_with_range_test.py
deleted file mode 100644
index 3c5046724d919a..00000000000000
--- a/tools/mo/unit_tests/mo/front/broadcast_with_range_test.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.broadcast_with_range import ExpandRangeConstant
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect, \
- regular_op_with_empty_data
-
-
-class TestRangeBroadcast(unittest.TestCase):
- def test_broadcast_with_range_positive_test(self):
- graph = build_graph({
- **regular_op_with_shaped_data('shape', [2], {'type': 'Parameter'}),
- **valued_const_with_data('value', np.arange(0, 384).reshape((1, 384))),
- **regular_op_with_empty_data('bc', {'type': 'Broadcast'}),
- **result(),
- }, [
- *connect('value', '0:bc'),
- *connect('shape', '1:bc'),
- *connect('bc', 'output'),
- ], nodes_with_edges_only=True)
- ExpandRangeConstant().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attrs={
- **regular_op_with_shaped_data('shape', [2], {'type': 'Parameter'}),
- **valued_const_with_data('value', np.arange(0, 384).reshape((1, 384))),
- **regular_op_with_empty_data('bc', {'type': 'Broadcast'}),
- **regular_op_with_empty_data('shapeof', {'type': 'ShapeOf'}),
- **regular_op_with_empty_data('select', {'type': 'Select'}),
- **regular_op_with_empty_data('gather', {'type': 'Gather'}),
- 'gather_const': {'type': 'Gather', 'kind': 'op', 'op': 'Gather'},
- 'equal': {'type': 'Equal', 'kind': 'op', 'op': 'Equal'},
-
- # start
- **valued_const_with_data('start', np.array(0)),
- # limit
- **valued_const_with_data('minus_one_0', np.array(-1)),
- **valued_const_with_data('zero_0', np.array(0)),
- **valued_const_with_data('minus_one_1', np.array(-1)),
- **valued_const_with_data('zero_1', np.array(0)),
- # delta
- **valued_const_with_data('delta', np.array(1)),
- **regular_op_with_shaped_data('range', [1, 384], {'type': 'Range'}),
-
- # keep dims
- **valued_const_with_data('axes', np.array([0])),
- **regular_op_with_shaped_data('keep_shape', [1, 384], {'type': 'Unsqueeze'}),
-
- **valued_const_with_data('one', np.array(1)),
-
- **result(),
- },
- edges=[
- *connect('value', 'shapeof'),
- *connect('gather', '0:equal'),
- ('gather', 'select', {'in': 2, 'out': 0}),
- ('gather_const', 'select', {'in': 1}),
- ('equal', 'select', {'in': 0}),
- *connect('minus_one_0', '1:gather'),
- *connect('zero_0', '2:gather'),
- *connect('shapeof', '0:gather_const'),
- *connect('minus_one_1', '1:gather_const'),
- *connect('zero_1', '2:gather_const'),
- *connect('start', '0:range'),
- *connect('select', '1:range'),
- *connect('delta', '2:range'),
- *connect('range', '0:keep_shape'),
- *connect('axes', '1:keep_shape'),
- *connect('keep_shape', '0:bc'),
- *connect('one', '1:equal'),
- *connect('shape', '1:bc'),
- ('shape_d', 'gather', {'out': 0, 'in': 0}),
- *connect('bc', 'output'),
- ],
- update_attributes={
- 'range_d': {'value': np.arange(0, 384).reshape((1, 384))},
- 'keep_shape_d': {'value': np.arange(0, 384).reshape((1, 384))},
- })
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/caffe/MVNCaffeToMVN_test.py b/tools/mo/unit_tests/mo/front/caffe/MVNCaffeToMVN_test.py
deleted file mode 100644
index 5f03e3d087f4ad..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/MVNCaffeToMVN_test.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.MVNCaffeToMVN import MVNCaffeToMVN
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, const, connect_front
-
-nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('mvn_caffe', {'op': 'MVNCaffe'}),
- **result(),
-
- # nodes after replacement
- **const('start_1', np.array(1)),
- **const('start_2', np.array(2)),
- **const('step', np.array(1)),
- **regular_op_with_empty_data('rank', {'op': 'Rank', 'type': None}),
- **regular_op_with_empty_data('range', {'op': 'Range', 'type': None}),
- **regular_op_with_empty_data('mvn', {'op': 'MVN', 'type': None}),
-}
-
-
-class MVNCaffeToMVNTest(unittest.TestCase):
- def test_mvn_normalizer(self):
- graph = build_graph(nodes, [('input', 'mvn_caffe'),
- ('mvn_caffe', 'output')],
- {'mvn_caffe': {'across_channels': 0}},
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- MVNCaffeToMVN().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [('input', 'mvn', {'out': 0}),
- ('input', 'rank', {'out': 0}),
- *connect_front('start_2', '0:range'),
- *connect_front('rank', '1:range'),
- *connect_front('step', '2:range'),
- *connect_front('range', '1:mvn'),
- ('mvn', 'output')],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_mvn_normalizer_across_channels(self):
- graph = build_graph(nodes, [('input', 'mvn_caffe'),
- ('mvn_caffe', 'output')],
- {'mvn_caffe': {'across_channels': 1}},
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- MVNCaffeToMVN().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [('input', 'mvn', {'out': 0}),
- ('input', 'rank', {'out': 0}),
- *connect_front('start_1', '0:range'),
- *connect_front('rank', '1:range'),
- *connect_front('step', '2:range'),
- *connect_front('range', '1:mvn'),
- ('mvn', 'output')],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/caffe/__init__.py b/tools/mo/unit_tests/mo/front/caffe/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/caffe/argmax_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/argmax_ext_test.py
deleted file mode 100644
index 6346098eae577b..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/argmax_ext_test.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.argmax_ext import ArgMaxFrontExtractor
-from openvino.tools.mo.ops.argmax import ArgMaxOp, arg_ops_infer
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeArgMaxProtoLayer:
- def __init__(self, val):
- self.argmax_param = val
-
-
-class TestArgMaxExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['ArgMax'] = ArgMaxOp
-
- def test_argmax_no_pb_no_ml(self):
- self.assertRaises(AttributeError, ArgMaxFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.argmax_ext.merge_attrs')
- def test_argmax_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'out_max_val': True,
- 'top_k': 100,
- 'axis': 2
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakeArgMaxProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- ArgMaxFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'out_max_val': True,
- 'top_k': 100,
- 'axis': 2,
- 'infer': arg_ops_infer,
- 'remove_values_output': True,
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/axpy_test.py b/tools/mo/unit_tests/mo/front/caffe/axpy_test.py
deleted file mode 100644
index 3eec6d41f2705a..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/axpy_test.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.caffe.axpy import AxpyToSSandAdd
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-class TestAxpyReplacer(unittest.TestCase):
- def test_axpy(self):
- nodes = {
- 'node_1': {'kind': 'op', 'type': 'Identity', 'op': 'Parameter'},
- 'node_2': {'kind': 'op', 'type': 'Identity', 'op': 'Parameter'},
- 'node_3': {'kind': 'op', 'type': 'Identity', 'op': 'Parameter'},
- 'axpy': {'type': 'Axpy', 'kind': 'op', 'op': 'Axpy'},
- 'node_4': {'kind': 'op', 'type': 'Identity', 'op': 'Parameter'}}
- edges = [
- ('node_1', 'axpy', {'in': 0, 'out': 0}),
- ('node_2', 'axpy', {'in': 1, 'out': 0}),
- ('node_3', 'axpy', {'in': 2, 'out': 0}),
- ('axpy', 'node_4', {'in': 0, 'out': 0})]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'axpy')
- replacer = AxpyToSSandAdd()
- replacer.replace_op(graph, node)
-
- scale_node = [node for node, attrs in list(graph.nodes(data=True)) if attrs['type'] == 'ScaleShift']
- self.assertEqual(len(scale_node), 1)
- add_node = [node for node, attrs in list(graph.nodes(data=True)) if attrs['type'] == 'Add']
- self.assertEqual(len(add_node), 1)
diff --git a/tools/mo/unit_tests/mo/front/caffe/bn_test.py b/tools/mo/unit_tests/mo/front/caffe/bn_test.py
deleted file mode 100644
index f9b2c52e04b8df..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/bn_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import unittest
-
-from openvino.tools.mo.front.caffe.bn import BNToScaleShift
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.extractors import FakeParam
-from unit_tests.utils.graph import build_graph_with_edge_attrs, build_graph_with_attrs
-
-
-class FakeBNProtoLayer:
- def __init__(self, val):
- self.bn_param = val
-
-
-class FakeBNBinLayer:
- def __init__(self, val):
- self.blobs = val
-
-
-class TestBNReplacer(unittest.TestCase):
- def test_bn(self):
- bn_pb = FakeBNProtoLayer(FakeParam('eps', 0.0001))
- mean = [1, 2.5, 3]
- var = [0.5, 0.1, 1.2]
- scale = [2.3, 3.4, 4.5]
- shift = [0.8, 0.6, 0.4]
- bn_bin = FakeBNBinLayer([FakeParam('data', mean),
- FakeParam('data', var),
- FakeParam('data', scale),
- FakeParam('data', shift)])
- nodes = [
- ('input', {'kind': 'op', 'type': 'Identity', 'op': 'Identity'}),
- ('bn', {'type': None, 'kind': 'op', 'op': 'BN', 'pb': bn_pb, 'model_pb': bn_bin}),
- ('output', {'kind': 'op', 'type': 'Identity', 'op': 'Identity'}),
- ]
- edges = [
- ('input', 'bn', {'in': 0, 'out': 0}),
- ('bn', 'output', {'in': 0, 'out': 0}),
- ]
- graph = build_graph_with_attrs(nodes, edges)
- node = Node(graph, 'bn')
- graph.stage = 'front'
-
- BNToScaleShift().find_and_replace_pattern(graph)
-
- ref_nodes = {
- 'input': {'kind': 'op', 'type': 'Identity', 'op': 'Identity'},
- 'scale': {'kind': 'op', 'type': 'Const', 'op': 'Const',
- 'value': np.array([1.11796412, 3.2272172, 4.74282367])},
- 'shift': {'kind': 'op', 'type': 'Const', 'op': 'Const',
- 'value': np.array([-2.07131747, -10.87253847, -20.14270653])},
- 'ss': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'},
- 'output': {'kind': 'op', 'type': 'Identity', 'op': 'Identity'},
- }
- ref_edges = [
- ('input', 'ss', {'in': 0, 'out': 0}),
- ('scale', 'ss', {'in': 1, 'out': 0}),
- ('shift', 'ss', {'in': 2, 'out': 0}),
- ('ss', 'output', {'in': 0, 'out': 0}),
- ]
- ref_graph = build_graph_with_edge_attrs(ref_nodes, ref_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'input', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/caffe/conv_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/conv_ext_test.py
deleted file mode 100644
index eb430a67c1fdeb..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/conv_ext_test.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.conv_ext import ConvFrontExtractor, DeconvFrontExtractor, conv_create_attrs, conv_set_params
-from openvino.tools.mo.front.caffe.extractors.utils import get_list_from_container
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.extractors import PB, FakeParam, FakeMultiParam
-
-
-class FakeConvProtoLayer:
- def __init__(self, val):
- self.convolution_param = val
- self.bottom = [0]
-
-
-class TestConvShapesParsing(unittest.TestCase):
- def test_conv_no_pb_no_ml(self):
- node = PB({'pb': None})
- self.assertRaises(Error, ConvFrontExtractor.extract, node)
-
- @patch('openvino.tools.mo.front.caffe.conv_ext.weights_biases')
- @patch('openvino.tools.mo.front.caffe.conv_ext.layout_attrs')
- def test_conv_ext_ideal_numbers(self, weights_biases_mock, layout_attrs_mock):
- weights_biases_mock.return_value = {}
- layout_attrs_mock.return_value = {}
- params = {
- 'pad': 10,
- 'kernel_size': 11,
- 'stride': 12,
- 'dilation': 13,
- 'group': 14,
- 'num_output': 15,
- 'bias_term': True
- }
- node = PB({'pb': FakeConvProtoLayer(FakeMultiParam(params))})
- ConvFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'op': 'Conv2D',
- 'pad': np.array([[0, 0], [0, 0], [10, 10], [10, 10]]),
- 'pad_spatial_shape': np.array([[10, 10], [10, 10]]),
- 'stride': np.array([1, 1, 12, 12]),
- 'kernel_spatial': np.array([11, 11]),
- 'dilation': np.array([1, 1, 13, 13]),
- 'group': 14,
- 'bias_addable': True,
- 'bias_term': True,
- }
- self.assertTrue(weights_biases_mock.called)
- self.assertTrue(layout_attrs_mock.called)
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
- @patch('openvino.tools.mo.front.caffe.conv_ext.weights_biases')
- @patch('openvino.tools.mo.front.caffe.conv_ext.layout_attrs')
- def test_conv_ext_empty_numbers(self, weights_biases_mock, layout_attrs_mock):
- weights_biases_mock.return_value = {}
- layout_attrs_mock.return_value = {}
- params = {
- 'pad': None,
- 'kernel_size': None,
- 'stride': None,
- 'dilation': None,
- 'group': 14,
- 'num_output': 15,
- 'bias_term': True,
- 'pad_w': 3,
- 'pad_h': 4,
- 'kernel_w': 5,
- 'kernel_h': 6,
- 'stride_h': 3,
- 'stride_w': 2,
- }
- node = PB({'pb': FakeConvProtoLayer(FakeMultiParam(params))})
- ConvFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'op': 'Conv2D',
- 'pad': np.array([[0, 0], [0, 0], [4, 4], [3, 3]]),
- 'pad_spatial_shape': np.array([[4, 4], [3, 3]]),
- 'stride': np.array([1, 1, 3, 2]),
- 'kernel_spatial': np.array([6, 5]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'group': 14,
- 'bias_addable': True,
- 'bias_term': True,
- }
- self.assertTrue(weights_biases_mock.called)
- self.assertTrue(layout_attrs_mock.called)
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
- def test_attrs(self):
- params = {
- 'type_str': 'Conv2D',
- 'padding': [10, 10],
- 'stride': [12, 12],
- 'kernel': [11, 11],
- 'dilate': [13, 13],
- 'group': 14,
- 'output': 13,
- 'bias_term': True
- }
-
- res = conv_create_attrs(params)
-
- exp_res = {
- 'pad': np.array([[0, 0], [0, 0], [10, 10], [10, 10]]),
- 'pad_spatial_shape': np.array([[10, 10], [10, 10]]),
- 'stride': np.array([1, 1, 12, 12]),
- 'kernel_spatial': np.array([11, 11]),
- 'dilation': np.array([1, 1, 13, 13]),
- 'group': 14,
- 'bias_addable': True,
- 'bias_term': True,
- 'output_spatial_shape': None,
- 'output_shape': None,
- 'output': 13,
- }
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
- def test_get_list_from_container_no_existing_param(self):
- res = get_list_from_container(FakeParam("p", "1"), 'prop', int)
- self.assertEqual(res, [])
-
- def test_get_list_from_container_no_param(self):
- res = get_list_from_container(None, 'prop', int)
- self.assertEqual(res, [])
-
- def test_get_list_from_container_simple_type_match(self):
- res = get_list_from_container(FakeParam('prop', 10), 'prop', int)
- self.assertEqual(res, [10])
-
- def test_get_list_from_container_list_match(self):
- res = get_list_from_container(FakeParam('prop', [10, 11]), 'prop', int)
- self.assertEqual(res, [10, 11])
-
- def test_get_list_from_container_list_match_empty(self):
- res = get_list_from_container(FakeParam('prop', []), 'prop', int)
- self.assertEqual(res, [])
-
- def test_params_creation(self):
- params = {
- 'pad': None,
- 'kernel_size': None,
- 'stride': None,
- 'dilation': None,
- 'group': 14,
- 'num_output': 15,
- 'bias_term': True,
- 'pad_w': 3,
- 'pad_h': 4,
- 'kernel_w': 5,
- 'kernel_h': 6,
- 'stride_h': 3,
- 'stride_w': 2,
- }
- exp_res = {
- 'padding': [3, 4],
- 'stride': [2, 3],
- 'kernel': [5, 6],
- 'dilate': [1, 1],
- 'group': 14,
- 'output': 15
- }
- res = conv_set_params(FakeConvProtoLayer(FakeMultiParam(params)).convolution_param, 'Conv2D')
-
- for key in exp_res.keys():
- if key in ('padding', 'stride', 'stride', 'kernel', 'dilate'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
-
-class TestDeconvShapesParsing(unittest.TestCase):
- def test_deconv_no_pb_no_ml(self):
- node = PB({'pb': None})
- self.assertRaises(Error, DeconvFrontExtractor.extract, node)
-
- @patch('openvino.tools.mo.front.caffe.conv_ext.weights_biases')
- @patch('openvino.tools.mo.front.caffe.conv_ext.layout_attrs')
- def test_conv_ext_ideal_numbers(self, weights_biases_mock, layout_attrs_mock):
- weights_biases_mock.return_value = {}
- layout_attrs_mock.return_value = {}
- params = {
- 'pad': 10,
- 'kernel_size': 11,
- 'stride': 12,
- 'dilation': 13,
- 'group': 14,
- 'num_output': 15,
- 'bias_term': True
- }
- node = PB({'pb': FakeConvProtoLayer(FakeMultiParam(params))})
- res = DeconvFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'op': 'Deconv2D',
- 'pad': np.array([[0, 0], [0, 0], [10, 10], [10, 10]]),
- 'pad_spatial_shape': np.array([[10, 10], [10, 10]]),
- 'stride': np.array([1, 1, 12, 12]),
- 'kernel_spatial': np.array([11, 11]),
- 'dilation': np.array([1, 1, 13, 13]),
- 'group': 14,
- 'bias_addable': True,
- }
- self.assertTrue(weights_biases_mock.called)
- self.assertTrue(layout_attrs_mock.called)
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
- @patch('openvino.tools.mo.front.caffe.conv_ext.weights_biases')
- @patch('openvino.tools.mo.front.caffe.conv_ext.layout_attrs')
- def test_conv_ext_false_bias_term(self, weights_biases_mock, layout_attrs_mock):
- weights_biases_mock.return_value = {}
- layout_attrs_mock.return_value = {}
- params = {
- 'pad': 10,
- 'kernel_size': 11,
- 'stride': 12,
- 'dilation': 13,
- 'group': 14,
- 'num_output': 15,
- 'bias_term': False
- }
- node = PB({'pb': FakeConvProtoLayer(FakeMultiParam(params))})
- res = DeconvFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'op': 'Deconv2D',
- 'pad': np.array([[0, 0], [0, 0], [10, 10], [10, 10]]),
- 'pad_spatial_shape': np.array([[10, 10], [10, 10]]),
- 'stride': np.array([1, 1, 12, 12]),
- 'kernel_spatial': np.array([11, 11]),
- 'dilation': np.array([1, 1, 13, 13]),
- 'group': 14,
- 'bias_addable': True,
- 'bias_term': False,
- }
- self.assertTrue(weights_biases_mock.called)
- self.assertTrue(layout_attrs_mock.called)
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation', 'bias_term'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
- @patch('openvino.tools.mo.front.caffe.conv_ext.weights_biases')
- @patch('openvino.tools.mo.front.caffe.conv_ext.layout_attrs')
- def test_conv_ext_empty_numbers(self, weights_biases_mock, layout_attrs_mock):
- weights_biases_mock.return_value = {}
- layout_attrs_mock.return_value = {}
- params = {
- 'pad': None,
- 'kernel_size': None,
- 'stride': None,
- 'dilation': None,
- 'group': 14,
- 'num_output': 15,
- 'bias_term': True,
- 'pad_w': 3,
- 'pad_h': 4,
- 'kernel_w': 5,
- 'kernel_h': 6,
- 'stride_h': 3,
- 'stride_w': 2,
- }
- node = PB({'pb': FakeConvProtoLayer(FakeMultiParam(params))})
- res = DeconvFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'op': 'Deconv2D',
- 'pad': np.array([[0, 0], [0, 0], [4, 4], [3, 3]]),
- 'pad_spatial_shape': np.array([[4, 4], [3, 3]]),
- 'stride': np.array([1, 1, 3, 2]),
- 'kernel_spatial': np.array([6, 5]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'group': 14,
- 'bias_addable': True,
- }
- self.assertTrue(weights_biases_mock.called)
- self.assertTrue(layout_attrs_mock.called)
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
-
- def test_attrs(self):
- params = {
- 'type_str': 'Deconv2D',
- 'padding': [10, 10],
- 'stride': [12, 12],
- 'kernel': [11, 11],
- 'dilate': [13, 13],
- 'group': 14,
- 'output': 13,
- 'bias_term': True
- }
- res = conv_create_attrs(params)
-
- exp_res = {
- 'pad': np.array([[0, 0], [0, 0], [10, 10], [10, 10]]),
- 'pad_spatial_shape': np.array([[10, 10], [10, 10]]),
- 'stride': np.array([1, 1, 12, 12]),
- 'kernel_spatial': np.array([11, 11]),
- 'dilation': np.array([1, 1, 13, 13]),
- 'group': 14,
- 'bias_addable': True,
- 'output_spatial_shape': None,
- 'output_shape': None,
- 'output': 13,
- }
- for key in exp_res.keys():
- if key in ('pad', 'pad_spatial_shape', 'stride', 'kernel_spatial', 'dilation'):
- np.testing.assert_equal(res[key], exp_res[key])
- else:
- self.assertEqual(res[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/crop_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/crop_ext_test.py
deleted file mode 100644
index 9f3610d19a77b2..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/crop_ext_test.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.crop_ext import CropFrontExtractor
-from openvino.tools.mo.front.common.partial_infer.crop import crop_infer
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeCropProtoLayer:
- def __init__(self, val):
- self.crop_param = val
-
-
-class TestCropExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Crop'] = Crop
-
- def test_da_no_pb_no_ml(self):
- self.assertRaises(AttributeError, CropFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.collect_attributes')
- def test_crop_ext(self, collect_attributes_mock):
- params = {
- 'axis': 0,
- 'offset': 0,
- }
- collect_attributes_mock.return_value = {
- **params,
- 'test': 54,
- 'test2': 'test3'
- }
- fake_pl = FakeCropProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- CropFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'op': 'Crop',
- 'axis': 0,
- 'offset': 0,
- 'dim': None, # set in infer
- 'infer': crop_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(exp_res[key], fake_node[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/ctcgreedydecoder_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/ctcgreedydecoder_ext_test.py
deleted file mode 100644
index 103a0c0f50fda0..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/ctcgreedydecoder_ext_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.ctcgreedydecoder_ext import CTCGreedyDecoderFrontExtractor
-from openvino.tools.mo.ops.ctc_greedy_decoder import CTCGreedyDecoderOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeCTCGreedyDecoderProtoLayer:
- def __init__(self, val):
- self.ctc_decoder_param = val
-
-
-class TestCTCGreedyDecoderExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['CTCGreedyDecoder'] = CTCGreedyDecoderOp
-
- def test_ctcgreedydecoder_no_pb_no_ml(self):
- self.assertRaises(AttributeError, CTCGreedyDecoderFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.ctcgreedydecoder_ext.merge_attrs')
- def test_ctcgreedydecoder_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'ctc_merge_repeated': True
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakeCTCGreedyDecoderProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- CTCGreedyDecoderFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "CTCGreedyDecoder",
- 'ctc_merge_repeated': 1,
- 'infer': CTCGreedyDecoderOp.infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/custom_layers_mapping_test.py b/tools/mo/unit_tests/mo/front/caffe/custom_layers_mapping_test.py
deleted file mode 100644
index ba9a2390ff864c..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/custom_layers_mapping_test.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from google.protobuf import text_format
-
-from openvino.tools.mo.front.caffe.custom_layers_mapping import proto_extractor
-from openvino.tools.mo.front.caffe.proto import caffe_pb2
-
-
-class TestCustomLayerMapping(unittest.TestCase):
- def test_extractor_custom_layer(self):
- expected_conv_params = {
- 'num_output': 64,
- 'pad': 1,
- 'kernel_size': 3,
- 'stride': 1,
- 'bias_term': True,
- 'axis': 1,
- 'engine': 'caffe.ConvolutionParameter.DEFAULT',
- 'group': 1,
- 'force_nd_im2col': False,
- 'pad_h': 0,
- 'pad_w': 0
- }
- layer = """
- name: "conv"
- type: "Convolution"
- bottom: "input"
- top: "conv"
- convolution_param {
- num_output: 64
- pad: 1
- kernel_size: 3
- stride: 1
- }
- """
- mapping = {
- 'NativeType': 'Convolution',
- 'hasParam': 'true',
- 'protoParamName': 'convolution_param'
- }
- proto = caffe_pb2.LayerParameter()
- text_format.Merge(layer, proto)
- attrs = proto_extractor(proto, None, mapping, False, False)
- for key, val in expected_conv_params.items():
- if key == 'bias_term' or key == 'force_nd_im2col':
- self.assertTrue(str(int(val)) == attrs[key])
- else:
- self.assertTrue(str(val) == attrs[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/elementwise_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/elementwise_ext_test.py
deleted file mode 100644
index ff51a84eaba430..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/elementwise_ext_test.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.elementwise_ext import BiasToAdd
-from unit_tests.utils.extractors import FakeModelLayer, FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeBiasProtoLayer:
- def __init__(self, val):
- self.bias_param = val
-
-
-class TestBias(unittest.TestCase):
-
- @patch('openvino.tools.mo.front.caffe.elementwise_ext.embed_input')
- def test_bias(self, embed_input_mock):
- embed_input_mock.return_value = {}
- params = {'axis': 1}
- add_node = FakeNode(FakeBiasProtoLayer(FakeMultiParam(params)),
- FakeModelLayer([1, 2, 3, 4, 5]))
- BiasToAdd.extract(add_node)
-
- exp_res = {
- 'type': "Add",
- 'axis': 1
- }
-
- for key in exp_res.keys():
- self.assertEqual(add_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/eltwise_add_normalize_test.py b/tools/mo/unit_tests/mo/front/caffe/eltwise_add_normalize_test.py
deleted file mode 100644
index 8f15aef9441461..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/eltwise_add_normalize_test.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.eltwise_add_normalize import EltwiseAddNormalize
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-input_shape = int64_array([1, 4, 10])
-const_1_value = np.array([2.0])
-const_2_value = np.array([3.0])
-const_3_value = np.array([4.0])
-
-nodes_attributes = {
- 'placeholder_1': {'shape': input_shape, 'type': 'Placeholder', 'kind': 'op', 'op': 'Placeholder'},
- 'placeholder_2': {'shape': input_shape, 'type': 'Placeholder', 'kind': 'op', 'op': 'Placeholder'},
- 'placeholder_3': {'shape': input_shape, 'type': 'Placeholder', 'kind': 'op', 'op': 'Placeholder'},
- 'eltwise': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'eltwise_n': {'type': 'EltwiseN', 'kind': 'op', 'op': 'EltwiseN', 'operation': 'sum'},
-
- 'sigmoid_1': {'type': 'Sigmoid', 'kind': 'op', 'op': 'Sigmoid'},
- 'sigmoid_2': {'type': 'Sigmoid', 'kind': 'op', 'op': 'Sigmoid'},
-
- 'mul_1': {'type': 'Multiply', 'op': 'Mul', 'kind': 'op'},
- 'const_1': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'mul_2': {'type': 'Multiply', 'op': 'Mul', 'kind': 'op'},
- 'const_2': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'mul_3': {'type': 'Multiply', 'op': 'Mul', 'kind': 'op'},
- 'const_3': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
-}
-
-
-class EltwiseAddNormalizationTest(unittest.TestCase):
- def test_first_input_coeff_not_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'eltwise': {'coeff': np.array([2.0, 1.0])}
- }, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'mul_1'),
- ('const_1', 'mul_1'),
- ('mul_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'const_1': {'value': const_1_value, 'shape': const_1_value.shape},
- }, nodes_with_edges_only=True)
-
- EltwiseAddNormalize().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_second_input_coeff_not_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'eltwise': {'coeff': np.array([1.0, const_2_value[0]])}
- }, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'mul_2'),
- ('const_2', 'mul_2'),
- ('mul_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'const_2': {'value': const_2_value, 'shape': const_2_value.shape},
- }, nodes_with_edges_only=True)
-
- EltwiseAddNormalize().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_both_input_coeff_not_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'eltwise': {'coeff': np.array([const_1_value[0], const_2_value[0]])}
- }, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'mul_1'),
- ('const_1', 'mul_1'),
- ('mul_1', 'eltwise'),
- ('placeholder_2', 'mul_2'),
- ('const_2', 'mul_2'),
- ('mul_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'const_1': {'value': const_1_value, 'shape': const_1_value.shape},
- 'const_2': {'value': const_2_value, 'shape': const_2_value.shape},
- }, nodes_with_edges_only=True)
-
- EltwiseAddNormalize().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_both_input_coeff_equal_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'eltwise': {'coeff': np.array([1.0, 1.0])}
- }, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {}, nodes_with_edges_only=True)
-
- EltwiseAddNormalize().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_both_input_coeff_not_defined(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {'eltwise': {'coeff': None}
- }, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ('eltwise', 'sigmoid_2'),
- ],
- {}, nodes_with_edges_only=True)
-
- EltwiseAddNormalize().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
- def test_3_inputs_with_coeffs(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'eltwise'),
- ('placeholder_2', 'eltwise'),
- ('placeholder_3', 'eltwise'),
- ('eltwise', 'sigmoid_1'),
- ],
- {'eltwise': {'coeff': np.array([const_1_value[0], const_2_value[0], const_3_value[0]])}
- }, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'mul_1'),
- ('const_1', 'mul_1'),
- ('mul_1', 'eltwise_n'),
- ('placeholder_2', 'mul_2'),
- ('const_2', 'mul_2'),
- ('mul_2', 'eltwise_n'),
- ('placeholder_3', 'mul_3'),
- ('const_3', 'mul_3'),
- ('mul_3', 'eltwise_n'),
- ('eltwise_n', 'sigmoid_1'),
- ],
- {'const_1': {'value': const_1_value, 'shape': const_1_value.shape},
- 'const_2': {'value': const_2_value, 'shape': const_2_value.shape},
- 'const_3': {'value': const_3_value, 'shape': const_3_value.shape},
- }, nodes_with_edges_only=True)
-
- EltwiseAddNormalize().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/caffe/elu_test.py b/tools/mo/unit_tests/mo/front/caffe/elu_test.py
deleted file mode 100644
index c26a58b8ffd416..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/elu_test.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.elu import ELUFrontExtractor
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeProtoLayer:
- def __init__(self, val):
- self.elu_param = val
-
-
-class TestElu(unittest.TestCase):
- @patch('openvino.tools.mo.front.caffe.elu.collect_attributes')
- def test_elu_ext(self, collect_attrs_mock):
- params = {
- 'alpha': 4
- }
- collect_attrs_mock.return_value = {
- **params,
- 'test': 54,
- 'test2': 'test3'
- }
-
- fn = FakeNode(FakeProtoLayer(FakeMultiParam(params)), None)
- ELUFrontExtractor.extract(fn)
-
- exp_res = {
- 'type': 'Elu',
- 'alpha': 4
- }
-
- for i in exp_res:
- self.assertEqual(fn[i], exp_res[i])
diff --git a/tools/mo/unit_tests/mo/front/caffe/extractor_test.py b/tools/mo/unit_tests/mo/front/caffe/extractor_test.py
deleted file mode 100644
index 435c59a8ecdd38..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/extractor_test.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.extractor import check_phase, register_caffe_python_extractor
-from openvino.tools.mo.front.extractor import CaffePythonFrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'node_2': {'type': 'Identity', 'kind': 'op'}}
-
-
-class TestExtractor(unittest.TestCase):
- def test_check_phase_train_phase(self):
- phase_param = {
- 'phase': 0
- }
-
- include_param = {
- 'include': [FakeMultiParam(phase_param)]
- }
-
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2')],
- {
- 'node_1': {'pb': FakeMultiParam(include_param)}
- })
-
- node = Node(graph, 'node_1')
- res = check_phase(node)
- exp_res = {'phase': 0}
- self.assertEqual(res, exp_res)
-
- def test_check_phase_test_phase(self):
- phase_param = {
- 'phase': 1
- }
-
- include_param = {
- 'include': [FakeMultiParam(phase_param)]
- }
-
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2')],
- {
- 'node_1': {'pb': FakeMultiParam(include_param)}
- })
-
- node = Node(graph, 'node_1')
- res = check_phase(node)
- exp_res = {'phase': 1}
- self.assertEqual(res, exp_res)
-
- def test_check_phase_no_phase(self):
- phase_param = {}
-
- include_param = {
- 'include': [FakeMultiParam(phase_param)]
- }
-
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2')],
- {
- 'node_1': {'pb': FakeMultiParam(include_param)}
- })
-
- node = Node(graph, 'node_1')
- res = check_phase(node)
- exp_res = {}
- self.assertEqual(res, exp_res)
-
- def test_check_phase_no_include(self):
- include_param = {}
-
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2')],
- {
- 'node_1': {'pb': FakeMultiParam(include_param)}
- })
-
- node = Node(graph, 'node_1')
- res = check_phase(node)
- exp_res = {}
- self.assertEqual(res, exp_res)
-
- def test_check_phase_no_pb(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2')],
- {})
-
- node = Node(graph, 'node_1')
- res = check_phase(node)
- exp_res = {}
- self.assertEqual(res, exp_res)
-
- @patch('openvino.tools.mo.ops.activation.Activation')
- def test_register_caffe_python_extractor_by_name(self, op_mock):
- op_mock.op = 'TestLayer'
- name = 'myTestLayer'
- register_caffe_python_extractor(op_mock, name)
- self.assertIn(name, CaffePythonFrontExtractorOp.registered_ops)
-
- @patch('openvino.tools.mo.ops.activation.Activation')
- def test_register_caffe_python_extractor_by_op(self, op_mock):
- op_mock.op = 'TestLayer'
- register_caffe_python_extractor(op_mock)
- self.assertIn(op_mock.op, CaffePythonFrontExtractorOp.registered_ops)
diff --git a/tools/mo/unit_tests/mo/front/caffe/extractors/__init__.py b/tools/mo/unit_tests/mo/front/caffe/extractors/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/caffe/extractors/utils_test.py b/tools/mo/unit_tests/mo/front/caffe/extractors/utils_test.py
deleted file mode 100644
index 9b28206ab6f7ae..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/extractors/utils_test.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch, call
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.extractors.utils import weights_biases, embed_input, get_canonical_axis_index
-from unit_tests.utils.extractors import FakeModelLayer
-
-
-class TestWeightsBiases(unittest.TestCase):
- def test_weights_biases_no_layer_no_bias(self):
- res = weights_biases(False, None)
- self.assertEqual(res, {})
-
- @patch('openvino.tools.mo.front.caffe.extractors.utils.embed_input')
- def test_weights_biases_layer_no_bias(self, embed_input_mock):
- weights_biases(False, FakeModelLayer([[1, 2], ]))
- calls = [call({}, 1, 'weights', [1, 2])]
- embed_input_mock.assert_has_calls(calls)
-
- @patch('openvino.tools.mo.front.caffe.extractors.utils.embed_input')
- def test_weights_biases_layer_bias(self, embed_input_mock):
- weights_biases(True, FakeModelLayer([[1, 2], [3, 4]]))
- calls = [call({}, 1, 'weights', [1, 2]), call({}, 2, 'biases', [3, 4])]
- embed_input_mock.assert_has_calls(calls)
-
-
-class TestEmbedInput(unittest.TestCase):
- def test_embed_input_no_bin_name_no_bias(self):
- attrs = {}
- blob = np.array([1, 2])
- name = 'weights'
- embed_input(attrs, 1, name, blob, None)
- exp_res = {
- 'weights': blob,
- 'embedded_inputs': [
- (1, name, {'bin': name})
- ]
- }
- for key in exp_res.keys():
- if key == name:
- np.testing.assert_equal(attrs[key], exp_res[key])
- else:
- self.assertEqual(attrs[key], exp_res[key])
-
- def test_embed_input_w_bin_name(self):
- attrs = {}
- blob = np.array([1, 2])
- name = 'weights'
- embed_input(attrs, 1, name, blob, 'special_name')
- exp_res = {
- 'weights': blob,
- 'embedded_inputs': [
- (1, name, {'bin': 'special_name'})
- ]
- }
- for key in exp_res.keys():
- if key == name:
- np.testing.assert_equal(attrs[key], exp_res[key])
- else:
- self.assertEqual(attrs[key], exp_res[key])
-
-
-class TestCanonicalAxisIndex(unittest.TestCase):
- def test_negative_index(self):
- shape = [1, 2, 3, 4]
- inds = [-4, -3, -2, -1]
- expected_inds = [0, 1, 2, 3]
- for i in range(len(inds)):
- assert get_canonical_axis_index(shape, inds[i]) == expected_inds[i]
-
- def test_posirive_index(self):
- shape = [1, 2, 3, 4]
- inds = [0, 1, 2, 3]
- expected_inds = [0, 1, 2, 3]
- for i in range(len(inds)):
- assert get_canonical_axis_index(shape, inds[i]) == expected_inds[i]
diff --git a/tools/mo/unit_tests/mo/front/caffe/grn_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/grn_ext_test.py
deleted file mode 100644
index 0b5d22115d1ea6..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/grn_ext_test.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.grn_ext import GRNFrontExtractor
-from openvino.tools.mo.ops.grn import GRNOp
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeGRNProtoLayer:
- def __init__(self, val):
- self.grn_param = val
-
-
-class TestGRNExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['GRN'] = GRNOp
-
- def test_grn_no_pb_no_ml(self):
- self.assertRaises(AttributeError, GRNFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.grn_ext.merge_attrs')
- def test_grn_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'bias': 0.7
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakeGRNProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- GRNFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "GRN",
- 'bias': 0.7,
- 'infer': copy_shape_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/loader_test.py b/tools/mo/unit_tests/mo/front/caffe/loader_test.py
deleted file mode 100644
index 6348440c9cd7a8..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/loader_test.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-from google.protobuf import text_format
-
-from openvino.tools.mo.front.caffe.loader import caffe_pb_to_nx
-from openvino.tools.mo.front.caffe.proto import caffe_pb2
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-
-proto_str_one_input = 'name: "network" ' \
- 'layer { ' \
- 'name: "Input0" ' \
- 'type: "Input" ' \
- 'top: "Input0" ' \
- 'input_param { ' \
- 'shape: { ' \
- 'dim: 1 ' \
- 'dim: 3 ' \
- 'dim: 224 ' \
- 'dim: 224 ' \
- '} ' \
- '} ' \
- '}'
-
-proto_str_old_styled_multi_input = 'name: "network" ' \
- 'input: "Input0" ' \
- 'input_dim: 1 ' \
- 'input_dim: 3 ' \
- 'input_dim: 224 ' \
- 'input_dim: 224 ' \
- 'input: "data" ' \
- 'input_dim: 1 ' \
- 'input_dim: 3 '
-
-proto_str_input = 'name: "network" ' \
- 'input: "data" ' \
- 'input_shape ' \
- '{ ' \
- 'dim: 1 ' \
- 'dim: 3 ' \
- 'dim: 224 ' \
- 'dim: 224 ' \
- '}'
-
-proto_str_multi_input = 'name: "network" ' \
- 'input: "data" ' \
- 'input_shape ' \
- '{ ' \
- 'dim: 1 ' \
- 'dim: 3 ' \
- 'dim: 224 ' \
- 'dim: 224 ' \
- '} ' \
- 'input: "data1" ' \
- 'input_shape ' \
- '{ ' \
- 'dim: 1 ' \
- 'dim: 3 ' \
- '}'
-
-proto_str_old_styled_input = 'name: "network" ' \
- 'input: "data" ' \
- 'input_dim: 1 ' \
- 'input_dim: 3 ' \
- 'input_dim: 224 ' \
- 'input_dim: 224 '
-
-layer_proto_str = 'layer { ' \
- 'name: "conv1" ' \
- 'type: "Convolution" ' \
- 'bottom: "data" ' \
- 'top: "conv1" ' \
- '}'
-
-proto_same_name_layers = 'layer { ' \
- 'name: "conv1" ' \
- 'type: "Convolution" ' \
- 'bottom: "data" ' \
- 'top: "conv1" ' \
- '} ' \
- 'layer { ' \
- 'name: "conv1" ' \
- 'type: "Convolution" ' \
- 'bottom: "data1" ' \
- 'top: "conv1_2" ' \
- '}'
-
-class TestLoader(UnitTestWithMockedTelemetry):
- def test_caffe_pb_to_nx_one_input(self):
- proto = caffe_pb2.NetParameter()
- text_format.Merge(proto_str_one_input, proto)
- input_shapes = caffe_pb_to_nx(Graph(), proto, None)
- expected_input_shapes = {
- 'Input0': np.array([1, 3, 224, 224])
- }
-
- for i in expected_input_shapes:
- np.testing.assert_array_equal(input_shapes[i], expected_input_shapes[i])
-
- def test_caffe_pb_to_nx_old_styled_multi_input(self):
- proto = caffe_pb2.NetParameter()
- text_format.Merge(proto_str_old_styled_multi_input + layer_proto_str, proto)
- self.assertRaises(Error, caffe_pb_to_nx, Graph(), proto, None)
-
- def test_caffe_pb_to_nx_old_styled_input(self):
- proto = caffe_pb2.NetParameter()
- text_format.Merge(proto_str_old_styled_input + layer_proto_str, proto)
- input_shapes = caffe_pb_to_nx(Graph(), proto, None)
- expected_input_shapes = {
- 'data': np.array([1, 3, 224, 224])
- }
-
- for i in expected_input_shapes:
- np.testing.assert_array_equal(input_shapes[i], expected_input_shapes[i])
-
- def test_caffe_pb_to_standart_input(self):
- proto = caffe_pb2.NetParameter()
- text_format.Merge(proto_str_input + layer_proto_str, proto)
- input_shapes = caffe_pb_to_nx(Graph(), proto, None)
- expected_input_shapes = {
- 'data': np.array([1, 3, 224, 224])
- }
-
- for i in expected_input_shapes:
- np.testing.assert_array_equal(input_shapes[i], expected_input_shapes[i])
-
- def test_caffe_pb_to_multi_input(self):
- proto = caffe_pb2.NetParameter()
- text_format.Merge(proto_str_multi_input + layer_proto_str, proto)
- input_shapes = caffe_pb_to_nx(Graph(), proto, None)
- expected_input_shapes = {
- 'data': np.array([1, 3, 224, 224]),
- 'data1': np.array([1, 3])
- }
-
- for i in expected_input_shapes:
- np.testing.assert_array_equal(input_shapes[i], expected_input_shapes[i])
-
- def test_caffe_same_name_layer(self):
- proto = caffe_pb2.NetParameter()
- text_format.Merge(proto_str_multi_input + proto_same_name_layers, proto)
- graph = Graph()
- caffe_pb_to_nx(graph, proto, None)
- # 6 nodes because: 2 inputs + 2 convolutions + 2 identity nodes used as fake outputs
- np.testing.assert_equal(len(graph.nodes()), 6)
diff --git a/tools/mo/unit_tests/mo/front/caffe/normalize_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/normalize_ext_test.py
deleted file mode 100644
index a2e724e1d690dd..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/normalize_ext_test.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.normalize_ext import NormalizeFrontExtractor
-from openvino.tools.mo.ops.normalize import NormalizeOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeNormalizeProtoLayer:
- def __init__(self, val):
- self.norm_param = val
-
-
-class TestNormalizeExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Normalize'] = NormalizeOp
-
- def test_normalize_no_pb_no_ml(self):
- self.assertRaises(AttributeError, NormalizeFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.normalize_ext.collect_attributes')
- def test_normalize_ext_ideal_numbers(self, collect_attributes_mock):
- params = {
- 'across_spatial': 1,
- 'channel_shared': 0,
- 'eps': 0.00001
- }
- collect_attributes_mock.return_value = {
- **params
- }
-
- fake_pl = FakeNormalizeProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- NormalizeFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "Normalize",
- 'across_spatial': 1,
- 'channel_shared': 0,
- 'eps': 0.00001,
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/pooling_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/pooling_ext_test.py
deleted file mode 100644
index cd00cb39dbb020..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/pooling_ext_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.pooling_ext import PoolingFrontExtractor
-from openvino.tools.mo.front.common.extractors.utils import layout_attrs
-from openvino.tools.mo.ops.pooling import Pooling
-from unit_tests.utils.extractors import PB, FakeMultiParam
-
-
-class FakeProtoLayer:
- def __init__(self, val):
- self.pooling_param = val
-
-
-class TestPooling(unittest.TestCase):
- def test_pooling_ext_global(self):
- params = {
- 'kernel_size': 1,
- 'stride': 2,
- 'pad': 3,
- 'pool': 0,
- 'global_pooling': True,
- 'ceil_mode': 1
- }
- node = PB({'pb': FakeProtoLayer(FakeMultiParam(params))})
- PoolingFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'window': np.array([1, 1, 0, 0], dtype=np.int64),
- 'stride': np.array([1, 1, 1, 1], dtype=np.int64),
- 'pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]], dtype=np.int64),
- 'pad_spatial_shape': np.array([[0, 0], [0, 0]], dtype=np.int64),
- 'pool_method': 'max',
- 'exclude_pad': True,
- 'infer': Pooling.infer,
- 'global_pool': True,
- 'output_spatial_shape': None,
- 'pooling_convention': 'full',
- 'rounding_type': 'ceil'
-
- }
- exp_res.update(layout_attrs())
- for i in exp_res.keys():
- if i in ('window', 'stride',
- 'pad', 'pad_spatial_shape',
- 'spatial_dims', 'batch_dims',
- 'channel_dims'):
- np.testing.assert_array_equal(res[i], exp_res[i])
- else:
- self.assertEqual(res[i], exp_res[i])
-
- def test_pooling_ext(self):
- params = {
- 'kernel_size': 1,
- 'stride': 2,
- 'pad': 3,
- 'pool': 1,
- 'global_pooling': False,
- 'ceil_mode': 0
- }
- node = PB({'pb': FakeProtoLayer(FakeMultiParam(params))})
- PoolingFrontExtractor.extract(node)
- res = node
- exp_res = {
- 'window': np.array([1, 1, 1, 1], dtype=np.int64),
- 'stride': np.array([1, 1, 2, 2], dtype=np.int64),
- 'pad': np.array([[0, 0], [0, 0], [3, 3], [3, 3]], dtype=np.int64),
- 'pad_spatial_shape': np.array([[3, 3], [3, 3]], dtype=np.int64),
- 'pool_method': 'avg',
- 'exclude_pad': False,
- 'infer': Pooling.infer,
- 'global_pool': False,
- 'output_spatial_shape': None,
- 'pooling_convention': 'valid'
- }
- exp_res.update(layout_attrs())
- for i in exp_res.keys():
- if i in ('window', 'stride',
- 'pad', 'pad_spatial_shape',
- 'spatial_dims', 'batch_dims',
- 'channel_dims'):
- np.testing.assert_array_equal(res[i], exp_res[i])
- else:
- self.assertEqual(res[i], exp_res[i])
-
- def test_pooling_ext_exception(self):
- params = {
- 'kernel_size': 1,
- 'stride': 2,
- 'pad': 3,
- 'pool': 3,
- 'global_pooling': True
- }
- node = PB({'pb': FakeProtoLayer(FakeMultiParam(params))})
- self.assertRaises(ValueError, PoolingFrontExtractor.extract, node)
diff --git a/tools/mo/unit_tests/mo/front/caffe/prelu_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/prelu_ext_test.py
deleted file mode 100644
index 71939faacada0f..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/prelu_ext_test.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.prelu_ext import PreluFrontExtractor
-from openvino.tools.mo.ops.prelu import PReLU
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakePReLUProtoLayer:
- def __init__(self, val):
- self.prelu_param = val
-
-
-class TestPreluExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['PReLU'] = PReLU
-
- def test_prelu_no_pb_no_ml(self):
- self.assertRaises(AttributeError, PreluFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.prelu_ext.merge_attrs')
- def test_reogyolo_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'channel_shared': False
- }
-
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakePReLUProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- PreluFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': 'PReLU',
- 'op': 'PReLU',
- 'channel_shared': 0,
- 'infer': PReLU.infer,
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/priorbox_clustered_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/priorbox_clustered_ext_test.py
deleted file mode 100644
index 7492f183805a19..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/priorbox_clustered_ext_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.priorbox_clustered_ext import PriorBoxClusteredFrontExtractor
-from openvino.tools.mo.ops.priorbox_clustered import PriorBoxClusteredOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakePriorBoxClusteredProtoLayer:
- def __init__(self, val):
- self.prior_box_param = val
-
-
-class TestPriorBoxClusteredExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['PriorBoxClustered'] = PriorBoxClusteredOp
-
- def test_priorboxclustered_no_pb_no_ml(self):
- self.assertRaises(AttributeError, PriorBoxClusteredFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.priorbox_clustered_ext.merge_attrs')
- def test_priorboxclustered_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'width': '30.0',
- 'height': '60.0',
- 'clip': False,
- 'flip': True,
- 'variance': np.array(['0.2', '0.3', '0.2', '0.3']),
- 'img_size': '300',
- 'img_h': '0',
- 'img_w': '0',
- 'step': '0,5',
- 'step_h': '0',
- 'step_w': '0',
- 'offset': '0.6'
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakePriorBoxClusteredProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- PriorBoxClusteredFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'op': 'PriorBoxClustered',
- 'type': 'PriorBoxClustered',
- 'width': '30.0',
- 'height': '60.0',
- 'clip': 0,
- 'flip': 1,
- 'variance': np.array(['0.2', '0.3', '0.2', '0.3']),
- 'img_size': '300',
- 'img_h': '0',
- 'img_w': '0',
- 'step': '0,5',
- 'step_h': '0',
- 'step_w': '0',
- 'offset': '0.6'
- }
-
- for key in exp_res.keys():
- if key in ['width', 'height', 'variance']:
- np.testing.assert_equal(fake_node[key], exp_res[key])
- else:
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/priorbox_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/priorbox_ext_test.py
deleted file mode 100644
index f81bc854d80afa..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/priorbox_ext_test.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-import numpy as np
-
-from openvino.tools.mo.front.caffe.priorbox_ext import PriorBoxFrontExtractor
-from openvino.tools.mo.ops.priorbox import PriorBoxOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam, FakeParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeMultiParamListFields(FakeMultiParam):
- def __init__(self, val):
- super().__init__(val)
-
- def ListFields(self):
- keys = []
- for k in self.dict_values.keys():
- keys.append([FakeParam('name', k)])
- return keys
-
-
-class FakePriorBoxProtoLayer:
- def __init__(self, val):
- self.prior_box_param = val
-
-
-class TestPriorBoxExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['PriorBox'] = PriorBoxOp
-
- def test_priorbox_no_pb_no_ml(self):
- self.assertRaises(AttributeError, PriorBoxFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.priorbox_ext.merge_attrs')
- def test_priorbox_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'clip': False,
- 'flip': True,
- 'min_size': np.array([]),
- 'max_size': np.array([]),
- 'aspect_ratio': np.array([2, 3]),
- 'variance': np.array(['0.2', '0.3', '0.2', '0.3']),
- 'img_size': '300',
- 'img_h': '0',
- 'img_w': '0',
- 'step': '0,5',
- 'step_h': '0',
- 'step_w': '0',
- 'offset': '0.6'
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakePriorBoxProtoLayer(FakeMultiParamListFields(params))
- fake_node = FakeNode(fake_pl, None)
-
- PriorBoxFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'op': 'PriorBox',
- 'type': 'PriorBox',
- 'clip': 0,
- 'variance': np.array(['0.2', '0.3', '0.2', '0.3']),
- 'img_size': '300',
- 'img_h': '0',
- 'img_w': '0',
- 'step': '0,5',
- 'step_h': '0',
- 'step_w': '0',
- 'offset': '0.6'
- }
-
- for key in exp_res.keys():
- if key in ['width', 'height', 'variance']:
- np.testing.assert_equal(fake_node[key], exp_res[key])
- else:
- self.assertEqual(fake_node[key], exp_res[key])
-
- @patch('openvino.tools.mo.front.caffe.priorbox_ext.merge_attrs')
- def test_priorbox_ext_ideal_numbers_density(self, merge_attrs_mock):
- params = {
- 'clip': False,
- 'flip': True,
- 'min_size': np.array([]),
- 'max_size': np.array([]),
- 'aspect_ratio': np.array([2, 3]),
- 'variance': np.array(['0.2', '0.3', '0.2', '0.3']),
- 'img_size': '300',
- 'img_h': '0',
- 'img_w': '0',
- 'step': '0,5',
- 'step_h': '0',
- 'step_w': '0',
- 'offset': '0.6',
- 'fixed_size': np.array(['1', '32']),
- 'fixed_ratio': np.array(['0.2', '0.5']),
- 'density': np.array(['0.3', '0.6'])
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakePriorBoxProtoLayer(FakeMultiParamListFields(params))
- fake_node = FakeNode(fake_pl, None)
-
- PriorBoxFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'op': 'PriorBox',
- 'type': 'PriorBox',
- 'clip': 0,
- 'variance': np.array(['0.2', '0.3', '0.2', '0.3']),
- 'img_size': '300',
- 'img_h': '0',
- 'img_w': '0',
- 'step': '0,5',
- 'step_h': '0',
- 'step_w': '0',
- 'offset': '0.6',
- 'fixed_size': np.array(['1', '32']),
- 'fixed_ratio': np.array(['0.2', '0.5']),
- 'density': np.array(['0.3', '0.6'])
- }
-
- for key in exp_res.keys():
- if key in ['width', 'height', 'variance', 'fixed_size', 'fixed_ratio', 'density']:
- np.testing.assert_equal(fake_node[key], exp_res[key])
- else:
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/proposal_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/proposal_ext_test.py
deleted file mode 100644
index 862dfa40186231..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/proposal_ext_test.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.proposal_ext import ProposalFrontExtractor
-from openvino.tools.mo.ops.proposal import ProposalOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeProposalProtoLayer:
- def __init__(self, val):
- self.proposal_param = val
-
-
-class TestProposalExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Proposal'] = ProposalOp
-
- def test_proposal_no_pb_no_ml(self):
- self.assertRaises(AttributeError, ProposalFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.proposal_ext.merge_attrs')
- def test_proposal_ext_ideal_numbers(self, merge_attrs):
- params = {
- 'feat_stride': 1,
- 'base_size': 16,
- 'min_size': 16,
- 'ratio': 1,
- 'scale': 2,
- 'pre_nms_topn': 6000,
- 'post_nms_topn': 300,
- 'nms_thresh': 0.7
- }
- merge_attrs.return_value = {
- **params
- }
-
- fake_pl = FakeProposalProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- ProposalFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "Proposal",
- 'feat_stride': 1,
- 'base_size': 16,
- 'min_size': 16,
- 'ratio': 1,
- 'scale': 2,
- 'pre_nms_topn': 6000,
- 'post_nms_topn': 300,
- 'nms_thresh': 0.7,
- 'infer': ProposalOp.proposal_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/proposal_python_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/proposal_python_ext_test.py
deleted file mode 100644
index 9bfb4a138e32cc..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/proposal_python_ext_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.caffe.proposal_python_ext import ProposalPythonFrontExtractor
-from openvino.tools.mo.ops.proposal import ProposalOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeProposalPythonProtoLayer:
- def __init__(self, val):
- self.python_param = val
-
-
-class TestProposalPythonExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Proposal'] = ProposalOp
-
- def test_proposal_no_pb_no_ml(self):
- self.assertRaises(AttributeError, ProposalPythonFrontExtractor.extract, None)
-
- def test_proposal_ext_ideal_numbers(self):
- params = {
- 'param_str': "'feat_stride': 16"
- }
- fake_pl = FakeProposalPythonProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- ProposalPythonFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "Proposal",
- 'feat_stride': 16,
- 'base_size': 16,
- 'min_size': 16,
- 'ratio': [0.5, 1, 2],
- 'scale': [8, 16, 32],
- 'pre_nms_topn': 6000,
- 'post_nms_topn': 300,
- 'nms_thresh': 0.7,
- 'infer': ProposalOp.proposal_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
-
- def test_proposal_ext_scales(self):
- params = {
- 'param_str': "'feat_stride': 16, 'scales': [1,2,3], 'ratios':[5, 6,7]"
- }
- fake_pl = FakeProposalPythonProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- ProposalPythonFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "Proposal",
- 'feat_stride': 16,
- 'base_size': 16,
- 'min_size': 16,
- 'ratio': [5, 6, 7],
- 'scale': [1, 2, 3],
- 'pre_nms_topn': 6000,
- 'post_nms_topn': 300,
- 'nms_thresh': 0.7,
- 'infer': ProposalOp.proposal_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
-
- def test_proposal_ext_scale(self):
- params = {
- 'param_str': "'feat_stride': 16, 'scale': [1,2,3], 'ratio':[5, 6,7]"
- }
- fake_pl = FakeProposalPythonProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- ProposalPythonFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "Proposal",
- 'feat_stride': 16,
- 'base_size': 16,
- 'min_size': 16,
- 'ratio': [5, 6, 7],
- 'scale': [1, 2, 3],
- 'pre_nms_topn': 6000,
- 'post_nms_topn': 300,
- 'nms_thresh': 0.7,
- 'infer': ProposalOp.proposal_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/python_layer_extractor_test.py b/tools/mo/unit_tests/mo/front/caffe/python_layer_extractor_test.py
deleted file mode 100644
index 5126a8bd45dd94..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/python_layer_extractor_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.caffe.python_layer_extractor import PythonFrontExtractorOp
-from openvino.tools.mo.front.extractor import CaffePythonFrontExtractorOp
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakePythonProtoLayer:
- def __init__(self, params: FakeMultiParam):
- self.type = 'Python'
- self.python_param = params
-
-
-class FakePythonExtractor:
- @classmethod
- def extract(cls, node: Node):
- return True
-
-
-class TestPythonLayerExtractor(unittest.TestCase):
- def test_python_extractor_for_op(self):
- module = 'test_module'
- layer = 'test_layer'
- CaffePythonFrontExtractorOp.registered_ops['{}.{}'.format(module, layer)] = \
- lambda node: CaffePythonFrontExtractorOp.parse_param_str(node.pb.python_param.param_str)
- params = FakeMultiParam({
- 'module': module,
- 'layer': layer,
- 'param_str': "'feat_stride': 16"
- })
- ext = PythonFrontExtractorOp.extract(FakeNode(FakePythonProtoLayer(params), None))
- self.assertEqual({'feat_stride': 16}, ext)
-
- def test_python_extractor_for_extractors(self):
- module = 'test_module'
- layer = 'test_layer'
- CaffePythonFrontExtractorOp.registered_ops['{}.{}'.format(module, layer)] = FakePythonExtractor
- params = FakeMultiParam({
- 'module': module,
- 'layer': layer,
- 'param_str': "'feat_stride': 16"
- })
- self.assertTrue(PythonFrontExtractorOp.extract(FakeNode(FakePythonProtoLayer(params), None)))
diff --git a/tools/mo/unit_tests/mo/front/caffe/regionyolo_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/regionyolo_ext_test.py
deleted file mode 100644
index e2f8b7a5eebe6b..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/regionyolo_ext_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.regionyolo_ext import RegionYoloFrontExtractor
-from openvino.tools.mo.ops.regionyolo import RegionYoloOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeRegionYoloProtoLayer:
- def __init__(self, val, val_f):
- self.region_yolo_param = val
- self.flatten_param = val_f
-
-
-class TestReorgYoloExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['RegionYolo'] = RegionYoloOp
-
- def test_reogyolo_no_pb_no_ml(self):
- self.assertRaises(AttributeError, RegionYoloFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.regionyolo_ext.merge_attrs')
- def test_reogyolo_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'coords': 4,
- 'classes': 20,
- 'num': 5,
- 'do_softmax': 1,
- 'anchors': 5,
- 'mask': 5,
- }
- params_flatten = {
- 'axis': 1,
- 'end_axis': -1
- }
- merge_attrs_mock.return_value = {
- **params,
- **params_flatten
- }
-
- fake_pl = FakeRegionYoloProtoLayer(FakeMultiParam(params), FakeMultiParam(params_flatten))
- fake_node = FakeNode(fake_pl, None)
-
- RegionYoloFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "RegionYolo",
- 'coords': 4,
- 'classes': 20,
- 'num': 5,
- 'axis': 1,
- 'end_axis': -1,
- 'do_softmax': 1,
- 'anchors': 5,
- 'mask': 5,
- 'infer': RegionYoloOp.regionyolo_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/caffe/reorgyolo_ext_test.py b/tools/mo/unit_tests/mo/front/caffe/reorgyolo_ext_test.py
deleted file mode 100644
index 3b4122e04c7cd2..00000000000000
--- a/tools/mo/unit_tests/mo/front/caffe/reorgyolo_ext_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.front.caffe.reorgyolo_ext import ReorgYoloFrontExtractor
-from openvino.tools.mo.ops.reorgyolo import ReorgYoloOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import FakeNode
-
-
-class FakeReorgYoloProtoLayer:
- def __init__(self, val):
- self.reorg_yolo_param = val
-
-
-class TestReorgYoloExt(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['ReorgYolo'] = ReorgYoloOp
-
- def test_elu_no_pb_no_ml(self):
- self.assertRaises(AttributeError, ReorgYoloFrontExtractor.extract, None)
-
- @patch('openvino.tools.mo.front.caffe.reorgyolo_ext.merge_attrs')
- def test_elu_ext_ideal_numbers(self, merge_attrs_mock):
- params = {
- 'stride': 2
- }
- merge_attrs_mock.return_value = {
- **params
- }
-
- fake_pl = FakeReorgYoloProtoLayer(FakeMultiParam(params))
- fake_node = FakeNode(fake_pl, None)
-
- ReorgYoloFrontExtractor.extract(fake_node)
-
- exp_res = {
- 'type': "ReorgYolo",
- 'stride': 2,
- 'infer': ReorgYoloOp.reorgyolo_infer
- }
-
- for key in exp_res.keys():
- self.assertEqual(fake_node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/common/__init__.py b/tools/mo/unit_tests/mo/front/common/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/common/layout_test.py b/tools/mo/unit_tests/mo/front/common/layout_test.py
deleted file mode 100644
index 11330ae05f4560..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/layout_test.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.layout import get_batch_dim, get_width_dim, get_height_dim, get_features_dim, get_depth_dim, \
- shape_for_layout
-from openvino.tools.mo.utils.error import Error
-
-
-class TestLayoutFunctions(unittest.TestCase):
- def test_get_batch_dim_NCHW(self):
- self.assertEqual(get_batch_dim('NCHW', 4), 0)
-
- def test_get_batch_dim_NHWC(self):
- self.assertEqual(get_batch_dim('NHWC', 4), 0)
-
- def test_get_batch_dim_NCDHW(self):
- self.assertEqual(get_batch_dim('NCHW', 5), 0)
-
- def test_get_batch_dim_NDHWC(self):
- self.assertEqual(get_batch_dim('NHWC', 5), 0)
-
- def test_get_features_dim_NCHW(self):
- self.assertEqual(get_features_dim('NCHW', 4), 1)
-
- def test_get_features_dim_NHWC(self):
- self.assertEqual(get_features_dim('NHWC', 4), 3)
-
- def test_get_features_dim_NCDHW(self):
- self.assertEqual(get_features_dim('NCHW', 5), 1)
-
- def test_get_features_dim_NDHWC(self):
- self.assertEqual(get_features_dim('NHWC', 5), 4)
-
- def test_get_width_dim_NCHW(self):
- self.assertEqual(get_width_dim('NCHW', 4), 3)
-
- def test_get_width_dim_NHWC(self):
- self.assertEqual(get_width_dim('NHWC', 4), 2)
-
- def test_get_width_dim_NCDHW(self):
- self.assertEqual(get_width_dim('NCHW', 5), 4)
-
- def test_get_width_dim_NDHWC(self):
- self.assertEqual(get_width_dim('NHWC', 5), 3)
-
- def test_get_height_dim_NCHW(self):
- self.assertEqual(get_height_dim('NCHW', 4), 2)
-
- def test_get_height_dim_NHWC(self):
- self.assertEqual(get_height_dim('NHWC', 4), 1)
-
- def test_get_height_dim_NCDHW(self):
- self.assertEqual(get_height_dim('NCHW', 5), 3)
-
- def test_get_height_dim_NDHWC(self):
- self.assertEqual(get_height_dim('NHWC', 5), 2)
-
- def test_get_depth_dim_NCDHW(self):
- self.assertEqual(get_depth_dim('NCHW', 5), 2)
-
- def test_get_depth_dim_NDHWC(self):
- self.assertEqual(get_depth_dim('NHWC', 5), 1)
-
- def test_get_batch_dim_wrong_layout(self):
- self.assertRaises(AssertionError, get_batch_dim, 'NCDHW', 5)
-
- def test_get_width_dim_wrong_layout(self):
- self.assertRaises(AssertionError, get_width_dim, 'NCDHW', 5)
-
- def test_get_height_dim_wrong_layout(self):
- self.assertRaises(AssertionError, get_height_dim, 'NCDHW', 5)
-
- def test_get_features_dim_wrong_layout(self):
- self.assertRaises(AssertionError, get_features_dim, 'NCDHW', 5)
-
- def test_shape_for_layout_NCHW(self):
- self.assertListEqual([2, 3, 4, 5], list(shape_for_layout('NCHW', batch=2, features=3, height=4, width=5)))
-
- def test_shape_for_layout_NHWC(self):
- self.assertListEqual([2, 4, 5, 3], list(shape_for_layout('NHWC', batch=2, features=3, height=4, width=5)))
-
- def test_shape_for_layout_missing_batch(self):
- with self.assertRaises(Error):
- shape_for_layout('NCHW', features=3, height=4, width=5)
-
- def test_shape_for_layout_missing_features(self):
- with self.assertRaises(Error):
- shape_for_layout('NCHW', batch=2, height=4, width=5)
-
- def test_shape_for_layout_missing_height(self):
- with self.assertRaises(Error):
- shape_for_layout('NHWC', batch=2, features=3, width=5)
-
- def test_shape_for_layout_missing_width(self):
- with self.assertRaises(Error):
- shape_for_layout('NHWC', batch=2, features=3, height=4)
-
- def test_shape_for_layout_unknown_parameter(self):
- with self.assertRaises(Error):
- shape_for_layout('NHWC', batch=2, features=3, height=4, width=5, unknown_parameter=123)
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/__init__.py b/tools/mo/unit_tests/mo/front/common/partial_infer/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/caffe_fallback_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/caffe_fallback_test.py
deleted file mode 100644
index b656b5e038f67b..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/caffe_fallback_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import MagicMock
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.caffe_fallback import build_net
-from unit_tests.utils.extractors import FakeMultiParam, FakeValue
-from unit_tests.utils.graph import build_graph
-
-
-class Net:
- def __init__(self, blobs):
- self.blobs = blobs
- self.reshape_blob = MagicMock(return_value=np.array([1, 1, 1, 1]))
- self.reshape = MagicMock(return_value=np.array([1, 1, 1, 1]))
- self.forward = MagicMock(return_value={'top_node': FakeValue(np.array([1, 3, 112, 112]))})
-
-
-my_mock_net = None
-
-
-class Caffe:
- def __init__(self):
- self.TEST = 'TEST'
-
- def Net(self, *args):
- return my_mock_net
-
-
-class TestCaffeNativePartialInfer(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- import sys
- sys.modules['caffe'] = Caffe()
- cls.nodes_attributes = {
- 'node_1': {'type': 'Parameter', 'kind': 'op'},
- 'node_2': {'type': 'Parameter', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'node_4': {'type': 'Identity', 'kind': 'op'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
- def test_build_net_equal_inputs(self):
- global my_mock_net
- my_blobs = {
- 'node_1': FakeValue(np.array([1, 3, 227, 227])),
- 'node_2': FakeValue(np.array([1, 3, 224, 224]))
- }
- my_mock_net = Net(my_blobs)
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'node_3'),
- ('node_2', 'node_3'),
- ('node_3', 'node_4'),
- ('node_4', 'op_output')
- ],
- {
- 'node_4': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'node_2': {'shape': np.array([1, 3, 224, 224])},
- 'node_3': {'top': 'top_node'}
- })
- graph.proto_path = 'path_to_proto'
- graph.caffemodel_path = 'path_to_proto'
- build_net(graph)
- my_mock_net.reshape.assert_not_called()
- my_mock_net.forward.assert_called_once_with()
- self.assertIsNotNone(graph.caffe_net)
-
- def test_build_net_not_equal_inputs(self):
- global my_mock_net
- input_node_param = {
- 'shape': np.array([1, 3, 112, 112]),
- 'reshape': MagicMock(return_value=134)
- }
- my_blobs = {
- 'node_1': FakeMultiParam(input_node_param),
- }
- my_mock_net = Net(my_blobs)
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'node_3'),
- ('node_3', 'node_4'),
- ('node_4', 'op_output')
- ],
- {'node_4': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'node_3': {'top': 'top_node'}
- },
- nodes_with_edges_only=True)
- graph.proto_path = 'path_to_proto'
- graph.caffemodel_path = 'path_to_proto'
- build_net(graph)
- my_mock_net.reshape.assert_called_once_with()
- my_mock_net.forward.assert_called_once_with()
- self.assertIsNotNone(graph.caffe_net)
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/concat_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/concat_test.py
deleted file mode 100644
index 4808f992038ab5..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/concat_test.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'kind': 'data', 'value': None},
- 'node_2': {'kind': 'data', 'value': None},
- 'concat': {'type': 'Concat', 'kind': 'op'},
- 'node_3': {'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-class TestConcatPartialInfer():
- @pytest.mark.parametrize("shape1, shape2, output_shape, axis",[([1, 3, 227, 227], [1, 3, 220, 227],
- [1, 3, 447, 227], 2),
- ([1, 3, 227, 227], [1, 3, 227, 220], [1, 3, 227, 447], -1),
- ([1, 3, dynamic_dimension_value, 227], [1, dynamic_dimension_value, 227, 220], [1, 3, 227, 447], -1),
- ([1, 3, 10, 227], [1, 3, 10, dynamic_dimension_value], [1, 3, 10, dynamic_dimension_value], -1),
- ])
- def test_concat_infer(self, shape1, shape2, output_shape, axis):
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': shape_array(shape1)},
- 'node_2': {'shape': shape_array(shape2)},
- 'concat': {'axis': axis}
- })
-
- concat_node = Node(graph, 'concat')
- concat_infer(concat_node)
- res_shape = graph.node['node_3']['shape']
- assert strict_compare_tensors(output_shape, res_shape)
-
- @pytest.mark.parametrize("value1, value2, output_value, axis",[(shape_array([1]),
- shape_array([4]), shape_array([1, 4]), 0),
- (shape_array([dynamic_dimension_value]), shape_array([4]),
- shape_array([dynamic_dimension_value, 4]), -1),
- ])
- def test_concat_value_infer(self, value1, value2, output_value, axis):
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': output_value.shape, 'value': output_value},
- 'node_1': {'shape': value1.shape, 'value': value1},
- 'node_2': {'shape': value2.shape, 'value': value2},
- 'concat': {'axis': axis}
- })
-
- concat_node = Node(graph, 'concat')
- concat_infer(concat_node)
- res_value = graph.node['node_3']['value']
- assert strict_compare_tensors(output_value, res_value)
-
- def test_concat_infer_not_match(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'node_2': {'shape': np.array([1, 2, 227, 227])},
- 'concat': {'axis': 2}
- })
-
- concat_node = Node(graph, 'concat')
- with pytest.raises(Error, match="Concat input shapes do not match for node*"):
- concat_infer(concat_node)
-
- def test_concat_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'node_2': {'shape': None},
- 'concat': {'axis': 2}
- })
-
- concat_node = Node(graph, 'concat')
- with pytest.raises(Error, match="One of the input shapes is not defined for node *"):
- concat_infer(concat_node)
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/crop_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/crop_test.py
deleted file mode 100644
index 504a4168129fda..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/crop_test.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.crop import crop_infer
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'value': None, 'kind': 'data'},
- 'node_2': {'value': None, 'kind': 'data'},
- 'crop_1': {'op': 'Crop', 'kind': 'op'},
- 'node_3': {'value': None, 'kind': 'data'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestCropInfer(unittest.TestCase):
- def test_crop_infer_ideal(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'crop_1'),
- ('node_2', 'crop_1'),
- ('crop_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 2, 500, 500])},
- 'node_2': {'shape': np.array([1, 2, 256, 256])},
- 'crop_1': {'axis': 2, 'offset': [0, 0], 'dim': None}
- })
-
- crop_node = Node(graph, 'crop_1')
-
- crop_infer(crop_node)
- exp_shape = np.array([1, 2, 256, 256])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- self.assertEqual(crop_node.axis, [2, 3])
- self.assertEqual(crop_node.offset, [0, 0])
- self.assertEqual(crop_node.dim, [256, 256])
-
- def test_crop_infer_negative_axis(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'crop_1'),
- ('node_2', 'crop_1'),
- ('crop_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 2, 500, 500])},
- 'node_2': {'shape': np.array([1, 2, 256, 256])},
- 'crop_1': {'axis': -1, 'offset': [0, 0], 'dim': None}
- })
-
- crop_node = Node(graph, 'crop_1')
-
- crop_infer(crop_node)
- exp_shape = np.array([1, 2, 500, 256])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- self.assertEqual(crop_node.axis, [3])
- self.assertEqual(crop_node.offset, [0])
- self.assertEqual(crop_node.dim, [256])
-
- def test_crop_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'crop_1'),
- ('node_2', 'crop_1'),
- ('crop_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 2, 500, 500])},
- 'node_2': {'shape': None},
- 'crop_1': {'axis': 2, 'offset': [0, 0], 'dim': None}
- })
-
- crop_node = Node(graph, 'crop_1')
-
- crop_infer(crop_node)
- self.assertIsNone(graph.node['node_3']['shape'])
-
- def test_crop_infer_one_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'crop_1'),
- ('crop_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 2, 500, 500])},
- 'crop_1': {'axis': 2, 'offset': [0], 'dim': None}
- })
-
- crop_node = Node(graph, 'crop_1')
-
- crop_infer(crop_node)
- self.assertIsNone(graph.node['node_3']['shape'])
-
- def test_crop_infer_out_offset(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'crop_1'),
- ('node_2', 'crop_1'),
- ('crop_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 2, 500, 500])},
- 'node_2': {'shape': np.array([1, 2, 256, 256])},
- 'crop_1': {'axis': 2, 'offset': [300], 'dim': None}
- })
-
- crop_node = Node(graph, 'crop_1')
-
- crop_infer(crop_node)
- self.assertIsNone(graph.node['node_3']['shape'])
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/elemental_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/elemental_test.py
deleted file mode 100644
index 7a782b72bbc1e9..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/elemental_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-
-
-class FakeNode:
- def __init__(self, blob):
- self.blob = blob
-
- def in_shape(self):
- return self.blob
-
-
-class TestElementalInference(unittest.TestCase):
- @patch('openvino.tools.mo.front.common.partial_infer.elemental.single_output_infer')
- def test_copy_shape_infer(self, single_output_infer_mock):
- single_output_infer_mock.return_value = 0
- node = FakeNode(np.array([1, 2]))
- copy_shape_infer(node)
- self.assertTrue(single_output_infer_mock.called)
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/eltwise_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/eltwise_test.py
deleted file mode 100644
index fd7acc9fa076ae..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/eltwise_test.py
+++ /dev/null
@@ -1,245 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer, eltwise_reverse_infer
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, strict_compare_tensors, \
- dynamic_dimension_value, reverse_bypass_infer
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import result, regular_op_with_empty_data, connect, \
- build_graph, shaped_parameter
-
-nodes_attributes = {'node_1': {'value': 2, 'kind': 'data'},
- 'node_2': {'value': 3, 'kind': 'data'},
- 'eltw_1': {'kind': 'op'},
- 'node_3': {'value': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-
-class TestEltwiseInfer():
- @pytest.mark.parametrize("value1, shape1, value2, shape2, shape_infer, exp_value, exp_shape",[
- (np.array(2), [], np.array(3), [], lambda a, b: np.multiply(a, b), np.array(6), []),
- (np.array(2), [], np.array(3), [], lambda a, b: np.maximum(a, b), np.array(3), []),
- (np.array(2), [], np.array(3), [], lambda a, b: np.add(a, b), np.array(5), []),
- (None, [1, 5], None, [1, 1], lambda a, b: np.add(a, b), None, [1, 5]),
- (None, [dynamic_dimension_value, 3], None, [1, 1], lambda a, b: np.add(a, b), None,
- [dynamic_dimension_value, 3]),
- (None, [dynamic_dimension_value, 3], None, [1, dynamic_dimension_value], lambda a, b: np.add(a, b), None,
- [dynamic_dimension_value, 3]),
- (None, [4, 5, dynamic_dimension_value, 3], None, [1, dynamic_dimension_value], lambda a, b: np.add(a, b), None,
- [4, 5, dynamic_dimension_value, 3]),
- (None, [1, 10, 20, 30], None, [dynamic_dimension_value, 10, 20, 30], lambda a, b: np.add(a, b), None,
- [dynamic_dimension_value, 10, 20, 30]),
- # dynamic value propagation
- (shape_array([dynamic_dimension_value, 5]), [2], np.array(3), [], lambda a, b: np.add(a, b),
- shape_array([dynamic_dimension_value, 8]), [2]),
- (shape_array([dynamic_dimension_value, 5]), [2], np.array([3, 7]), [], lambda a, b: np.add(a, b),
- shape_array([dynamic_dimension_value, 12]), [2]),
- ])
- def test_eltwise_infer(self, value1, shape1, value2, shape2, shape_infer, exp_value, exp_shape):
- graph = build_graph(nodes_attributes,
- [('node_1', 'eltw_1'),
- ('node_2', 'eltw_1'),
- ('eltw_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': shape_array(value1).shape if value1 is not None else shape_array(shape1),
- 'value': value1},
- 'node_2': {'shape': shape_array(value2).shape if value2 is not None else shape_array(shape2),
- 'value': value2}
- })
-
- graph.graph['layout'] = 'NCHW'
-
- eltwise_node = Node(graph, 'eltw_1')
-
- eltwise_infer(eltwise_node, shape_infer)
- res_shape = graph.node['node_3']['shape']
- res_value = eltwise_node.out_node().value
- if exp_value is not None:
- assert strict_compare_tensors(res_value, shape_array(exp_value))
- assert strict_compare_tensors(res_shape, shape_array(exp_shape))
-
- def test_eltwise_infer_none_val(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'eltw_1'),
- ('node_2', 'eltw_1'),
- ('eltw_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 256, 256]), 'value': None},
- 'node_2': {'shape': np.array([1, 3, 256, 256])}
- })
- graph.graph['layout'] = 'NCHW'
- eltwise_node = Node(graph, 'eltw_1')
-
- eltwise_infer(eltwise_node, lambda a, b: a * b)
- exp_shape = np.array([1, 3, 256, 256])
- res_shape = graph.node['node_3']['shape']
- res_value = eltwise_node.out_node().value
- for i in range(0, len(exp_shape)):
- assert exp_shape[i] == res_shape[i]
-
- assert res_value is None
-
- def test_eltwise_infer_none_min_max(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'eltw_1'),
- ('node_2', 'eltw_1'),
- ('eltw_1', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 257, 256])},
- 'node_2': {'shape': np.array([1, 3, 256, 257])}
- })
- graph.graph['layout'] = 'NCHW'
- eltwise_node = Node(graph, 'eltw_1')
-
- with pytest.raises(Error, match='Input shapes mismatch*'):
- eltwise_infer(eltwise_node)
-
-
-dyn = dynamic_dimension_value
-
-
-class TestElementwiseReverseInfer(unittest.TestCase):
- @staticmethod
- def build_and_test_reverse_inference(inp_shape_1, inp_shape_2, out_shape, ref_shape, auto_broadcast='numpy'):
- in_port_with_defined_shape = 0 if inp_shape_1 is not None else 1
- defined_shape = shape_array(inp_shape_1 if inp_shape_1 is not None else inp_shape_2)
-
- nodes = {
- **shaped_parameter('undefined_shape_data', None, {'reverse_infer': Parameter.reverse_infer}),
- **shaped_parameter('data', shape_array(defined_shape), {'reverse_infer': Parameter.reverse_infer}),
- **regular_op_with_empty_data('elementwise', {'op': 'Add', 'type': 'Add',
- 'infer': eltwise_infer,
- 'reverse_infer': eltwise_reverse_infer,
- 'auto_broadcast': auto_broadcast}),
- **result('res'),
- }
-
- edges = [
- *connect('undefined_shape_data', '{}:elementwise'.format(int(not in_port_with_defined_shape))),
- *connect('data', '{}:elementwise'.format(in_port_with_defined_shape)),
- *connect('elementwise', 'res')
- ]
-
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- Node(graph, 'elementwise').out_port(0).data.set_shape(shape_array(out_shape))
- Node(graph, 'elementwise').in_port(in_port_with_defined_shape).data.set_shape(defined_shape)
-
- partial_infer(graph)
- actual_shape = Node(graph, 'undefined_shape_data').out_port(0).data.get_shape()
- if ref_shape is None:
- assert actual_shape == ref_shape
- else:
- assert strict_compare_tensors(actual_shape, shape_array(ref_shape))
-
- def test_reverse_infer_1(self):
- self.build_and_test_reverse_inference(inp_shape_1=[dyn, dyn],
- inp_shape_2=None,
- out_shape=[dyn, dyn, dyn, dyn],
- ref_shape=[dyn, dyn, dyn, dyn])
-
- def test_reverse_infer_2(self):
- self.build_and_test_reverse_inference(inp_shape_1=None,
- inp_shape_2=[dyn, dyn],
- out_shape=[dyn, dyn, dyn, dyn],
- ref_shape=[dyn, dyn, dyn, dyn])
-
- def test_reverse_infer_3(self):
- self.build_and_test_reverse_inference(inp_shape_1=[1],
- inp_shape_2=None,
- out_shape=[dyn, 400, 400, 3],
- ref_shape=[dyn, 400, 400, 3])
-
- def test_reverse_infer_4(self):
- self.build_and_test_reverse_inference(inp_shape_1=[4, 1],
- inp_shape_2=None,
- out_shape=[dyn, dyn, 4, 3],
- ref_shape=[dyn, dyn, dyn, 3])
-
- def test_reverse_infer_5(self):
- self.build_and_test_reverse_inference(inp_shape_1=[4, 1],
- inp_shape_2=None,
- out_shape=[dyn, dyn, 4, 1],
- ref_shape=[dyn, dyn, dyn, 1])
-
- def test_reverse_infer_6(self):
- # both output and input has the same rank, cannot deduce other inputs rank
- with self.assertRaisesRegex(Error, "Model Optimizer is unable to deduce input shapes"):
- self.build_and_test_reverse_inference(inp_shape_1=[dyn, dyn, dyn, dyn],
- inp_shape_2=None,
- out_shape=[dyn, dyn, 4, 1],
- ref_shape=None)
-
- def test_reverse_infer_7(self):
- self.build_and_test_reverse_inference(inp_shape_1=[4, dyn],
- inp_shape_2=None,
- out_shape=[1, dyn, dyn, 1],
- ref_shape=[1, dyn, dyn, 1])
-
- def test_reverse_infer_8(self):
- with self.assertRaisesRegex(AssertionError, "Shapes of Elementwise node '.*' are not compatible"):
- self.build_and_test_reverse_inference(inp_shape_1=[4, dyn],
- inp_shape_2=None,
- out_shape=[1, dyn, 7, 1],
- ref_shape=None)
-
- def test_reverse_infer_no_broadcast(self):
- self.build_and_test_reverse_inference(inp_shape_1=[1, 4, dyn, dyn],
- inp_shape_2=None,
- out_shape=[1, dyn, dyn, 1],
- ref_shape=[1, 4, dyn, 1],
- auto_broadcast='none')
-
-
-class TestUnaryElementwiseReverseInfer(unittest.TestCase):
- @staticmethod
- def build_and_test_reverse_inference(out_shape):
-
- nodes = {
- **shaped_parameter('undefined_shape_data', None, {'reverse_infer': Parameter.reverse_infer}),
- **regular_op_with_empty_data('elementwise',
- {'op': 'Sqrt', 'type': 'Sqrt',
- 'infer': eltwise_infer,
- 'reverse_infer': lambda node: reverse_bypass_infer(node,in_ports=[0])}),
- **result('res'),
- }
-
- edges = [
- *connect('undefined_shape_data', '0:elementwise'),
- *connect('elementwise', 'res'),
- ]
-
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- Node(graph, 'elementwise').out_port(0).data.set_shape(shape_array(out_shape))
-
- partial_infer(graph)
- actual_shape = Node(graph, 'elementwise').in_port(0).data.get_shape()
-
- # check that out_shape is transferred into only existing in_port(0)
- assert strict_compare_tensors(actual_shape, shape_array(out_shape))
-
- def test_reverse_infer_1(self):
- self.build_and_test_reverse_inference(out_shape=[dyn, dyn, dyn, dyn])
-
- def test_reverse_infer_2(self):
- self.build_and_test_reverse_inference(out_shape=[dyn, dyn])
-
- def test_reverse_infer_3(self):
- self.build_and_test_reverse_inference(out_shape=[1, 100])
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/multi_box_detection_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/multi_box_detection_test.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/multi_box_prior_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/multi_box_prior_test.py
deleted file mode 100644
index 3701cad39d6d2f..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/multi_box_prior_test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.multi_box_prior import multi_box_prior_infer_mxnet
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'value': None, 'kind': 'data'},
- 'node_2': {'value': None, 'kind': 'data'},
- 'prior_box_1': {'type': 'PriorBox', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'data'}
- }
-
-
-class TestMultiBoxPriorInfer(unittest.TestCase):
- def test_prior_box_infer_ideal(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'prior_box_1'),
- ('node_2', 'prior_box_1'),
- ('prior_box_1', 'node_3')],
- {'node_1': {'shape': np.array([1, 1024, 19, 19])},
- 'node_2': {'shape': np.array([1, 3, 300, 300])},
- 'prior_box_1': {'aspect_ratio': [1.0, 2.0, 0.5, 3.0, 0.333333333333],
- 'min_size': [0.2, 0.272],
- 'max_size': '', 'offset': 0.5, 'step': 0.2, 'sizes': [0.2, 0.272]},
- 'node_3': {'shape': np.array([1, 2, 3])},
- })
-
- multi_box_prior_node = Node(graph, 'prior_box_1')
-
- multi_box_prior_infer_mxnet(multi_box_prior_node)
- exp_shape = np.array([1, 2, 8664])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- self.assertEqual(multi_box_prior_node.min_size, [0.2, 0.272])
- self.assertEqual(multi_box_prior_node.max_size, '')
- self.assertEqual(multi_box_prior_node.aspect_ratio, [1.0, 2.0, 0.5, 3.0, 0.333333333333])
- self.assertEqual(round(multi_box_prior_node.step, 1), 0.2)
- self.assertEqual(round(multi_box_prior_node.offset, 1), 0.5)
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/roipooling_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/roipooling_test.py
deleted file mode 100644
index 114e81a279a945..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/roipooling_test.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.roipooling import roipooling_infer
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'kind': 'data'},
- 'node_2': {'kind': 'data'},
- 'node_3': {'kind': 'data'},
- 'node_4': {'kind': 'data'},
- 'roipool': {'type': 'ROIPooling', 'kind': 'op', 'pooled_h': None, 'pooled_w': None},
- 'output': {'value': None, 'kind': 'data'},
- 'op_output': { 'kind': 'op', 'op': 'Result'},
- }
-
-
-class TestRoipoolingInfer(unittest.TestCase):
- def test_roipooling_infer_ideal(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'roipool'),
- ('node_2', 'roipool'),
- ('roipool', 'output'),
- ('output', 'op_output')
- ],
- {'output': {'shape': None},
- 'node_1': {'shape': np.array([1, 256, 20, 20])},
- 'node_2': {'shape': np.array([150, 5])},
- 'roipool': {'pooled_h': 6, 'pooled_w': 6}
- })
- graph.graph['layout'] = 'NCHW'
- roipooling_node = Node(graph, 'roipool')
-
- roipooling_infer(roipooling_node)
- exp_shape = np.array([150, 256, 6, 6])
- res_shape = graph.node['output']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_roipooling_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'roipool'),
- ('node_2', 'roipool'),
- ('roipool', 'output'),
- ('output', 'op_output')
- ],
- {'output': {'shape': None},
- 'node_1': {'shape': None},
- 'node_2': {'shape': np.array([1, 256])},
- 'roipool': {'pooled_h': 6, 'pooled_w': 6}
- })
- graph.graph['layout'] = 'NCHW'
-
- roipooling_node = Node(graph, 'roipool')
-
- roipooling_infer(roipooling_node)
- self.assertIsNone(graph.node['output']['shape'])
-
- def test_roipooling_infer_tf(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'roipool'),
- ('node_2', 'roipool'),
- ('node_3', 'roipool'),
- ('node_4', 'roipool'),
- ('roipool', 'output'),
- ('output', 'op_output')
- ],
- {'output': {'shape': None},
- 'node_1': {'shape': np.array([1, 20, 20, 256])},
- 'node_2': {'shape': np.array([150, 5])},
- 'node_3': {'shape': np.array([150])},
- 'node_4': {'shape': np.array([2], dtype=np.int64), 'value': np.array([7, 6],
- dtype=np.int64)},
- })
- graph.graph['layout'] = 'NHWC'
- roipooling_node = Node(graph, 'roipool')
-
- roipooling_infer(roipooling_node)
- exp_shape = np.array([150, 7, 6, 256])
- res_shape = graph.node['output']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/front/common/partial_infer/utils_test.py b/tools/mo/unit_tests/mo/front/common/partial_infer/utils_test.py
deleted file mode 100644
index 59baf44e8dc5b3..00000000000000
--- a/tools/mo/unit_tests/mo/front/common/partial_infer/utils_test.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, mo_array, is_fully_defined, \
- dynamic_dimension_value, dynamic_dimension, shape_array, compatible_shapes, shape_delete, shape_insert, \
- strict_compare_tensors, clarify_partial_shape
-from openvino.tools.mo.utils.error import Error
-
-
-def gen_masked_array(array, masked_indices):
- """
- Creates a masked array from the input array by masking specific elements.
-
- :param array: the input array
- :param masked_indices: element indices to be masked
- :return: the result masked array
- """
- res = np.ma.masked_array(array)
- for index in masked_indices:
- res[index] = np.ma.masked
- return res
-
-
-class TestIsFullyDefinedTest():
- @pytest.mark.parametrize("data, result",[(None, False),
- (int64_array([2, 3, 5, 7]), True), # int64 array with valid values
- (np.array([2, 3, 5, 7]), True), # any numpy array with valid values
- (np.array([2, dynamic_dimension_value]), True), # array with dynamic dimension value is fully defined!
- (shape_array([2, dynamic_dimension_value, 5]), False), # masked array with at least one masked element
- (shape_array([2, 4, 5]), True), # masked array with no masked elements is fully defined
- (dynamic_dimension, False), # dynamic dimension is not fully defined
- (dynamic_dimension_value, True), # dynamic dimension value is fully defined
- ((dynamic_dimension_value, dynamic_dimension_value), True), # list with dynamic dimension values is
- # fully defined
- ((dynamic_dimension, 1), False), # tuple with dynamic dimension is not fully defined
- ([dynamic_dimension, 1], False), # list with dynamic dimension is not fully defined
- ])
- def test_is_fully_defined(self, data, result):
- assert is_fully_defined(data) == result
-
-
-class TestShapeArrayTest():
- @pytest.mark.parametrize("data, ref, result",[([1], shape_array([1]), True),
- # if we provide a list with dynamic_dimension_value then it is converted to dynamic dimension
- ([dynamic_dimension_value, 5], gen_masked_array([1, 5], [0]), True),
- # if we provide a list with dynamic_dimension then the generated shape array still have it
- ([7, dynamic_dimension], gen_masked_array([7, 1], [1]), True),
- # negative test to make sure that np.ma.allequal works properly
- ([2], gen_masked_array([1], []), False),
- ])
- def test_shape_array(self, data, ref, result):
- assert strict_compare_tensors(shape_array(data), ref) == result
-
-
-class TestCompareShapesTest():
- @pytest.mark.parametrize("input1, input2, result",[(gen_masked_array([1, 2, 3], []),
- gen_masked_array([1, 2, 3], []), True),
- (gen_masked_array([4, 2, 3], []), gen_masked_array([1, 2, 3], []), False),
- (gen_masked_array([1, 2], []), gen_masked_array([1, 2, 3], []), False),
- (gen_masked_array([1, 2, 3], []), gen_masked_array([1, 2], []), False),
- (gen_masked_array([1, 2, 3], [1]), gen_masked_array([1, 5, 3], [1]), True), # [1, d, 3] vs [1, d, 3]
- (gen_masked_array([1, 2, 3], [2]), gen_masked_array([1, 5, 3], [1]), True), # [1, 2, d] vs [1, d, 3]
- (gen_masked_array([1, 2, 3], []), gen_masked_array([1, 5, 3], [1]), True), # [1, 2, 3] vs [1, d, 3]
- (gen_masked_array([1, 2, 3], [0]), gen_masked_array([1, 5, 3], []), False), # [d, 2, 3] vs [1, 5, 3]
- (np.array([1, 2, 3]), gen_masked_array([1, 5, 3], [1]), True), # [1, 2, 3] vs [1, d, 3]
- (np.array([1, 2]), gen_masked_array([1, 5, 3], [1]), False),
- (np.array([1, 2]), np.array([1, 2]), True),
- (np.array([1, 2]), np.array([3, 2]), False),
- ])
- def test_compare_shapes(self, input1, input2, result):
- assert compatible_shapes(input1, input2) == result
-
-
-class TestShapeDeleteTest():
- @pytest.mark.parametrize("shape, indices, result",[(gen_masked_array([1, 2, 3], []), [],
- gen_masked_array([1, 2, 3], [])),
- # [1, d, 3] -> [d, 3]. Indices input is a list
- (gen_masked_array([1, 2, 3], [1]), [0], gen_masked_array([2, 3], [0])),
- # [1, d, 3] -> [d, 3]. Indices input is a numpy array
- (gen_masked_array([1, 2, 3], [1]), np.array([0]), gen_masked_array([2, 3], [0])),
- # [1, d, 3] -> [d, 3]. Indices input is a masked array
- (gen_masked_array([1, 2, 3], [1]), gen_masked_array([0], []), gen_masked_array([2, 3], [0])),
- # [1, d, 3] -> [d, 3]. Indices input is a numpy array with scalar
- (gen_masked_array([1, 2, 3], [1]), np.array(0), gen_masked_array([2, 3], [0])),
- # [1, d, 3] -> [d, 3]. Indices input is an integer
- (gen_masked_array([1, 2, 3], [1]), 0, gen_masked_array([2, 3], [0])), # [1, d, 3] -> [d, 3]
- (gen_masked_array([1, 2, 3, 4], [1]), [0, 2], gen_masked_array([2, 4], [0])), # [1, d, 3, 4] -> [d, 4]
- (gen_masked_array([1, 2, 3], [1]), [0, 2, 1], gen_masked_array([], [])), # [1, d, 3] -> []
- (gen_masked_array([1, 2, 3], [1]), [0, 2], gen_masked_array([2], [0])), # [1, d, 3] -> [d]
- # [1, d, d, 4] -> [d, d]
- (gen_masked_array([1, 2, 3, 4], [1, 2]), [3, 0], gen_masked_array([2, 3], [0, 1])),
- (gen_masked_array([1, 2, 3, 4], [2]), 3, gen_masked_array([1, 2, 3], [2])), # [1, 2, d, 4] -> [1, 2, d]
- ([1, 2, 3, 4], [1], [1, 3, 4]), # [1, 2, 3, 4] -> [1, 3, 4]. Input is a regular lists
- (np.array([1, 2, 3, 4]), [1], [1, 3, 4]), # [1, 2, 3, 4] -> [1, 3, 4]. Input is a regular arrays
- (np.array([1, 2, 3, 4]), [-1, -3], [1, 3]), # [1, 2, 3, 4] -> [1, 3]. Negative indices
- (np.array([1, 2, 3, 4]), -2, [1, 2, 4]), # [1, 2, 3, 4] -> [1, 2, 4]. Negative index
- ])
- def test_shape_delete(self, shape, indices, result):
- assert strict_compare_tensors(shape_delete(shape, indices), result)
-
- def test_shape_delete_raise_exception(self):
- with pytest.raises(Error, match ='.*Incorrect parameter type.*'):
- shape_delete(gen_masked_array([1, 2, 3], []), {})
-
-
-class TestShapeInsertTest():
- @pytest.mark.parametrize("shape, pos, values, result",[(gen_masked_array([1, 2, 3], []), 1, [5],
- gen_masked_array([1, 5, 2, 3], [])),
- (gen_masked_array([1, 2, 3], [1]), 1, [5], gen_masked_array([1, 5, 2, 3], [2])),
- (gen_masked_array([1, 2, 3], [1]), 1, [dynamic_dimension], gen_masked_array([1, 5, 2, 3], [1, 2])),
- (gen_masked_array([1, 2, 3], [1]), 0, [dynamic_dimension], gen_masked_array([5, 1, 2, 3], [0, 2])),
- (gen_masked_array([1, 2, 3], [1]), np.int64(0), [dynamic_dimension],
- gen_masked_array([5, 1, 2, 3], [0, 2])),
- (gen_masked_array([1, 2, 3], [1]), 3, [dynamic_dimension], gen_masked_array([1, 2, 3, 5], [1, 3])),
- (gen_masked_array([1, 2, 3], [1]), 3, [dynamic_dimension, dynamic_dimension],
- gen_masked_array([1, 2, 3, 5, 6], [1, 3, 4])),
- (gen_masked_array([1], [0]), 0, [7, dynamic_dimension], gen_masked_array([7, 5, 2], [1, 2])),
- ])
- def test_shape_insert(self, shape, pos, values, result):
- assert strict_compare_tensors(shape_insert(shape, pos, values), result)
-
- def test_shape_insert_raise_exception(self):
- with pytest.raises(Error, match='.*Incorrect parameter type.*'):
- shape_insert(gen_masked_array([1, 2, 3], []), 2, {})
-
-
-class Testmo_array_test():
- @pytest.mark.parametrize("data, result",[(mo_array([2, 3, 5, 7]), np.array([2, 3, 5, 7])),
- (mo_array([2., 3., 5., 7.], dtype=np.float64), np.array([2., 3., 5., 7.])),
- (mo_array([2., 3., 5., 7.]), np.array([2., 3., 5., 7.], dtype=np.float32)),
- ])
- def test_mo_array_positive(self, data, result):
- assert data.dtype == result.dtype
-
- @pytest.mark.parametrize("data, result",[(mo_array([2., 3., 5., 7.]), np.array([2., 3., 5., 7.])),
- ])
- def test_mo_array_negative(self, data, result):
- assert data.dtype != result.dtype
-
-
-class clarify_partial_shape_test(unittest.TestCase):
-
- def test_clarify_1(self):
- actual_result = clarify_partial_shape([shape_array([dynamic_dimension, 10, dynamic_dimension]),
- shape_array([4, dynamic_dimension, dynamic_dimension])])
- ref_result = shape_array([4, 10, dynamic_dimension])
- assert strict_compare_tensors(actual_result, ref_result)
diff --git a/tools/mo/unit_tests/mo/front/conv_test.py b/tools/mo/unit_tests/mo/front/conv_test.py
deleted file mode 100644
index a351c96003061f..00000000000000
--- a/tools/mo/unit_tests/mo/front/conv_test.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.middle.passes.conv import fuse_pad
-from openvino.tools.mo.middle.passes.fusing.mark_unfused_nodes import mark_shape_of_sugraph_as_unfusable
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.middle.pattern_match import for_graph_and_each_sub_graph_recursively
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.elementwise import eltwise_infer
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.pad import Pad
-from openvino.tools.mo.ops.shape import Shape
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, \
- shaped_parameter, valued_const_with_data
-
-
-class PadFusingTest(unittest.TestCase):
-
- # standard case: not in the shape subgraph
- def test_pad_fusing(self):
- nodes = {
- **shaped_parameter('input', shape_array([1, 3, 248, 248])),
-
- **valued_const_with_data('pads_begin', shape_array([0, 0, 1, 1])),
- **valued_const_with_data('pads_end', shape_array([0, 0, 1, 1])),
- **valued_const_with_data('fill_value', shape_array(0.0)),
- **valued_const_with_data('weights', shape_array(np.zeros([3, 16, 4, 4]))),
-
- **regular_op_with_empty_data('pad', {'type': 'Pad',
- 'op': 'Pad',
- 'infer': Pad.infer,
- 'mode': 'constant'}),
-
- **regular_op_with_empty_data('conv', {'type': 'Convolution',
- 'op': 'Convolution',
- 'infer': Convolution.infer,
- # zeros, no paddings
- 'pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'group': 1,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'output': 64,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0}),
- **result(),
- }
-
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect('input', '0:pad'),
- *connect('pads_begin', '1:pad'),
- *connect('pads_end', '2:pad'),
- *connect('fill_value', '3:pad'),
- *connect('pad', '0:conv'),
- *connect('weights', '1:conv'),
- *connect('conv', 'output'),
- ], nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'middle'
-
- graph = partial_infer(graph)
- mark_shape_of_sugraph_as_unfusable(graph)
- for_graph_and_each_sub_graph_recursively(graph, fuse_pad)
- graph.clean_up()
-
- conv_fused_with_pad = regular_op_with_empty_data('conv', {'type': 'Convolution',
- 'op': 'Convolution',
- # ones are taken from fused Pad
- 'pad': np.array([[0, 0], [0, 0], [1, 1], [1, 1]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'group': 1,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'output': 64,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
-
- 'infer': Convolution.infer})
-
- graph_ref = build_graph(nodes_attrs=nodes, update_attributes=conv_fused_with_pad, edges=[
- *connect('input', '0:conv'),
- *connect('weights', '1:conv'),
- *connect('conv', 'output'),
- ], nodes_with_edges_only=True)
- graph_ref.graph['layout'] = 'NCHW'
- graph_ref.stage = 'middle'
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Pad in the shape subgraph
- def test_pad_fusing_shape_subgraph(self):
- nodes = {
- **shaped_parameter('input', shape_array([1, 3, 1020, 1020])),
- **regular_op_with_empty_data('input_shape', {'type': 'ShapeOf', 'op': 'ShapeOf', 'output_type': np.int64,
- 'infer': Shape.infer}),
- **regular_op_with_empty_data('gathered_shape', {'type': 'Gather', 'batch_dims': 0, 'infer': Gather.infer}),
- **valued_const_with_data('axis', np.array([0])),
- **valued_const_with_data('indices', np.array([2, 3])),
-
- **regular_op_with_empty_data('div', {'type': 'Div',
- 'infer': lambda node: eltwise_infer(node, lambda a, b: a / b)}),
- **regular_op_with_empty_data('sub_1', {'type': 'Sub',
- 'infer': lambda node: eltwise_infer(node, lambda a, b: a - b)}),
- **regular_op_with_empty_data('sub_2', {'type': 'Sub',
- 'infer': lambda node: eltwise_infer(node, lambda a, b: a - b)}),
-
- **valued_const_with_data('div_const', shape_array([2])),
- **valued_const_with_data('sub_const', shape_array([512])),
-
- **regular_op_with_empty_data('pad', {'type': 'Pad',
- 'op': 'Pad',
- 'infer': Pad.infer,
- 'mode': 'constant'}),
-
- **regular_op_with_empty_data('concat', {'type': 'Concat',
- 'op': 'Concat',
- 'axis': 0,
- 'infer': concat_infer}),
-
- **valued_const_with_data('pad_end', shape_array([0, 0, 0, 0])),
- **valued_const_with_data('blank_zeros', shape_array([0, 0])),
-
- **regular_op_with_empty_data('conv', {'type': 'Convolution',
- 'op': 'Convolution',
-
- 'pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'group': 1,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'output': 64,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
-
- 'infer': Convolution.infer}),
- **valued_const_with_data('weights', shape_array(np.zeros([3, 16, 4, 4]))),
- **result(),
- }
-
- graph = build_graph(nodes_attrs=nodes,
- update_attributes={
- 'gathered_shape_d': {'kind': 'data', 'value': shape_array([256, 256]),
- 'shape': shape_array([2])}},
- edges=[
- *connect('input', 'input_shape', skip_data=True),
- *connect('input_shape', '0:gathered_shape'),
- *connect('indices', '1:gathered_shape'),
- *connect('axis', '2:gathered_shape'),
-
- *connect('gathered_shape', 'sub_1'),
- *connect('sub_const', 'sub_1'),
- *connect('sub_1', 'div'),
- *connect('div_const', 'div'),
- *connect('div', '0:sub_2'),
- *connect('sub_1', '1:sub_2'),
- *connect('input', '0:pad'),
-
- *connect('blank_zeros', '0:concat'),
- *connect('sub_2', '1:concat'),
- *connect('concat', '1:pad'),
-
- *connect('pad_end', '2:pad'),
- *connect('pad', '0:conv'),
- *connect('weights', '1:conv'),
- *connect('conv', 'output'),
- ], nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'middle'
-
- graph = partial_infer(graph)
-
- # graph must remain unchanged
- graph_ref = graph.copy()
-
- mark_shape_of_sugraph_as_unfusable(graph)
- for_graph_and_each_sub_graph_recursively(graph, fuse_pad)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/div_test.py b/tools/mo/unit_tests/mo/front/div_test.py
deleted file mode 100644
index 2c818035378777..00000000000000
--- a/tools/mo/unit_tests/mo/front/div_test.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.div import Div
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect, \
- connect_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder_1', [1, 227, 227, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('placeholder_2', [1, 227, 227, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('div', None, {'op': 'Div', 'type': 'Divide', 'name': 'my_div'}),
-
- **regular_op_with_shaped_data('reciprocal', [1, 227, 227, 3], {'type': 'Power'}),
- **valued_const_with_data('minus_one', np.array(-1.)),
- **regular_op_with_shaped_data('mul', None, {'type': 'Multiply'}),
-
- **result(),
-}
-
-
-class TestDiv(unittest.TestCase):
- def test_div_test_1(self):
- # Test with two different inputs from two placeholders
- graph = build_graph(nodes, [
- *connect('placeholder_1', '0:div'),
- *connect('placeholder_2', '1:div'),
- *connect('div', 'output'),
- ], nodes_with_edges_only=True)
- Div().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_1', '0:mul'),
- *connect('placeholder_2', '0:reciprocal'),
- *connect('minus_one', '1:reciprocal'),
- *connect('reciprocal', '1:mul'),
- *connect('mul', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='Multiply')[0]]['name'] == 'my_div')
-
- def test_div_test_2(self):
- # Test with two same inputs from one placeholder
- graph = build_graph(nodes, [
- *connect('placeholder_1:0', '0:div'),
- *connect_data('placeholder_1:0', '1:div'),
- *connect('div', 'output'),
- ], nodes_with_edges_only=True)
- Div().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_1:0', '0:mul'),
- *connect_data('placeholder_1:0', '0:reciprocal'),
- *connect('minus_one', '1:reciprocal'),
- *connect('reciprocal', '1:mul'),
- *connect('mul', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='Multiply')[0]]['name'] == 'my_div')
-
- def test_div_with_integer(self):
- # Test where transformation should not be applied because the divisor is integer
- graph = build_graph({
- **regular_op_with_shaped_data('parameter', [1, 227, 227, 3], {'type': 'Parameter', 'data_type': np.int32}),
- **valued_const_with_data('const', np.array([-1.], dtype=np.int32)),
- **regular_op_with_shaped_data('div', None, {'op': 'Div', 'type': 'Divide', 'name': 'my_div'}),
- **result()},
- [
- *connect('parameter:0', '0:div'),
- *connect_data('const:0', '1:div'),
- *connect('div', 'output'),
- ])
- graph_ref = graph.copy()
- Div().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/eltwise_n_test.py b/tools/mo/unit_tests/mo/front/eltwise_n_test.py
deleted file mode 100644
index 3891bc6f74b8cc..00000000000000
--- a/tools/mo/unit_tests/mo/front/eltwise_n_test.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.eltwise_n import EltwiseNReplacement
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_4': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- # EltwiseN operations
- 'EltwiseN_1': {'value': None, 'operation': None, 'type': None, 'kind': 'op', 'op': 'EltwiseN'},
- # Test operation
- 'last': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op', 'op': None},
- # Max operation
- 'max_1': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op'},
- # Mui operations
- 'mul_1': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op'},
- 'mul_2': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op'},
- # Add operations
- 'add_1': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op'},
- 'add_2': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op'},
- 'add_3': {'value': None, 'operation': None, 'type': 'Eltwise', 'kind': 'op'},
-}
-
-
-class TestEltwiseNFrontReplacement(unittest.TestCase):
- def test_eltwiseN_test_1(self):
- # EltwiseN test with N = 2 from 2 placeholders and operation = max
-
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'EltwiseN_1'),
- ('placeholder_2', 'EltwiseN_1'),
- ('EltwiseN_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2': {'shape': np.array([1, 227, 227, 3])},
- 'EltwiseN_1': {'operation': 'max'},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'max_1'),
- ('placeholder_2', 'max_1'),
- ('max_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2': {'shape': np.array([1, 227, 227, 3])},
- 'max_1': {'type': 'Maximum'}
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- replacer = EltwiseNReplacement()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_eltwise_test_2(self):
- # EltwiseN test with N = 3 from 3 placeholders and operation = mul
-
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'EltwiseN_1'),
- ('placeholder_2', 'EltwiseN_1'),
- ('placeholder_3', 'EltwiseN_1'),
- ('EltwiseN_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_3': {'shape': np.array([1, 227, 227, 3])},
- 'EltwiseN_1': {'operation': 'mul'},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'mul_1'),
- ('placeholder_2', 'mul_1'),
- ('mul_1', 'mul_2'),
- ('placeholder_3', 'mul_2'),
- ('mul_2', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_3': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1': {'type': 'Multiply'},
- 'mul_2': {'type': 'Multiply'},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- replacer = EltwiseNReplacement()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_eltwise_test_3(self):
- # EltwiseN test with N = 4 from 1 placeholder and operation = sum
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'EltwiseN_1'),
- ('placeholder_2', 'EltwiseN_1'),
- ('placeholder_3', 'EltwiseN_1'),
- ('placeholder_4', 'EltwiseN_1'),
- ('EltwiseN_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_3': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_4': {'shape': np.array([1, 227, 227, 3])},
- 'EltwiseN_1': {'operation': 'sum'},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'add_1'),
- ('placeholder_2', 'add_1'),
- ('add_1', 'add_2'),
- ('placeholder_3', 'add_2'),
- ('add_2', 'add_3'),
- ('placeholder_4', 'add_3'),
- ('add_3', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_3': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_4': {'shape': np.array([1, 227, 227, 3])},
- 'add_1': {'type': 'Add'},
- 'add_2': {'type': 'Add'},
- 'add_3': {'type': 'Add'},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- replacer = EltwiseNReplacement()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_eltwise_test_4(self):
- # EltwiseN test with N = 4 from 1 placeholder and operation = sum
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'EltwiseN_1'),
- ('placeholder_1', 'EltwiseN_1'),
- ('placeholder_1', 'EltwiseN_1'),
- ('placeholder_1', 'EltwiseN_1'),
- ('EltwiseN_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'EltwiseN_1': {'operation': 'sum'},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'add_1'),
- ('placeholder_1', 'add_1'),
- ('add_1', 'add_2'),
- ('placeholder_1', 'add_2'),
- ('add_2', 'add_3'),
- ('placeholder_1', 'add_3'),
- ('add_3', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'add_1': {'type': 'Add'},
- 'add_2': {'type': 'Add'},
- 'add_3': {'type': 'Add'},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- replacer = EltwiseNReplacement()
- 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/tools/mo/unit_tests/mo/front/extractor_test.py b/tools/mo/unit_tests/mo/front/extractor_test.py
deleted file mode 100644
index 7983d39d76fb22..00000000000000
--- a/tools/mo/unit_tests/mo/front/extractor_test.py
+++ /dev/null
@@ -1,682 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import pytest
-from openvino.tools.mo.front.common.partial_infer.utils import strict_compare_tensors
-from openvino.tools.mo.front.extractor import input_user_data_repack, output_user_data_repack, update_ie_fields, add_input_op, \
- get_node_id_with_ports
-from openvino.tools.mo.front.extractor import spatial_attr_getter, add_input_ops, attr_getter, CaffePythonFrontExtractorOp, \
- add_output_ops, bool_to_str
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.extractors import FakeMultiParam
-from unit_tests.utils.graph import build_graph, build_graph_with_edge_attrs, build_graph_with_attrs
-from openvino.runtime import PartialShape
-
-
-class FakePythonParam:
- def __init__(self, param: FakeMultiParam):
- self.__setattr__('python_param', param)
-
-
-nodes_attributes = {'input': {'kind': 'data'},
- 'pool_1': {'type': 'Pooling', 'kind': 'op'},
- 'output': {'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-class UpdateIEFieldsTest(unittest.TestCase):
- def test_default_update_ie_fields(self):
- update_ie_fields({}, ir_version=None)
-
- def test_not_set_update_ie_fields(self):
- with self.assertRaisesRegex(Error, 'Unrecognized IR version.*'):
- update_ie_fields({}, ir_version='abracadabra')
-
-
-class TestExtractor(unittest.TestCase):
- def test_spatial_attr_getter(self):
- input_shape = np.array([1, 125, 13, 13])
- params = {
- 'kernel': np.array([1, 1, 1, 2]),
- 'pad': np.array([1, 1, 3, 4]),
- 'stride': np.array([1, 1, 2, 3]),
- }
- graph = build_graph(nodes_attributes,
- [('input', 'pool_1'),
- ('pool_1', 'output'),
- ('output', 'op_output')
- ],
- {'input': {'shape': input_shape},
- 'pool_1': {**params, 'spatial_dims': [2, 3]},
- 'output': {'shape': None}})
- pool_1_node = Node(graph, 'pool_1')
- for param in params.keys():
- if type(params[param]) is np.ndarray:
- port_lambda = lambda x: x
- self.assertEqual(params[param][2],
- spatial_attr_getter(pool_1_node, field=param, dim=0, post=port_lambda))
- self.assertEqual(params[param][3],
- spatial_attr_getter(pool_1_node, field=param, dim=1, post=port_lambda))
-
- def test_attr_getter(self):
- nodes = {'input': {'kind': 'data'},
- 'reshape': {'type': 'Reshape', 'kind': 'op'},
- 'output': {'kind': 'data'},
- 'op_output': {'type': 'Result', 'kind': 'op'},
- }
- input_shape = np.array([1, 125, 13, 13])
- params = {
- 'dim': [1, 1, 2, 3],
- 'max_size': np.array([3, 2, 1, 0])
- }
- expect_params = {
- 'dim': "1,1,2,3",
- 'max_size': "3,2,1,0",
- }
- graph = build_graph(nodes,
- [('input', 'reshape'),
- ('reshape', 'output'),
- ('output', 'op_output')
- ],
- {'input': {'shape': input_shape},
- 'reshape': {**params, 'spatial_dims': [2, 3]},
- 'output': {'shape': None}})
- pool_1_node = Node(graph, 'reshape')
- for param in params.keys():
- if type(params[param]) is list:
- self.assertEqual(expect_params[param],
- attr_getter(pool_1_node, param))
-
-
-class TestAddInputOp(unittest.TestCase):
- nodes = [
- ('op_node', {'kind': 'op'}),
- ('future_input', {'kind': 'op'}),
- ('another_node', {'kind': 'op'}),
- ]
- edges = [('future_input', 'op_node', {'in': 1, 'out': 0}),
- ('another_node', 'op_node', {'in': 0, 'out': 0})]
-
- def test_in_port_no_data(self):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges)
- new_input_shape = np.array([1, 2, 3, 4])
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges[1:],
- new_nodes_with_attrs=[('input_node', {'kind': 'op', 'op': 'Parameter',
- 'shape': new_input_shape})],
- new_edges_with_attrs=[('input_node', 'op_node', {'in': 1, 'out': 0})])
- add_input_op(graph, 'op_node', 1, data=False, shape=new_input_shape)
- graph.remove_edge('future_input', 'op_node')
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='op_node')
- self.assertTrue(flag, resp)
-
- def test_in_port_with_data(self):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges)
- graph.stage = 'middle'
- new_input_shape = np.array([1, 2, 3, 4])
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges[1:],
- new_nodes_with_attrs=[('input_node', {'kind': 'op', 'op': 'Parameter',
- 'shape': new_input_shape}),
- ('input_data', {'kind': 'data'})],
- new_edges_with_attrs=[('input_node', 'input_data', {'in': 0, 'out': 0}),
- ('input_data', 'op_node', {'in': 1, 'out': 0})])
- add_input_op(graph, 'op_node', 1, data=True, shape=new_input_shape)
- graph.remove_edge('future_input', 'op_node')
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='op_node')
- self.assertTrue(flag, resp)
-
- nodes_out = [
- ('op_node', {'kind': 'op'}),
- ('future_input', {'kind': 'op'}),
- ('another_node', {'kind': 'op'}),
- ]
- edges_out = [('op_node', 'future_input', {'in': 0, 'out': 1}),
- ('op_node', 'another_node', {'in': 0, 'out': 0})]
-
- def test_out_port_no_data(self):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes_out, edges_with_attrs=self.edges_out)
- new_input_shape = np.array([1, 2, 3, 4])
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes_out, edges_with_attrs=self.edges_out[1:],
- new_nodes_with_attrs=[('input_node', {'kind': 'op', 'op': 'Parameter',
- 'shape': new_input_shape})],
- new_edges_with_attrs=[('input_node', 'future_input', {'in': 0, 'out': 0})])
- add_input_op(graph, 'op_node', 1, data=False, shape=new_input_shape, is_out_port=True)
- graph.remove_edge('op_node', 'future_input')
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='another_node')
- self.assertTrue(flag, resp)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='future_input')
- self.assertTrue(flag, resp)
-
- def test_out_port_with_data(self):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes_out, edges_with_attrs=self.edges_out[1:],
- new_nodes_with_attrs=[('input_data', {'kind': 'data', 'shape': None, 'value': None})],
- new_edges_with_attrs=[('op_node', 'input_data', {'out': 1, 'in': 0}),
- ('input_data', 'future_input', {'in': 0, 'out': 0})])
- graph.stage = 'middle'
- new_input_shape = np.array([1, 2, 3, 4])
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes_out, edges_with_attrs=self.edges_out[1:],
- new_nodes_with_attrs=[('input_node', {'kind': 'op', 'op': 'Parameter',
- 'shape': new_input_shape}),
- ('input_data', {'kind': 'data', 'shape': None})],
- new_edges_with_attrs=[('input_node', 'input_data', {'in': 0, 'out': 0}),
- ('input_data', 'future_input', {'in': 0, 'out': 0})])
- add_input_op(graph, 'op_node', 1, data=True, shape=new_input_shape, is_out_port=True)
- graph.remove_edge('op_node', 'input_data')
-
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='another_node')
- self.assertTrue(flag, resp)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='future_input')
- self.assertTrue(flag, resp)
-
-
-class TestInputAddition(UnitTestWithMockedTelemetry):
- # Tests for input
- nodes = {'node_1': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'},
- }
- edges = [
- ('node_1', 'conv_1'),
- ('conv_1', 'relu_1'),
- ]
-
- def test_none_out_port_raise(self):
- graph = build_graph(self.nodes, self.edges)
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape, 'out': None}]}
- with self.assertRaisesRegex(Error, 'Output port for input node conv_1 should be specified, it cannot be None!'):
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
-
- def test_wrong_output_port_raise(self):
- graph = build_graph(self.nodes, self.edges)
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape, 'out': 5}]}
- with self.assertRaisesRegex(Error, 'Output port index 5 is out of number of available output ports for node'):
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
-
- def test_wrong_input_port_raise(self):
- graph = build_graph(self.nodes, self.edges)
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape, 'in': 5}]}
- with self.assertRaisesRegex(Error, 'Input port index 5 is out of number of available input ports for node'):
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
-
- def test_one_input_one_shape(self):
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape}]}
- nodes = {
- 'old_input': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'}
- }
- edges = [
- ('old_input', 'conv_1'),
- ('conv_1', 'relu_1'),
- ('relu_1', 'output')
- ]
- graph = build_graph(nodes, edges)
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
- new_input = list(graph.in_edges('conv_1'))[0][0]
- self.assertFalse(graph.node['old_input']['is_input'])
- self.assertTrue(graph.node[new_input]['is_input'])
- self.assertTrue((new_input, 'conv_1') in graph.edges())
- self.assertTrue(('old_input', 'conv_1') not in graph.edges())
- shapes_are_equal = np.array_equal(graph.node[new_input]['shape'], shape)
- self.assertTrue(shapes_are_equal)
-
- def test_one_input_no_shape(self):
- shape = None
- inputs = {'conv_1': [{'shape': shape}]}
- nodes = {
- 'old_input': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'old_input_data': {'kind': 'data', 'value': None, 'shape': np.array([-1, 224, 224, 3])},
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'conv_1_data': {'kind': 'data', 'value': True, 'shape': np.array([-1, 224, 224, 3])},
- 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'relu_1_data': {'kind': 'data', 'value': None, 'shape': np.array([-1, 112, 112, 64])},
- 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'output_data': {'name': 'output_data', 'kind': 'data', 'shape': np.array([-1, 112, 112, 64])},
- 'op_output': {'kind': 'op', 'op': 'Result'}
- }
- edges = [
- ('old_input', 'old_input_data'),
- ('old_input_data', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'relu_1'),
- ('relu_1', 'relu_1_data'),
- ('relu_1_data', 'output'),
- ('output', 'output_data'),
- ('output_data', 'op_output')
- ]
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=False)
- new_input = list(graph.in_edges(list(graph.in_edges('conv_1'))[0][0]))[0][0]
- new_input_data = list(graph.in_edges('conv_1'))[0][0]
- self.assertFalse(graph.node['old_input']['is_input'])
- self.assertTrue(graph.node[new_input]['is_input'])
- self.assertTrue((new_input_data, 'conv_1') in graph.edges())
- self.assertTrue(('old_input_data', 'conv_1') not in graph.edges())
- self.assertIsNotNone(graph.node[new_input_data]['shape'])
-
- def test_two_inputs_two_shapes_positive_1(self):
- shape_1 = [1, 2, 3, 4]
- shape_2 = [4, 3, 2, 1]
- inputs = {'node_1': [{'shape': shape_1}], 'node_4': [{'shape': shape_2}]}
- nodes = {
- 'input_1': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'input_2': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'node_1': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'node_2': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'node_3': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'node_4': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'output': {'kind': 'op', 'op': 'Result'}
- }
- edges = [
- ('input_1', 'node_1'),
- ('node_1', 'node_2'),
- ('node_3', 'output'),
- ('input_2', 'node_4'),
- ('node_4', 'output')
- ]
- graph = build_graph(nodes, edges)
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
- new_input_1 = list(graph.in_edges('node_1'))[0][0]
- new_input_2 = list(graph.in_edges('node_4'))[0][0]
- self.assertFalse(graph.node['input_1']['is_input'])
- self.assertTrue(graph.node[new_input_1]['is_input'])
- self.assertTrue(graph.node[new_input_2]['is_input'])
- self.assertTrue((new_input_1, 'node_1') in graph.edges())
- self.assertTrue((new_input_2, 'node_4') in graph.edges())
- self.assertTrue(strict_compare_tensors(shape_1, graph.node[new_input_1]['shape']))
- self.assertTrue(strict_compare_tensors(shape_2, graph.node[new_input_2]['shape']))
-
- def test_two_inputs_two_shapes_not_all_inputs(self):
- shape_1 = [1, 2, 3, 4]
- shape_2 = [4, 3, 2, 1]
- inputs = {'node_1': [{'shape': shape_1}], 'node_4': [{'shape': shape_2}]}
- nodes = {
- 'input_1': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'input_2': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'node_1': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'node_2': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'node_3': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'node_4': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'output': { 'kind': 'op', 'op': 'Result'},
- 'input_3': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'}
- }
- edges = [
- ('input_1', 'node_1'),
- ('node_1', 'node_2'),
- ('node_3', 'output'),
- ('input_2', 'node_4'),
- ('node_4', 'output'),
- ('input_3', 'output')
- ]
- graph = build_graph(nodes, edges)
- self.assertRaises(Error, add_input_ops, graph, inputs, True)
-
- # Tests for cases with input/output ports cutting
- def test_add_input_with_input_port_before_infer(self):
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape, 'in': 0}]}
- nodes = {
- 'old_input': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'}
- }
- edges = [
- ('old_input', 'conv_1'),
- ('conv_1', 'relu_1'),
- ('relu_1', 'output')
- ]
- graph = build_graph(nodes, edges)
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
-
- # Check that graph
- graph_ref = build_graph(nodes, edges, update_attributes={'old_input': {'shape': shape}})
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output')
- self.assertTrue(flag, resp)
-
- # also checks that new old_input was changed
- new_input = list(graph.in_edges('conv_1'))[0][0]
- self.assertFalse(graph.node['old_input']['is_input'])
- self.assertTrue(graph.node[new_input]['is_input'])
- self.assertTrue((new_input, 'conv_1') in graph.edges())
- self.assertTrue(('old_input', 'conv_1') not in graph.edges())
-
- def test_add_input_with_output_port_before_infer(self):
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape, 'out': 0}]}
- nodes = {
- 'old_input': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'},
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'}
- }
- edges = [
- ('old_input', 'conv_1'),
- ('conv_1', 'relu_1'),
- ('conv_2', 'relu_1'),
- ('relu_1', 'output')
- ]
- graph = build_graph(nodes, edges)
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
-
- graph_ref = build_graph(nodes_attrs={'new_input': {'kind': 'op', 'op': 'Parameter', 'shape': shape},
- **nodes},
- edges=[('new_input', 'relu_1'),
- ('relu_1', 'output'),
- ('conv_2', 'relu_1'),
- ('old_input', 'conv_1'),],)
- # Check that new input is added right (with right ports !)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='output')
- self.assertTrue(flag, resp)
-
- # Check that other graph is not damaged
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='conv_1')
- self.assertTrue(flag, resp)
-
- # Checks for new input and edges
- self.assertTrue('conv_1/placeholder_out_port_0' in graph.nodes())
- new_input = 'conv_1/placeholder_out_port_0'
- self.assertTrue(graph.node[new_input]['is_input'])
- self.assertTrue((new_input, 'relu_1') in graph.edges())
- self.assertTrue(('old_input', 'relu_1') not in graph.edges())
-
- def test_add_input_with_output_port_after_infer(self):
- shape = np.array([1, 2, 3, 4])
- inputs = {'conv_1': [{'shape': shape, 'out': 0}]}
- nodes = {
- 'old_input': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'inp_data' : {'kind': 'data', 'shape': shape + 1},
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'},
- 'conv_data': {'kind': 'data', 'shape': shape, 'value': None, 'data_attr': 'data_attr_value'},
- 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'},
- }
- edges = [
- ('old_input', 'inp_data'),
- ('inp_data', 'conv_1'),
- ('conv_1', 'conv_data'),
- ('conv_data', 'relu_1', {'edge_attr': 'edge_value'}),
- ]
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=False)
-
- graph_ref = build_graph(nodes_attrs={'new_input': {'kind': 'op', 'op': 'Parameter', 'shape': shape},
- **nodes},
- edges=[('old_input', 'inp_data'),
- ('inp_data', 'conv_1'),
- ('new_input', 'conv_data'),
- ('conv_data', 'relu_1', {'edge_attr': 'edge_value'}),
- ],)
- # Check that new input is added right (with right ports !)
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='relu_1')
- self.assertTrue(flag, resp)
-
- # Check that other graph is not damaged
- (flag, resp) = compare_graphs(graph, graph_ref, last_node='conv_1')
- self.assertTrue(flag, resp)
-
- # Checks for new input and edges
- self.assertTrue('conv_1/placeholder_out_port_0' in graph.nodes())
- new_input = 'conv_1/placeholder_out_port_0'
-
- self.assertTrue(graph.node[new_input]['is_input'])
-
- self.assertTrue(Node(graph, 'relu_1').in_node(0)['data_attr'] == 'data_attr_value')
- self.assertTrue(Node(graph, 'relu_1').in_edge(0)['edge_attr'] == 'edge_value')
-
-
-class TestOutputCut():
- # {'embeddings': [{'port': None}]}
- @pytest.mark.parametrize("output",[{'C':[{'port': None}]}, {'C': [{'out': 0}]}, {'C': [{'out': 1}]}])
- def test_output_port_cut(self, output):
- nodes = {'A': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- 'B': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- 'C': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- 'D': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- 'E': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- }
- edges = [
- ('A', 'C', {'in': 0, 'out': 0}),
- ('B', 'C', {'in': 1, 'out': 0}),
- ('C', 'D', {'in': 0, 'out': 0}),
- ('C', 'E', {'in': 0, 'out': 1})
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- sinks = add_output_ops(graph, output)
- graph.clean_up()
- assert len(Node(graph, 'C').out_nodes()) == 1
- assert len(Node(graph, 'C').in_nodes()) == 2
-
- @pytest.mark.parametrize("output",[{'C': [{'in': 0}]}, {'C': [{'in': 1}]}])
- def test_output_port_cut(self, output):
- nodes = {'A': {'op': 'Parameter', 'kind': 'op'},
- 'B': {'op': 'Parameter', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- 'D': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- 'E': {'type': 'Identity', 'kind': 'op', 'op': 'Identity'},
- }
- edges = [
- ('A', 'C', {'in': 0, 'out': 0}),
- ('B', 'C', {'in': 1, 'out': 0}),
- ('C', 'D', {'in': 0, 'out': 0}),
- ('C', 'E', {'in': 0, 'out': 1})
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- sinks = add_output_ops(graph, output)
- graph.clean_up()
- assert len(graph.nodes()) == 2
-
-
-class TestUserDataRepack(UnitTestWithMockedTelemetry):
- nodes = {'A': {'name': 'Aa', 'op': 'Parameter', 'kind': 'op'},
- 'B': {'name': 'Bb', 'op': 'Parameter', 'kind': 'op'},
- 'C': {'name': 'Cc', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'D': {'name': 'Dd', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'E': {'name': 'Ee', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- }
- edges = [
- ('A', 'C', {'in': 0, 'out': 0}),
- ('B', 'C', {'in': 1, 'out': 0}),
- ('C', 'D', {'in': 0, 'out': 0}),
- ('C', 'E', {'in': 0, 'out': 1})
- ]
-
- def test_input_user_data_repack_none(self):
- graph = build_graph(self.nodes, self.edges)
- input, freeze_placeholder = input_user_data_repack(graph, None, None)
- self.assertEqual(input, None)
- self.assertEqual(freeze_placeholder, None)
-
- def test_input_user_data_repack_names_to_ids_list(self):
- graph = build_graph(self.nodes, self.edges)
- input, freeze_placeholder = input_user_data_repack(graph, ['Aa', 'Bb'], None)
- self.assertDictEqual(input, {'A': [{'shape': None, 'port': None}], 'B': [{'shape': None, 'port': None}]})
- self.assertEqual(freeze_placeholder, None)
-
- def test_input_user_data_repack_names_ports_in_out(self):
- graph = build_graph(self.nodes, self.edges)
- input, freeze_placeholder = input_user_data_repack(graph, ['Aa:0', '1:Cc'], None)
- self.assertDictEqual(input, {'A': [{'shape': None, 'out': 0}], 'C': [{'shape': None, 'in': 1}]})
- self.assertEqual(freeze_placeholder, None)
-
- def test_input_user_data_repack_dict_with_shapes(self):
- graph = build_graph(self.nodes, self.edges)
- shape_1 = np.array([1, 160, 160, 3])
- shape_2 = np.array([1, 127, 127, 3])
- input, freeze_placeholder = input_user_data_repack(graph, {'Aa': shape_1, 'Bb': shape_2}, None)
- self.assertDictEqual(input, {'A': [{'shape': shape_1, 'port': None}], 'B': [{'shape': shape_2, 'port': None}]})
- self.assertEqual(freeze_placeholder, None)
-
- def test_input_user_data_repack_dict_with_shapes_and_ports(self):
- graph = build_graph(self.nodes, self.edges)
- shape_1 = np.array([1, 160, 160, 3])
- shape_2 = np.array([1, 127, 127, 3])
- input, freeze_placeholder = input_user_data_repack(graph, {'Aa:0': shape_1, 'Bb:0': shape_2}, None)
- self.assertDictEqual(input, {'A': [{'shape': shape_1, 'out': 0}], 'B': [{'shape': shape_2, 'out': 0}]})
- self.assertEqual(freeze_placeholder, None)
-
- def test_freeze_placeholder_and_input(self):
- graph = build_graph(self.nodes, self.edges)
- shape_1 = np.array([1, 160, 160, 3])
- input, freeze_placeholder = input_user_data_repack(graph, {'Aa:0': shape_1}, {'Bb': False})
- self.assertDictEqual(input, {'A': [{'shape': shape_1, 'out': 0}], 'B': [{'shape': None, 'port': None}]})
- self.assertEqual(freeze_placeholder, {'B': False})
-
- def test_error(self):
- graph = build_graph(self.nodes, self.edges)
- self.assertRaises(Error, input_user_data_repack, graph, PartialShape([1, 227, 227, 3]), None)
-
- def test_error_2(self):
- graph = build_graph(self.nodes, self.edges)
- self.assertRaises(Error, input_user_data_repack, graph, PartialShape([1, 227, 227, 3]), None)
-
- def test_error_3(self):
- graph = build_graph(self.nodes, self.edges)
- self.assertRaises(Error, input_user_data_repack, graph, ['Bcb'], None)
-
- def test_input_and_freeze(self):
- graph = build_graph(self.nodes, self.edges)
- shape_1 = PartialShape([1, 160, 160, 3])
- input, freeze_placeholder = input_user_data_repack(graph, shape_1, {'Bb': True})
- self.assertDictEqual(input, {'A': [{'shape': shape_1, 'port': None}], 'B': [{'shape': None, 'port': None}]})
- self.assertDictEqual(freeze_placeholder, {'B': True})
-
- def test_freeze_new_placeholder_1(self):
- # create a new placeholder Cc:0 by cutting output port with shape_2 = [5] and freeze a value [1.0 1.0 2.0 3.0 5.0]
- graph = build_graph(self.nodes, self.edges)
- shape_1 = np.array([1, 160, 160, 3])
- shape_2 = np.array([5])
- input, freeze_placeholder = input_user_data_repack(graph, {'Aa:0': shape_1, 'Cc:0' : shape_2}, {'Bb': False, 'Cc:0' : [1.0, 1.0, 2.0, 3.0, 5.0]})
- self.assertDictEqual(input, {'A' : [{'shape' : shape_1, 'out' : 0}], 'B' : [{'shape' : None, 'port' : None}], 'C' : [{'shape' : shape_2, 'out' : 0}]})
- self.assertEqual(freeze_placeholder, {'B' : False, 'C/placeholder_out_port_0' : [1.0, 1.0, 2.0, 3.0, 5.0]})
-
- def test_freeze_new_placeholder_2(self):
- # create a new placeholder Ee by cutting input port with shape_2 = [2, 2] and freeze a value [[1.0, 1.0], [2.0, 3.0]]
- graph = build_graph(self.nodes, self.edges)
- shape_1 = np.array([1, 160, 160, 3])
- shape_2 = np.array([2, 2])
- input, freeze_placeholder = input_user_data_repack(graph, {'Aa:0': shape_1, 'Ee' : shape_2}, {'Bb': False, 'Ee' : [[1.0, 1.0], [2.0, 3.0]]})
- self.assertDictEqual(input, {'A' : [{'shape' : shape_1, 'out' : 0}], 'B' : [{'shape' : None, 'port' : None}], 'E' : [{'shape' : shape_2, 'port' : None}]})
- self.assertEqual(freeze_placeholder, {'B' : False, 'E/placeholder_port_None' : [[1.0, 1.0], [2.0, 3.0]]})
-
- def test_freeze_new_placeholder_error(self):
- # shape is not specified for new placeholder Cc:0 with frozen value
- graph = build_graph(self.nodes, self.edges)
- shape_1 = np.array([1, 160, 160, 3])
- self.assertRaises(Error, input_user_data_repack, graph, {'Aa:0': shape_1}, {'Bb': False, 'Cc:0' : [1.0, 1.0, 2.0, 3.0, 5.0]})
-
- def test_output_user_data_repack(self):
- graph = build_graph(self.nodes, self.edges)
- output = output_user_data_repack(graph, ['Cc'])
- self.assertDictEqual(output, {'C': [{'port': None}]})
-
- def test_output_user_data_repack_ports(self):
- graph = build_graph(self.nodes, self.edges)
- output = output_user_data_repack(graph, ['Cc:1', '0:Cc'])
- self.assertDictEqual(output, {'C': [{'out': 1}, {'in': 0}]})
-
- def test_output_user_data_repack_none(self):
- graph = build_graph(self.nodes, self.edges)
- output = output_user_data_repack(graph, None)
- self.assertEqual(output, None)
-
-
-class TestExtractPort(unittest.TestCase):
- def setUp(self) -> None:
- nodes = {
- 'input_id': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter', 'name': '1input1:0'},
- 'conv_id': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder', 'name': '1input1'},
- 'relu_id': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder', 'name': 'relu'},
- 'squeeze_id': {'type': 'Squeeze', 'kind': 'op', 'op': 'NotPlaceholder', 'name': 'relu:0'},
- }
- edges = [
- ('input_id', 'conv_id'),
- ('conv_id', 'relu_id'),
- ('relu_id', 'squeeze_id'),
- ]
- self.graph = build_graph(nodes, edges)
-
- def test_out_port(self):
- node_id, direction, port = get_node_id_with_ports(self.graph, '1input1:0:0')
- self.assertEqual(node_id, 'input_id')
- self.assertEqual(direction, 'out')
- self.assertEqual(port, 0)
-
- def test_in_port1(self):
- node_id, direction, port = get_node_id_with_ports(self.graph, '0:1input1')
- self.assertEqual(node_id, 'conv_id')
- self.assertEqual(direction, 'in')
- self.assertEqual(port, 0)
-
- def test_in_port2(self):
- node_id, direction, port = get_node_id_with_ports(self.graph, '0:relu:0')
- self.assertEqual(node_id, 'squeeze_id')
- self.assertEqual(direction, 'in')
- self.assertEqual(port, 0)
-
- def test_no_port1(self):
- node_id, direction, port = get_node_id_with_ports(self.graph, '1input1')
- self.assertEqual(node_id, 'conv_id')
- self.assertEqual(direction, 'port')
- self.assertEqual(port, None)
-
- def test_no_port2(self):
- self.assertRaises(Error, get_node_id_with_ports, self.graph, '1input1:0')
-
- def test_non_int(self):
- self.assertRaises(Error, get_node_id_with_ports, self.graph, 'port:1input1')
-
- def test_two_ports(self):
- self.assertRaises(Error, get_node_id_with_ports, self.graph, '0:1input1:1')
-
- def test_name_looks_like_port_number(self):
- nodes = {
- 'input_id': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter', 'name': '0'},
- 'conv_id': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder', 'name': '1'},
- 'relu_id': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder', 'name': '2'},
- }
- edges = [
- ('input_id', 'conv_id'),
- ('conv_id', 'relu_id'),
- ]
- graph = build_graph(nodes, edges)
- node_id, direction, port = get_node_id_with_ports(graph, '0:2')
- self.assertEqual(node_id, 'relu_id')
- self.assertEqual(direction, 'in')
- self.assertEqual(port, 0)
-
-
-class TestCaffePythonFrontExtractorOp(unittest.TestCase):
- def test_get_attrs(self):
- exp_attrs = {"test_attr_1": 12, "test_attr_2": "sdf sdf"}
- param_str = "'test_attr_1': 12, 'test_attr_2': 'sdf sdf'"
- attrs = CaffePythonFrontExtractorOp.get_attrs(FakePythonParam(FakeMultiParam({'param_str': param_str})))
- self.assertEqual(exp_attrs, attrs)
-
-class TestBoolToSrtFunction(unittest.TestCase):
- def test_bool_to_str(self):
- graph = build_graph(nodes_attributes,
- [('input', 'pool_1'),
- ('pool_1', 'output'),
- ('output', 'op_output')
- ],
- {'pool_1': {'bool_attr': None}
- })
- pool_1_node = Node(graph, 'pool_1')
- attrs = [(True, 'true'), (False, 'false'), (1, 'true'), (0, 'false')]
- for attr in attrs:
- pool_1_node.bool_attr = attr[0]
- self.assertEqual(attr[1], bool_to_str(pool_1_node, 'bool_attr'))
diff --git a/tools/mo/unit_tests/mo/front/freeze_placeholder_value_test.py b/tools/mo/unit_tests/mo/front/freeze_placeholder_value_test.py
deleted file mode 100644
index 5ce767f55fceb8..00000000000000
--- a/tools/mo/unit_tests/mo/front/freeze_placeholder_value_test.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.freeze_placeholder_value import FreezePlaceholderValue
-from unit_tests.utils.graph import build_graph
-
-nodes_bool = {
- '0': {'name': 'input1', 'kind': 'op', 'op': 'Parameter', 'data_type': bool, 'shape': np.array([])},
- '1': {'name': 'input2', 'kind': 'op', 'op': 'Parameter', 'data_type': bool, 'shape': np.array([])},
- '2': {'name': 'node_1', 'kind': 'op', 'op': 'NotPlaceholder'},
- '3': {'name': 'node_2', 'kind': 'op', 'op': 'NotPlaceholder'},
- '4': {'name': 'node_3', 'kind': 'op', 'op': 'NotPlaceholder'},
- '5': {'name': 'node_4', 'kind': 'op', 'op': 'NotPlaceholder'},
- '6': {'name': 'output1', 'kind': 'op', 'op': 'Result', 'type': 'Result'},
- '7': {'name': 'output2', 'kind': 'op', 'op': 'Result', 'type': 'Result'}
-
-}
-edges = {
- ('0', '2'),
- ('2', '3'),
- ('4', '6'),
- ('1', '5'),
- ('5', '7')
-}
-
-
-class TestFreezePlaceholderValue(unittest.TestCase):
- def test_freeze_true(self):
- graph = build_graph(nodes_bool, edges)
- graph.graph['fw'] = 'tf'
- tested_class = FreezePlaceholderValue()
- graph.graph['freeze_placeholder'] = {'input1': 'True'}
- before_pattern = graph.nodes()
- tested_class.find_and_replace_pattern(graph=graph)
- after_pattern = graph.nodes()
- # number of nodes in the grpaph didn't change
- self.assertEqual(len(before_pattern), len(after_pattern))
- # reach new placeholder
- try:
- new_ph_dict = graph.node[[u for u, v in graph.in_edges('2')][0]]
- except Exception as e:
- self.fail("Can't get frozen placeholder. Broken edge. Additional information: {}".format(e))
- # check value
- self.assertEqual('value' in new_ph_dict, True)
- self.assertEqual(new_ph_dict['value'], True)
-
- def test_freeze_false(self):
- graph = build_graph(nodes_bool, edges)
- graph.graph['fw'] = 'tf'
- tested_class = FreezePlaceholderValue()
- graph.graph['freeze_placeholder'] = {'input1': 'False'}
- before_pattern = graph.nodes()
- tested_class.find_and_replace_pattern(graph=graph)
- after_pattern = graph.nodes()
- # number of nodes in the grpaph didn't change
- self.assertEqual(len(before_pattern), len(after_pattern))
- # reach new placeholder
- try:
- new_ph_dict = graph.node[[u for u, v in graph.in_edges('2')][0]]
- except Exception as e:
- self.fail("Can't get frozen placeholder. Broken edge. Additional information: {}".format(e))
- # check value
- self.assertEqual('value' in new_ph_dict, True)
- self.assertEqual(new_ph_dict['value'], False)
-
- def test_freeze_both(self):
- graph = build_graph(nodes_bool, edges)
- graph.graph['fw'] = 'tf'
- tested_class = FreezePlaceholderValue()
- graph.graph['freeze_placeholder'] = {'input1': 'False', 'input2': 'True'}
- before_pattern = graph.nodes()
- tested_class.find_and_replace_pattern(graph=graph)
- after_pattern = graph.nodes()
- # number of nodes in the graph didn't change
- self.assertEqual(len(before_pattern), len(after_pattern))
- # reach new placeholder
- try:
- new_ph_dict_1 = graph.node[[u for u, v in graph.in_edges('2')][0]]
- new_ph_dict_2 = graph.node[[u for u, v in graph.in_edges('5')][0]]
- except Exception as e:
- self.fail("Can't get frozen placeholder. Broken edge. Additional information: {}".format(e))
- # check value
- self.assertEqual('value' in new_ph_dict_1, True)
- self.assertEqual('value' in new_ph_dict_2, True)
- self.assertEqual(new_ph_dict_1['value'], False)
- self.assertEqual(new_ph_dict_2['value'], True)
diff --git a/tools/mo/unit_tests/mo/front/image_scaler_test.py b/tools/mo/unit_tests/mo/front/image_scaler_test.py
deleted file mode 100644
index f16c04175faa7d..00000000000000
--- a/tools/mo/unit_tests/mo/front/image_scaler_test.py
+++ /dev/null
@@ -1,283 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.image_scaler import ImageScaler
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.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},
- # ImageScaler operation
- 'im_scaler': {'type': None, 'kind': 'op', 'op': 'ImageScaler'},
- 'im_scaler_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Test operation
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None},
- 'last_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_1': {'type': None, 'value': None, 'kind': 'op', 'op': 'Mul'},
- 'const_mul_1_w': {'type': None, 'value': None, 'kind': 'op', 'op': 'Const'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'add_1': {'type': None, 'value': None, 'kind': 'op', 'op': 'Add'},
- 'const_add_1_w': {'type': None, 'value': None, 'kind': 'op', 'op': 'Const'},
- 'add_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'add_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-}
-
-
-class ImageScalerTest(unittest.TestCase):
- # Tests for MIDDLE stage
- # Graph with Mul and Add operations
- def test_image_scaler_test_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'im_scaler'),
- ('im_scaler', 'im_scaler_data'),
- ('im_scaler_data', 'last'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(2.0), 'bias': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = 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', 'last')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array(2.0).shape, 'value': np.array(2.0)},
- 'const_add_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'middle'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Graph with Add operation
- def test_image_scaler_test_2(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'im_scaler'),
- ('im_scaler', 'im_scaler_data'),
- ('im_scaler_data', 'last'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(1.0), 'bias': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- 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', 'last')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_add_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'middle'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Graph with Mul operation
- def test_image_scaler_test_3(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'im_scaler'),
- ('im_scaler', 'im_scaler_data'),
- ('im_scaler_data', 'last'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(2.0), 'bias': np.reshape(np.array([0, 0, 0]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = 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', 'last')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array(2.0).shape, 'value': np.array(2.0)},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'middle'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Graph without Mul and Add operations
- def test_image_scaler_test_4(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'im_scaler'),
- ('im_scaler', 'im_scaler_data'),
- ('im_scaler_data', 'last'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler_data': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(1.0), 'bias': np.reshape(np.array([0, 0, 0]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'last')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'middle'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Tests for FRONT stage
- # Graph with Mul and Add operations
- def test_image_scaler_test_5(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'im_scaler'),
- ('im_scaler', 'last'),
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(2.0), 'bias': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'mul_1'),
- ('const_mul_1_w', 'mul_1'),
- ('mul_1', 'add_1'),
- ('const_add_1_w', 'add_1'),
- ('add_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array(2.0).shape, 'value': np.array(2.0)},
- 'const_add_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Graph with Add operation
- def test_image_scaler_test_6(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'im_scaler'),
- ('im_scaler', 'last'),
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(1.0), 'bias': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'add_1'),
- ('const_add_1_w', 'add_1'),
- ('add_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'const_add_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.reshape(np.array([1, 2, 3]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Graph with Mul operation
- def test_image_scaler_test_7(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'im_scaler'),
- ('im_scaler', 'last'),
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(2.0), 'bias': np.reshape(np.array([0, 0, 0]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'mul_1'),
- ('const_mul_1_w', 'mul_1'),
- ('mul_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array(2.0).shape, 'value': np.array(2.0)},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
-
- # Graph without Mul and Add operations
- def test_image_scaler_test_8(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'im_scaler'),
- ('im_scaler', 'last'),
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'im_scaler': {'scale': np.array(1.0), 'bias': np.reshape(np.array([0, 0, 0]), [3, 1, 1])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- replacer = ImageScaler()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/instance_normalization_test.py b/tools/mo/unit_tests/mo/front/instance_normalization_test.py
deleted file mode 100644
index a631ad859a9016..00000000000000
--- a/tools/mo/unit_tests/mo/front/instance_normalization_test.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.instance_normalization import InstanceNormalization
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'input': {'kind': 'op', 'op': 'AnyOp'},
- 'scale': {'kind': 'op', 'op': 'AnyOp'},
- 'B': {'kind': 'op', 'op': 'AnyOp'},
- 'node': {'kind': 'op', 'op': 'InstanceNormalization', 'epsilon': None},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
-}
-
-nodes_ref_attributes = {
- 'input': {'kind': 'op', 'op': 'AnyOp'},
- 'scale': {'kind': 'op', 'op': 'AnyOp'},
- 'B': {'kind': 'op', 'op': 'AnyOp'},
- 'start': {'kind': 'op', 'op': 'Const'},
- 'step': {'kind': 'op', 'op': 'Const'},
- 'rank': {'kind': 'op', 'op': 'Rank'},
- 'mvn_axes': {'kind': 'op', 'op': 'Range'},
- 'mvn': {'kind': 'op', 'op': 'MVN', 'name': 'node/Ins_Norm/MVN_', 'eps': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'name': 'node/Ins_Norm/mul_'},
- 'add': {'kind': 'op', 'op': 'Add', 'name': 'node/Ins_Norm/add_'},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
-}
-
-
-class TestInstanceNormalization(unittest.TestCase):
- def test_instance_normalization_test_1(self):
- graph = build_graph(nodes_attributes,
- [('input', 'node'),
- ('scale', 'node'),
- ('B', 'node'),
- ('node', 'out')
- ],
- {'node': {'epsilon': 0.123},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'mvn', {'out': 0}),
- ('input', 'rank', {'out': 0}),
- ('start', 'mvn_axes'),
- ('rank', 'mvn_axes'),
- ('step', 'mvn_axes'),
- ('mvn_axes', 'mvn'),
- ('mvn', 'mul'),
- ('scale', 'mul'),
- ('mul', 'add'),
- ('B', 'add'),
- ('add', 'out')
- ],
- {'mvn': {'eps': 0.123, 'eps_mode': 'inside_sqrt', 'normalize_variance': 1},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- tested_class = InstanceNormalization()
- tested_class.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=False)
- self.assertTrue(flag, resp)
-
- def test_instance_normalization_test_2(self):
- graph = build_graph(nodes_attributes,
- [('input', 'out', {'out': 0, 'in': 0}),
- ('input', 'node', {'out': 1}),
- ('scale', 'node'),
- ('B', 'node'),
- ('node', 'out', {'in': 1})
- ],
- {'node': {'epsilon': 0.123},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'out', {'out': 0, 'in': 0}),
- ('input', 'mvn', {'out': 1}),
- ('input', 'rank', {'out': 1}),
- ('start', 'mvn_axes'),
- ('rank', 'mvn_axes'),
- ('step', 'mvn_axes'),
- ('mvn_axes', 'mvn'),
- ('mvn', 'mul'),
- ('scale', 'mul'),
- ('mul', 'add'),
- ('B', 'add'),
- ('add', 'out', {'in': 1})
- ],
- {'mvn': {'eps': 0.123, 'eps_mode': 'inside_sqrt', 'normalize_variance': 1},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- tested_class = InstanceNormalization()
- tested_class.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=False)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/interpolate_reshape_test.py b/tools/mo/unit_tests/mo/front/interpolate_reshape_test.py
deleted file mode 100644
index 1da581459662dc..00000000000000
--- a/tools/mo/unit_tests/mo/front/interpolate_reshape_test.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.front.interpolate_reshape import InterpolateWithConcat
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect, \
- connect_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 3, 30, 40], {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('out_shape', np.array([60, 160])),
-
- **regular_op_with_shaped_data('interpolate', [1, 3, 60, 160],
- {'type': 'Interpolate', 'axes': int64_array([2, 3]), 'op': 'Interpolate',
- 'version': 'opset1'}),
- **regular_op_with_shaped_data('identity_00', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
- **regular_op_with_shaped_data('identity_01', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
-
- **regular_op_with_shaped_data('shape', [4], {'type': 'ShapeOf', 'op': 'ShapeOf'}),
- **valued_const_with_data('indices', np.array([2, 3])),
- **valued_const_with_data('axis', np.array(0)),
- **regular_op_with_shaped_data('gather', [2], {'type': 'Gather', 'op': 'Gather'}),
-
- **regular_op_with_shaped_data('placeholder_1', [1, 3, 60, 160], {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('identity_10', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
- **regular_op_with_shaped_data('identity_11', [1, 3, 60, 160], {'identity': True, 'op': 'Identity'}),
- **regular_op_with_shaped_data('concat', [1, 7, 60, 160], {'type': 'Concat', 'axis': 1, 'op': 'Concat'}),
-
- **valued_const_with_data('N', np.array([1])),
-
- **result('output'),
- **result('output_1'),
-}
-
-
-class TestInterpolateConcat():
- def test_interpolate_concat_reshape_graph_comparison(self):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect('placeholder_1', '1:concat'),
- *connect('concat', 'output'),
- ], nodes_with_edges_only=True)
-
- InterpolateWithConcat().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('placeholder_1', 'shape'),
- *connect('shape', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect_data('placeholder_1', '1:concat'),
- *connect('concat', 'output'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- def test_interpolate_identity_concat_reshape_graph_comparison(self):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', 'identity_00'),
- *connect('identity_00', 'identity_01'),
- *connect('identity_01', '0:concat'),
- *connect('placeholder_1', 'identity_10'),
- *connect('identity_10', 'identity_11'),
- *connect('identity_11', '1:concat'),
- *connect('concat', 'output'),
- ], nodes_with_edges_only=True)
-
- InterpolateWithConcat().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect_data('identity_11', 'shape'),
- *connect('shape', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', '1:interpolate'),
- *connect('interpolate', 'identity_00'),
- *connect('identity_00', 'identity_01'),
- *connect('identity_01', '0:concat'),
- *connect('placeholder_1', 'identity_10'),
- *connect('identity_10', 'identity_11'),
- *connect('identity_11', '1:concat'),
- *connect('concat', 'output'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- def test_interpolate_concat_negate(self):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', 'identity_00'),
- *connect('interpolate', 'identity_01'),
- *connect('identity_00', 'output'),
- *connect('identity_01', 'output_1'),
- ], nodes_with_edges_only=True)
-
- InterpolateWithConcat().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', 'identity_00'),
- *connect('interpolate', 'identity_01'),
- *connect('identity_00', 'output'),
- *connect('identity_01', 'output_1'),
- ], nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- @pytest.mark.parametrize("update_attrs",[
- {'concat': {'axis': None}},
-
- {'concat': {'axis': -1}},
- {'interpolate': {'axes': None}},
- {'interpolate': {'axes': np.array([1])}},
- {'interpolate': {'axes': np.array([2, -1])}},
- ])
- def test_negative_axes_conditions(self, update_attrs):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect('placeholder_1', '1:concat'),
- *connect('concat', 'output'),
- ], update_attributes=update_attrs, nodes_with_edges_only=True)
- InterpolateWithConcat().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect('placeholder_1', '1:concat'),
- *connect('concat', 'output'),
- ], update_attributes=update_attrs, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
-
- def test_interpolate_tf_style_concat(self):
- graph = build_graph(nodes, [
- *connect('placeholder', '0:interpolate'),
- *connect('out_shape', '1:interpolate'),
- *connect('interpolate', '0:concat'),
- *connect('N', '1:concat'),
- *connect('concat', 'output'),
- ], update_attributes={'concat': {'N': 1}}, nodes_with_edges_only=True)
- graph_ref = graph.copy()
- InterpolateWithConcat().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/front/kaldi/__init__.py b/tools/mo/unit_tests/mo/front/kaldi/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/kaldi/add_reshape_transpose_around_conv_pool_test.py b/tools/mo/unit_tests/mo/front/kaldi/add_reshape_transpose_around_conv_pool_test.py
deleted file mode 100644
index c63957f3529b5e..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/add_reshape_transpose_around_conv_pool_test.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.kaldi.add_reshape_transpose_around_conv_pool import AddReshapeTransposeAroundConvPool
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, connect_front, const, regular_op, shaped_parameter
-
-
-class AddReshapeTransposeAroundConvPoolTests(unittest.TestCase):
- nodes = {
- **shaped_parameter('input', [1, 33]),
- **regular_op('some_op', {'op': 'some_op'}),
- **regular_op('splice', {'op': 'Splice', 'context': [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]}),
- **regular_op('conv', {'kind': 'op', 'op': 'Convolution', 'kernel': [1, 11, 1, 5], 'patch_stride': 5,
- 'kernel_spatial': [1, 5]}),
- **regular_op('pool', {'kind': 'op', 'op': 'Pooling', 'pool_stride': 5, 'pool_step': [1, 1, 1, 1]}),
- **regular_op('out_op', {'op': "SomeOp"}),
- }
-
- ref_nodes = {
- **shaped_parameter('input', [1, 33]),
- **regular_op('some_op', {}),
- **regular_op('splice', {'op': 'Splice', 'context': [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]}),
-
- **regular_op('shapeof', {'op': 'ShapeOf', 'type': 'ShapeOf'}),
- **const('ind', int64_array([0])),
- **const('axis', int64_array(0)),
- **regular_op('gather_batch', {'op': 'Gather', 'type': 'Gather'}),
- **const('t', int64_array([11])),
- **const('h', int64_array([5])),
- **const('ind_h', int64_array([1])),
- **regular_op('gather_h', {'op': "Gather", 'type': 'Gather'}),
- **const('th', int64_array([55])),
- **regular_op('div', {'op': 'Div', 'type': 'Divide'}),
- **regular_op('concat', {'op': 'Concat', 'type': 'Concat'}),
-
- **regular_op('reshape_in', {'op': 'Reshape', 'type': 'Reshape'}),
- **const('transpose_in_order', int64_array([0, 3, 1, 2])),
- **regular_op('transpose_in', {'op': 'Transpose', 'type': 'Transpose'}),
- **regular_op('conv', {'kind': 'op', 'op': 'Convolution', 'kernel': [1, 1, 11, 5]}),
- **regular_op('pool', {'kind': 'op', 'op': 'Pooling', 'pool_stride': 5, 'pool_step': [1, 1, 1, 1]}),
- **const('transpose_out_order', int64_array([0, 2, 3, 1])),
- **regular_op('transpose_out', {'op': 'Transpose', 'type': 'Transpose'}),
- **const('reshape_out_shape', int64_array([0, -1])),
- **regular_op('reshape_out', {'op': 'Reshape', 'type': 'Reshape'}),
- **regular_op('out_op', {'op': "SomeOp"})
- }
-
- def test_simple_convolution(self):
- graph = build_graph(self.nodes, [
- *connect_front('input', 'splice'),
- *connect_front('splice', 'conv'),
- *connect_front('conv', 'out_op')
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- AddReshapeTransposeAroundConvPool.find_and_replace_pattern(graph)
-
- ref_graph = build_graph(self.ref_nodes,
- [
- *connect_front('input', 'splice'),
- *connect_front('splice', '0:reshape_in'),
-
- *connect_front('splice', 'shapeof'),
- *connect_front('shapeof:0', '0:gather_batch'),
- *connect_front('ind', '1:gather_batch'),
- *connect_front('axis', '2:gather_batch'),
- *connect_front('shapeof:0', '0:gather_h'),
- *connect_front('ind_h', '1:gather_h'),
- *connect_front('axis', '2:gather_h'),
- *connect_front('gather_h', '0:div'),
- *connect_front('th', '1:div'),
- *connect_front('gather_batch', '0:concat'),
- *connect_front('t', '1:concat'),
- *connect_front('h', '2:concat'),
- *connect_front('div', '3:concat'),
- *connect_front('concat', '1:reshape_in'),
-
- *connect_front('reshape_in', '0:transpose_in'),
- *connect_front('transpose_in_order', "1:transpose_in"),
- *connect_front('transpose_in', 'conv'),
- *connect_front('conv', '0:transpose_out'),
- *connect_front('transpose_out_order', '1:transpose_out'),
- *connect_front('transpose_out', '0:reshape_out'),
- *connect_front('reshape_out_shape', '1:reshape_out'),
- *connect_front('reshape_out', 'out_op')
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_op', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_simple_convolution_wo_splice(self):
- graph = build_graph(self.nodes, [
- *connect_front('input', 'conv'),
- *connect_front('input', 'some_op'),
- *connect_front('conv', 'out_op')
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- AddReshapeTransposeAroundConvPool.find_and_replace_pattern(graph)
-
- ref_graph = build_graph(self.ref_nodes,
- [
- *connect_front('input', '0:reshape_in'),
- *connect_front('input', 'some_op'),
- *connect_front('input', 'shapeof'),
- *connect_front('shapeof:0', '0:gather_batch'),
- *connect_front('ind', '1:gather_batch'),
- *connect_front('axis', '2:gather_batch'),
- *connect_front('shapeof:0', '0:gather_h'),
- *connect_front('ind_h', '1:gather_h'),
- *connect_front('axis', '2:gather_h'),
- *connect_front('gather_h', '0:div'),
- *connect_front('th', '1:div'),
- *connect_front('gather_batch', '0:concat'),
- *connect_front('t', '1:concat'),
- *connect_front('h', '2:concat'),
- *connect_front('div', '3:concat'),
- *connect_front('concat', '1:reshape_in'),
-
- *connect_front('reshape_in', '0:transpose_in'),
- *connect_front('transpose_in_order', "1:transpose_in"),
- *connect_front('transpose_in', 'conv'),
- *connect_front('conv', '0:transpose_out'),
- *connect_front('transpose_out_order', '1:transpose_out'),
- *connect_front('transpose_out', '0:reshape_out'),
- *connect_front('reshape_out_shape', '1:reshape_out'),
- *connect_front('reshape_out', 'out_op')
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_op', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_simple_pooling(self):
- graph = build_graph(self.nodes, [
- *connect_front('input', 'splice'),
- *connect_front('splice', 'pool'),
- *connect_front('pool', 'out_op')
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- AddReshapeTransposeAroundConvPool.find_and_replace_pattern(graph)
-
- ref_graph = build_graph(self.ref_nodes,
- [
- *connect_front('input', 'splice'),
- *connect_front('splice', '0:reshape_in'),
-
- *connect_front('splice', 'shapeof'),
- *connect_front('shapeof:0', '0:gather_batch'),
- *connect_front('ind', '1:gather_batch'),
- *connect_front('axis', '2:gather_batch'),
- *connect_front('shapeof:0', '0:gather_h'),
- *connect_front('ind_h', '1:gather_h'),
- *connect_front('axis', '2:gather_h'),
- *connect_front('gather_h', '0:div'),
- *connect_front('th', '1:div'),
- *connect_front('gather_batch', '0:concat'),
- *connect_front('t', '1:concat'),
- *connect_front('h', '3:concat'),
- *connect_front('div', '2:concat'),
- *connect_front('concat', '1:reshape_in'),
-
- *connect_front('reshape_in', '0:transpose_in'),
- *connect_front('transpose_in_order', "1:transpose_in"),
- *connect_front('transpose_in', 'pool'),
- *connect_front('pool', '0:transpose_out'),
- *connect_front('transpose_out_order', '1:transpose_out'),
- *connect_front('transpose_out', '0:reshape_out'),
- *connect_front('reshape_out_shape', '1:reshape_out'),
- *connect_front('reshape_out', 'out_op')
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_op', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/apply_counts_test.py b/tools/mo/unit_tests/mo/front/kaldi/apply_counts_test.py
deleted file mode 100644
index c0c685e867fe5d..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/apply_counts_test.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.apply_counts import apply_biases_to_last_layer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class TestKaldiPipeline(unittest.TestCase):
- def test_apply_biases_to_ScaleShift(self):
- counts = -0.5 * np.ones(10)
- nodes = {'input': {'kind': 'op', 'op': None},
- 'weights': {'kind': 'op', 'op': 'Const'},
- 'biases': {'kind': 'op', 'op': 'Const', 'value': None, 'shape': None, 'data_type': None},
- 'sc': {'op': 'ScaleShift', 'kind': 'op'},
- 'sub': {'op': 'Add', 'kind': 'op'},
- "const": {'op': 'Const', 'value': -counts, 'kind': 'op'},
- 'op_output': {'op': 'Result', 'kind': 'op'}
- }
- graph = build_graph(nodes,
- [
- ('input', 'sc', {'in': 0}),
- ('weights', 'sc', {'in': 1}),
- ('biases', 'sc', {'in': 2}),
- ('sc', 'op_output')
- ], nodes_with_edges_only=True)
-
- graph.stage = "front"
- ref_graph = build_graph(nodes,
- [
- ('input', 'sc', {'in': 0}),
- ('weights', 'sc', {'in': 1}),
- ('biases', 'sc', {'in': 2}),
- ('sc', 'sub', {'in': 0}),
- ('const', 'sub', {'in': 1}),
- ('sub', 'op_output')
- ], nodes_with_edges_only=True)
-
- apply_biases_to_last_layer(graph, counts)
- compare_graphs(graph, ref_graph, 'op_output', check_op_attrs=True)
-
- def test_apply_biases_to_graph_with_SoftMax(self):
- counts = -0.5 * np.ones(10)
- nodes = {'input': {'kind': 'op', 'op': None},
- 'weights': {'kind': 'op', 'op': 'Const'},
- 'biases': {'kind': 'op', 'op': 'Const', 'value': None, 'shape': None, 'data_type': None},
- 'fc': {'op': 'FullyConnected', 'kind': 'op'},
- 'softmax': {'op': 'SoftMax', 'kind': 'op'},
- 'op_output': {'op': 'Result', 'kind': 'op'},
- 'sub': {'op': 'Add', 'kind': 'op'},
- "const": {'op': 'Const', 'value': -counts, 'kind': 'op'},
- }
- graph = build_graph(nodes,
- [
- ('input', 'fc', {'in': 0}),
- ('weights', 'fc', {'in': 1}),
- ('biases', 'fc', {'in': 2}),
- ('fc', 'softmax'),
- ('softmax','op_output')
- ], nodes_with_edges_only=True)
- ref_graph = build_graph(nodes,
- [
- ('input', 'fc', {'in': 0}),
- ('weights', 'fc', {'in': 1}),
- ('biases', 'fc', {'in': 2}),
- ('fc', 'sub', {'in': 0}),
- ('const', 'sub', {'in': 1}),
- ('sub', 'op_output')
- ], nodes_with_edges_only=True)
-
- graph.stage = "front"
- apply_biases_to_last_layer(graph, counts)
- compare_graphs(graph, ref_graph, 'op_output', check_op_attrs=True)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/__init__.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/add_shift_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/add_shift_ext_test.py
deleted file mode 100644
index f497412ff932d9..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/add_shift_ext_test.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.extractors.add_shift_ext import AddShiftFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class AddShiftFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['ScaleShift'] = ScaleShiftOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- input_shape = cls.test_node.in_node().shape
- pb = cls.write_tag_with_value('', 0)
- pb += cls.write_tag_with_value('FV', input_shape[1])
- for i in np.zeros(input_shape[1], dtype=np.uint32):
- pb += TestKaldiUtilsLoading.pack_value(i, TestKaldiUtilsLoading.uint32_fmt)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- AddShiftFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, AddShiftFrontExtractor.extract, None)
-
- def test_extracted_shapes_add_shift(self):
- weights = self.test_node.weights
- biases = self.test_node.biases
- weights_shape = weights.shape[0]
- self.assertEqual(self.test_node.in_node().shape[1], weights_shape)
- self.assertEqual(biases.shape[0], weights_shape)
-
- def test_extracted_blobs_add_shift(self):
- weights = self.test_node.weights
- biases = self.test_node.biases
- self.assertTrue(np.array_equal(weights, np.ones(weights.shape)))
- self.assertTrue(np.array_equal(biases, np.zeros(biases.shape)))
- self.assertTrue(self.test_node.bias_term)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/affine_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/affine_component_ext_test.py
deleted file mode 100644
index 36ac52b2e9c7f5..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/affine_component_ext_test.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.MatMul import FullyConnected
-from openvino.tools.mo.front.kaldi.extractors.affine_transform_ext import AffineTransformFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class AffineComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['FullyConnected'] = FullyConnected
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.generate_learn_info()
- pb += KaldiFrontExtractorTest.generate_matrix([10, 10])
- pb += KaldiFrontExtractorTest.generate_vector(10)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- AffineTransformFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, AffineTransformFrontExtractor.extract, None)
-
- def test_attrs(self):
- self.assertEqual(self.test_node['out-size'], 10)
-
- def test_out_blobs(self):
- self.assertTrue(np.array_equal(self.test_node.weights, range(10 * 10)))
- self.assertTrue(np.array_equal(self.test_node.biases, range(10)))
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/affine_transform_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/affine_transform_ext_test.py
deleted file mode 100644
index a9ddefa16e0a7c..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/affine_transform_ext_test.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.MatMul import FullyConnected
-from openvino.tools.mo.front.kaldi.extractors.affine_transform_ext import AffineTransformFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class AffineTransformFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['FullyConnected'] = FullyConnected
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.generate_learn_info()
- pb += KaldiFrontExtractorTest.generate_matrix([10, 10])
- pb += KaldiFrontExtractorTest.generate_vector(10)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- AffineTransformFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, AffineTransformFrontExtractor.extract, None)
-
- def test_attrs(self):
- self.assertEqual(self.test_node['out-size'], 10)
-
- def test_out_blobs(self):
- self.assertTrue(np.array_equal(self.test_node.weights, range(10 * 10)))
- self.assertTrue(np.array_equal(self.test_node.biases, range(10)))
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/batchnorm_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/batchnorm_component_ext_test.py
deleted file mode 100644
index 315afcad90a234..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/batchnorm_component_ext_test.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.extractors.batchnorm_component_ext import BatchNormComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class BatchNormComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['ScaleShift'] = ScaleShiftOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.write_tag_with_value('', 16)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 16)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 0.00001, np.float32)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 0.5, np.float32)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 'F', np.string_)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 16)
- pb += b' '
- pb += KaldiFrontExtractorTest.generate_vector(16)
- pb += b' '
- pb += KaldiFrontExtractorTest.generate_vector(16)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
-
- def test_extract(self):
- BatchNormComponentFrontExtractor.extract(self.test_node)
- self.assertEqual(len(self.test_node['embedded_inputs']), 2)
- ref_weights = list([1.5811389e+02, 4.9999750e-01, 3.5355249e-01, 2.8867465e-01, 2.4999970e-01,
- 2.2360659e-01, 2.0412397e-01, 1.8898210e-01, 1.7677659e-01, 1.6666657e-01,
- 1.5811381e-01, 1.5075560e-01, 1.4433751e-01, 1.3867499e-01, 1.3363057e-01, 1.2909940e-01])
- ref_biases = list([-0., -0.4999975, -0.707105, -0.86602396, -0.9999988, -1.1180329,
- -1.2247438, -1.3228748, -1.4142127, -1.4999992, -1.5811381, -1.6583116,
- -1.7320502, -1.8027749, -1.870828, -1.936491])
- self.assertEqual(np.allclose(self.test_node['weights'], ref_weights), True)
- self.assertEqual(np.allclose(self.test_node['biases'], ref_biases), True)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/bias_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/bias_component_ext_test.py
deleted file mode 100644
index b316f40805c0ee..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/bias_component_ext_test.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.extractors.bias_component_ext import FixedBiasComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class FixedBiasComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['ScaleShift'] = ScaleShiftOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- cls.input_shape = 10
-
- pb = b' '
- pb += KaldiFrontExtractorTest.generate_vector(cls.input_shape)
- pb += b' '
-
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- FixedBiasComponentFrontExtractor.extract(cls.test_node)
-
- def test_fixedbias_extractor(self):
- input_shape = FixedBiasComponentFrontExtractorTest.input_shape
-
- exp_res = {
- 'op': 'ScaleShift',
- 'layout': 'NCHW',
- 'bias_term': True,
- 'out-size': input_shape,
- 'biases': np.arange(input_shape)
- }
-
- self.compare_node_attrs(exp_res)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/common_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/common_ext_test.py
deleted file mode 100644
index 08980e1b2ba2c6..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/common_ext_test.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import build_graph
-
-
-class KaldiFrontExtractorTest(UnitTestWithMockedTelemetry):
- graph = Graph()
- nodes_attributes = {}
- test_node = None
-
- @classmethod
- def setUp(cls):
- super().setUp(cls)
- cls.nodes_attributes = {
- 'input_data_node': {
- 'name': 'input_data_node',
- 'kind': 'data',
- 'shape': np.array([1, 32, 1, 40], dtype=np.int64),
- },
- 'weights': {
- 'name': 'weights',
- 'kind': 'data',
- 'shape': np.array([10, 32, 1, 8], dtype=np.int64),
- 'value': np.zeros((10, 32, 1, 8)),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis'],
- },
- 'test_node': {
- 'name': 'test_node',
- 'kind': 'op'
- },
- 'output_data_node': {
- 'name': 'output_data_node',
- 'kind': 'data',
- 'shape': None
- }
- }
- cls.create_graph()
- cls.test_node = Node(cls.graph, 'test_node')
- cls.graph.add_node(cls.test_node.id, type='test_node')
- cls.register_op()
- cls.create_pb_for_test_node()
-
- @staticmethod
- def register_op():
- raise NotImplementedError('Please, implement register_op')
-
- @classmethod
- def create_graph(cls):
- cls.graph = build_graph(cls.nodes_attributes, [
- ('input_data_node', 'test_node'),
- ('test_node', 'output_data_node')
- ], nodes_with_edges_only=True)
-
- @classmethod
- def create_pb_for_test_node(cls):
- pass
-
- @staticmethod
- def generate_learn_info():
- pb = KaldiFrontExtractorTest.write_tag_with_value('', 0)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 1)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 2)
- return pb
-
- @staticmethod
- def generate_matrix(shape):
- pb = KaldiFrontExtractorTest.write_tag_with_value('FM', shape[0])
- pb += KaldiFrontExtractorTest.write_int_value(shape[1])
- pb += KaldiFrontExtractorTest.generate_blob(np.prod(shape))
- return pb
-
- @staticmethod
- def generate_vector(size: int) -> bytes:
- pb = KaldiFrontExtractorTest.write_tag_with_value('FV', size)
- pb += KaldiFrontExtractorTest.generate_blob(size)
- return pb
-
- @staticmethod
- def generate_blob(size: int) -> bytes:
- pb = b''
- for i in range(size):
- pb += TestKaldiUtilsLoading.pack_value(i, TestKaldiUtilsLoading.float32_fmt)
- return pb
-
- @staticmethod
- def write_tag_with_value(tag: str, value, value_type=np.int32) -> bytes:
- pb = bytes(tag + ' ', 'ascii')
- if value_type == np.int32:
- return pb + KaldiFrontExtractorTest.write_int_value(value)
- elif value_type == np.float32:
- return pb + KaldiFrontExtractorTest.write_float_value(value)
- else:
- return pb + KaldiFrontExtractorTest.write_str_value(value)
-
- @staticmethod
- def write_int_value(value) -> bytes:
- pb = TestKaldiUtilsLoading.pack_value(4, 'B')
- pb += TestKaldiUtilsLoading.pack_value(value, TestKaldiUtilsLoading.uint32_fmt)
- return pb
-
- @staticmethod
- def write_float_value(value) -> bytes:
- pb = TestKaldiUtilsLoading.pack_value(4, 'B')
- pb += TestKaldiUtilsLoading.pack_value(value, TestKaldiUtilsLoading.float32_fmt)
- return pb
-
- @staticmethod
- def write_str_value(value) -> bytes:
- pb = bytes(value, 'ascii')
- return pb
-
- def compare_node_attrs(self, exp_res):
- node = self.test_node
- for key in exp_res.keys():
- if type(node[key]) in [list, np.ndarray]:
- self.assertTrue(np.array_equal(np.array(node[key]), np.array(exp_res[key])))
- else:
- self.assertEqual(node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/concat_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/concat_ext_test.py
deleted file mode 100644
index eab18f66a83c57..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/concat_ext_test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.kaldi.extractors.concat_ext import ConcatFrontExtractor
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-
-
-class ConcatFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['Concat'] = Convolution
-
- def test_concat(self):
- ConcatFrontExtractor.extract(self.test_node)
- self.assertEqual(self.test_node.axis, 1)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/convolutional_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/convolutional_component_ext_test.py
deleted file mode 100644
index 19100e860d47a8..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/convolutional_component_ext_test.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.extractors.convolutional_component_ext import ConvolutionalComponentFrontExtractor
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class ConvolutionalComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['Convolution'] = Convolution
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.write_tag_with_value('', 2)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 2)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 4)
- pb += KaldiFrontExtractorTest.generate_learn_info()
- pb += b' '
- pb += KaldiFrontExtractorTest.generate_matrix([2, 4])
- pb += b' '
- pb += KaldiFrontExtractorTest.generate_vector(2)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- ConvolutionalComponentFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, ConvolutionalComponentFrontExtractor.extract, None)
-
- def test_attrs(self):
- val_attrs = {
- 'kernel': [2, 2, 1, 2],
- 'stride': [1, 1, 1, 2],
- 'pad': [[[0, 0], [0, 0], [0, 0], [0, 0]]],
- 'output': 2,
- 'patch_stride': 4,
- 'spatial_dims': [2, 3],
- 'channel_dims': [1],
- 'batch_dims': [0],
- 'dilation': [1, 1, 1, 1]
- }
- for attr in val_attrs:
- if isinstance(val_attrs[attr], list):
- self.assertTrue((self.test_node[attr] == val_attrs[attr]).all())
- else:
- self.assertEqual(self.test_node[attr], val_attrs[attr])
-
- def test_convolution_blobs(self):
- self.assertTrue(np.array_equal(self.test_node.weights, [0, 1, 2, 3, 4, 5, 6, 7]))
- self.assertTrue(np.array_equal(self.test_node.biases, [0, 1]))
-
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/fixed_affine_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/fixed_affine_component_ext_test.py
deleted file mode 100644
index 344fb9c75278d2..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/fixed_affine_component_ext_test.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.MatMul import FullyConnected
-from openvino.tools.mo.front.kaldi.extractors.fixed_affine_component_ext import FixedAffineComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class FixedAffineComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['FullyConnected'] = FullyConnected
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = b' ' + KaldiFrontExtractorTest.generate_matrix([10, 10])
- pb += b' ' + KaldiFrontExtractorTest.generate_vector(10)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- FixedAffineComponentFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, FixedAffineComponentFrontExtractor.extract, None)
-
- def test_attrs(self):
- self.assertEqual(self.test_node['out-size'], 10)
-
- def test_out_blobs(self):
- self.assertTrue(np.array_equal(self.test_node.weights, range(10 * 10)))
- self.assertTrue(np.array_equal(self.test_node.biases, range(10)))
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/max_pooling_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/max_pooling_ext_test.py
deleted file mode 100644
index 4a3906e9019e7b..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/max_pooling_ext_test.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.kaldi.extractors.max_pooling_ext import MaxPoolingComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.pooling import Pooling
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class MaxPoolingComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['Pooling'] = Pooling
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.write_tag_with_value('', 2)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 2)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 4)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- MaxPoolingComponentFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, MaxPoolingComponentFrontExtractor.extract, None)
-
- def test_attrs(self):
- val_attrs = {
- 'window': [1, 1, 1, 2],
- 'stride': [1, 1, 1, 2],
- 'pool_stride': 4,
- 'pad': [[[0, 0], [0, 0], [0, 0], [0, 0]]]
- }
- for attr in val_attrs:
- if isinstance(val_attrs[attr], list):
- self.assertTrue((self.test_node[attr] == val_attrs[attr]).all())
- else:
- self.assertEqual(self.test_node[attr], val_attrs[attr])
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/memoryoffset_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/memoryoffset_ext_test.py
deleted file mode 100644
index ed0af3882223cf..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/memoryoffset_ext_test.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.kaldi.extractors.memoryoffset_ext import MemoryOffsetFrontExtractor
-from openvino.tools.mo.ops.memoryoffset import MemoryOffset
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-
-
-class MemoryOffsetFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['memoryoffset'] = MemoryOffset
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = {'pair_name': 'my_pair',
- 't': -5,
- 'has_default': False
- }
- cls.test_node['parameters'] = pb
-
- def test_extract(self):
- MemoryOffsetFrontExtractor.extract(self.test_node)
- self.assertEqual(self.test_node['pair_name'], 'my_pair')
- self.assertEqual(self.test_node['t'], -5)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/normalize_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/normalize_component_ext_test.py
deleted file mode 100644
index 7c5dbc17a8d7cc..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/normalize_component_ext_test.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.normalize import NormalizeOp
-from openvino.tools.mo.front.kaldi.extractors.normalize_component_ext import NormalizeComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class NormalizeComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['Normalize'] = NormalizeOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.write_tag_with_value('', 16)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 0.5, np.float32)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 'F', np.string_)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
-
- def test_extract(self):
- NormalizeComponentFrontExtractor.extract(self.test_node)
- self.assertEqual(len(self.test_node['embedded_inputs']), 1)
- self.assertListEqual(list(self.test_node['weights']), [2.0])
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/pnorm_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/pnorm_component_ext_test.py
deleted file mode 100644
index d3eff6c561b84f..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/pnorm_component_ext_test.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.pnorm import PNormOp
-from openvino.tools.mo.front.kaldi.extractors.pnorm_component_ext import PNormComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class PNormComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['pnorm'] = PNormOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- pb = KaldiFrontExtractorTest.write_tag_with_value('', 3500)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 350)
- pb += KaldiFrontExtractorTest.write_tag_with_value('', 2, np.float32)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
-
- def test_extract(self):
- PNormComponentFrontExtractor.extract(self.test_node)
- self.assertEqual(self.test_node['p'], 2)
- self.assertEqual(self.test_node['group'], 10)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/rescale_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/rescale_ext_test.py
deleted file mode 100644
index 2fa2c89d5d0069..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/rescale_ext_test.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.extractors.rescale_ext import RescaleFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class RescaleFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['ScaleShift'] = ScaleShiftOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- input_shape = cls.test_node.in_node().shape
- pb = cls.write_tag_with_value('', 0)
- pb += cls.write_tag_with_value('FV', input_shape[1])
- for i in range(input_shape[1]):
- pb += TestKaldiUtilsLoading.pack_value(i, TestKaldiUtilsLoading.float32_fmt)
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- RescaleFrontExtractor.extract(cls.test_node)
-
- def test_assertion(self):
- self.assertRaises(AttributeError, RescaleFrontExtractor.extract, None)
-
- def test_extracted_shapes_add_shift(self):
- weights = self.test_node.weights
- weights_shape = weights.shape[0]
- self.assertEqual(self.test_node.in_node().shape[1], weights_shape)
-
- def test_extracted_blobs_add_shift(self):
- weights = self.test_node.weights
- self.assertTrue(np.array_equal(weights, range(self.test_node.in_node().shape[1])))
diff --git a/tools/mo/unit_tests/mo/front/kaldi/extractors/scale_component_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/extractors/scale_component_ext_test.py
deleted file mode 100644
index 989e79cfbd102b..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/extractors/scale_component_ext_test.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.extractors.scale_component_ext import FixedScaleComponentFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.scale_shift import ScaleShiftOp
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from unit_tests.mo.front.kaldi.loader.utils_test import TestKaldiUtilsLoading
-
-
-class FixedScaleComponentFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['ScaleShift'] = ScaleShiftOp
-
- @classmethod
- def create_pb_for_test_node(cls):
- cls.input_shape = 10
-
- pb = b' '
- pb += KaldiFrontExtractorTest.generate_vector(cls.input_shape)
- pb += b' '
-
- cls.test_node['parameters'] = TestKaldiUtilsLoading.bytesio_from(pb)
- FixedScaleComponentFrontExtractor.extract(cls.test_node)
-
- def test_fixedscale_extractor(self):
- input_shape = FixedScaleComponentFrontExtractorTest.input_shape
-
- exp_res = {
- 'op': 'ScaleShift',
- 'layout': 'NCHW',
- 'out-size': input_shape,
- 'weights': np.arange(input_shape)
- }
-
- self.compare_node_attrs(exp_res)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/loader/__init__.py b/tools/mo/unit_tests/mo/front/kaldi/loader/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/kaldi/loader/loader_test.py b/tools/mo/unit_tests/mo/front/kaldi/loader/loader_test.py
deleted file mode 100644
index ab2f1158faf9a0..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/loader/loader_test.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import io
-import struct
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.loader.loader import load_topology_map, load_components
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class TestKaldiModelsLoading(unittest.TestCase):
-
- def test_component_map_loading_sequence(self):
- test_map = "input-node name=input dim=16 \n" + \
- "component-node name=lda component=lda input=input \n" + \
- "component-node name=tdnn1.affine component=tdnn1.affine input=lda \n" + \
- "component-node name=tdnn1.relu component=tdnn1.relu input=tdnn1.affine \n" + \
- "component-node name=tdnn1.batchnorm component=tdnn1.batchnorm input=tdnn1.relu \n\n"
- graph = Graph(name="test_graph_component_map_loading_sequence")
-
- test_top_map = load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)
-
- ref_map = {b"lda": ["lda"],
- b"tdnn1.affine": ["tdnn1.affine"],
- b"tdnn1.relu": ["tdnn1.relu"],
- b"tdnn1.batchnorm": ["tdnn1.batchnorm"]}
- self.assertEqual(test_top_map, ref_map)
- self.assertTrue("input" in graph.nodes())
- self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])
-
- ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op'},
- 'tdnn1.affine': {'kind': 'op'},
- 'tdnn1.relu': {'kind': 'op'},
- 'tdnn1.batchnorm': {'kind': 'op'},
- },
- [
- ('input', 'lda'),
- ('lda', 'tdnn1.affine'),
- ('tdnn1.affine', 'tdnn1.relu'),
- ('tdnn1.relu', 'tdnn1.batchnorm'),
- ]
- )
- (flag, resp) = compare_graphs(graph, ref_graph, 'tdnn1.batchnorm')
- self.assertTrue(flag, resp)
-
- # NOTE: this test is disabled because it's broken and need to be fixed! Merge request 948.
- # Fail in load_topology_map() in read_node() method - we create edge with node which doesn't exist in graph
- def test_component_map_loading_swap(self):
- test_map = "input-node name=input dim=16 \n" + \
- "component-node name=lda component=lda input=input \n" + \
- "component-node name=tdnn1.batchnorm component=tdnn1.batchnorm input=tdnn1.relu \n" + \
- "component-node name=tdnn1.relu component=tdnn1.relu input=tdnn1.affine \n" + \
- "component-node name=tdnn1.affine component=tdnn1.affine input=lda \n" + \
- "\n"
- graph = Graph(name="test_graph_component_map_loading_swap")
-
- test_top_map = load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)
-
- ref_map = {b"lda": ["lda"],
- b"tdnn1.affine": ["tdnn1.affine"],
- b"tdnn1.relu": ["tdnn1.relu"],
- b"tdnn1.batchnorm": ["tdnn1.batchnorm"]}
- self.assertEqual(test_top_map, ref_map)
- self.assertTrue("input" in graph.nodes())
- self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])
-
- ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op'},
- 'tdnn1.affine': {'kind': 'op'},
- 'tdnn1.relu': {'kind': 'op'},
- 'tdnn1.batchnorm': {'kind': 'op'},
- },
- [
- ('input', 'lda'),
- ('lda', 'tdnn1.affine'),
- ('tdnn1.affine', 'tdnn1.relu'),
- ('tdnn1.relu', 'tdnn1.batchnorm'),
- ]
- )
- (flag, resp) = compare_graphs(graph, ref_graph, 'tdnn1.batchnorm')
- self.assertTrue(flag, resp)
-
- def test_component_map_loading_append(self):
- test_map = "input-node name=input dim=16 \n" + \
- "component-node name=lda component=lda input=input \n" + \
- "component-node name=tdnn1.affine component=tdnn1.affine input=Append(input, lda) \n" + \
- "component-node name=tdnn1.relu component=tdnn1.relu input=Append(tdnn1.affine, input, lda) \n" + \
- "\n"
- graph = Graph(name="test_graph_component_map_loading_append")
-
- test_top_map= load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)
-
- ref_map = {b"lda": ["lda"],
- b"tdnn1.affine": ["tdnn1.affine"],
- b"tdnn1.relu": ["tdnn1.relu"]}
- self.assertEqual(test_top_map, ref_map)
- self.assertTrue("input" in graph.nodes())
- self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])
-
- ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op'},
- 'tdnn1.affine': {'kind': 'op'},
- 'tdnn1.relu': {'kind': 'op'},
- 'append_input_lda': {'kind': 'op', 'op': 'Concat'},
- 'append_affine_input_lda': {'kind': 'op', 'op': 'Concat'},
- },
- [
- ('input', 'lda', {'out': 0}),
- ('lda', 'append_input_lda', {'in': 1, 'out': 0}),
- ('input', 'append_input_lda', {'in': 0, 'out': 1}),
- ('append_input_lda', 'tdnn1.affine', {'out': 0}),
- ('input', 'append_affine_input_lda', {'in': 1, 'out': 2}),
- ('lda', 'append_affine_input_lda', {'in': 2, 'out': 1}),
- ('tdnn1.affine', 'append_affine_input_lda', {'in': 0, 'out': 0}),
- ('append_affine_input_lda', 'tdnn1.relu', {'out': 0}),
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'tdnn1.relu')
- self.assertTrue(flag, resp)
-
- def test_component_map_loading_offset(self):
- test_map = "input-node name=input dim=16\n" + \
- "component-node name=lda component=lda input=Offset(input, -3)\n" + \
- "component-node name=tdnn1.affine component=tdnn1.affine input=Append(Offset(input, -1), Offset(lda, 1))\n" + \
- "component-node name=tdnn1.relu component=tdnn1.relu input=tdnn1.affine\n" + \
- "\n"
- graph = Graph(name="test_graph_component_map_loading_offset")
-
- test_top_map= load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)
-
- ref_map = {b"lda": ["lda"],
- b"tdnn1.affine": ["tdnn1.affine"],
- b"tdnn1.relu": ["tdnn1.relu"]}
- self.assertEqual(test_top_map, ref_map)
- self.assertTrue("input" in graph.nodes())
- self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])
-
- ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op'},
- 'tdnn1.affine': {'kind': 'op'},
- 'tdnn1.relu': {'kind': 'op'},
- 'append_input_lda': {'kind': 'op', 'op': 'Concat'},
- 'offset_in_input_3': {'kind': 'op', 'op': 'memoryoffset', 't': -3, 'pair_name': 'offset_out_input_3'},
- 'offset_in_input_1': {'kind': 'op', 'op': 'memoryoffset', 't': -1, 'pair_name': 'offset_out_input_1'},
- 'offset_in_lda_1': {'kind': 'op', 'op': 'memoryoffset', 't': -1, 'pair_name': 'offset_out_lda_1'},
- },
- [
- ('input', 'offset_in_input_3', {'out': 0}),
- ('offset_in_input_3', 'lda', {'out': 0}),
- ('lda', 'offset_in_lda_1', {'out': 0}),
- ('input', 'offset_in_input_1', {'out': 1}),
- ('offset_in_lda_1', 'append_input_lda', {'in': 1, 'out': 0}),
- ('offset_in_input_1', 'append_input_lda', {'in': 0, 'out': 0}),
- ('append_input_lda', 'tdnn1.affine', {'out': 0}),
- ('tdnn1.affine', 'tdnn1.relu', {'out': 0}),
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'tdnn1.relu')
- self.assertTrue(flag, resp)
-
- def test_load_components(self):
- test_map = b" " + struct.pack('B', 4) + struct.pack('I', 3) + \
- b" lda " + \
- b" tdnn1.affine @? " + \
- b" tdnn1.relu FV "
-
- graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op', 'op': 'fixedaffinecomponent'},
- 'tdnn1.affine': {'kind': 'op', 'op': 'fixedaffinecomponent'},
- 'tdnn1.relu': {'kind': 'op', 'op': 'relu'},
- },
- [
- ('input', 'lda'),
- ('lda', 'tdnn1.affine'),
- ('tdnn1.affine', 'tdnn1.relu'),
- ]
- )
-
- ref_map = {b"lda": ["lda"],
- b"tdnn1.affine": ["tdnn1.affine"],
- b"tdnn1.relu": ["tdnn1.relu"]}
-
- load_components(io.BytesIO(test_map), graph, ref_map)
-
- ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op', 'op': 'fixedaffinecomponent', 'parameters': ' '},
- 'tdnn1.affine': {'kind': 'op', 'op': 'naturalgradientaffinecomponent', 'parameters': " @? ·С8 "},
- 'tdnn1.relu': {'kind': 'op', 'op': 'rectifiedlinearcomponent', 'parameters': " FV "},
- },
- [
- ('input', 'lda'),
- ('lda', 'tdnn1.affine'),
- ('tdnn1.affine', 'tdnn1.relu'),
- ]
- )
- (flag, resp) = compare_graphs(graph, ref_graph, 'tdnn1.relu')
- self.assertTrue(flag, resp)
-
- def test_component_map_loading_scale(self):
- test_map = "input-node name=input dim=16\n" + \
- "component-node name=lda component=lda input=Scale(0.1, input)\n" + \
- "\n"
- graph = Graph(name="test_graph_component_map_loading_scale")
-
- test_top_map = load_topology_map(io.BytesIO(bytes(test_map, 'ascii')), graph)
-
- ref_map = {b"lda": ["lda"]}
- self.assertEqual(test_top_map, ref_map)
- self.assertTrue("input" in graph.nodes())
- self.assertListEqual(list(Node(graph, 'input')['shape']), [1, 16])
-
- ref_graph = build_graph({'input': {'shape': np.array([1, 16]), 'kind': 'op', 'op': 'Parameter'},
- 'lda': {'kind': 'op'},
- 'mul': {'kind': 'op'},
- 'scale_const': {'kind': 'op', 'op': 'Const'},
- },
- [
- ('input', 'mul', {'in': 0}),
- ('scale_const', 'mul', {'in': 1}),
- ('mul', 'lda', {'out': 0}),
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'lda')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/loader/utils_test.py b/tools/mo/unit_tests/mo/front/kaldi/loader/utils_test.py
deleted file mode 100644
index bd5e6610a83dcb..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/loader/utils_test.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import io
-import struct
-import unittest
-
-from openvino.tools.mo.front.kaldi.loader.utils import end_of_nnet_tag, end_of_component_tag, get_bool, get_uint16, get_uint32, \
- get_uint64, read_binary_bool_token, read_binary_integer32_token, read_binary_integer64_token, read_string, \
- read_binary_float_token, find_next_tag, find_next_component, find_end_of_component, get_parameters, \
- collect_until_token_and_read, get_args_for_specifier
-from openvino.tools.mo.utils.error import Error
-
-
-class TestKaldiUtilsLoading(unittest.TestCase):
- bool_fmt = '?'
- uint16_fmt = 'H'
- uint32_fmt = 'I'
- uint64_fmt = 'q'
- float32_fmt = 'f'
-
- @staticmethod
- def bytesio_from(buffer):
- return io.BytesIO(buffer)
-
- @staticmethod
- def pack_value(value, fmt):
- return struct.pack(fmt, value)
-
- def test_check_common_tags(self):
- self.assertEqual(end_of_nnet_tag, '
')
- self.assertEqual(end_of_component_tag, '')
-
- def test_check_results_getting_function(self):
- self.assertTrue(get_bool(self.pack_value(True, self.bool_fmt)))
- self.assertFalse(get_bool(self.pack_value(False, self.bool_fmt)))
- self.assertEqual(get_uint16(self.pack_value(16, self.uint16_fmt)), 16)
- self.assertEqual(get_uint32(self.pack_value(32, self.uint32_fmt)), 32)
- self.assertEqual(get_uint64(self.pack_value(64, self.uint64_fmt)), 64)
-
- def test_read_binary_bool_token(self):
- true_value = self.bytesio_from(self.pack_value(True, self.bool_fmt))
- false_value = self.bytesio_from(self.pack_value(False, self.bool_fmt))
- self.assertTrue(read_binary_bool_token(true_value))
- self.assertFalse(read_binary_bool_token(false_value))
-
- def test_read_binary_integer32_token(self):
- stream = self.bytesio_from(self.pack_value(4, 'B') + self.pack_value(32, self.uint32_fmt))
- self.assertEqual(read_binary_integer32_token(stream), 32)
-
- def test_read_binary_integer64_token(self):
- stream = self.bytesio_from(self.pack_value(8, 'B') + self.pack_value(64, self.uint64_fmt))
- self.assertEqual(read_binary_integer64_token(stream), 64)
-
- def test_read_binary_float_token(self):
- stream = self.bytesio_from(self.pack_value(4, 'B') + self.pack_value(0.001, self.float32_fmt))
- self.assertAlmostEqual(read_binary_float_token(stream), 0.001)
-
- def test_read_string_token(self):
- stream = self.bytesio_from(b"opgru3.renorm ")
- self.assertEqual(read_string(stream), b"opgru3.renorm")
-
- def test_find_next_tag(self):
- test_token = b''
- self.assertEqual(find_next_tag(self.bytesio_from(test_token)), test_token.decode('ascii'))
- fake_token = b''
- test_file = b'somefakeinfoinfo' + component + b' '
- self.assertEqual(find_next_component(self.bytesio_from(test_file)), component.decode('ascii').lower()[1:-1])
-
- def test_find_next_component_eoc(self):
- component = b''
- test_file = b'' + component + b' '
- self.assertEqual(find_next_component(self.bytesio_from(test_file)), component.decode('ascii').lower()[1:-1])
-
- def test_find_next_component_end_of_nnet(self):
- test_file = b'somefakeinfoinfo '
- self.assertRaises(Error, find_next_component, self.bytesio_from(test_file))
-
- def test_find_end_of_component(self):
- component = ''
- test_file = b'somefakeinfoinfo' + bytes(end_of_component_tag, 'ascii') + b' '
- end_tag, position = find_end_of_component(self.bytesio_from(test_file), component.lower()[1:-1])
- self.assertEqual(end_tag, end_of_component_tag)
- self.assertEqual(position, test_file.decode('ascii').index(end_of_component_tag) + len(end_of_component_tag))
-
- def test_get_pb(self):
- component = ''
- test_file = b'somefakeinfoinfo' + bytes(end_of_component_tag, 'ascii') + b' '
- end_tag, end_position = find_end_of_component(self.bytesio_from(test_file), component[1:-1].lower())
- pb = get_parameters(self.bytesio_from(test_file), 0, end_position)
-
- def test_collect_until_token_and_read(self):
- tag = b''
- test_file = b' opgru3.renorm ' + self.pack_value(4, 'B') + \
- self.pack_value(256, 'I') + b' ' + self.pack_value(4, 'B') + \
- self.pack_value(0.5, 'f') + b' F '
- value = collect_until_token_and_read(self.bytesio_from(test_file), tag)
- self.assertEqual(value, 256)
-
- def test_get_args_for_specifier(self):
- string = b"(Offset(input, -2), Offset(input, -1), input, Offset(input, 1), Offset(input, 2))"
- args = get_args_for_specifier(string)
- ref = [b"Offset(input, -2)", b"Offset(input, -1)", b"input", b"Offset(input, 1)", b"Offset(input, 2)"]
- self.assertEqual(args, ref)
-
- def test_get_args_for_specifier_2(self):
- string = b"(Offset(input, -2), input, Offset(Offset(input, -1), 1))"
- args = get_args_for_specifier(string)
- ref = [b"Offset(input, -2)", b"input", b"Offset(Offset(input, -1), 1)"]
- self.assertEqual(args, ref)
-
- def test_get_args_for_specifier_3(self):
- string = b"(Offset(input, 1), Offset(input, 2))"
- args = get_args_for_specifier(string)
- ref = [b"Offset(input, 1)", b"Offset(input, 2)"]
- self.assertEqual(args, ref)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/memory_offset_adjustment_test.py b/tools/mo/unit_tests/mo/front/kaldi/memory_offset_adjustment_test.py
deleted file mode 100644
index 2861597480540b..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/memory_offset_adjustment_test.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.kaldi.memory_offset_adjustment import MemoryOffsetAdjustment
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class MemoruOffsetAdjustmentTests(unittest.TestCase):
-
- def test_several_memory_concat(self):
- graph = build_graph({'in': {'kind': 'op', 'op': None},
- 'memory_2': {'kind': 'op', 'op': 'MemoryOffset', 't': 2},
- 'memory_1': {'kind': 'op', 'op': 'MemoryOffset', 't': 1},
- 'memory__3': {'kind': 'op', 'op': 'MemoryOffset', 't': -3},
- 'concat': {'kind': 'op', 'op': 'Concat'}},
- [('in', 'memory_2', {'out': 0}), ('in', 'memory_1', {'out': 1}),
- ('in', 'memory__3', {'out': 3}),
- ('memory_2', 'concat', {'in': 0}),
- ('memory_1', 'concat', {'in': 1}),
- ('in', 'concat', {'in': 2, 'out': 2}),
- ('memory__3', 'concat', {'in': 3})],
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- ref_graph = build_graph({'in': {'kind': 'op', 'op': None},
- 'memory__5': {'kind': 'op', 'op': 'MemoryOffset', 't': -5},
- 'memory__1': {'kind': 'op', 'op': 'MemoryOffset', 't': -1},
- 'memory__2': {'kind': 'op', 'op': 'MemoryOffset', 't': -2},
- 'concat': {'kind': 'op', 'op': 'Concat'}},
- [('in', 'memory__5', {'out': 3}), ('in', 'memory__1', {'out': 1}),
- ('in', 'memory__2', {'out': 2}),
- ('in', 'concat', {'in': 0, 'out': 0}),
- ('memory__2', 'concat', {'in': 2}),
- ('memory__1', 'concat', {'in': 1}),
- ('memory__5', 'concat', {'in': 3})],
- nodes_with_edges_only=True)
-
- MemoryOffsetAdjustment().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_memory_before_several_memory_concat(self):
- graph = build_graph({'in': {'kind': 'op', 'op': None},
- 'memory_2': {'kind': 'op', 'op': 'MemoryOffset', 't': 2},
- 'memory_1': {'kind': 'op', 'op': 'MemoryOffset', 't': 1},
- 'memory__3': {'kind': 'op', 'op': 'MemoryOffset', 't': -3},
- 'concat': {'kind': 'op', 'op': 'Concat'}},
- [('in', 'memory_1', {'out': 0}), ('memory_1', 'memory_2', {'out': 0}),
- ('memory_1', 'memory__3', {'out': 0}),
- ('memory_2', 'concat', {'in': 1}),
- ('memory__3', 'concat', {'in': 0}),
- ('memory_1', 'concat', {'in': 2, 'out': 0}),
- ('in', 'concat', {'in': 3, 'out': 1})],
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- ref_graph = build_graph({'in': {'kind': 'op', 'op': None},
- 'memory__3': {'kind': 'op', 'op': 'MemoryOffset', 't': -3},
- 'memory__6': {'kind': 'op', 'op': 'MemoryOffset', 't': -5},
- 'memory__2': {'kind': 'op', 'op': 'MemoryOffset', 't': -2},
- 'concat': {'kind': 'op', 'op': 'Concat'}},
- [('in', 'memory__2', {'out': 0}), ('memory__2', 'concat', {"in": 1, 'out': 0}),
- ('memory__2', 'memory__6', {'out': 0}),
- ('memory__6', 'concat', {'in': 0}),
- ('memory__3', 'concat', {'in': 3}),
- ('memory__2', 'concat', {"in": 2, 'out': 0}),
- ('in', 'memory__3', {'out': 1})],
- nodes_with_edges_only=True)
-
- MemoryOffsetAdjustment().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_memory_parallel_several_memory_concat(self):
- graph = build_graph({'in': {'kind': 'op', 'op': None},
- 'memory_3': {'kind': 'op', 'op': 'MemoryOffset', 't': 3},
- 'memory__1': {'kind': 'op', 'op': 'MemoryOffset', 't': -1},
- 'memory_5': {'kind': 'op', 'op': 'MemoryOffset', 't': 5},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_1': {'kind': 'op', 'op': 'Concat'},
- 'split': {'kind': 'op', 'op': 'Split'}},
- [('in', 'split', {'out': 0}), ('in', 'memory_5', {'out': 0}),
- ('split', 'memory_3', {'out': 0}),
- ('split', 'memory__1', {'out': 1}),
- ('memory_3', 'concat', {'in': 0}),
- ('memory__1', 'concat', {'in': 1}),
- ('concat', 'concat_1', {'in': 0, 'out': 0}),
- ('memory_5', 'concat_1', {'in': 1, 'out': 0}),
- ],
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- ref_graph = build_graph({'in': {'kind': 'op', 'op': None},
- 'memory__4': {'kind': 'op', 'op': 'MemoryOffset', 't': -4},
- 'memory__2': {'kind': 'op', 'op': 'MemoryOffset', 't': -2},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_1': {'kind': 'op', 'op': 'Concat'},
- 'split': {'kind': 'op', 'op': 'Split'},
- },
- [('in', 'split', {'out': 0}), ('in', 'concat_1', {'in': 1, 'out': 0}),
- ('split', 'concat', {'out': 0, 'in': 0}), ('split', 'memory__4', {'out': 1}),
- ('memory__4', 'concat', {'in': 1}),
- ('concat', 'memory__2'),
- ('memory__2', 'concat_1', {'in': 0}),
- ],
- nodes_with_edges_only=True)
-
- MemoryOffsetAdjustment().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'concat_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/replace_lstm_nonlinearity_test.py b/tools/mo/unit_tests/mo/front/kaldi/replace_lstm_nonlinearity_test.py
deleted file mode 100644
index e16edb2849c4d7..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/replace_lstm_nonlinearity_test.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.replace_lstm_nonlinearity import ReplaceLstmNonLinearityPattern
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class ReplaceLstmNonlinearityTests(unittest.TestCase):
- # i_t = Sigmoid(i_part + w_ic*ct_1)
- # f_t = Sigmoid(f_part + w_fc*ct_1)
- # c_t = f_t * f_scale * ct_1 + i_t * i_scale * tanh(c_part)
- # o_t = Sigmoid(o_part + w_oc*c_t)
- # m_t = o_t * o_scale * Tanh(c_t)
- nodes_attributes = {
- 'in': {'kind': 'op', 'op': 'Parameter'},
- 'i_part': {'kind': 'op', 'op': 'Parameter'},
- 'f_part': {'kind': 'op', 'op': 'Parameter'},
- 'c_part': {'kind': 'op', 'op': 'Parameter'},
- 'o_part': {'kind': 'op', 'op': 'Parameter'},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_dropout': {'kind': 'op', 'op': 'AttributedVariadicSplit', 'size_splits': [-1, 1, 1, 1]},
- 'sigmoid_i': {'kind': 'op', 'op': 'Sigmoid'},
- 'sigmoid_f': {'kind': 'op', 'op': 'Sigmoid'},
- 'sigmoid_o': {'kind': 'op', 'op': 'Sigmoid'},
- 'i_plus_c': {'kind': 'op', 'op': 'Eltwise', 'operation': 'sum'},
- 'f_plus_c': {'kind': 'op', 'op': 'Eltwise', 'operation': 'sum'},
- 'fc_plus_itanhc': {'kind': 'op', 'op': 'Eltwise', 'operation': 'sum'},
- 'o_plus_c': {'kind': 'op', 'op': 'Eltwise', 'operation': 'sum'},
- 'scaled_i': {'kind': 'op', 'op': 'Mul'},
- 'scaled_f': {'kind': 'op', 'op': 'Mul'},
- 'scaled_o': {'kind': 'op', 'op': 'Mul'},
- 'scale_i_c': {'kind': 'op', 'op': 'ScaleShift'},
- 'scale_f_c': {'kind': 'op', 'op': 'ScaleShift'},
- 'scale_o_c': {'kind': 'op', 'op': 'ScaleShift'},
- 'f_mul_c': {'kind': 'op', 'op': 'Eltwise', 'operation': 'mul'},
- 'i_mul_tanhc': {'kind': 'op', 'op': 'Eltwise', 'operation': 'mul'},
- 'o_mul_tanhc': {'kind': 'op', 'op': 'Eltwise', 'operation': 'mul'},
- 'tanhcp': {'kind': 'op', 'op': 'Tanh'},
- 'tanhc': {'kind': 'op', 'op': 'Tanh'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'out': {'kind': 'op', 'op': 'Placeholder'},
- 'lstm': {'kind': 'op', 'op': 'LstmNonLinearity',
- 'i_weights': np.array([]),
- 'f_weights': np.array([]),
- 'o_weights': np.array([])}
- }
-
- def test_lstm_nonlinearity(self):
- graph = build_graph({'in': {'kind': 'op', 'op': 'Parameter'},
- 'lstm': {'kind': 'op', 'op': 'LstmNonLinearity',
- 'use_dropout': False,
- 'i_weights': np.array([]),
- 'f_weights': np.array([]),
- 'o_weights': np.array([]),},
- 'out': {'kind': 'op', 'op': 'Placeholder'}},
- [('in', 'lstm'), ('lstm', 'out')], nodes_with_edges_only=True)
- graph.stage = 'front'
- # split input to (i_part, f_part, c_part, o_part, ct_1)
- ref_graph = build_graph(self.nodes_attributes, [
- ('in', 'split'),
- ('split', 'scale_i_c', {'out': 4}),
- ('scale_i_c', 'i_plus_c'),
- ('split', 'i_plus_c', {'out': 0}),
- ('i_plus_c', 'sigmoid_i'),
- ('split', 'scale_f_c', {'out': 4}),
- ('scale_f_c', 'f_plus_c'),
- ('split', 'f_plus_c', {'out': 1}),
- ('f_plus_c', 'sigmoid_f'),
- ('split', 'tanhcp', {'out': 2}),
- ('tanhcp', 'i_mul_tanhc'),
- ('sigmoid_i', 'i_mul_tanhc'),
- ('sigmoid_f', 'f_mul_c'),
- ('split', 'f_mul_c', {'out': 4}),
- ('f_mul_c', 'fc_plus_itanhc'),
- ('i_mul_tanhc', 'fc_plus_itanhc'),
- ('split', 'scale_o_c', {'out': 4}),
- ('scale_o_c', 'o_plus_c'),
- ('split', 'o_plus_c', {'out': 3}),
- ('o_plus_c', 'sigmoid_o'),
- ('fc_plus_itanhc', 'tanhc'),
- ('sigmoid_o', 'o_mul_tanhc'),
- ('tanhc', 'o_mul_tanhc'),
- ('fc_plus_itanhc', 'concat'),
- ('o_mul_tanhc', 'concat'),
- ('lstm', 'out'),
- ], nodes_with_edges_only=True)
- ReplaceLstmNonLinearityPattern().replace_op(graph, Node(graph, 'lstm'))
- (flag, resp) = compare_graphs(graph, ref_graph, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_lstm_nonlinearity_dropout(self):
- graph = build_graph({'in': {'kind': 'op', 'op': 'Parameter'},
- 'lstm': {'kind': 'op', 'op': 'LstmNonLinearity',
- 'use_dropout': True,
- 'i_weights': np.array([]),
- 'f_weights': np.array([]),
- 'o_weights': np.array([]),},
- 'out': {'kind': 'op', 'op': 'Placeholder'}},
- [('in', 'lstm'), ('lstm', 'out')], nodes_with_edges_only=True)
- graph.stage = 'front'
- # split input to (i_part, f_part, c_part, o_part, ct_1)
- ref_graph = build_graph(self.nodes_attributes, [
- ('in', 'split_dropout'),
- ('split_dropout', 'split', {'out': 0}),
- ('split', 'scale_i_c', {'out': 4}),
- ('scale_i_c', 'i_plus_c'),
- ('split', 'i_plus_c', {'out': 0}),
- ('i_plus_c', 'sigmoid_i'),
- ('sigmoid_i', 'scaled_i', {'in': 0}),
- ('split_dropout', 'scaled_i', {'out': 1, 'in': 1}),
- ('split', 'scale_f_c', {'out': 4}),
- ('scale_f_c', 'f_plus_c'),
- ('split', 'f_plus_c', {'out': 1}),
- ('f_plus_c', 'sigmoid_f'),
- ('sigmoid_f', 'scaled_f', {'in': 0}),
- ('split_dropout', 'scaled_f', {'out': 2, 'in': 1}),
- ('split', 'tanhcp', {'out': 2}),
- ('tanhcp', 'i_mul_tanhc'),
- ('scaled_i', 'i_mul_tanhc'),
- ('scaled_f', 'f_mul_c'),
- ('split', 'f_mul_c', {'out': 4}),
- ('f_mul_c', 'fc_plus_itanhc'),
- ('i_mul_tanhc', 'fc_plus_itanhc'),
- ('split', 'scale_o_c', {'out': 4}),
- ('scale_o_c', 'o_plus_c'),
- ('split', 'o_plus_c', {'out': 3}),
- ('o_plus_c', 'sigmoid_o'),
- ('sigmoid_o', 'scaled_o', {'in': 0}),
- ('split_dropout', 'scaled_o', {'out': 3, 'in': 1}),
- ('fc_plus_itanhc', 'tanhc'),
- ('scaled_o', 'o_mul_tanhc'),
- ('tanhc', 'o_mul_tanhc'),
- ('fc_plus_itanhc', 'concat'),
- ('o_mul_tanhc', 'concat'),
- ('lstm', 'out'),
- ], nodes_with_edges_only=True)
- ReplaceLstmNonLinearityPattern().replace_op(graph, Node(graph, 'lstm'))
- (flag, resp) = compare_graphs(graph, ref_graph, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/replace_timeheightconvolution_test.py b/tools/mo/unit_tests/mo/front/kaldi/replace_timeheightconvolution_test.py
deleted file mode 100644
index 5160621b028372..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/replace_timeheightconvolution_test.py
+++ /dev/null
@@ -1,324 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.replace_timeheightconvolution import ReplaceTimeHeightConvolutionPattern
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op, connect_front, const
-
-
-class TimeheightconvolutionReplacerTest(unittest.TestCase):
- nodes = {
- **regular_op('placeholder', {}),
- **regular_op('timeheightconv', {'op': 'timeheightconvolutioncomponent'}),
- **const('weights', int64_array([])),
- **const('biases', int64_array([])),
- **regular_op('placeholder_out', {}),
-
- **regular_op('concat', {'type': 'Concat', 'axis': 1}),
- **regular_op('memoryoffset_0', {'type': None, 'op': 'MemoryOffset', 't': -1, 'has_default': False}),
- **regular_op('memoryoffset_1', {'type': None, 'op': 'MemoryOffset', 't': 0, 'has_default': False}),
- **regular_op('memoryoffset_2', {'type': None, 'op': 'MemoryOffset', 't': 1, 'has_default': True}),
- **regular_op('conv', {'op': 'Convolution', 'type': 'Convolution', 'output': 12, 'height_in': 80}),
- }
-
- def test_timeheightconvolution_1offset(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 1
- conv['height_in'] = 80
- conv['height_out'] = 80
- conv['in_channels'] = 1
- conv['out_channels'] = 12
- conv['offsets'] = int64_array([[-1, -1], [-1, 0], [-1, 1]])
- conv['time_offsets'] = [-1]
- graph.nodes['weights']['value'] = np.zeros([36])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_0'),
- *connect_front('memoryoffset_0', '0:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.zeros([36])
- new_conv = ref_graph.nodes['conv']
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [1, 1]])
- new_conv['dilation'] = int64_array([1, 1, 1, 1])
- new_conv['kernel'] = int64_array([12, 1, 1, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 1])
-
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_timeheightconvolution_2_offsets(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 1
- conv['height_in'] = 80
- conv['height_out'] = 80
- conv['in_channels'] = 1
- conv['out_channels'] = 12
- conv['offsets'] = int64_array([[-1, -1], [-1, 0], [-1, 1], [0, -1], [0, 0], [0, 1]])
- conv['time_offsets'] = int64_array([-1, 0])
- graph.nodes['weights']['value'] = np.zeros([72])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_0'),
- *connect_front('placeholder', 'memoryoffset_1'),
- *connect_front('memoryoffset_0', '0:concat'),
- *connect_front('memoryoffset_1', '1:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.zeros([72])
- new_conv = ref_graph.nodes['conv']
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [1, 1]])
- new_conv['dilation'] = int64_array([1, 1, 1, 1])
- new_conv['kernel'] = int64_array([12, 1, 2, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 1])
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_timeheightconvolution_2_offsets_def(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 1
- conv['height_in'] = 80
- conv['height_out'] = 80
- conv['in_channels'] = 1
- conv['out_channels'] = 12
- conv['offsets'] = int64_array([[0, -1], [0, 0], [0, 1], [1, -1], [1, 0], [1, 1]])
- conv['time_offsets'] = int64_array([0])
- graph.nodes['weights']['value'] = np.zeros([72])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_1'),
- *connect_front('placeholder', 'memoryoffset_2'),
- *connect_front('memoryoffset_1', '0:concat'),
- *connect_front('memoryoffset_2', '1:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.zeros([72])
- new_conv = ref_graph.nodes['conv']
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [1, 1]])
- new_conv['dilation'] = int64_array([1, 1, 1, 1])
- new_conv['kernel'] = int64_array([12, 1, 2, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 1])
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_timeheightconvolution_2_offsets_dilation(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 1
- conv['height_in'] = 80
- conv['height_out'] = 80
- conv['in_channels'] = 1
- conv['out_channels'] = 12
- conv['offsets'] = int64_array([[-1, -3], [-1, 0], [-1, 3], [1, -3], [1, 0], [1, 3]])
- conv['time_offsets'] = int64_array([-1])
- graph.nodes['weights']['value'] = np.zeros([72])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_0'),
- *connect_front('placeholder', 'memoryoffset_2'),
- *connect_front('memoryoffset_0', '0:concat'),
- *connect_front('memoryoffset_2', '1:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.zeros([72])
- new_conv = ref_graph.nodes['conv']
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [3, 3]])
- new_conv['dilation'] = int64_array([1, 1, 2, 3])
- new_conv['kernel'] = int64_array([12, 1, 2, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 1])
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_timeheightconvolution_2_offsets_pad(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 1
- conv['height_in'] = 80
- conv['height_out'] = 74
- conv['in_channels'] = 1
- conv['out_channels'] = 12
- conv['offsets'] = int64_array([[-1, 0], [-1, 3], [-1, 6], [1, 0], [1, 3], [1, 6]])
- conv['time_offsets'] = int64_array([-1])
- graph.nodes['weights']['value'] = np.zeros([72])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_0'),
- *connect_front('placeholder', 'memoryoffset_2'),
- *connect_front('memoryoffset_0', '0:concat'),
- *connect_front('memoryoffset_2', '1:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.zeros([72])
- new_conv = ref_graph.nodes['conv']
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [0, 0]])
- new_conv['dilation'] = int64_array([1, 1, 2, 3])
- new_conv['kernel'] = int64_array([12, 1, 2, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 1])
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_timeheightconvolution_out_channels(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 1
- conv['height_in'] = 80
- conv['height_out'] = 74
- conv['in_channels'] = 3
- conv['out_channels'] = 4
- conv['offsets'] = int64_array([[-1, 0], [-1, 3], [-1, 6], [1, 0], [1, 3], [1, 6]])
- conv['time_offsets'] = int64_array([-1])
- graph.nodes['weights']['value'] = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_0'),
- *connect_front('placeholder', 'memoryoffset_2'),
- *connect_front('memoryoffset_0', '0:concat'),
- *connect_front('memoryoffset_2', '1:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.array([1, 4, 7, 10, 13, 16, 2, 5, 8, 11, 14, 17, 3, 6, 9, 12, 15, 18,
- 19, 22, 25, 28, 31, 34, 20, 23, 26, 29, 32, 35, 21, 24, 27, 30, 33, 36,
- 37, 40, 43, 46, 49, 52, 38, 41, 44, 47, 50, 53, 39, 42, 45, 48, 51, 54,
- 55, 58, 61, 64, 67, 70, 56, 59, 62, 65, 68, 71, 57, 60, 63, 66, 69, 72])
- new_conv = ref_graph.nodes['conv']
- new_conv['output'] = 4
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [0, 0]])
- new_conv['dilation'] = int64_array([1, 1, 2, 3])
- new_conv['kernel'] = int64_array([4, 3, 2, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 1])
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_timeheightconvolution_2_offsets_stride(self):
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:timeheightconv'),
- *connect_front('weights', '1:timeheightconv'),
- *connect_front('biases', '2:timeheightconv'),
- *connect_front('timeheightconv', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
- conv = graph.nodes['timeheightconv']
- conv['height_subsample'] = 2
- conv['height_in'] = 80
- conv['height_out'] = 37
- conv['in_channels'] = 1
- conv['out_channels'] = 12
- conv['offsets'] = int64_array([[-1, 0], [-1, 3], [-1, 6], [1, 0], [1, 3], [1, 6]])
- conv['time_offsets'] = int64_array([-1])
- graph.nodes['weights']['value'] = np.zeros([72])
-
- ref_graph = build_graph(self.nodes, [
- *connect_front('placeholder', 'memoryoffset_0'),
- *connect_front('placeholder', 'memoryoffset_2'),
- *connect_front('memoryoffset_0', '0:concat'),
- *connect_front('memoryoffset_2', '1:concat'),
- *connect_front('concat', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('biases', '2:conv'),
- *connect_front('conv', 'placeholder_out')
- ], nodes_with_edges_only=True)
- ref_graph.nodes['weights']['value'] = np.zeros([72])
- new_conv = ref_graph.nodes['conv']
- new_conv['pad'] = int64_array([[0, 0], [0, 0], [0, 0], [0, 0]])
- new_conv['dilation'] = int64_array([1, 1, 2, 3])
- new_conv['kernel'] = int64_array([12, 1, 2, 3])
- new_conv['stride'] = int64_array([1, 1, 1, 2])
-
- ReplaceTimeHeightConvolutionPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/restrictedattentioncomponent_replacer_test.py b/tools/mo/unit_tests/mo/front/kaldi/restrictedattentioncomponent_replacer_test.py
deleted file mode 100644
index 22e8ef01720431..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/restrictedattentioncomponent_replacer_test.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.kaldi.restrictedattentioncomponent_replacer \
- import RestrictedAttentionComponentReplacer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.common.partial_infer.utils import mo_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op, connect_front, const
-
-
-class RestrictedAttentionComponentReplacerTest(unittest.TestCase):
- nodes = {
- **regular_op('placeholder', {}),
- **regular_op('restrictedattention', {'op': 'restrictedattentioncomponent'}),
- **regular_op('placeholder_out', {}),
- **regular_op('reshape_1', {'type': 'Reshape'}),
- **const('reshape_1_shape', int64_array([10, -1])),
- **regular_op('split_1', {'kind': 'op', 'type': 'VariadicSplit'}),
- **const('split_1_axis', int64_array(1)),
- **const('split_1_shape', int64_array([44, 55, 47])),
- **regular_op('memoryoffset_1_0', {'type': None,
- 't': -2, 'has_default': False}),
- **regular_op('memoryoffset_1_1', {'type': None,
- 't': 2, 'has_default': False}),
- **regular_op('concat_1', {'type': 'Concat'}),
- **regular_op('split_2', {'type': 'VariadicSplit'}),
- **const('split_2_axis', int64_array(1)),
- **const('split_2_shape', int64_array([44, 3])),
- **regular_op('einsum_1', {'type': 'Einsum', 'equation': 'ij,ik->i'}),
- **regular_op('reshape_helper_1', {'type': 'Reshape'}),
- **const('reshape_helper_1_shape', int64_array([10, 1])),
- **regular_op('mul', {'type': 'Multiply'}),
- **const('mul_scale', mo_array(0.5, dtype=float)),
- **regular_op('add', {'type': 'Add'}),
- **regular_op('softmax', {'type': 'SoftMax'}),
- **regular_op('reshape_helper_3', {'type': 'Reshape'}),
- **const('reshape_helper_3_shape', int64_array([10, 1, 3])),
- **regular_op('memoryoffset_2_0', {'type': None,
- 't': -2, 'has_default': False}),
- **regular_op('memoryoffset_2_1', {'type': None,
- 't': 2, 'has_default': False}),
- **regular_op('concat_2', {'type': 'Concat'}),
- **regular_op('reshape_helper_2', {'type': 'Reshape'}),
- **const('reshape_helper_2_shape', int64_array([10, 55, 3])),
- **regular_op('einsum_2', {'type': 'Einsum', 'equation': 'ijk,ilk->ij'}),
- **regular_op('concat_3', {'type': 'Concat'}),
- **regular_op('reshape_2', {'type': 'Reshape'}),
- **const('reshape_2_shape', int64_array([1, -1])),
- }
-
- def test_restrictedattentioncomponent(self):
- """
- Test case that validates if supgraph replaced by RestrictedAttentionComponentReplacer
- class instead of RestrictedAttention operator is correct.
- """
- graph = build_graph(self.nodes, [
- *connect_front('placeholder', '0:restrictedattention'),
- *connect_front('restrictedattention', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- restricted_attention_node = graph.nodes['restrictedattention']
- restricted_attention_node['num_left_inputs'] = 1
- restricted_attention_node['num_right_inputs'] = 1
- restricted_attention_node['num_heads'] = 10
- restricted_attention_node['key_dim'] = 44
- restricted_attention_node['value_dim'] = 55
- restricted_attention_node['time_stride'] = 2
- restricted_attention_node['key_scale'] = 0.5
-
- ref_graph = build_graph(self.nodes, [
- ('placeholder', 'reshape_1', {'in': 0, 'out': 0}),
- ('reshape_1_shape', 'reshape_1', {'in': 1, 'out': 0}),
- ('reshape_1', 'split_1', {'in': 0, 'out': 0}),
- ('split_1_axis', 'split_1', {'in': 1, 'out': 0}),
- ('split_1_shape', 'split_1', {'in': 2, 'out': 0}),
- ('split_1', 'memoryoffset_1_0', {'in': 0, 'out': 0}),
- ('split_1', 'memoryoffset_1_1', {"in": 0, 'out': 0}),
- ('split_1', 'memoryoffset_2_0', {"in": 0, 'out': 1}),
- ('split_1', 'memoryoffset_2_1', {"in": 0, 'out': 1}),
- ('split_1', 'split_2', {'in': 0, 'out': 2}),
- ('split_2_axis', 'split_2', {'in': 1, 'out': 0}),
- ('split_2_shape', 'split_2', {'in': 2, 'out': 0}),
- ('memoryoffset_1_0', 'concat_1', {'in': 0, 'out': 0}),
- ('split_1', 'concat_1', {'in': 1, 'out': 0}),
- ('memoryoffset_1_1', 'concat_1', {'in': 2, 'out': 0}),
- ('concat_1', 'einsum_1', {'in': 0, 'out': 0}),
- ('split_2', 'einsum_1', {'in': 1, 'out': 0}),
- ('einsum_1', 'reshape_helper_1', {'in': 0, 'out': 0}),
- ('reshape_helper_1_shape', 'reshape_helper_1', {'in': 1, 'out': 0}),
- ('reshape_helper_1', 'mul', {'in': 0, 'out': 0}),
- ('mul_scale', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'add', {'in': 1, 'out': 0}),
- ('split_2', 'add', {'in': 0, 'out': 1}),
- ('add', 'softmax', {'in': 0, 'out': 0}),
- ('memoryoffset_2_0', 'concat_2', {'in': 0, 'out': 0}),
- ('split_1', 'concat_2', {'in': 1, 'out': 1}),
- ('memoryoffset_2_1', 'concat_2', {'in': 2, 'out': 0}),
- ('concat_2', 'reshape_helper_2', {'in': 0, 'out': 0}),
- ('reshape_helper_2_shape', 'reshape_helper_2', {'in': 1, 'out': 0}),
- ('reshape_helper_2', 'einsum_2', {'in': 0, 'out': 0}),
- ('softmax', 'reshape_helper_3', {'in': 0, 'out': 0}),
- ('reshape_helper_3_shape', 'reshape_helper_3', {'in': 1, 'out': 0}),
- ('reshape_helper_3', 'einsum_2', {'in': 1, 'out': 0}),
- ('einsum_2', 'concat_3', {'in': 0, 'out': 0}),
- ('softmax', 'concat_3', {'in': 1, 'out': 0}),
- ('concat_3', 'reshape_2', {'in': 0, 'out': 0}),
- ('reshape_2_shape', 'reshape_2', {'in': 1, 'out': 0}),
- ('reshape_2', 'placeholder_out')
- ], nodes_with_edges_only=True)
-
- RestrictedAttentionComponentReplacer().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph,
- 'placeholder_out', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/set_ports_test.py b/tools/mo/unit_tests/mo/front/kaldi/set_ports_test.py
deleted file mode 100644
index 00562bb4b9d62c..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/set_ports_test.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.kaldi.set_ports import SetPortsPattern
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op, connect_front, Node
-
-
-class SetPortsTest(unittest.TestCase):
- def test_set_ports_chain(self):
- nodes = {
- **regular_op('op1', {}),
- **regular_op('op2', {}),
- **regular_op('op3', {}),
- }
-
- graph = build_graph(nodes, [
- ('op1', 'op2', {'fw_tensor_debug_info': {}}),
- ('op2', 'op3', {'fw_tensor_debug_info': {}})
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- ref_graph = build_graph(nodes, [
- *connect_front('op1:0', '0:op2'),
- *connect_front('op2:0', '0:op3')
- ], nodes_with_edges_only=True)
-
- SetPortsPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'op3', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_set_ports_split(self):
- nodes = {
- **regular_op('op1', {}),
- **regular_op('split', {'op': 'Split'}),
- **regular_op('op2', {}),
- **regular_op('op3', {}),
- **regular_op('op4', {}),
- }
-
- graph = build_graph(nodes, [
- ('op1', 'split', {'fw_tensor_debug_info': {}}),
- ('split', 'op2', {'fw_tensor_debug_info': {}, 'out_port': 0}),
- ('split', 'op3', {'fw_tensor_debug_info': {}, 'out_port': 1}),
- ('split', 'op4', {'fw_tensor_debug_info': {}, 'out_port': 2})
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
- graph.nodes()['split']['out_ports_count'] = 3
-
- ref_graph = build_graph(nodes, [
- *connect_front('op1:0', '0:split'),
- *connect_front('split:0', '0:op2'),
- *connect_front('split:1', '0:op3'),
- *connect_front('split:2', '0:op4')
- ], nodes_with_edges_only=True)
-
- SetPortsPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'op4', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_set_ports_split2(self):
- nodes = {
- **regular_op('op1', {}),
- **regular_op('split', {'op': 'Split'}),
- **regular_op('op2', {}),
- **regular_op('op3', {}),
- **regular_op('op4', {}),
- }
-
- graph = build_graph(nodes, [
- ('op1', 'split', {'fw_tensor_debug_info': {}}),
- ('split', 'op2', {'fw_tensor_debug_info': {}, 'out_port': 0}),
- ('split', 'op4', {'fw_tensor_debug_info': {}, 'out_port': 4}),
- ('split', 'op3', {'fw_tensor_debug_info': {}, 'out_port': 6})
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
- graph.nodes()['split']['out_ports_count'] = 3
-
- ref_graph = build_graph(nodes, [
- *connect_front('op1:0', '0:split'),
- *connect_front('split:0', '0:op2'),
- *connect_front('split:1', '0:op4'),
- *connect_front('split:2', '0:op3')
- ], nodes_with_edges_only=True)
-
- SetPortsPattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'op4', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_set_ports_split3(self):
- nodes = {
- **regular_op('op1', {}),
- **regular_op('split', {'op': 'Split'}),
- **regular_op('op2', {}),
- **regular_op('op3', {}),
- **regular_op('op4', {}),
- }
-
- graph = build_graph(nodes, [
- ('op1', 'split', {'fw_tensor_debug_info': {}}),
- ('split', 'op2', {'fw_tensor_debug_info': {}, 'out_port': 0}),
- ('split', 'op3', {'fw_tensor_debug_info': {}, 'out_port': 1}),
- ('split', 'op4', {'fw_tensor_debug_info': {}, 'out_port': 2})
- ], nodes_with_edges_only=True)
-
- Node(graph, 'split').out_port(0).get_connection().add_destination(Node(graph, 'op4').in_port(0))
- graph.nodes()['split']['out_ports_count'] = 2
-
- graph.stage = 'front'
-
- self.assertRaises(Error, SetPortsPattern().find_and_replace_pattern, graph)
diff --git a/tools/mo/unit_tests/mo/front/kaldi/sigmoid_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/sigmoid_ext_test.py
deleted file mode 100644
index af04a98535e830..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/sigmoid_ext_test.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.kaldi.sigmoid_ext import SigmoidFrontExtractor
-from openvino.tools.mo.ops.activation_ops import Sigmoid
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from openvino.tools.mo.ops.op import Op
-
-
-class SigmoidFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['Sigmoid'] = Sigmoid
-
- def test_assertion(self):
- self.assertRaises(AttributeError, SigmoidFrontExtractor.extract, None)
-
- def test_extracted_blobs_add_shift(self):
- SigmoidFrontExtractor.extract(self.test_node)
- self.assertTrue(self.test_node.op, 'Sigmoid')
diff --git a/tools/mo/unit_tests/mo/front/kaldi/tanh_ext_test.py b/tools/mo/unit_tests/mo/front/kaldi/tanh_ext_test.py
deleted file mode 100644
index 1d69996dc08355..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/tanh_ext_test.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.kaldi.tanh_component_ext import TanhFrontExtractor
-from openvino.tools.mo.ops.activation_ops import Tanh
-from unit_tests.mo.front.kaldi.extractors.common_ext_test import KaldiFrontExtractorTest
-from openvino.tools.mo.ops.op import Op
-
-
-class TanhFrontExtractorTest(KaldiFrontExtractorTest):
- @classmethod
- def register_op(cls):
- Op.registered_ops['Tanh'] = Tanh
-
- def test_assertion(self):
- self.assertRaises(AttributeError, TanhFrontExtractor.extract, None)
-
- def test_extracted_blobs_add_shift(self):
- TanhFrontExtractor.extract(self.test_node)
- self.assertTrue(self.test_node.op, 'Tanh')
diff --git a/tools/mo/unit_tests/mo/front/kaldi/tdnn_component_replacer_test.py b/tools/mo/unit_tests/mo/front/kaldi/tdnn_component_replacer_test.py
deleted file mode 100644
index 10567a94a73c4a..00000000000000
--- a/tools/mo/unit_tests/mo/front/kaldi/tdnn_component_replacer_test.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.front.kaldi.tdnn_component_replacer import TdnnComponentReplacer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op, result, connect_front, const
-
-
-class TestTdnnComponentReplacerTest():
-
- @pytest.mark.parametrize("weights, biases, time_offsets",[
- ([[1, 1, 1], [4, 4, 4]], [1, 2], [-1, 1],),
- ([[1, 1, 1], [4, 4, 4]], [1, 2], [-1, 1, 2, 10, 1000],),
- ([[1, 1, 1], [4, 4, 4]], [1, 2], [-1, 0]),
- ])
- def test_tdnnreplacer(self, weights, biases, time_offsets):
- def generate_offsets():
- offset_edges = []
- offset_nodes = {}
-
- for i, t in enumerate(time_offsets):
- offset_nodes.update(**regular_op('memoryoffset_' + str(i), {'type': None}))
-
- if t != 0:
- offset_edges.append(('placeholder', 'memoryoffset_' + str(i), {'out': 0, 'in': 0}))
- offset_edges.append(('memoryoffset_' + str(i), 'concat', {'out': 0, 'in': i}))
- else:
- offset_edges.append(('placeholder', 'concat', {'out': 0, 'in': i}))
-
- return offset_nodes, offset_edges
-
- offset_nodes, ref_offset_edges = generate_offsets()
-
- nodes = {
- **offset_nodes,
- **regular_op('placeholder', {'type': 'Parameter'}),
- **regular_op('tdnncomponent', {'op': 'tdnncomponent',
- 'weights': np.array(weights),
- 'biases': np.array(biases),
- 'time_offsets': np.array(time_offsets)}),
- **const('weights', np.array(weights)),
- **const('biases', np.array(biases)),
- **regular_op('concat', {'type': 'Concat', 'axis': 1}),
- **regular_op('memoryoffset_0', {'type': None}),
- **regular_op('memoryoffset_1', {'type': None}),
- **regular_op('memoryoffset_2', {'type': None}),
- **regular_op('fully_connected', {'type': 'FullyConnected'}),
- **result('result'),
- }
-
- graph = build_graph(nodes, [
- *connect_front('placeholder', 'tdnncomponent'),
- *connect_front('tdnncomponent', 'result')
- ], nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- ref_graph = build_graph(nodes, [
- *ref_offset_edges,
- *connect_front('concat', '0:fully_connected'),
- *connect_front('weights', '1:fully_connected'),
- *connect_front('biases', '2:fully_connected'),
- *connect_front('fully_connected', 'result')
- ], nodes_with_edges_only=True)
-
- TdnnComponentReplacer().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/front/onnx/AttributedSliceToSlice_test.py b/tools/mo/unit_tests/mo/front/onnx/AttributedSliceToSlice_test.py
deleted file mode 100644
index 44b5781ff49e34..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/AttributedSliceToSlice_test.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.onnx.AttributedSliceToSlice import AttributedSliceToSliceReplacer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, const, connect_front
-
-
-class TestSliceReplacerTest():
- @pytest.mark.parametrize("attributed_slice_attrs",[
- {'op': 'AttributedSlice', 'type': None, 'starts': np.array([0, 0]), 'ends': np.array([1, -1]), 'axes': np.array([0, 1])}
- ])
- def test_attributed_slice_replacer(self, attributed_slice_attrs):
- nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('attributed_slice', attributed_slice_attrs),
- **result(),
-
- # nodes after replacement
- **const('start', np.array([0, 0])),
- **const('end', np.array([1, -1])),
- **const('axis', np.array(np.array([0, 1]))),
- **regular_op_with_empty_data('slice', {'op': 'Slice', 'type': None}),
- }
-
- graph = build_graph(nodes_attrs=nodes, edges=[
- ('input', 'attributed_slice'),
- ('attributed_slice', 'output'),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
-
- AttributedSliceToSliceReplacer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attrs=nodes, edges=[
- ('input', 'slice'),
- *connect_front('start', '1:slice'),
- *connect_front('end', '2:slice'),
- *connect_front('axis', '3:slice'),
- ('slice', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/front/onnx/MvnOnnxToMvn_test.py b/tools/mo/unit_tests/mo/front/onnx/MvnOnnxToMvn_test.py
deleted file mode 100644
index 140bcbcdb7dc65..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/MvnOnnxToMvn_test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.onnx.MvnOnnxToMvn import MvnOnnxToMvn
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, const, connect_front
-
-nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('mvn_onnx', {'op': 'MVNOnnx',
- 'axes': int64_array([2, 3]),
- 'eps': 1e-9,
- 'eps_mode': 'outside_sqrt',
- 'normalize_variance': 1}),
- **result(),
-
- # nodes after replacement
- **const('axes', int64_array([2, 3])),
- **regular_op_with_empty_data('mvn', {'op': 'MVN', 'type': None}),
-}
-
-
-class MvnOnnxToMvnTest(unittest.TestCase):
- def test_mvn_normalize(self):
- graph = build_graph(nodes, [('input', 'mvn_onnx'),
- ('mvn_onnx', 'output')],
- nodes_with_edges_only=True)
- graph.stage = 'front'
-
- MvnOnnxToMvn().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [('input', 'mvn'),
- *connect_front('axes', '1:mvn'),
- ('mvn', 'output')],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/onnx/__init__.py b/tools/mo/unit_tests/mo/front/onnx/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/onnx/activation_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/activation_ext_test.py
deleted file mode 100644
index c02e3c3f1f3d88..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/activation_ext_test.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import onnx
-import pytest
-
-import openvino.tools.mo.front.onnx.activation_ext as extractors
-from openvino.tools.mo.ops.activation_ops import Elu
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import PB
-from unit_tests.utils.graph import build_graph
-
-
-class TestActivationOpsONNXExtractorTest():
- @staticmethod
- def _create_node(op_name: str):
- pb = onnx.helper.make_node(op_name, ["X"], ["Y"])
- graph = build_graph({'node_0': {'pb': pb}}, [])
- return Node(graph, 'node_0')
-
- @staticmethod
- def _base_attrs(op_name: str):
- # reference output Node attributes
- return (
- dict(
- op=op_name,
- )
- )
-
- def _match(self, out, ref):
- for key in ref.keys():
- status = out[key] == ref[key]
- if type(status) in [list, np.ndarray]:
- status = np.all(status)
- assert status, f"Mismatch for field {key}, observed: {out[key]}, expected: {ref[key]}"
-
- @staticmethod
- def _extract(op_name):
- node = __class__._create_node(op_name)
- getattr(extractors, op_name + 'Extractor').extract(node)
- return node.graph.node[node.id]
-
- @pytest.mark.parametrize("op_name",['Abs', 'Acos', 'Asin', 'Atan', 'Acosh', 'Asinh', 'Atanh', 'Cos', 'Cosh', 'Erf', 'Exp', 'Floor', 'Log', 'Not', 'Sigmoid', 'Sin',
- 'Sinh', 'Tan', 'Tanh'])
- def test_default(self, op_name):
- ref = self._base_attrs(op_name)
- if ref['op'] == 'Not':
- ref['op'] = 'LogicalNot'
- out = self._extract(op_name)
- self._match(out, ref)
-
-
-class TestEluONNXExt():
- @staticmethod
- def _create_elu_node(alpha=1.0):
- pb = onnx.helper.make_node(
- 'Elu',
- inputs=['x'],
- outputs=['y'],
- alpha=alpha
- )
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Elu'] = Elu
-
- @pytest.mark.parametrize("alpha",[1.0, 2.0, 3.0])
- def test_elu_ext(self, alpha):
- node = self._create_elu_node(alpha)
- extractors.EluExtractor.extract(node)
-
- exp_res = {
- 'type': 'Elu',
- 'alpha': alpha,
- 'infer': Elu.infer
- }
-
- for key in exp_res.keys():
- assert node[key] == exp_res[key]
diff --git a/tools/mo/unit_tests/mo/front/onnx/affine_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/affine_ext_test.py
deleted file mode 100644
index f425bce0cd944f..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/affine_ext_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.affine_ext import AffineFrontExtractor
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-class AffineONNXExtractorTest(unittest.TestCase):
- @staticmethod
- def _create_node(attrs: dict):
- pb = onnx.helper.make_node("Affine", ["X"], ["Y"], **attrs)
- graph = build_graph({'node_0': {'pb': pb}}, [])
- return Node(graph, 'node_0')
-
- @staticmethod
- def _base_attrs():
- # Commonly used attributes in the tests
- # Each test takes these ones and then adds/modifies/deletes particular fields
- return (
- # test input ONNX attributes
- dict(
- alpha=1.0,
- beta=0.0
- ),
- # reference output Node attributes
- dict(
- op='ImageScaler',
- scale=1.0,
- bias=0.0
- )
- )
-
- @staticmethod
- def _extract(inp):
- node = __class__._create_node(inp)
- AffineFrontExtractor.extract(node)
- return node.graph.node[node.id]
-
- def _match(self, out, ref):
- for key in ref.keys():
- status = out[key] == ref[key]
- if type(status) in [list, np.ndarray]:
- status = np.all(status)
- self.assertTrue(status, 'Mismatch for field {}, observed: {}, expected: {}'.format(key, out[key], ref[key]))
-
- def test_default(self):
- inp, ref = self._base_attrs()
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_random(self):
- inp, ref = self._base_attrs()
- inp['alpha'] = 123.
- inp['beta'] = 321.
-
- ref['scale'] = 123.
- ref['bias'] = 321.
-
- out = self._extract(inp)
- self._match(out, ref)
diff --git a/tools/mo/unit_tests/mo/front/onnx/conv_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/conv_ext_test.py
deleted file mode 100644
index c161a44d8842f3..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/conv_ext_test.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.conv_ext import ConvTransposeFrontExtractor
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-
-class ConvTransposeONNXExtractorTest(unittest.TestCase):
- @staticmethod
- def _create_node(attrs: dict):
- pb = onnx.helper.make_node("ConvTranspose", ["X", "W"], ["Y"], **attrs)
- graph = build_graph({'node_0': {'pb': pb}}, [])
- return Node(graph, 'node_0')
-
- @staticmethod
- def _base_attrs():
- # Commonly used attributes in the tests
- # Each test takes these ones and then adds/modifies/deletes particular fields
- return (
- # test input ONNX attributes
- dict(
- pads=[1, 2, 3, 4],
- kernel_shape=[5, 6]
- ),
- # reference output Node attributes
- dict(
- type='Deconvolution',
- pad=[[0, 0], [0, 0], [1, 3], [2, 4]],
- bias_term=None,
- output_shape=None,
- output_padding=None,
- dilation=None,
- stride=None,
- output_spatial_shape=None,
- group=1
- )
- )
-
- @staticmethod
- def _extract(inp):
- node = __class__._create_node(inp)
- ConvTransposeFrontExtractor.extract(node)
- return node.graph.node[node.id]
-
- def _match(self, out, ref):
- for key in ref.keys():
- status = out[key] == ref[key]
- if type(status) in [list, np.ndarray]:
- status = np.all(status)
- self.assertTrue(status, 'Mismatch for field {}, observed: {}, expected: {}'.format(key, out[key], ref[key]))
-
- def test_all_valid_default(self):
- inp, ref = self._base_attrs()
- del inp['pads']
- del ref['pad']
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_most_used(self):
- inp, ref = self._base_attrs()
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_dilation(self):
- inp, ref = self._base_attrs()
- inp['dilations'] = [10, 11]
- ref['dilation'] = [1, 1, 10, 11]
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_stride(self):
- inp, ref = self._base_attrs()
- inp['strides'] = [12, 13]
- ref['stride'] = [1, 1, 12, 13]
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_group(self):
- inp, ref = self._base_attrs()
- inp['group'] = 14
- ref['group'] = 14
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_auto_pad_supported(self):
- inp, ref = self._base_attrs()
- del inp['pads']
- inp['auto_pad'] = 'SAME_UPPER'
-
- ref['auto_pad'] = 'same_upper'
- del ref['pad']
-
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_pads_not_even_invalid(self):
- inp, ref = self._base_attrs()
- inp['pads'] = [1, 2, 3]
- with self.assertRaisesRegex(Error, '.*pads.*not correct.*'):
- out = self._extract(inp)
-
- def test_missing_kernel_shape_not_supported(self):
- inp, ref = self._base_attrs()
- del inp['kernel_shape']
- with self.assertRaisesRegex(Error, '.*kernel_shape.*not supported.*'):
- out = self._extract(inp)
-
- def test_output_padding(self):
- inp, ref = self._base_attrs()
- inp['output_padding'] = [19, 20]
- ref['output_padding'] = [0, 0, 19, 20]
- out = self._extract(inp)
- self._match(out, ref)
diff --git a/tools/mo/unit_tests/mo/front/onnx/crop_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/crop_ext_test.py
deleted file mode 100644
index 621b906d8304b2..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/crop_ext_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.crop_ext import CropFrontExtractor
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-class CropONNXExtractorTest(unittest.TestCase):
- @staticmethod
- def _create_node(attrs: dict):
- pb = onnx.helper.make_node("Crop", ["X"], ["Y"], **attrs)
- graph = build_graph({'node_0': {'pb': pb}}, [])
- return Node(graph, 'node_0')
-
- @staticmethod
- def _base_attrs():
- # Commonly used attributes in the tests
- # Each test takes these ones and then adds/modifies/deletes particular fields
- return (
- # test input ONNX attributes
- dict(
- border=[5, 10, 15, 20],
- ),
- # reference output Node attributes
- dict(
- op='Crop',
- crop_begin=np.array([10, 5]),
- crop_end=np.array([20, 15]),
- axis=np.array([2, 3])
- )
- )
-
- @staticmethod
- def _extract(inp):
- node = __class__._create_node(inp)
- CropFrontExtractor.extract(node)
- return node.graph.node[node.id]
-
- def _match(self, out, ref):
- for key in ref.keys():
- status = out[key] == ref[key]
- if type(status) in [list, np.ndarray]:
- status = np.all(status)
- self.assertTrue(status, 'Mismatch for field {}, observed: {}, expected: {}'.format(key, out[key], ref[key]))
-
- def test_default(self):
- inp, ref = self._base_attrs()
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_with_scale(self):
- inp, ref = self._base_attrs()
- inp['scale'] = np.array([34, 50])
-
- del ref['crop_begin']
- del ref['crop_end']
- ref['dim'] = np.array([34, 50])
- ref['offset'] = np.array([10, 5])
-
- out = self._extract(inp)
- self._match(out, ref)
diff --git a/tools/mo/unit_tests/mo/front/onnx/detection_output_test.py b/tools/mo/unit_tests/mo/front/onnx/detection_output_test.py
deleted file mode 100644
index 4e0ff529ebb64a..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/detection_output_test.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.detection_output_ext import DetectionOutputFrontExtractor
-from openvino.tools.mo.ops.DetectionOutput import DetectionOutput
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import PB
-
-
-class TestDetectionOutputExt(unittest.TestCase):
- @staticmethod
- def _create_do_node(num_classes=0, share_location=0, background_label_id=0,
- code_type="", variance_encoded_in_target=0, keep_top_k=0,
- confidence_threshold=0, nms_threshold=0, top_k=0, eta=0):
- pb = onnx.helper.make_node(
- 'DetectionOutput',
- inputs=['x'],
- outputs=['y'],
- num_classes=num_classes,
- share_location=share_location,
- background_label_id=background_label_id,
- code_type=code_type,
- variance_encoded_in_target=variance_encoded_in_target,
- keep_top_k=keep_top_k,
- confidence_threshold=confidence_threshold,
- # nms_param
- nms_threshold=nms_threshold,
- top_k=top_k,
- eta=eta,
- )
-
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['DetectionOutput'] = DetectionOutput
-
- def test_do_no_pb_no_ml(self):
- self.assertRaises(AttributeError, DetectionOutputFrontExtractor.extract, None)
-
- def test_do_ext_ideal_numbers(self):
- node = self._create_do_node(num_classes=21, share_location=1,
- code_type="CENTER_SIZE", keep_top_k=200,
- confidence_threshold=0.01, nms_threshold=0.45, top_k=400, eta=1.0)
-
- DetectionOutputFrontExtractor.extract(node)
-
- exp_res = {
- 'op': 'DetectionOutput',
- 'type': 'DetectionOutput',
- 'num_classes': 21,
- 'share_location': 1,
- 'background_label_id': 0,
- 'code_type': "caffe.PriorBoxParameter.CENTER_SIZE",
- 'variance_encoded_in_target': 0,
- 'keep_top_k': 200,
- 'confidence_threshold': 0.01,
- 'visualize_threshold': 0.6,
- # nms_param
- 'nms_threshold': 0.45,
- 'top_k': 400,
- 'eta': 1.0,
- # ONNX have not such parameters
- # save_output_param.resize_param
- 'prob': 0,
- 'resize_mode': "",
- 'height': 0,
- 'width': 0,
- 'height_scale': 0,
- 'width_scale': 0,
- 'pad_mode': "",
- 'pad_value': "",
- 'interp_mode': "",
- 'input_width': 1,
- 'input_height': 1,
- 'normalized': 1,
- }
-
- for key in exp_res.keys():
- if key in ['confidence_threshold', 'visualise_threshold', 'nms_threshold', 'eta']:
- np.testing.assert_almost_equal(node[key], exp_res[key])
- else:
- self.assertEqual(node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/onnx/gru_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/gru_ext_test.py
deleted file mode 100644
index ffb92db6999abf..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/gru_ext_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.gru_ext import GRUFrontExtractor
-from unit_tests.utils.extractors import PB
-
-
-class GRUExtractorTest(unittest.TestCase):
- @staticmethod
- def _create_node(**attrs):
- pb = onnx.helper.make_node(
- 'GRU',
- inputs=['X', 'W', 'R', 'B',],
- outputs=['Y', 'Y_h', 'Y_c'],
- hidden_size=128,
- **attrs,
- )
- node = PB({'pb': pb})
- return node
-
- base_attrs = {
- 'type': 'RNNSequence',
- 'op': 'GRU',
- 'batch_dim': 1,
- 'sequence_dim': 0,
- 'blobs_wrb': True,
- 'has_num_directions': True,
- 'num_layers': 1,
- 'format': 'onnx',
- 'multilayers': False,
- 'gate_order': np.array([0, 1, 2]),
- 'direction': 'forward',
- 'linear_before_reset': 0,
- }
-
- def test_base_attrs(self):
- node = self._create_node()
- GRUFrontExtractor.extract(node)
-
- exp_res = self.base_attrs
-
- for key in exp_res.keys():
- equal = np.all(np.equal(node[key], exp_res[key], dtype=object))
- self.assertTrue(equal, 'Values for attr {} are not equal'.format(key))
-
- def test_additional_attributes(self):
- additional_attrs = {
- 'activation_alpha': [1.0, 0.0, 2.0],
- 'activations': [b'relu', b'tanh', b'sigmoid'],
- 'clip': 10.0,
- 'linear_before_reset': 1,
- }
-
- node = self._create_node(**additional_attrs)
- GRUFrontExtractor.extract(node)
-
- exp_res = {**self.base_attrs, **additional_attrs}
- exp_res['activations'] = ['relu', 'tanh', 'sigmoid']
-
- for key in exp_res.keys():
- equal = np.all(np.equal(node[key], exp_res[key], dtype=object))
- self.assertTrue(equal, 'Values for attr {} are not equal'.format(key))
diff --git a/tools/mo/unit_tests/mo/front/onnx/image_scaler_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/image_scaler_ext_test.py
deleted file mode 100644
index 169077ec6fe63c..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/image_scaler_ext_test.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.image_scaler_ext import ImageScalerFrontExtractor
-from unit_tests.utils.extractors import PB
-
-
-class TestImageScalerONNXExt(unittest.TestCase):
- @staticmethod
- def _create_image_scaler_node():
- pb = onnx.helper.make_node(
- 'ImageScaler',
- inputs=['a'],
- outputs=['b'],
- scale=1.0,
- bias=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
- )
- node = PB({'pb': pb, 'graph': PB({'graph': {'layout': 'NCHW'}})})
- return node
-
- def test_image_scaler_ext(self):
- node = self._create_image_scaler_node()
- ImageScalerFrontExtractor.extract(node)
-
- exp_res = {
- 'scale': 1.0,
- 'bias': [[[1.0]], [[2.0]], [[3.0]], [[4.0]], [[5.0]], [[6.0]], [[7.0]], [[8.0]]],
- }
-
- for key in exp_res.keys():
- if type(node[key]) in [list, np.ndarray]:
- self.assertTrue(np.array_equal(np.array(node[key]), np.array(exp_res[key])))
- else:
- self.assertEqual(node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/onnx/instance_normalization_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/instance_normalization_ext_test.py
deleted file mode 100644
index a0d7763d56c9cd..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/instance_normalization_ext_test.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import onnx
-
-from openvino.tools.mo.front.onnx.instance_normalization_ext import InstanceNormalizationExtractor
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class TestInstanceNormalization(BaseExtractorsTestingClass):
- @staticmethod
- def _create_node():
- pb = onnx.helper.make_node(
- 'InstanceNormalization',
- inputs=['a'],
- outputs=['b'],
- epsilon=0.5,
- )
- node = PB({'pb': pb})
- return node
-
- def test_image_scaler_ext(self):
- node = self._create_node()
- InstanceNormalizationExtractor.extract(node)
- self.res = node
-
- self.expected = {
- 'epsilon': 0.5,
- }
-
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/onnx/lstm_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/lstm_ext_test.py
deleted file mode 100644
index c5a4c9c6489246..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/lstm_ext_test.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.lstm_ext import LSTMFrontExtractor
-from unit_tests.utils.extractors import PB
-
-
-class LSTMExtractorTest(unittest.TestCase):
- @staticmethod
- def _create_node(**attrs):
- pb = onnx.helper.make_node(
- 'LSTM',
- inputs=['X', 'W', 'R', 'B',],
- outputs=['Y', 'Y_h', 'Y_c'],
- hidden_size=128,
- **attrs,
- )
- node = PB({'pb': pb})
- return node
-
- base_attrs = {
- 'type': 'RNNSequence',
- 'op': 'LSTM',
- 'batch_dim': 1,
- 'sequence_dim': 0,
- 'blobs_wrb': True,
- 'has_num_directions': True,
- 'num_layers': 1,
- 'format': 'onnx',
- 'multilayers': False,
- 'gate_order': np.array([2, 0, 3, 1]),
- 'direction': 'forward',
- }
-
- def test_base_attrs(self):
- node = self._create_node()
- LSTMFrontExtractor.extract(node)
-
- exp_res = self.base_attrs
-
- for key in exp_res.keys():
- equal = np.all(np.equal(node[key], exp_res[key], dtype=object))
- self.assertTrue(equal)
-
- def test_additional_attributes(self):
- additional_attrs = {
- 'activation_alpha': [1.0, 0.0, 2.0],
- 'activations': [b'relu', b'tanh', b'sigmoid'],
- 'clip': 10.0,
- }
-
- node = self._create_node(**additional_attrs)
- LSTMFrontExtractor.extract(node)
-
- exp_res = dict(**self.base_attrs, **additional_attrs)
- exp_res['activations'] = ['relu', 'tanh', 'sigmoid']
-
- for key in exp_res.keys():
- equal = np.all(np.equal(node[key], exp_res[key], dtype=object))
- self.assertTrue(equal, 'Values for attr {} are not equal'.format(key))
diff --git a/tools/mo/unit_tests/mo/front/onnx/normalize_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/normalize_ext_test.py
deleted file mode 100644
index 5468e3c6498b4c..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/normalize_ext_test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import onnx
-
-from openvino.tools.mo.front.onnx.normalize_ext import NormalizeFrontExtractor
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class TestNormalize(BaseExtractorsTestingClass):
- @staticmethod
- def _create_node(across_spatial=None, channel_shared=None, eps=None):
- if across_spatial is None:
- across_spatial = 0
- if channel_shared is None:
- channel_shared = 0
- if eps is None:
- eps = 0.1
- pb = onnx.helper.make_node(
- 'Normalize',
- across_spatial=across_spatial,
- channel_shared=channel_shared,
- eps=eps,
- inputs=['a'],
- outputs=['b']
- )
- node = PB({'pb': pb})
- return node
-
- def test_ok(self):
- node = self._create_node()
- NormalizeFrontExtractor.extract(node)
- self.res = node
-
- self.expected = {
- 'across_spatial': False,
- 'channel_shared': False,
- 'eps': 0.1
- }
-
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/onnx/pad_converter_test.py b/tools/mo/unit_tests/mo/front/onnx/pad_converter_test.py
deleted file mode 100644
index bc10fb391699f2..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/pad_converter_test.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.onnx.pad_converter import ONNXPadToPad
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-nodes_attributes = {
- 'placeholder': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- **const('pads', np.array([1, 2, 3, 4], dtype=np.int64)),
- **const('value', np.array(0.5, dtype=np.float32)),
- 'onnx_pad': {'type': None, 'kind': 'op', 'op': 'ONNXPad', 'name': 'my_pad', 'mode': 'constant'},
- 'result': {'type': 'Result', 'value': None, 'kind': 'op', 'op': 'Result'},
-
- 'pad': {'type': 'Pad', 'kind': 'op', 'op': 'Pad'},
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 2},
- **const('split_axis', np.array(0, dtype=np.int32)),
-}
-
-
-class AttributedClampNormalizerTest(unittest.TestCase):
- def test_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'onnx_pad', {'in': 0, 'out': 0}),
- ('pads', 'onnx_pad', {'in': 1, 'out': 0}),
- ('value', 'onnx_pad', {'in': 2, 'out': 0}),
- ('onnx_pad', 'result', {'in': 0, 'out': 0}),
- ],
- {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'pad', {'in': 0, 'out': 0}),
- ('pads', 'split', {'in': 0, 'out': 0}),
- ('split_axis', 'split', {'in': 1, 'out': 0}),
- ('split', 'pad', {'in': 1, 'out': 0}),
- ('split', 'pad', {'in': 2, 'out': 1}),
- ('value', 'pad', {'in': 3, 'out': 0}),
- ('pad', 'result')
- ],
- {}, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- ONNXPadToPad().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Pad')[0]]['name'] == 'my_pad')
diff --git a/tools/mo/unit_tests/mo/front/onnx/pad_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/pad_ext_test.py
deleted file mode 100644
index e59c4f4af271da..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/pad_ext_test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import onnx
-
-from openvino.tools.mo.front.onnx.pad_ext import PadFrontExtractor
-from openvino.tools.mo.graph.graph import Graph
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class TestPad(BaseExtractorsTestingClass):
- @staticmethod
- def _create_node(pads=None, value=None, mode=None):
- if pads is None:
- pads = [1, 2, 3, 4]
- if value is None:
- value = 0.0
- if mode is None:
- mode = 'constant'
- pb = onnx.helper.make_node(
- 'Pad',
- pads=pads,
- mode=mode,
- value=value,
- inputs=['a'],
- outputs=['b']
- )
- graph = Graph()
- node = PB({'pb': pb, 'graph': graph})
-
- return node
-
- def test_ok(self):
- node = self._create_node()
- PadFrontExtractor.extract(node)
- self.res = node
-
- self.expected = {
- 'pads': [[1, 3], [2, 4]],
- 'mode': 'constant',
- 'fill_value': 0
- }
-
- self.compare()
-
- def test_older_pad_opset_11(self):
- node = self._create_node()
- node.graph.graph['fw_opset_version'] = 11
- PadFrontExtractor.extract(node)
- self.res = node
-
- self.expected = {
- 'pads': [[1, 3], [2, 4]],
- 'mode': 'constant',
- 'fill_value': 0
- }
-
- self.compare()
-
- def test_reflect(self):
- node = self._create_node(mode='reflect')
- PadFrontExtractor.extract(node)
- self.res = node
-
- self.expected = {
- 'pads': [[1, 3], [2, 4]],
- 'mode': 'reflect',
- 'fill_value': 0
- }
-
- self.compare()
-
- def test_non_zero_fill_value(self):
- node = self._create_node(value=1.0)
- PadFrontExtractor.extract(node)
- self.res = node
-
- self.expected = {
- 'pads': [[1, 3], [2, 4]],
- 'mode': 'constant',
- 'fill_value': 1.0
- }
-
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/onnx/priorbox_clustered_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/priorbox_clustered_ext_test.py
deleted file mode 100644
index 9feb0233150fd8..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/priorbox_clustered_ext_test.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.priorbox_clustered_ext import PriorBoxClusteredFrontExtractor
-from openvino.tools.mo.ops.priorbox_clustered import PriorBoxClusteredOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import PB
-
-
-class TestPriorBoxClusteredExt(unittest.TestCase):
- @staticmethod
- def _create_priorbox_clustered_node(width=np.array([]), height=np.array([]),
- flip=False, clip=False, variance=None, img_size=0, img_h=0,
- img_w=0, step=0, step_h=0, step_w=0, offset=0):
- pb = onnx.helper.make_node(
- 'PriorBoxClustered',
- inputs=['x'],
- outputs=['y'],
- width=width,
- height=height,
- flip=flip,
- clip=clip,
- variance=variance,
- img_size=img_size,
- img_h=img_h,
- img_w=img_w,
- step=step,
- step_h=step_h,
- step_w=step_w,
- offset=offset,
- )
-
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['PriorBoxClustered'] = PriorBoxClusteredOp
-
- def test_priorbox_clustered_no_pb_no_ml(self):
- self.assertRaises(AttributeError, PriorBoxClusteredFrontExtractor.extract, None)
-
- def test_priorbox_clustered_ext_ideal_numbers(self):
- node = self._create_priorbox_clustered_node(width= np.array([2, 3], dtype=float),
- height=np.array([4, 5], dtype=float),
- variance=np.array([0.2, 0.3, 0.2, 0.3]),
- img_size=300, step=5.0, offset=0.6, flip=True)
-
- PriorBoxClusteredFrontExtractor.extract(node)
-
- exp_res = {
- 'op': 'PriorBoxClustered',
- 'type': 'PriorBoxClustered',
- 'clip': 0,
- 'flip': 1,
- 'width': np.array([2, 3], dtype=float),
- 'height': np.array([4, 5], dtype=float),
- 'variance': [0.2, 0.3, 0.2, 0.3],
- 'img_size': 300,
- 'img_h': 0,
- 'img_w': 0,
- 'step': 5,
- 'step_h': 0,
- 'step_w': 0,
- 'offset': 0.6
- }
-
- for key in exp_res.keys():
- if key in ['variance', 'width', 'height', 'step_h', 'step_w', 'offset']:
- np.testing.assert_almost_equal(node[key], exp_res[key])
- else:
- self.assertEqual(node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/onnx/priorbox_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/priorbox_ext_test.py
deleted file mode 100644
index 78b19c72f04381..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/priorbox_ext_test.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.priorbox_ext import PriorBoxFrontExtractor
-from openvino.tools.mo.ops.priorbox import PriorBoxOp
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import PB
-
-
-class TestPriorBoxExt(unittest.TestCase):
- @staticmethod
- def _create_priorbox_node(aspect_ratio=[], min_size=None, max_size=None,
- flip=False, clip=False, variance=None, img_size=0, img_h=0,
- img_w=0, step=0, step_h=0, step_w=0, offset=0):
- pb = onnx.helper.make_node(
- 'PriorBox',
- inputs=['x'],
- outputs=['y'],
- aspect_ratio=aspect_ratio,
- min_size=min_size,
- max_size=max_size,
- flip=flip,
- clip=clip,
- variance=variance,
- img_size=img_size,
- img_h=img_h,
- img_w=img_w,
- step=step,
- step_h=step_h,
- step_w=step_w,
- offset=offset,
- )
-
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['PriorBox'] = PriorBoxOp
-
- def test_priorbox_no_pb_no_ml(self):
- self.assertRaises(AttributeError, PriorBoxFrontExtractor.extract, None)
-
- def test_priorbox_ext_ideal_numbers(self):
- node = self._create_priorbox_node(aspect_ratio=np.array([2, 3], dtype=float),
- variance=np.array([0.2, 0.3, 0.2, 0.3]),
- img_size=300, step=5.0, offset=0.6, flip=True)
-
- PriorBoxFrontExtractor.extract(node)
-
- exp_res = {
- 'op': 'PriorBox',
- 'type': 'PriorBox',
- 'clip': 0,
- 'flip': 1,
- 'aspect_ratio': np.array([2, 3], dtype=float),
- 'variance': [0.2, 0.3, 0.2, 0.3],
- 'img_size': 300,
- 'img_h': 0,
- 'img_w': 0,
- 'step': 5,
- 'step_h': 0,
- 'step_w': 0,
- 'offset': 0.6
- }
-
- for key in exp_res.keys():
- if key in ['variance', 'aspect_ratio', 'step_h', 'step_w', 'offset']:
- np.testing.assert_almost_equal(node[key], exp_res[key])
- else:
- self.assertEqual(node[key], exp_res[key])
diff --git a/tools/mo/unit_tests/mo/front/onnx/rnn_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/rnn_ext_test.py
deleted file mode 100644
index 0d2d1f8b75a0ae..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/rnn_ext_test.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.rnn_ext import RNNFrontExtractor
-from unit_tests.utils.extractors import PB
-
-
-class RNNExtractorTest(unittest.TestCase):
- @staticmethod
- def _create_node(**attrs):
- pb = onnx.helper.make_node(
- 'RNN',
- inputs=['X', 'W', 'R', 'B',],
- outputs=['Y', 'Y_h', 'Y_c'],
- hidden_size=128,
- **attrs,
- )
- node = PB({'pb': pb})
- return node
-
- base_attrs = {
- 'type': 'RNNSequence',
- 'op': 'RNN',
- 'batch_dim': 1,
- 'sequence_dim': 0,
- 'blobs_wrb': True,
- 'has_num_directions': True,
- 'num_layers': 1,
- 'format': 'onnx',
- 'multilayers': False,
- 'gate_order': np.array([0]),
- 'direction': 'forward',
- }
-
- def test_base_attrs(self):
- node = self._create_node()
- RNNFrontExtractor.extract(node)
-
- exp_res = self.base_attrs
-
- for key in exp_res.keys():
- equal = np.all(np.equal(node[key], exp_res[key], dtype=object))
- self.assertTrue(equal)
-
- def test_additional_attributes(self):
- additional_attrs = {
- 'activation_alpha': [1.0, 0.0, 2.0],
- 'activations': [b'relu', b'tanh', b'sigmoid'],
- 'clip': 10.0,
- }
-
- node = self._create_node(**additional_attrs)
- RNNFrontExtractor.extract(node)
-
- exp_res = {**self.base_attrs, **additional_attrs}
- exp_res['activations'] = ['relu', 'tanh', 'sigmoid']
-
- for key in exp_res.keys():
- equal = np.all(np.equal(node[key], exp_res[key], dtype=object))
- self.assertTrue(equal, 'Values for attr {} are not equal'.format(key))
diff --git a/tools/mo/unit_tests/mo/front/onnx/squeeze_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/squeeze_ext_test.py
deleted file mode 100644
index d93c05b777723e..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/squeeze_ext_test.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import onnx
-import pytest
-
-from openvino.tools.mo.front.onnx.squeeze_ext import SqueezeFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.squeeze import Squeeze
-from unit_tests.utils.extractors import PB
-
-
-class TestSqueezeONNXExt():
- @staticmethod
- def _create_squeeze_node(axes):
- if axes is None:
- pb = onnx.helper.make_node(
- 'Squeeze',
- inputs=['x'],
- outputs=['y'],
- )
- else:
- pb = onnx.helper.make_node(
- 'Squeeze',
- inputs=['x'],
- outputs=['y'],
- axes=axes,
- )
-
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Squeeze'] = Squeeze
-
- @pytest.mark.parametrize("axes",[[0, 1, 2, 3], [1], None])
- def test_squeeze_ext(self, axes):
- node = self._create_squeeze_node(axes)
- SqueezeFrontExtractor.extract(node)
-
- exp_res = {
- 'type': 'Squeeze',
- 'squeeze_dims': axes,
- }
-
- for key in exp_res.keys():
- if type(node[key]) in [list, np.ndarray]:
- assert np.array_equal(np.array(node[key]), np.array(exp_res[key]))
- else:
- assert node[key] == exp_res[key]
diff --git a/tools/mo/unit_tests/mo/front/onnx/transpose_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/transpose_ext_test.py
deleted file mode 100644
index 5fba56077d0cd4..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/transpose_ext_test.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import itertools
-import pytest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.transpose_ext import TransposeFrontExtractor
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.ops.op import Op
-from unit_tests.utils.extractors import PB
-
-
-class TestTransposeONNXExt():
- @staticmethod
- def _create_transpose_node(order: list):
- if order is None:
- # Default transpose
- pb = onnx.helper.make_node(
- 'Transpose',
- inputs=['data'],
- outputs=['transposed'],
- )
- else:
- # Transpose with order
- pb = onnx.helper.make_node(
- 'Transpose',
- inputs=['data'],
- outputs=['transposed'],
- perm=order
- )
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Transpose'] = Transpose
- pass
-
- # This generator generates all permutations for [0,1,2,3] and [0,1,2] orders
- @pytest.mark.parametrize("order",[list(order) for order in list(itertools.permutations(np.arange(4)))] +
- [list(order) for order in list(itertools.permutations(np.arange(3)))] + [None])
- def test_transpose_ext(self, order):
- node = self._create_transpose_node(order)
- TransposeFrontExtractor.extract(node)
-
- exp_res = {
- 'type': 'Transpose',
- 'order': order,
- 'infer': Transpose.infer
- }
-
- for key in exp_res.keys():
- if isinstance(exp_res[key], list):
- assert np.array_equal(node[key], exp_res[key]),\
- "Orders are not the same: {} and {}".format(node[key], exp_res[key])
- else:
- assert node[key] == exp_res[key]
diff --git a/tools/mo/unit_tests/mo/front/onnx/unsqueeze_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/unsqueeze_ext_test.py
deleted file mode 100644
index 04164a7ce4c652..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/unsqueeze_ext_test.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-import onnx
-
-from openvino.tools.mo.front.onnx.unsqueeze_ext import UnsqueezeFrontExtractor
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from unit_tests.utils.extractors import PB
-
-
-class TestUnsqueezeONNXExt():
- @staticmethod
- def _create_unsqueeze_node(axes):
- if axes is None:
- pb = onnx.helper.make_node(
- 'Unsqueeze',
- inputs=['x'],
- outputs=['y'],
- )
- else:
- pb = onnx.helper.make_node(
- 'Unsqueeze',
- inputs=['x'],
- outputs=['y'],
- axes=axes,
- )
-
- node = PB({'pb': pb})
- return node
-
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['Unsqueeze'] = Unsqueeze
-
- @pytest.mark.parametrize("axes",[[0, 1, 2, 3], [1]])
- def test_unsqueeze_ext(self, axes):
- node = self._create_unsqueeze_node(axes)
- UnsqueezeFrontExtractor.extract(node)
-
- exp_res = {
- 'expand_axis': axes,
- }
-
- for key in exp_res.keys():
- if type(node[key]) in [list, np.ndarray]:
- assert np.array_equal(np.array(node[key]), np.array(exp_res[key]))
- else:
- assert node[key] == exp_res[key]
diff --git a/tools/mo/unit_tests/mo/front/onnx/upsample_ext_test.py b/tools/mo/unit_tests/mo/front/onnx/upsample_ext_test.py
deleted file mode 100644
index c58a78dd3bfc87..00000000000000
--- a/tools/mo/unit_tests/mo/front/onnx/upsample_ext_test.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import onnx
-
-from openvino.tools.mo.front.onnx.upsample_ext import UpsampleFrontExtractor
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.extractors import BaseExtractorsTestingClass
-from unit_tests.utils.graph import build_graph
-
-
-class UpsampleONNXExtractorTest(BaseExtractorsTestingClass):
- @staticmethod
- def _create_node(attrs: dict):
- pb = onnx.helper.make_node("Upsample", ["X"], ["Y"], **attrs)
- graph = build_graph({'node_0': {'pb': pb}}, [])
- return Node(graph, 'node_0')
-
- @staticmethod
- def _base_attrs():
- # Commonly used attributes in the tests
- # Each test takes these ones and then adds/modifies/deletes particular fields
- return (
- # test input ONNX attributes
- dict(
- mode='nearest',
- scales=[1., 1., 2., 2.],
- ),
- # reference output Node attributes
- dict(
- width_scale=2.0,
- height_scale=2.0,
- mode='nearest',
- )
- )
-
- @staticmethod
- def _extract(inp):
- node = __class__._create_node(inp)
- UpsampleFrontExtractor.extract(node)
- return node
-
- def _match(self, out, ref):
- self.res = out
- self.expected = ref
- self.compare()
-
- def test_all_valid_default(self):
- inp, ref = self._base_attrs()
- out = self._extract(inp)
- self._match(out, ref)
-
- def test_invalid_mode(self):
- inp, ref = self._base_attrs()
- inp['mode'] = 'invalid_mode'
- with self.assertRaisesRegex(Error, '.*decoding Upsample.*supported modes.*'):
- out = self._extract(inp)
-
- def test_invalid_scales(self):
- inp, ref = self._base_attrs()
- inp['scales'] = [1.5, 1.5, 2.0, 2.0]
- with self.assertRaisesRegex(Error, '.*Upsampling of batch and feature dimensions is not supported for node.*'):
- out = self._extract(inp)
-
- def test_invalid_2D_scales(self):
- inp, ref = self._base_attrs()
- inp['scales'] = [2.0, 2.0]
- with self.assertRaisesRegex(Error,
- '.*Upsample scales attribute is wrong for node.*. Only 4D scales are supported.'):
- out = self._extract(inp)
diff --git a/tools/mo/unit_tests/mo/front/output_cut_test.py b/tools/mo/unit_tests/mo/front/output_cut_test.py
deleted file mode 100644
index 6ea687ec999f2c..00000000000000
--- a/tools/mo/unit_tests/mo/front/output_cut_test.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.output_cut import OutputCut
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op
-
-nodes = {
- **regular_op('Parameter1', {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}),
- **regular_op('Op1', {'type': 'Op1', 'kind': 'op', 'op': 'Op1'}),
- **regular_op('Op2', {'type': 'Op2', 'kind': 'op', 'op': 'Op2'}),
-
- **regular_op('FakeOutput1', {'type': 'Identity', 'kind': 'op', 'op': 'Identity', 'needs_removal': True, 'id': 0}),
- **regular_op('FakeOutput2', {'type': 'Identity', 'kind': 'op', 'op': 'Identity', 'needs_removal': True, 'id': 1}),
-
-}
-
-
-class TestsOutputCut(unittest.TestCase):
- def test_case1(self):
- graph = build_graph(nodes, [('Parameter1', 'FakeOutput1',
- {'in': 0, 'out': 0, 'fw_tensor_debug_info':
- [('Parameter1', 'Parameter1_tensor_name')]})])
- graph.graph['packed_outputs'] = None
- graph.graph['user_shapes'] = None
-
- graph.stage = 'front'
- OutputCut().find_and_replace_pattern(graph)
-
- param1 = Node(graph, 'Parameter1')
- self.assertTrue(param1.out_node()['type'] == 'Result')
- self.assertTrue(param1.out_edge()['fw_tensor_debug_info'] == [('Parameter1', 'Parameter1_tensor_name')])
- self.assertTrue(graph.get_op_nodes(name='FakeOutput1') == [])
-
- def test_case2(self):
- graph = build_graph(nodes, [('Parameter1', 'Op1'),
- ('Op1', 'FakeOutput1',
- {'in': 1, 'out': 1, 'fw_tensor_debug_info':
- [('Op1', 'Op1_tensor_name')]}),
- ('Parameter1', 'Op2'),
- ('Op2', 'FakeOutput2',
- {'in': 2, 'out': 3,
- 'fw_tensor_debug_info': [('Op2', 'Op2_tensor_name')]})])
- graph.graph['packed_outputs'] = None
- graph.graph['user_shapes'] = None
-
- graph.stage = 'front'
- OutputCut().find_and_replace_pattern(graph)
-
- op1 = Node(graph, 'Op1')
- op2 = Node(graph, 'Op2')
- self.assertTrue(op1.out_node(1)['type'] == 'Result')
- self.assertTrue(op2.out_node(3)['type'] == 'Result')
- self.assertTrue(op1.out_edge(1)['fw_tensor_debug_info'] == [('Op1', 'Op1_tensor_name')])
- self.assertTrue(op2.out_edge(3)['fw_tensor_debug_info'] == [('Op2', 'Op2_tensor_name')])
- self.assertTrue(graph.get_op_nodes(name='FakeOutput1') == [])
- self.assertTrue(graph.get_op_nodes(name='FakeOutput2') == [])
-
- def test_case3(self):
- graph = build_graph(nodes, [])
- graph.graph['packed_outputs'] = None
- graph.graph['user_shapes'] = None
-
- graph.stage = 'front'
- OutputCut().find_and_replace_pattern(graph)
-
- self.assertTrue(graph.get_op_nodes(name='FakeOutput1') == [])
- self.assertTrue(graph.get_op_nodes(name='FakeOutput2') == [])
diff --git a/tools/mo/unit_tests/mo/front/rank_decomposer_test.py b/tools/mo/unit_tests/mo/front/rank_decomposer_test.py
deleted file mode 100644
index 860e58c69327f7..00000000000000
--- a/tools/mo/unit_tests/mo/front/rank_decomposer_test.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.rank_decomposer import RankDecomposer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, \
- valued_const_with_data
-
-nodes = lambda output_type: {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('rank', {'op': 'Rank', 'type': None, 'output_type': output_type, 'name': 'my_rank'}),
- **result(),
-
- **regular_op_with_empty_data('shape', {'type': 'ShapeOf', 'output_type': output_type}),
- **regular_op_with_empty_data('rank_1D', {'type': 'ShapeOf', 'output_type': output_type}),
- **valued_const_with_data('zero', int64_array(0)),
- **regular_op_with_empty_data('rank_0D', {'type': 'Squeeze'}),
-}
-
-
-class TestRankDecomposerTest():
-
- @pytest.mark.parametrize("output_type", [np.int32, np.int64])
- def test_rank_decomposer(self, output_type):
- graph = build_graph(nodes_attrs=nodes(output_type), edges=[
- *connect('input', 'rank'),
- *connect('rank', 'output'),
- ], nodes_with_edges_only=True)
- RankDecomposer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attrs=nodes(output_type), edges=[
- *connect('input', 'shape'),
- *connect('shape', 'rank_1D'),
- *connect('rank_1D', '0:rank_0D'),
- *connect('zero', '1:rank_0D'),
- *connect('rank_0D', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
- assert graph.get_op_nodes(type='Squeeze')[0]['name'] == 'my_rank',\
- 'Name is not inherited from original node for RankDecomposer'
- print(output_type)
-
- def test_rank_decomposer_assertion(self):
- graph = build_graph(nodes_attrs=nodes(None), edges=[
- *connect('input', 'rank'),
- *connect('rank', 'output'),
- ], nodes_with_edges_only=True)
- with pytest.raises(AssertionError):
- RankDecomposer().find_and_replace_pattern (graph)
diff --git a/tools/mo/unit_tests/mo/front/reciprocal_test.py b/tools/mo/unit_tests/mo/front/reciprocal_test.py
deleted file mode 100644
index eeb88858000e21..00000000000000
--- a/tools/mo/unit_tests/mo/front/reciprocal_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.reciprocal import ReciprocalReplacer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- # Reciprocal operation
- 'reciprocal_1': {'kind': 'op', 'op': 'Reciprocal'},
- # Test operation
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None},
- # Pow operations
- 'const': {'value': np.array(-1), 'op': 'Const', 'kind': 'op'},
- 'pow': {'type': 'Power', 'kind': 'op', 'op': 'Pow'},
-}
-
-
-class ReciprocalReplacerTests(unittest.TestCase):
- def test_reciprocal_test_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'reciprocal_1'),
- ('reciprocal_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'pow', {'in': 0}),
- ('const', 'pow', {'in': 1}),
- ('pow', 'last'),
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- pattern = ReciprocalReplacer()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_neg_reciprocal_1(self):
- # Test if power = 0
-
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'reciprocal_1'),
- ('reciprocal_1', 'last')
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'pow'),
- ('const', 'pow', {'in': 1}),
- ('pow', 'last'),
- ],
- {'placeholder_1': {'shape': np.array([1, 227, 227, 3])},
- 'const': {'value': np.array(0)},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'front'
-
- pattern = ReciprocalReplacer()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(not flag)
diff --git a/tools/mo/unit_tests/mo/front/reduce_axis_normalizer_test.py b/tools/mo/unit_tests/mo/front/reduce_axis_normalizer_test.py
deleted file mode 100644
index 762141aa1a9602..00000000000000
--- a/tools/mo/unit_tests/mo/front/reduce_axis_normalizer_test.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.reduce_axis_normalizer import ReduceAxisNormalizer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect_front, regular_op
-
-nodes = {
- **regular_op('parameter', {'type': 'Parameter'}),
- **regular_op('reduce', {'op': 'ReduceSum', 'axis': None}),
- **regular_op('axis', {'op': 'Const', 'type': 'Const', 'value': int64_array([1])}),
- **result(),
-}
-
-edges = [
- *connect_front('parameter:0', '0:reduce'),
- *connect_front('reduce', 'output'),
-]
-
-
-class ReduceAxisNormalizerTest(unittest.TestCase):
- def test_reduce_axis_is_None(self):
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- ReduceAxisNormalizer().find_and_replace_pattern(graph)
-
- ref_nodes = nodes.copy()
- ref_nodes.update({**regular_op('rank', {'op': 'Rank', 'type': None}),
- **regular_op('range', {'op': 'Range', 'type': 'Range'}),
- **regular_op('begin', {'type': 'Const', 'value': int64_array([0])}),
- **regular_op('step', {'type': 'Const', 'value': int64_array([1])}),
- })
- graph_ref = build_graph(ref_nodes, [
- *edges,
- *connect_front('parameter:0', 'rank'),
- *connect_front('begin:0', '0:range'),
- *connect_front('rank:0', '1:range'),
- *connect_front('step:0', '2:range'),
- *connect_front('range:0', '1:reduce'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_reduce_axis_is_const(self):
- graph = build_graph(nodes, edges, {'reduce': {'axis': 1}}, nodes_with_edges_only=True)
- graph.stage = 'front'
-
- graph_ref = build_graph(nodes, [
- *edges,
- *connect_front('axis', '1:reduce'),
- ], {'axis': {'value': np.int64(1)}}, nodes_with_edges_only=True)
-
- ReduceAxisNormalizer().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/scatter_normalizer_test.py b/tools/mo/unit_tests/mo/front/scatter_normalizer_test.py
deleted file mode 100644
index cf8be349401969..00000000000000
--- a/tools/mo/unit_tests/mo/front/scatter_normalizer_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.scatter_normalizer import ScatterNormalizer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, \
- regular_op_with_empty_data
-
-nodes = {
- **regular_op_with_empty_data('placeholder_1', {'type': 'Parameter'}),
- **regular_op_with_empty_data('placeholder_2', {'type': 'Parameter'}),
- **regular_op_with_empty_data('placeholder_3', {'type': 'Parameter'}),
- **regular_op_with_empty_data('node', {'op': 'ScatterElementsUpdate', 'is_scatter': True}),
- **regular_op_with_empty_data('axis', {'type': 'Const', 'value': None}),
- **result(),
-}
-
-edges = [
- *connect('placeholder_1', '0:node'),
- *connect('placeholder_2', '1:node'),
- *connect('placeholder_3', '2:node'),
- *connect('node', 'output'),
-]
-
-
-class TestDiv(unittest.TestCase):
- def test_ScatterElementsUpdate_has_axis_and_3_inputs(self):
- graph = build_graph(nodes, edges, {'node': {'axis': 1}}, nodes_with_edges_only=True)
- ScatterNormalizer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *edges,
- *connect('axis', '3:node'),
- ], {'axis': {'value': np.int64(1)}}, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ScatterElementsUpdate_has_axis_and_4_inputs(self):
- graph = build_graph(nodes, [
- *edges,
- *connect('axis', '3:node'),
- ], {'node': {'axis': 1}, 'axis': {'value': np.int64(1)}}, nodes_with_edges_only=True)
- self.assertRaises(AssertionError, ScatterNormalizer().find_and_replace_pattern, graph)
-
- def test_ScatterElementsUpdate_has_no_axis_and_3_inputs(self):
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- self.assertRaises(AssertionError, ScatterNormalizer().find_and_replace_pattern, graph)
-
- def test_ScatterElementsUpdate_has_no_axis_and_4_inputs(self):
- graph = build_graph(nodes, [
- *edges,
- *connect('axis', '3:node'),
- ], {'axis': {'value': np.int64(1)}}, nodes_with_edges_only=True)
- ScatterNormalizer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *edges,
- *connect('axis', '3:node'),
- ], {'axis': {'value': np.int64(1)}}, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/size_replacer_test.py b/tools/mo/unit_tests/mo/front/size_replacer_test.py
deleted file mode 100644
index 2117e44c0fd25d..00000000000000
--- a/tools/mo/unit_tests/mo/front/size_replacer_test.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.SizeReplacer import SizeFrontReplacer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, \
- valued_const_with_data
-
-nodes = lambda output_type: {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('size', {'op': 'Size', 'type': None, 'output_type': output_type, 'name': 'my_size'}),
- **result(),
-
- **regular_op_with_empty_data('shape', {'type': 'ShapeOf', 'output_type': output_type}),
- **valued_const_with_data('zero', int64_array([0])),
- **regular_op_with_empty_data('reduce', {'type': 'ReduceProd', 'keep_dims': False}),
-}
-
-
-class TestSizeReplacerTest():
-
- @pytest.mark.parametrize("output_type" ,[np.int32, np.int64])
- def test_size_replacer(self, output_type):
- graph = build_graph(nodes_attrs=nodes(output_type), edges=[
- *connect('input', 'size'),
- *connect('size', 'output'),
- ], nodes_with_edges_only=True)
- SizeFrontReplacer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attrs=nodes(output_type), edges=[
- *connect('input', 'shape'),
- *connect('shape', '0:reduce'),
- *connect('zero', '1:reduce'),
- *connect('reduce', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
- assert graph.get_op_nodes(type='ReduceProd')[0]['name'] == 'my_size',\
- 'Name is not inherited from original node for SizeReplacer'
- print(output_type)
-
- def test_size_replacer_assertion(self):
- graph = build_graph(nodes_attrs=nodes(None), edges=[
- *connect('input', 'size'),
- *connect('size', 'output'),
- ], nodes_with_edges_only=True)
- with pytest.raises(AssertionError):
- SizeFrontReplacer().find_and_replace_pattern (graph)
diff --git a/tools/mo/unit_tests/mo/front/split_normalizer_test.py b/tools/mo/unit_tests/mo/front/split_normalizer_test.py
deleted file mode 100644
index 926f29422359d4..00000000000000
--- a/tools/mo/unit_tests/mo/front/split_normalizer_test.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.split_normalizer import SqueezeAxis
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-nodes_attributes = {
- 'placeholder': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'attr_split': {'type': None, 'kind': 'op', 'op': 'AttributedSplit', 'axis': 0, 'num_splits': 2,
- 'squeeze_axis': True},
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 2, 'squeeze_axis': True},
- **const('split_axis', int64_array(0)),
- 'concat': {'type': 'Concat', 'kind': 'op', 'op': 'Concat', 'axis': 0},
- 'result': {'type': 'Result', 'value': None, 'kind': 'op', 'op': 'Result'},
-
- 'squeeze1': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- 'squeeze2': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- **const('squeeze1_axis', int64_array(0)),
- **const('squeeze2_axis', int64_array(0)),
-}
-
-
-class SqueezeAxisTest(unittest.TestCase):
- def test_attributed(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'attr_split', {'in': 0, 'out': 0}),
- ('attr_split', 'concat', {'in': 0, 'out': 0}),
- ('attr_split', 'concat', {'in': 1, 'out': 1}),
- ('concat', 'result', {'in': 0, 'out': 0}),
- ], nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'attr_split', {'in': 0, 'out': 0}),
- ('attr_split', 'squeeze1', {'in': 0, 'out': 0}),
- ('squeeze1_axis', 'squeeze1', {'in': 1, 'out': 0}),
- ('attr_split', 'squeeze2', {'in': 0, 'out': 1}),
- ('squeeze2_axis', 'squeeze2', {'in': 1, 'out': 0}),
- ('squeeze1', 'concat', {'in': 0, 'out': 0}),
- ('squeeze2', 'concat', {'in': 1, 'out': 0}),
- ('concat', 'result', {'in': 0, 'out': 0}),
- ], nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- SqueezeAxis().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_split(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'split', {'in': 0, 'out': 0}),
- ('split_axis', 'split', {'in': 1, 'out': 0}),
- ('split', 'concat', {'in': 0, 'out': 0}),
- ('split', 'concat', {'in': 1, 'out': 1}),
- ('concat', 'result', {'in': 0, 'out': 0}),
- ], nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'split', {'in': 0, 'out': 0}),
- ('split_axis', 'split', {'in': 1, 'out': 0}),
- ('split', 'squeeze1', {'in': 0, 'out': 0}),
- ('split_axis', 'squeeze1', {'in': 1, 'out': 0}),
- ('split', 'squeeze2', {'in': 0, 'out': 1}),
- ('split_axis', 'squeeze2', {'in': 1, 'out': 0}),
- ('squeeze1', 'concat', {'in': 0, 'out': 0}),
- ('squeeze2', 'concat', {'in': 1, 'out': 0}),
- ('concat', 'result', {'in': 0, 'out': 0}),
- ], nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph.stage = 'front'
-
- SqueezeAxis().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/sub_test.py b/tools/mo/unit_tests/mo/front/sub_test.py
deleted file mode 100644
index 50cbe26634d9ad..00000000000000
--- a/tools/mo/unit_tests/mo/front/sub_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.sub import Sub
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect, \
- connect_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder_1', [1, 227, 227, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('placeholder_2', [1, 227, 227, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('sub', None, {'op': 'Sub', 'type': 'Subtract', 'name': 'my_sub'}),
-
- **regular_op_with_shaped_data('negate', [1, 227, 227, 3], {'type': 'Multiply'}),
- **valued_const_with_data('minus_one', np.array(-1.)),
- **regular_op_with_shaped_data('add', None, {'type': 'Add'}),
-
- **result(),
-}
-
-
-class TestSub(unittest.TestCase):
- def test_sub_test_1(self):
- # Test with two different inputs from two placeholders
- graph = build_graph(nodes, [
- *connect('placeholder_1', '0:sub'),
- *connect('placeholder_2', '1:sub'),
- *connect('sub', 'output'),
- ], nodes_with_edges_only=True)
- Sub().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_1', '0:add'),
- *connect('placeholder_2', '0:negate'),
- *connect('minus_one', '1:negate'),
- *connect('negate', '1:add'),
- *connect('add', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='Add')[0]]['name'] == 'my_sub')
-
- def test_sub_test_2(self):
- # Test with two same inputs from one placeholder
- graph = build_graph(nodes, [
- *connect('placeholder_1:0', '0:sub'),
- *connect_data('placeholder_1:0', '1:sub'),
- *connect('sub', 'output'),
- ], nodes_with_edges_only=True)
- Sub().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_1:0', '0:add'),
- *connect_data('placeholder_1:0', '0:negate'),
- *connect('minus_one', '1:negate'),
- *connect('negate', '1:add'),
- *connect('add', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='Add')[0]]['name'] == 'my_sub')
diff --git a/tools/mo/unit_tests/mo/front/tf/CTCGreedyDecoderReplacement_test.py b/tools/mo/unit_tests/mo/front/tf/CTCGreedyDecoderReplacement_test.py
deleted file mode 100644
index 4b4e4ebd069b1e..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/CTCGreedyDecoderReplacement_test.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.CTCGreedyDecoderReplacement import CTCGreedyDecoderReplacement, \
- CTCGreedyDecoderWithSparseToDenseShapeReplacement, CTCGreedyDecoderSingleReplacement
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-class CTCGreedyDecoderReplacementTests(unittest.TestCase):
- nodes_attributes = {
- # nodes from original graph
- 'logits': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'seq_len': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'order_arr': {'kind': 'op', 'op': 'Const'},
- 'transpose': {'type': 'Transpose', 'kind': 'op', 'op': 'Transpose'},
- 'decoder': {'kind': 'op', 'op': 'CTCGreedyDecoderSeqLen', 'merge_repeated': True, 'output_sparse_format': True},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'sparse_to_dense': {'kind': 'op', 'op': 'SparseToDense'},
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'last_1': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-
- # new nodes
- 'new_decoder': {'kind': 'op', 'op': 'CTCGreedyDecoderSeqLen', 'merge_repeated': True},
- **const('squeeze_axes', int64_array([2, 3])),
- 'squeeze_dec_seq': {'kind': 'op', 'op': 'Squeeze'},
- 'cast_to_int': {'kind': 'op', 'op': 'Cast'},
- 'out_seq_len': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- }
-
- def test_CTCGreedyDecoderWithSparseToDenseShape(self):
- graph = build_graph(self.nodes_attributes,
- [('logits', 'decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'decoder', {'out': 0, 'in': 1}),
- ('decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('decoder', 'sparse_to_dense', {'out': 2, 'in': 1}),
- ('decoder', 'cast', {'out': 1, 'in': 0}),
- ('cast', 'sparse_to_dense', {'out': 0}),
- ('sparse_to_dense', 'last', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- CTCGreedyDecoderWithSparseToDenseShapeReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('order_arr', 'transpose', {'out': 0, 'in': 1}),
- ('transpose', 'new_decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'new_decoder', {'out': 0, 'in': 1}),
- ('new_decoder', 'last', {'out': 0, 'in': 0}),
- ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_CTCGreedyDecoderReplacement(self):
- graph = build_graph(self.nodes_attributes,
- [('logits', 'decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'decoder', {'out': 0, 'in': 1}),
- ('decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('decoder', 'cast', {'out': 1, 'in': 0}),
- ('cast', 'sparse_to_dense', {'out': 0}),
- ('sparse_to_dense', 'last', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- CTCGreedyDecoderReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('order_arr', 'transpose', {'out': 0, 'in': 1}),
- ('transpose', 'new_decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'new_decoder', {'out': 0, 'in': 1}),
- ('new_decoder', 'last', {'out': 0, 'in': 0}),
- ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_CTCGreedyDecoderSingle(self):
- graph = build_graph(self.nodes_attributes,
- [('logits', 'decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'decoder', {'out': 0, 'in': 1}),
- ('decoder', 'last', {'out': 0, 'in': 0}),
- ('decoder', 'last_1', {'out': 1, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- CTCGreedyDecoderSingleReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('order_arr', 'transpose', {'out': 0, 'in': 1}),
- ('transpose', 'new_decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'new_decoder', {'out': 0, 'in': 1}),
- ('new_decoder', 'last', {'out': 0, 'in': 0}),
- ('new_decoder', 'last_1', {'out': 1, 'in': 0}),
- ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_CTCGreedyDecoderSingle_negative(self):
- edges = [('logits', 'decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'decoder', {'out': 0, 'in': 1}),
- ('decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('decoder', 'cast', {'out': 1, 'in': 0}),
- ('cast', 'sparse_to_dense', {'out': 0}),
- ('sparse_to_dense', 'last', {'out': 0, 'in': 0}),
- ]
- graph = build_graph(self.nodes_attributes,
- edges, nodes_with_edges_only=True)
- graph.stage = 'front'
- CTCGreedyDecoderSingleReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- edges, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_CTCGreedyDecoder_no_consequent_transforms(self):
- graph = build_graph(self.nodes_attributes,
- [('logits', 'decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'decoder', {'out': 0, 'in': 1}),
- ('decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('decoder', 'sparse_to_dense', {'out': 2, 'in': 1}),
- ('decoder', 'cast', {'out': 1, 'in': 0}),
- ('cast', 'sparse_to_dense', {'out': 0}),
- ('sparse_to_dense', 'last', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- CTCGreedyDecoderWithSparseToDenseShapeReplacement().find_and_replace_pattern(graph)
- CTCGreedyDecoderSingleReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('order_arr', 'transpose', {'out': 0, 'in': 1}),
- ('transpose', 'new_decoder', {'out': 0, 'in': 0}),
- ('seq_len', 'new_decoder', {'out': 0, 'in': 1}),
- ('new_decoder', 'last', {'out': 0, 'in': 0}),
- ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/CTCLossReplacement_test.py b/tools/mo/unit_tests/mo/front/tf/CTCLossReplacement_test.py
deleted file mode 100644
index eaf44cf4b5bd49..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/CTCLossReplacement_test.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import unittest
-from argparse import Namespace
-
-from openvino.tools.mo.front.tf.CTCLossReplacement import CTCLossReplacement
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-class CTCLossFrontReplacementTest(unittest.TestCase):
- nodes_attributes = {
- 'logits': {'shape': int64_array([2, 6, 100]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'seq_mask': {'shape': int64_array([2]), 'data_type': np.int32, 'kind': 'op', 'op': 'Parameter'},
- 'transpose': {'kind': 'op', 'op': 'Transpose'},
- 'ctc_greedy_decoder': {'kind': 'op', 'op': 'CTCGreedyDecoderSeqLen', 'merge_repeated': True,
- 'output_sparse_format': True},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'sparse_to_dense': {'kind': 'op', 'op': 'SparseToDense'},
- 'tf_ctc_loss_true_logits': {'kind': 'op', 'op': 'CTCLoss', 'preprocess_collapse_repeated': False,
- 'ctc_merge_repeated': True, 'unique': False, 'logits_time_major': True},
- 'tf_ctc_loss_false_logits': {'kind': 'op', 'op': 'CTCLoss', 'preprocess_collapse_repeated': False,
- 'ctc_merge_repeated': True, 'unique': False, 'logits_time_major': False},
- 'ctc_loss': {'kind': 'op', 'op': 'CTCLoss', 'preprocess_collapse_repeated': False,
- 'ctc_merge_repeated': True, 'unique': False},
- **const('default_value', int64_array(-1)),
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'transpose2': {'kind': 'op', 'op': 'Transpose'},
- **const('transpose2_axis', int64_array([1, 0, 2])),
-
- 'new_ctc_greedy_decoder': {'kind': 'op', 'op': 'CTCGreedyDecoderSeqLen', 'merge_repeated': True},
- }
-
- def CTCLossReplacement_test_true_logits(self):
- graph = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('transpose', 'ctc_greedy_decoder', {'out': 0, 'in': 0}),
- ('seq_mask', 'ctc_greedy_decoder', {'out': 0, 'in': 1}),
- ('transpose', 'tf_ctc_loss_true_logits', {'out': 0, 'in': 0}),
- ('seq_mask', 'tf_ctc_loss_true_logits', {'out': 0, 'in': 3}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 2, 'in': 1}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 1, 'in': 2}),
- ('default_value', 'sparse_to_dense', {'out': 0, 'in': 3}),
- ('ctc_greedy_decoder', 'cast', {'out': 1, 'in': 0}),
- ('ctc_greedy_decoder', 'tf_ctc_loss_true_logits', {'out': 0, 'in': 1}),
- ('cast', 'tf_ctc_loss_true_logits', {'out': 0, 'in': 2}),
- ('tf_ctc_loss_true_logits', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
- graph.graph['cmd_params'] = Namespace(data_type='FP32')
- graph.stage = 'front'
- CTCLossReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('transpose', 'transpose2', {'out': 0, 'in': 0}),
- ('transpose2_axis', 'transpose2', {'out': 0, 'in': 1}),
- ('transpose2', 'new_ctc_greedy_decoder', {'out': 0, 'in': 0}),
- ('seq_mask', 'new_ctc_greedy_decoder', {'out': 0, 'in': 1}),
- ('transpose2', 'ctc_loss', {'out': 0, 'in': 0}),
- ('new_ctc_greedy_decoder', 'ctc_loss', {'out': 0, 'in': 2}),
- ('new_ctc_greedy_decoder', 'ctc_loss', {'out': 1, 'in': 3}),
- ('seq_mask', 'ctc_loss', {'out': 0, 'in': 1}),
- ('ctc_loss', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def CTCLossReplacement_test_false_logits(self):
- graph = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('transpose', 'ctc_greedy_decoder', {'out': 0, 'in': 0}),
- ('seq_mask', 'ctc_greedy_decoder', {'out': 0, 'in': 1}),
- ('transpose', 'tf_ctc_loss_false_logits', {'out': 0, 'in': 0}),
- ('seq_mask', 'tf_ctc_loss_false_logits', {'out': 0, 'in': 3}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 2, 'in': 1}),
- ('ctc_greedy_decoder', 'sparse_to_dense', {'out': 1, 'in': 2}),
- ('default_value', 'sparse_to_dense', {'out': 0, 'in': 3}),
- ('ctc_greedy_decoder', 'cast', {'out': 1, 'in': 0}),
- ('ctc_greedy_decoder', 'tf_ctc_loss_false_logits', {'out': 0, 'in': 1}),
- ('cast', 'tf_ctc_loss_false_logits', {'out': 0, 'in': 2}),
- ('tf_ctc_loss_false_logits', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
- graph.graph['cmd_params'] = Namespace(data_type='FP32')
- graph.stage = 'front'
- CTCLossReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(self.nodes_attributes,
- [('logits', 'transpose', {'out': 0, 'in': 0}),
- ('transpose', 'transpose2', {'out': 0, 'in': 0}),
- ('transpose2_axis', 'transpose2', {'out': 0, 'in': 1}),
- ('transpose2', 'new_ctc_greedy_decoder', {'out': 0, 'in': 0}),
- ('seq_mask', 'new_ctc_greedy_decoder', {'out': 0, 'in': 1}),
- ('transpose', 'ctc_loss', {'out': 0, 'in': 0}),
- ('new_ctc_greedy_decoder', 'ctc_loss', {'out': 0, 'in': 2}),
- ('new_ctc_greedy_decoder', 'ctc_loss', {'out': 1, 'in': 3}),
- ('seq_mask', 'ctc_loss', {'out': 0, 'in': 1}),
- ('ctc_loss', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/ComplexAbsAfterComplex_test.py b/tools/mo/unit_tests/mo/front/tf/ComplexAbsAfterComplex_test.py
deleted file mode 100644
index 616730d868e2fc..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/ComplexAbsAfterComplex_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.ComplexAbsAfterComplex import ComplexAbsAfterComplex
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-graph_node_attrs = {
- 'placeholder_0': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'complex': {'kind': 'op', 'op': 'Complex'},
- 'complex_abs': {'kind': 'op', 'op': 'ComplexAbs'},
- 'relu': {'type': 'ReLU', 'kind': 'op', 'op': 'ReLU'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges = [
- ('placeholder_0', 'complex', {'in': 0}),
- ('placeholder_1', 'complex', {'in': 1}),
- ('complex', 'complex_abs', {'in': 0}),
- ('complex_abs', 'relu'),
- ('relu', 'output'),
-]
-
-
-ref_graph_node_attrs = {
- 'placeholder_0': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pow0_const': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': np.float32(2.0)
- },
- 'pow1_const': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': np.float32(2.0)
- },
- 'pow0': {'type': 'Power', 'kind': 'op', 'op': 'Pow'},
- 'pow1': {'type': 'Power', 'kind': 'op', 'op': 'Pow'},
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'sqrt_const': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': np.float32(0.5)
- },
- 'sqrt': {'type': 'Power', 'kind': 'op', 'op': 'Pow'},
- 'relu': {'type': 'ReLU', 'kind': 'op', 'op': 'ReLU'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-ref_graph_edges = [
- ('placeholder_0', 'pow0', {'in': 0}),
- ('placeholder_1', 'pow1', {'in': 0}),
- ('pow0_const', 'pow0', {'in': 1}),
- ('pow1_const', 'pow1', {'in': 1}),
- ('pow0', 'add', {'in': 0}),
- ('pow1', 'add', {'in': 1}),
- ('add', 'sqrt', {'in': 0}),
- ('sqrt_const', 'sqrt', {'in': 1}),
- ('sqrt', 'relu'),
- ('relu', 'output'),
-]
-
-
-class ComplexAbsAfterComplexTest(unittest.TestCase):
- def test_replacement(self):
- graph = build_graph(nodes_attrs=graph_node_attrs, edges=graph_edges)
- graph.stage = 'front'
- ComplexAbsAfterComplex().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs, edges=ref_graph_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/ComplexAbs_test.py b/tools/mo/unit_tests/mo/front/tf/ComplexAbs_test.py
deleted file mode 100644
index af9e6ba50eb52d..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/ComplexAbs_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.ComplexAbs import ComplexAbs
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'complex_abs': {'kind': 'op', 'op': 'ComplexAbs'},
- 'relu': {'type': 'ReLU', 'kind': 'op', 'op': 'ReLU'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges = [
- ('placeholder', 'complex_abs'),
- ('complex_abs', 'relu'),
- ('relu', 'output'),
-]
-
-
-ref_graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pow2_const': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': np.float32(2.0)
- },
- 'pow2': {'type': 'Power', 'kind': 'op', 'op': 'Pow'},
- 'sum_axis': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': int64_array(-1)
- },
- 'sum': {'type': 'ReduceSum', 'kind': 'op', 'op': 'ReduceSum'},
- 'sqrt_const': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': np.float32(0.5)
- },
- 'sqrt': {'type': 'Power', 'kind': 'op', 'op': 'Pow'},
- 'relu': {'type': 'ReLU', 'kind': 'op', 'op': 'ReLU'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-ref_graph_edges = [
- ('placeholder', 'pow2', {'in': 0}),
- ('pow2_const', 'pow2', {'in': 1}),
- ('sum_axis', 'sum', {'in': 1}),
- ('pow2', 'sum', {'in': 0}),
- ('sum', 'sqrt', {'in': 0}),
- ('sqrt_const', 'sqrt', {'in': 1}),
- ('sqrt', 'relu'),
- ('relu', 'output'),
-]
-
-
-class ComplexAbsTest(unittest.TestCase):
- def test_replacement(self):
- graph = build_graph(nodes_attrs=graph_node_attrs, edges=graph_edges)
- graph.stage = 'front'
- ComplexAbs().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs, edges=ref_graph_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/CorrectPaddingsForPadAfterComplex_test.py b/tools/mo/unit_tests/mo/front/tf/CorrectPaddingsForPadAfterComplex_test.py
deleted file mode 100644
index 29800e400e7557..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/CorrectPaddingsForPadAfterComplex_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import unittest
-import numpy as np
-
-
-from openvino.tools.mo.front.tf.CorrectPaddingsForPadAfterComplex import CorrectPaddingsForPadAfterComplex
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-graph_node_attrs = {
- 'placeholder_real': {'shape': int64_array([3, 100, 67]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_imag': {'shape': int64_array([3, 100, 67]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'complex': {'kind': 'op', 'op': 'Complex'},
- 'pad': {'type': 'Pad', 'kind': 'op', 'op': 'Pad', 'mode': 'constant'},
- **const('pad_begin', int64_array([1, 3, 5])),
- **const('pad_end', int64_array([2, 4, 6])),
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges = [
- ('placeholder_real', 'complex', {'in': 0}),
- ('placeholder_imag', 'complex', {'in': 1}),
- ('complex', 'pad', {'in': 0, 'out': 0}),
- ('pad_begin', 'pad', {'in': 1, 'out': 0}),
- ('pad_end', 'pad', {'in': 2, 'out': 0}),
- ('pad', 'abs'),
- ('abs', 'output'),
-]
-
-
-ref_graph_node_attrs = {
- 'placeholder_real': {'shape': int64_array([3, 100, 67]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_imag': {'shape': int64_array([3, 100, 67]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'complex': {'kind': 'op', 'op': 'Complex'},
- 'pad': {'type': 'Pad', 'kind': 'op', 'op': 'Pad', 'mode': 'constant'},
- **const('pad_begin', int64_array([1, 3, 5])),
- **const('pad_end', int64_array([2, 4, 6])),
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- **const('additional_pad_begin', int64_array([0])),
- **const('additional_pad_end', int64_array([0])),
- 'concat_for_pad_begin': {'kind': 'op', 'op': 'Concat', 'type': 'Concat', 'axis': 0},
- 'concat_for_pad_end': {'kind': 'op', 'op': 'Concat', 'type': 'Concat', 'axis': 0},
-}
-
-ref_graph_edges = [
- ('placeholder_real', 'complex', {'in': 0}),
- ('placeholder_imag', 'complex', {'in': 1}),
- ('complex', 'pad', {'in': 0, 'out': 0}),
- ('pad_begin', 'concat_for_pad_begin', {'in': 0, 'out': 0}),
- ('additional_pad_begin', 'concat_for_pad_begin', {'in': 1, 'out': 0}),
- ('pad_end', 'concat_for_pad_end', {'in': 0, 'out': 0}),
- ('additional_pad_end', 'concat_for_pad_end', {'in': 1, 'out': 0}),
- ('concat_for_pad_begin', 'pad', {'in': 1, 'out': 0}),
- ('concat_for_pad_end', 'pad', {'in': 2, 'out': 0}),
- ('pad', 'abs'),
- ('abs', 'output'),
-]
-
-
-class CorrectPaddingsForPadAfterComplexTest(unittest.TestCase):
- def test_replacement(self):
- graph = build_graph(nodes_attrs=graph_node_attrs, edges=graph_edges)
- graph.stage = 'front'
- CorrectPaddingsForPadAfterComplex().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs, edges=ref_graph_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/IteratorGetNextCut_test.py b/tools/mo/unit_tests/mo/front/tf/IteratorGetNextCut_test.py
deleted file mode 100644
index 6654f1bee8e6a5..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/IteratorGetNextCut_test.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.IteratorGetNextCut import IteratorGetNextCut
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-class IteratorGetNextAnalysisTest(unittest.TestCase):
-
- def test_one_output(self):
- graph = build_graph_with_edge_attrs(
- {
- 'iter_get_next': {'kind': 'op', 'op': 'IteratorGetNext', 'shapes': shape_array([[2, 2]]),
- 'types': [np.int32]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- },
- [
- ('iter_get_next', 'sub', {'out': 0, 'in': 0}),
- ]
- )
-
- graph_ref = build_graph_with_edge_attrs(
- {
- 'parameter_1': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([2, 2]), 'type': np.int32},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- },
- [
- ('parameter_1', 'sub', {'out': 0, 'in': 0}),
- ]
- )
-
- IteratorGetNextCut().find_and_replace_pattern(graph)
-
- flag, msg = compare_graphs(graph, graph_ref, last_node='sub')
- self.assertTrue(flag, msg)
-
- def test_two_outputs(self):
- graph = build_graph_with_edge_attrs(
- {
- 'iter_get_next': {'kind': 'op', 'op': 'IteratorGetNext', 'shapes': [shape_array([2, 2]),
- shape_array([1, 1])],
- 'types': [np.int32, np.float32]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'concat': {'kind': 'op', 'op': 'Concat'}
- },
- [
- ('iter_get_next', 'sub', {'out': 0, 'in': 0}),
- ('iter_get_next', 'add', {'out': 1, 'in': 0}),
- ('sub', 'concat', {'out': 0, 'in': 0}),
- ('add', 'concat', {'out': 0, 'in': 1})
- ]
- )
-
- graph_ref = build_graph_with_edge_attrs(
- {
- 'parameter_1': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([2, 2]), 'data_type': np.int32},
- 'parameter_2': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([1, 1]), 'data_type': np.float32},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'concat': {'kind': 'op', 'op': 'Concat'}
- },
- [
- ('parameter_1', 'sub', {'out': 0, 'in': 0}),
- ('parameter_2', 'add', {'out': 0, 'in': 0}),
- ('sub', 'concat', {'out': 0, 'in': 0}),
- ('add', 'concat', {'out': 0, 'in': 1})
- ]
- )
-
- IteratorGetNextCut().find_and_replace_pattern(graph)
-
- flag, msg = compare_graphs(graph, graph_ref, last_node='concat', check_op_attrs=True)
- self.assertTrue(flag, msg)
-
- def test_unsupported_data_type(self):
- graph = build_graph_with_edge_attrs(
- {
- 'iter_get_next': {'kind': 'op', 'op': 'IteratorGetNext', 'shapes': [shape_array([2, 2])],
- 'types': [None]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'result': {'kind': 'op', 'op': 'Result'}
- },
- [
- ('iter_get_next', 'sub', {'out': 0, 'in': 0}),
- ('sub', 'result', {'out': 0, 'in': 0}),
- ]
- )
-
- self.assertRaises(Error, IteratorGetNextCut().find_and_replace_pattern, graph)
diff --git a/tools/mo/unit_tests/mo/front/tf/NonConstBeginStridedSliceReplacement_test.py b/tools/mo/unit_tests/mo/front/tf/NonConstBeginStridedSliceReplacement_test.py
deleted file mode 100644
index a603fdd6af7e9c..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/NonConstBeginStridedSliceReplacement_test.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.NonConstBeginStridedSliceReplacement import NonConstBeginStridedSliceReplacement
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-class NonConstBeginStridedSliceReplacementTests(unittest.TestCase):
- def test1(self):
- nodes_attributes = {
- # nodes from original graph
- 'input': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'index': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- **const('slice_size', int64_array(1)),
- 'begin': {'type': 'Pack', 'kind': 'op', 'op': 'Pack'},
- **const('begin_1', int64_array(0)),
- **const('begin_3', int64_array(0)),
- 'end': {'type': 'Pack', 'kind': 'op', 'op': 'Pack'},
- **const('end_1', int64_array(0)),
- **const('end_3', int64_array(0)),
- **const('step', int64_array([1, 1, 1])),
- 'strided_slice': {'type': 'StridedSlice', 'kind': 'op', 'op': 'StridedSlice',
- 'begin_mask': int64_array([0, 1, 0]), 'end_mask': int64_array([0, 1, 0]),
- 'shrink_axis_mask': int64_array([0, 1, 0]), 'name': 'non_const_begin_strided_slice'},
- 'result': {'type': 'Result', 'kind': 'op', 'op': 'Result'},
-
- # nodes from the reference graph
- 'unsqueeze': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- **const('unsqueeze_axis', int64_array(0)),
- 'gather': {'type': 'Gather', 'kind': 'op', 'op': 'Gather'},
- **const('gather_axis', int64_array(1)),
- 'squeeze': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- **const('squeeze_axis', int64_array(1)),
- }
-
- graph = build_graph(nodes_attributes,
- [('input', 'strided_slice', {'out': 0, 'in': 0}),
- ('begin_1', 'begin', {'out': 0, 'in': 0}),
- ('index', 'begin', {'out': 0, 'in': 1}),
- ('begin_3', 'begin', {'out': 0, 'in': 2}),
- ('begin', 'strided_slice', {'out': 0, 'in': 1}),
- ('end_1', 'end', {'out': 0, 'in': 0}),
- ('index', 'add', {'out': 0, 'in': 0}),
- ('slice_size', 'add', {'out': 0, 'in': 1}),
- ('add', 'end', {'out': 0, 'in': 1}),
- ('end_3', 'end', {'out': 0, 'in': 2}),
- ('end', 'strided_slice', {'out': 0, 'in': 2}),
- ('step', 'strided_slice', {'out': 0, 'in': 3}),
- ('strided_slice', 'result', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- NonConstBeginStridedSliceReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input', 'gather', {'out': 0, 'in': 0}),
- ('gather_axis', 'gather', {'out': 0, 'in': 2}),
- ('index', 'unsqueeze', {'out': 0, 'in': 0}),
- ('unsqueeze_axis', 'unsqueeze', {'out': 0, 'in': 1}),
- ('unsqueeze', 'gather', {'out': 0, 'in': 1}),
- ('gather', 'squeeze', {'out': 0, 'in': 0}),
- ('squeeze_axis', 'squeeze', {'out': 0, 'in': 1}),
- ('squeeze', 'result', {'out': 0, 'in': 0}),
- ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Squeeze')[0]]['name'] ==
- 'non_const_begin_strided_slice')
-
- def test2_not_applied_transform(self):
- # the transformation is not applied if begin and end are constant
- nodes_attributes = {
- # nodes from original graph
- 'input': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'begin': {'type': 'Pack', 'kind': 'op', 'op': 'Pack'},
- **const('begin_1', int64_array(0)),
- **const('begin_2', int64_array(0)),
- **const('begin_3', int64_array(0)),
- 'end': {'type': 'Pack', 'kind': 'op', 'op': 'Pack'},
- **const('end_1', int64_array(0)),
- **const('end_2', int64_array(3)),
- **const('end_3', int64_array(0)),
- **const('step', int64_array([1, 1, 1])),
- 'strided_slice': {'type': 'StridedSlice', 'kind': 'op', 'op': 'StridedSlice',
- 'begin_mask': int64_array([0, 1, 0]), 'end_mask': int64_array([0, 1, 0]),
- 'shrink_axis_mask': int64_array([0, 1, 0]), 'name': 'non_const_begin_strided_slice'},
- 'result': {'type': 'Result', 'kind': 'op', 'op': 'Result'},
- }
-
- graph = build_graph(nodes_attributes,
- [('input', 'strided_slice', {'out': 0, 'in': 0}),
- ('begin_1', 'begin', {'out': 0, 'in': 0}),
- ('begin_2', 'begin', {'out': 0, 'in': 1}),
- ('begin_3', 'begin', {'out': 0, 'in': 2}),
- ('begin', 'strided_slice', {'out': 0, 'in': 1}),
- ('end_1', 'end', {'out': 0, 'in': 0}),
- ('end_2', 'end', {'out': 0, 'in': 1}),
- ('end_3', 'end', {'out': 0, 'in': 2}),
- ('end', 'strided_slice', {'out': 0, 'in': 2}),
- ('step', 'strided_slice', {'out': 0, 'in': 3}),
- ('strided_slice', 'result', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- NonConstBeginStridedSliceReplacement().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input', 'strided_slice', {'out': 0, 'in': 0}),
- ('begin_1', 'begin', {'out': 0, 'in': 0}),
- ('begin_2', 'begin', {'out': 0, 'in': 1}),
- ('begin_3', 'begin', {'out': 0, 'in': 2}),
- ('begin', 'strided_slice', {'out': 0, 'in': 1}),
- ('end_1', 'end', {'out': 0, 'in': 0}),
- ('end_2', 'end', {'out': 0, 'in': 1}),
- ('end_3', 'end', {'out': 0, 'in': 2}),
- ('end', 'strided_slice', {'out': 0, 'in': 2}),
- ('step', 'strided_slice', {'out': 0, 'in': 3}),
- ('strided_slice', 'result', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/ObjectDetectionAPI_test.py b/tools/mo/unit_tests/mo/front/tf/ObjectDetectionAPI_test.py
deleted file mode 100644
index d8abd85e2a3268..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/ObjectDetectionAPI_test.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from argparse import Namespace
-from unittest.mock import patch
-import os
-
-import pytest
-
-from openvino.tools.mo.front.tf.ObjectDetectionAPI import calculate_shape_keeping_aspect_ratio, \
- calculate_placeholder_spatial_shape, ObjectDetectionAPIPreprocessor2Replacement
-from openvino.tools.mo.front.common.partial_infer.utils import float32_array
-from openvino.tools.mo.front.subgraph_matcher import SubgraphMatch
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.utils.custom_replacement_config import CustomReplacementDescriptor
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.mo.utils.pipeline_config_test import file_content
-from unit_tests.utils.graph import const, regular_op, result, build_graph, connect_front
-from openvino.runtime import PartialShape
-
-
-class FakePipelineConfig:
- def __init__(self, model_params: dict):
- self._model_params = model_params
-
- def get_param(self, param: str):
- if param not in self._model_params:
- return None
- return self._model_params[param]
-
-
-class TestCalculateShape():
- min_size = 600
- max_size = 1024
-
- @pytest.mark.parametrize("h, w, th, tw",[(100, 300, 341, 1024),
- (100, 600, 171, 1024),
- (100, 3000, 34, 1024),
- (300, 300, 600, 600),
- (300, 400, 600, 800),
- (300, 600, 512, 1024),
- (1000, 2500, 410, 1024),
- (1800, 2000, 600, 667),
- (300, 100, 1024, 341),
- (600, 100, 1024, 171),
- (3000, 100, 1024, 34),
- (400, 300, 800, 600),
- (600, 300, 1024, 512),
- (2500, 1000, 1024, 410),
- (2000, 1800, 667, 600),
- ])
- def test_calculate_shape(self, h, w, th, tw):
- assert calculate_shape_keeping_aspect_ratio(h, w, self.min_size, self.max_size) == (th, tw)
-
-
-class TestCalculatePlaceholderSpatialShape(unittest.TestCase):
- def setUp(self):
- self.graph = Graph()
- self.graph.graph['user_shapes'] = None
- self.replacement_desc = CustomReplacementDescriptor('dummy_id', {})
- self.match = SubgraphMatch(self.graph, self.replacement_desc, [], [], [], '')
- self.pipeline_config = FakePipelineConfig({})
-
- def test_default_fixed_shape_resizer(self):
- self.pipeline_config._model_params['resizer_image_height'] = 300
- self.pipeline_config._model_params['resizer_image_width'] = 600
- self.assertTupleEqual((300, 600),
- calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
-
- def test_fixed_shape_resizer_overrided_by_user(self):
- self.pipeline_config._model_params['resizer_image_height'] = 300
- self.pipeline_config._model_params['resizer_image_width'] = 600
- self.graph.graph['user_shapes'] = {'image_tensor': [{'shape': PartialShape([1, 400, 500, 3])}]}
- self.assertTupleEqual((400, 500),
- calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
-
- def test_default_keep_aspect_ratio_resizer(self):
- self.pipeline_config._model_params['resizer_min_dimension'] = 600
- self.pipeline_config._model_params['resizer_max_dimension'] = 1024
- self.assertTupleEqual((600, 600),
- calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
-
- def test_keep_aspect_ratio_resizer_overrided_by_user(self):
- self.pipeline_config._model_params['resizer_min_dimension'] = 600
- self.pipeline_config._model_params['resizer_max_dimension'] = 1024
- self.graph.graph['user_shapes'] = {'image_tensor': [{'shape': PartialShape([1, 400, 300, 3])}]}
- self.assertTupleEqual((800, 600),
- calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
-
- def test_keep_aspect_ratio_resizer_overrided_by_user_pad(self):
- self.pipeline_config._model_params['resizer_min_dimension'] = 600
- self.pipeline_config._model_params['resizer_max_dimension'] = 1024
- self.pipeline_config._model_params['pad_to_max_dimension'] = True
- self.graph.graph['user_shapes'] = {'image_tensor': [{'shape': PartialShape([1, 400, 300, 3])}]}
- self.assertTupleEqual((1024, 1024),
- calculate_placeholder_spatial_shape(self.graph, self.match, self.pipeline_config))
-
- def test_missing_input_shape_information(self):
- self.assertRaises(Error, calculate_placeholder_spatial_shape, self.graph, self.match, self.pipeline_config)
-
-
-@patch('openvino.tools.mo.front.tf.ObjectDetectionAPI.update_parameter_shape')
-class TestObjectDetectionAPIPreprocessor2Replacement(unittest.TestCase):
- def setUp(self):
- self.start_node_name = 'StatefulPartitionedCall/Preprocessor/unstack'
- self.end_node_name = 'StatefulPartitionedCall/Preprocessor/stack'
- self.end_node_name2 = 'StatefulPartitionedCall/Preprocessor/stack2'
- self.loop_start_node_name = 'prefix/map/while/Preprocessor/unstack'
- self.loop_end_node_name = 'prefix/map/while/Preprocessor/stack'
- self.mul_const = float32_array([0.025, 0.374, -0.45])
- self.sub_const = float32_array([2.0, 3.0, 4.0])
-
- self.nodes = {
- **regular_op('input', {'op': 'Parameter', 'type': 'Parameter'}),
-
- **regular_op('mul', {'op': 'Mul', 'type': 'Multiply', 'name': 'my_mul'}),
- **regular_op('sub', {'op': 'Sub', 'type': 'Subtract', 'name': 'my_sub'}),
- **const('mul_const', self.mul_const),
- **const('sub_const', self.sub_const),
-
- **regular_op(self.start_node_name, {'op': 'Identity'}),
- **regular_op(self.end_node_name, {'op': 'Identity'}),
- **regular_op(self.end_node_name2, {'op': 'Identity'}),
-
- **regular_op('loop', {'op': 'Loop', 'body': None}),
-
- **regular_op('resize', {'type': 'Interpolate'}),
- **result('result'),
- }
- self.replacement_desc = {'start_nodes': [self.start_node_name],
- 'end_nodes': [self.end_node_name, self.end_node_name2]}
-
- def build_ref_graph(self, preprocessing: bool):
- if preprocessing:
- ref_edges = [*connect_front('input', '0:mul'),
- *connect_front('mul_const', '1:mul'),
- *connect_front('sub_const', '0:sub'),
- *connect_front('mul', '1:sub'),
- *connect_front('sub', 'result'),
- ]
- else:
- ref_edges = [*connect_front('input', 'result')]
- ref_graph = build_graph(self.nodes, ref_edges, nodes_with_edges_only=True)
- ref_graph.stage = 'front'
- return ref_graph
-
- def test_case_1_pad_to_max_dim(self, update_parameter_shape_mock):
- # test for case #1 described in the ObjectDetectionAPIPreprocessor2Replacement
- # sub/mul should be removed because they are applied before prep-processing and pad_to_max_dimension is True
- update_parameter_shape_mock.return_value = (None, None)
- edges = [*connect_front('input', '0:mul'),
- *connect_front('mul_const', '1:mul'),
- *connect_front('sub_const', '0:sub'),
- *connect_front('mul', '1:sub'),
- *connect_front('sub', self.start_node_name),
- *connect_front(self.start_node_name, 'resize'),
- *connect_front('resize', self.end_node_name),
- *connect_front(self.end_node_name, 'result'),
- ]
- graph = build_graph(self.nodes, edges)
- graph.stage = 'front'
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(False), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_case_1_no_pad_to_max_dim(self, update_parameter_shape_mock):
- # test for case #1 described in the ObjectDetectionAPIPreprocessor2Replacement
- # sub/mul should be kept even though they are applied before prep-processing and pad_to_max_dimension is False
- update_parameter_shape_mock.return_value = (None, None)
- edges = [*connect_front('input', '0:mul'),
- *connect_front('mul_const', '1:mul'),
- *connect_front('sub_const', '0:sub'),
- *connect_front('mul', '1:sub'),
- *connect_front('sub', self.start_node_name),
- *connect_front(self.start_node_name, 'resize'),
- *connect_front('resize', self.end_node_name),
- *connect_front(self.end_node_name, 'result'),
- ]
- graph = build_graph(self.nodes, edges)
- graph.stage = 'front'
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- updated_pipeline_config_content = file_content.replace('pad_to_max_dimension: true',
- 'pad_to_max_dimension: false')
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=updated_pipeline_config_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(True), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_case_2(self, update_parameter_shape_mock):
- # test for case #2 described in the ObjectDetectionAPIPreprocessor2Replacement
- update_parameter_shape_mock.return_value = (None, None)
-
- edges = [*connect_front('input', self.start_node_name),
- *connect_front(self.start_node_name, 'resize'),
- *connect_front('resize', self.end_node_name),
- *connect_front(self.end_node_name, '0:mul'),
- *connect_front('mul_const', '1:mul'),
- *connect_front('sub_const', '0:sub'),
- *connect_front('mul', '1:sub'),
- *connect_front('sub', 'result'),
- ]
- graph = build_graph(self.nodes, edges)
- graph.stage = 'front'
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(True), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_case_3(self, update_parameter_shape_mock):
- # test for case #3 described in the ObjectDetectionAPIPreprocessor2Replacement
- update_parameter_shape_mock.return_value = (None, None)
-
- edges = [*connect_front('input', self.start_node_name),
- *connect_front(self.start_node_name, 'resize'),
- *connect_front('resize', self.end_node_name),
- *connect_front(self.end_node_name, 'result'),
- ]
- graph = build_graph(self.nodes, edges)
- graph.stage = 'front'
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(False), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def build_main_graph(self, pre_processing: str):
- def build_body_graph(pre_processing: str):
- nodes = {
- **regular_op('input', {'type': 'Parameter', 'op': 'Parameter'}),
-
- **regular_op('mul', {'op': 'Mul', 'type': 'Multiply', 'name': 'my_body_mul'}),
- **regular_op('sub', {'op': 'Sub', 'type': 'Subtract', 'name': 'my_body_sub'}),
- **const('body_mul_const', self.mul_const),
- **const('body_sub_const', self.sub_const),
-
- **regular_op(self.loop_start_node_name, {'op': 'Identity'}),
- **regular_op(self.loop_end_node_name, {'op': 'Identity'}),
-
- **regular_op('resize', {'type': 'Interpolate'}),
- **result('result'),
- }
- if pre_processing == 'no':
- edges = [*connect_front('input', self.loop_start_node_name),
- *connect_front(self.loop_start_node_name, 'resize'),
- *connect_front('resize', self.loop_end_node_name),
- *connect_front(self.loop_end_node_name, 'result'),
- ]
- elif pre_processing == 'trailing':
- edges = [*connect_front('input', self.loop_start_node_name),
- *connect_front(self.loop_start_node_name, 'resize'),
- *connect_front('resize', self.loop_end_node_name),
- *connect_front(self.loop_end_node_name, '0:mul'),
- *connect_front('body_mul_const', '1:mul'),
- *connect_front('body_sub_const', '0:sub'),
- *connect_front('mul', '1:sub'),
- *connect_front('sub', 'result'),
- ]
- else:
- edges = [*connect_front('input', '0:mul'),
- *connect_front('body_mul_const', '1:mul'),
- *connect_front('body_sub_const', '0:sub'),
- *connect_front('mul', '1:sub'),
- *connect_front('sub', self.loop_start_node_name),
- *connect_front(self.loop_start_node_name, 'resize'),
- *connect_front('resize', self.loop_end_node_name),
- *connect_front(self.loop_end_node_name, 'result'),
- ]
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'front'
- return graph
-
- edges = [*connect_front('input', self.start_node_name),
- *connect_front(self.start_node_name, 'loop'),
- *connect_front('loop:0', self.end_node_name),
- *connect_front('loop:1', self.end_node_name2),
- *connect_front(self.end_node_name, 'result'),
- ]
- graph = build_graph(self.nodes, edges, {'loop': {'body': build_body_graph(pre_processing)}},
- nodes_with_edges_only=True)
- graph.stage = 'front'
- return graph
-
- def test_case_4(self, update_parameter_shape_mock):
- # test for case #4 described in the ObjectDetectionAPIPreprocessor2Replacement
- update_parameter_shape_mock.return_value = (None, None)
-
- graph = self.build_main_graph('leading')
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(True), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_case_5(self, update_parameter_shape_mock):
- # test for case #5 described in the ObjectDetectionAPIPreprocessor2Replacement
- update_parameter_shape_mock.return_value = (None, None)
-
- graph = self.build_main_graph('trailing')
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(True), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_case_6(self, update_parameter_shape_mock):
- # test for case #6 described in the ObjectDetectionAPIPreprocessor2Replacement
- update_parameter_shape_mock.return_value = (None, None)
-
- graph = self.build_main_graph('no')
- graph.graph['cmd_params'] = Namespace(tensorflow_object_detection_api_pipeline_config=__file__)
-
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- ObjectDetectionAPIPreprocessor2Replacement().transform_graph(graph, self.replacement_desc)
-
- (flag, resp) = compare_graphs(graph, self.build_ref_graph(False), 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class TestPipelineConfig(unittest.TestCase):
- def test_pipeline_config_loading(self):
- from openvino.tools.mo.utils.pipeline_config import PipelineConfig
- pipeline_config = PipelineConfig(os.path.join(os.path.dirname(__file__), "test_configs/config1.config"))
- assert pipeline_config.get_param('ssd_anchor_generator_num_layers') == 6
- assert pipeline_config.get_param('num_classes') == 90
- assert pipeline_config.get_param('resizer_image_width') == 300
- assert pipeline_config.get_param('resizer_image_height') == 300
-
- pipeline_config = PipelineConfig(os.path.join(os.path.dirname(__file__), "test_configs/config2.config"))
- assert pipeline_config.get_param('ssd_anchor_generator_num_layers') is None
- assert pipeline_config.get_param('num_classes') == 10
- assert pipeline_config.get_param('resizer_image_width') == 640
- assert pipeline_config.get_param('resizer_image_height') == 640
diff --git a/tools/mo/unit_tests/mo/front/tf/RFFTRealImagToRFFTSplit_test.py b/tools/mo/unit_tests/mo/front/tf/RFFTRealImagToRFFTSplit_test.py
deleted file mode 100644
index e3789e8bec24dd..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/RFFTRealImagToRFFTSplit_test.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.RFFTRealImagToRFFTSplit import RFFTRealImagToRDFTSplit
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 192, 36, 64]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'rfft': {'kind': 'op', 'op': 'TFFFT', 'num_of_dimensions': 2, 'fft_kind': 'RDFT'},
- 'real': {'kind': 'op', 'op': 'Real'},
- 'imag': {'kind': 'op', 'op': 'Imag'},
- 'real_sigmoid': {'type': 'Sigmoid', 'kind': 'op', 'op': 'Sigmoid'},
- 'imag_sigmoid': {'type': 'Sigmoid', 'kind': 'op', 'op': 'Sigmoid'},
- 'rfft_lengths': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([36, 33])
- },
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges = [
- ('placeholder', 'rfft', {'in': 0}),
- ('rfft', 'real', {'out': 0, 'in': 0}),
- ('rfft', 'imag', {'out': 0, 'in': 0}),
- ('real', 'real_sigmoid', {'in': 0}),
- ('imag', 'imag_sigmoid', {'in': 0}),
- ('real_sigmoid', 'add', {'in': 0}),
- ('imag_sigmoid', 'add', {'in': 1}),
- ('rfft_lengths', 'rfft', {'in': 1}),
- ('add', 'abs'),
- ('abs', 'output'),
-]
-
-
-ref_graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 192, 36, 64]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'rfft': {'kind': 'op', 'op': 'TFFFT', 'num_of_dimensions': 2, 'fft_kind': 'RDFT'},
- 'real': {'kind': 'op', 'op': 'Real'},
- 'imag': {'kind': 'op', 'op': 'Imag'},
- 'real_sigmoid': {'type': 'Sigmoid', 'kind': 'op', 'op': 'Sigmoid'},
- 'imag_sigmoid': {'type': 'Sigmoid', 'kind': 'op', 'op': 'Sigmoid'},
- 'rfft_lengths': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([36, 33])
- },
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 2},
- 'split_axis': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array(-1).shape, 'value': int64_array(-1)
- },
- 'real_squeeze': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- 'imag_squeeze': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- 'real_squeeze_axis': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array(-1).shape, 'value': int64_array(-1)
- },
- 'imag_squeeze_axis': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array(-1).shape, 'value': int64_array(-1)
- },
-}
-
-ref_graph_edges = [
- ('placeholder', 'rfft', {'in': 0}),
- ('rfft', 'split', {'in': 0, 'out': 0}),
- ('split_axis', 'split', {'in': 1}),
- ('split', 'real_squeeze', {'in': 0, 'out': 0}),
- ('split', 'imag_squeeze', {'in': 0, 'out': 1}),
- ('real_squeeze_axis', 'real_squeeze', {'in': 1}),
- ('imag_squeeze_axis', 'imag_squeeze', {'in': 1}),
- ('rfft_lengths', 'rfft', {'in': 1}),
- ('real_squeeze', 'real_sigmoid', {'in': 0}),
- ('imag_squeeze', 'imag_sigmoid', {'in': 0}),
- ('real_sigmoid', 'add', {'in': 0}),
- ('imag_sigmoid', 'add', {'in': 1}),
- ('add', 'abs'),
- ('abs', 'output'),
-]
-
-
-class TestRFFTRealImagToRFFTSplitTest():
- @pytest.mark.parametrize("num_of_dims",[1, 2, 3])
- def test_replacement(self, num_of_dims):
- graph = build_graph(nodes_attrs=graph_node_attrs,
- edges=graph_edges,
- update_attributes={
- 'rfft': {'num_of_dimensions': num_of_dims}
- })
- graph.stage = 'front'
- RFFTRealImagToRDFTSplit().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs,
- edges=ref_graph_edges,
- update_attributes={
- 'rfft': {'num_of_dimensions': num_of_dims}
- })
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/front/tf/RollRealImagPack_test.py b/tools/mo/unit_tests/mo/front/tf/RollRealImagPack_test.py
deleted file mode 100644
index 155efb4dbbc787..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/RollRealImagPack_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import unittest
-
-from openvino.tools.mo.front.tf.RollRealImagPack import RollRealImagPack
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'unroll': {'kind': 'op', 'op': 'Roll', 'type': 'Roll'},
- 'real': {'kind': 'op', 'op': 'Real'},
- 'imag': {'kind': 'op', 'op': 'Imag'},
- 'pack': {'kind': 'op', 'op': 'Pack'},
- 'unroll_shift': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([50, 50])
- },
- 'unroll_axes': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([-2, -1])
- },
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges = [
- ('placeholder', 'unroll', {'in': 0}),
- ('unroll', 'real', {'out': 0, 'in': 0}),
- ('unroll', 'imag', {'out': 0, 'in': 0}),
- ('real', 'pack', {'in': 0}),
- ('imag', 'pack', {'in': 1}),
- ('pack', 'abs'),
- ('abs', 'output'),
- ('unroll_shift', 'unroll', {'in': 1}),
- ('unroll_axes', 'unroll', {'in': 2}),
-]
-
-
-ref_graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'unroll': {'kind': 'op', 'op': 'Roll', 'type': 'Roll'},
- 'unroll_shift': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([50, 50])
- },
- 'unroll_axes': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([-2, -1])
- },
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'mul': {'type': 'Multiply', 'kind': 'op', 'op': 'Mul'},
- 'less': {'type': 'Less', 'kind': 'op', 'op': 'Less'},
- 'zero': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([]), 'value': int64_array(0)
- },
- 'minus_one': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([]), 'value': int64_array(-1)
- },
-}
-
-ref_graph_edges = [
- ('placeholder', 'unroll', {'out': 0, 'in': 0}),
- ('unroll', 'abs'),
- ('abs', 'output'),
- ('unroll_shift', 'unroll', {'in': 1}),
- ('unroll_axes', 'unroll', {'in': 2}),
-
- ('mul', 'add', {'in': 1}),
- ('add', 'unroll', {'in': 2}),
- ('zero', 'less', {'in': 1}),
- ('minus_one', 'mul', {'in': 1}),
- ('less', 'mul', {'in': 0}),
- ('unroll_axes', 'less', {'out': 0, 'in': 0}),
- ('unroll_axes', 'add', {'out': 0, 'in': 0}),
-]
-
-
-class RollRealImagPackTest(unittest.TestCase):
- def test_replacement(self):
- graph = build_graph(nodes_attrs=graph_node_attrs, edges=graph_edges)
- graph.stage = 'front'
- RollRealImagPack().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs, edges=ref_graph_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/SwitchMergeOptimization_test.py b/tools/mo/unit_tests/mo/front/tf/SwitchMergeOptimization_test.py
deleted file mode 100644
index 376eb62e135058..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/SwitchMergeOptimization_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.SwitchMergeOptimization import SwitchMergeOptimization
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class SwitchMergeOptimizationTest(unittest.TestCase):
-
- def test(self):
- nodes_attributes = {
- 'switch_2_input': {'shape': int64_array([1, 3]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'switches_input': {'shape': int64_array([1, 3]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
-
- 'switch_input_0': {'kind': 'op', 'op': 'SomeOp'},
- 'switch_1_input_0': {'kind': 'op', 'op': 'SomeOp'},
-
- 'switch': {'kind': 'op', 'op': 'Switch'},
- 'switch_1': {'kind': 'op', 'op': 'Switch'},
- 'switch_2': {'kind': 'op', 'op': 'Switch'},
-
- 'some_op': {'kind': 'op', 'op': 'Max'},
- 'identity': {'kind': 'op', 'op': 'Identity'},
-
- 'merge': {'kind': 'op', 'op': 'Merge'},
-
- 'select': {'kind': 'op', 'op': 'Select'},
-
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- }
-
- # check two cases when switch_2 goes to 0-th and 1-st input port of the Merge
- for merge_input_port in range(2):
- graph = build_graph(nodes_attributes,
- [('switch_2_input', 'switch_2', {'in': 0}),
- ('switch_input_0', 'switch', {'in': 0}),
- ('switch_1_input_0', 'switch_1', {'in': 0}),
- ('switches_input', 'switch', {'in': 1, 'out': 0}),
- ('switches_input', 'switch_1', {'in': 1, 'out': 0}),
- ('switches_input', 'switch_2', {'in': 1, 'out': 0}),
- ('switch', 'some_op', {'in': 0}),
- ('switch_1', 'some_op', {'in': 1}),
- ('some_op', 'identity', {'in': 0}),
- ('switch_2', 'merge', {'in': merge_input_port}),
- ('identity', 'merge', {'in': 1 - merge_input_port}),
- ('merge', 'last', {'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- SwitchMergeOptimization().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('switches_input', 'select', {'in': 0}),
- ('switch_2_input', 'select', {'in': 1}),
- ('switch_input_0', 'some_op', {'in': 0}),
- ('switch_1_input_0', 'some_op', {'in': 1}),
- ('some_op', 'identity', {'in': 0}),
- ('identity', 'select', {'in': 2}),
- ('select', 'last', {'in': 0}),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/TFFFTToDFT_test.py b/tools/mo/unit_tests/mo/front/tf/TFFFTToDFT_test.py
deleted file mode 100644
index 7e301d6f2e591b..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/TFFFTToDFT_test.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-
-import pytest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.TFFFTToDFT import TFFFTToDFT
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-dft_graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'fft': {'kind': 'op', 'op': 'TFFFT', 'num_of_dimensions': 2, 'is_inverse': False},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-}
-
-dft_graph_edges = [
- ('placeholder', 'fft', {'in': 0}),
- ('fft', 'abs'),
- ('abs', 'output'),
-]
-
-
-ref_dft_graph_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'fft': {'kind': 'op', 'op': 'DFT'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'fft_axes': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([-2, -1])
- },
-}
-
-ref_dft_graph_edges = [
- ('placeholder', 'fft', {'in': 0}),
- ('fft', 'abs'),
- ('abs', 'output'),
- ('fft_axes', 'fft', {'in': 1}),
-]
-
-
-dft_graph_with_signal_size_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'fft': {'kind': 'op', 'op': 'TFFFT', 'num_of_dimensions': 2, 'is_inverse': False},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'signal_size': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([-2, -1])
- },
-}
-
-dft_graph_with_signal_size_edges = [
- ('placeholder', 'fft', {'in': 0}),
- ('signal_size', 'fft', {'in': 1}),
- ('fft', 'abs'),
- ('abs', 'output'),
-]
-
-
-ref_dft_graph_with_signal_size_node_attrs = {
- 'placeholder': {'shape': int64_array([3, 100, 100, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'fft': {'kind': 'op', 'op': 'DFT'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'output': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- 'fft_axes': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([-2, -1])
- },
- 'signal_size': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([2]), 'value': int64_array([-2, -1])
- },
-}
-
-ref_dft_graph_with_signal_size_edges = [
- ('placeholder', 'fft', {'in': 0}),
- ('fft', 'abs'),
- ('abs', 'output'),
- ('fft_axes', 'fft', {'in': 1}),
- ('signal_size', 'fft', {'in': 2}),
-]
-
-
-class TestTFFFTToDFTTest():
- @pytest.mark.parametrize("num_of_dimensions, dft_type, fft_axes",[(2, 'DFT', int64_array([-2, -1])),
- (2, 'IDFT', int64_array([-2, -1])),
- (1, 'DFT', int64_array([-1])),
- (1, 'IDFT', int64_array([-1])),
- (3, 'DFT', int64_array([-3, -2, -1])),
- (3, 'IDFT', int64_array([-3, -2, -1])),
- (2, 'RDFT', int64_array([-2, -1])),
- (2, 'IRDFT', int64_array([-2, -1])),
- (1, 'RDFT', int64_array([-1])),
- (1, 'IRDFT', int64_array([-1])),
- (3, 'RDFT', int64_array([-3, -2, -1])),
- (3, 'IRDFT', int64_array([-3, -2, -1]))])
- def test_replacement(self, num_of_dimensions, dft_type, fft_axes):
- graph = build_graph(nodes_attrs=dft_graph_node_attrs,
- edges=dft_graph_edges,
- update_attributes={
- 'fft': {'num_of_dimensions': num_of_dimensions, 'fft_kind': dft_type},
- })
- graph.stage = 'front'
- graph.graph['layout'] = 'NHWC'
- TFFFTToDFT().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_dft_graph_node_attrs,
- edges=ref_dft_graph_edges,
- update_attributes={
- 'fft': {'kind': 'op', 'op': dft_type},
- 'fft_axes': {'value': fft_axes, 'shape': int64_array(fft_axes.shape)},
- })
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- assert flag, resp
-
- @pytest.mark.parametrize("num_of_dims, fft_kind, fft_axes, input_shape, signal_size",[
- (2, 'RDFT', int64_array([-2, -1]), int64_array([3, 100, 100]), int64_array([100, -1])),
- (2, 'IRDFT', int64_array([-2, -1]), int64_array([3, 100, 100, 2]), int64_array([100, -1])),
- (2, 'RDFT', int64_array([-2, -1]), int64_array([3, 100, 100]), int64_array([95, 116])),
- (2, 'IRDFT', int64_array([-2, -1]), int64_array([3, 100, 100, 2]), int64_array([95, 116])),
-
- (3, 'RDFT', int64_array([-3, -2, -1]), int64_array([3, 100, 100]), int64_array([5, 100, -1])),
- (3, 'IRDFT', int64_array([-3, -2, -1]), int64_array([3, 100, 100, 2]), int64_array([5, 100, -1])),
- (3, 'RDFT', int64_array([-3, -2, -1]), int64_array([3, 100, 100]), int64_array([5, 95, 116])),
- (3, 'IRDFT', int64_array([-3, -2, -1]), int64_array([3, 100, 100, 2]), int64_array([5, 95, 116])),
-
- (1, 'RDFT', int64_array([-1]), int64_array([3, 100, 100]), int64_array([-1])),
- (1, 'IRDFT', int64_array([-1]), int64_array([3, 100, 100, 2]), int64_array([-1])),
- (1, 'RDFT', int64_array([-1]), int64_array([3, 100, 100]), int64_array([95])),
- (1, 'IRDFT', int64_array([-1]), int64_array([3, 100, 100, 2]), int64_array([95])),
- (1, 'RDFT', int64_array([-1]), int64_array([3, 100, 100]), int64_array([116])),
- (1, 'IRDFT', int64_array([-1]), int64_array([3, 100, 100, 2]), int64_array([116])),
- (1, 'RDFT', int64_array([-1]), int64_array([3, 100, 100]), int64_array([100])),
- (1, 'IRDFT', int64_array([-1]), int64_array([3, 100, 100, 2]), int64_array([100])),
- ])
- def test_replacement_for_signal_size(self, num_of_dims, fft_kind, fft_axes, input_shape, signal_size):
- graph = build_graph(nodes_attrs=dft_graph_with_signal_size_node_attrs,
- edges=dft_graph_with_signal_size_edges,
- update_attributes={
- 'placeholder': {'shape': input_shape},
- 'signal_size': {
- 'shape': signal_size.shape, 'value': signal_size
- },
- 'fft': {'num_of_dimensions': num_of_dims, 'fft_kind': fft_kind},
- })
- graph.stage = 'front'
- graph.graph['layout'] = 'NHWC'
- TFFFTToDFT().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=ref_dft_graph_with_signal_size_node_attrs,
- edges=ref_dft_graph_with_signal_size_edges,
- update_attributes={
- 'placeholder': {'shape': input_shape},
- 'signal_size': {
- 'shape': signal_size.shape, 'value': signal_size
- },
- 'fft': {'kind': 'op', 'op': fft_kind},
- 'fft_axes': {'value': fft_axes, 'shape': int64_array(fft_axes.shape)},
- })
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/front/tf/TFSliceToSlice_test.py b/tools/mo/unit_tests/mo/front/tf/TFSliceToSlice_test.py
deleted file mode 100644
index 96ebbad9f1ebb8..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/TFSliceToSlice_test.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.TFSliceToSlice import TFSliceToSliceReplacer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, const, connect_front
-
-nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('tfslice', {'op': 'TFSlice', 'type': None}),
- **const('begin', np.array(0)),
- **const('size', np.array([-1])),
- **regular_op_with_empty_data('john_doe', {'op': 'Sum', 'type': None}),
- **result(),
-
- # nodes after replacement
- **const('minus_one', np.array(-1)),
- **regular_op_with_empty_data('shapeof', {'op': 'ShapeOf', 'type': 'ShapeOf'}),
- **regular_op_with_empty_data('end_const', {'op': 'Add', 'type': 'Add'}),
- **regular_op_with_empty_data('equal', {'op': 'Equal', 'type': 'Equal'}),
- **regular_op_with_empty_data('select', {'op': 'Select', 'type': 'Select'}),
- **regular_op_with_empty_data('slice', {'op': 'Slice', 'type': None}),
- **regular_op_with_empty_data('cast', {'op': 'Cast', 'type': 'Convert'}),
-}
-
-
-class SliceReplacerTest(unittest.TestCase):
- def test_slice_replacer(self):
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect_front('input:0', '0:tfslice'),
- *connect_front('begin:0', '1:tfslice'),
- *connect_front('size:0', '2:tfslice'),
- *connect_front('tfslice:0', 'output'),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
-
- TFSliceToSliceReplacer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attrs=nodes, edges=[
- *connect_front('input:0', 'slice'),
- *connect_front('input:0', 'shapeof'),
- *connect_front('begin:0', '1:slice'),
- *connect_front('begin:0', '0:end_const'),
- *connect_front('size:0', '1:end_const'),
- *connect_front('size:0', '0:equal'),
- *connect_front('shapeof:0', '1:select'),
- *connect_front('minus_one:0', '1:equal'),
- *connect_front('equal:0', '0:select'),
- *connect_front('end_const:0', '0:cast'),
- *connect_front('cast:0', '2:select'),
- *connect_front('select:0', '2:slice'),
- *connect_front('slice:0', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/UnpackPackReverseInputChannels_test.py b/tools/mo/unit_tests/mo/front/tf/UnpackPackReverseInputChannels_test.py
deleted file mode 100644
index dfa7903fb7f56d..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/UnpackPackReverseInputChannels_test.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.UnpackPackReverseInputChannels import UnpackPackReverseInputChannels
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect_front
-
-nodes = {
- **regular_op_with_empty_data('input', {'type': 'Parameter'}),
- **regular_op_with_empty_data('unpack', {'op': 'AttributedSplit', 'axis': int64_array(0)}),
- **regular_op_with_empty_data('pack', {'op': 'Pack', 'axis': int64_array(0)}),
- **result(),
-
- **regular_op_with_empty_data('reverseChannels',
- {'op': 'ReverseChannels', 'order': int64_array([2, 1, 0]), 'axis': int64_array(0), 'type': None}),
-}
-
-
-class UnpackPackReverseInputChannelsTest(unittest.TestCase):
- def test_replace_to_reverse_channel(self):
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect_front('input:0', '0:unpack'),
- *connect_front('unpack:0', '2:pack'),
- *connect_front('unpack:1', '1:pack'),
- *connect_front('unpack:2', '0:pack'),
- *connect_front('pack:0', '0:output'),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
-
- UnpackPackReverseInputChannels().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attrs=nodes, edges=[
- *connect_front('input:0', '0:reverseChannels'),
- *connect_front('reverseChannels:0', '0:output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/WhereDecomposition_test.py b/tools/mo/unit_tests/mo/front/tf/WhereDecomposition_test.py
deleted file mode 100644
index 9786d6ddccfa85..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/WhereDecomposition_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.WhereDecomposition import WhereDecomposition
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-graph_node_attrs = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': None,
- 'kind': 'data',
- 'data_type': None
- },
- 'tf_where': {'op': 'Where', 'kind': 'op'},
- 'tf_where_data': {'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'tf_where'),
- ('tf_where', 'tf_where_data'),
- ('tf_where_data', 'output'),
-]
-
-
-ref_graph_node_attrs = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': None,
- 'kind': 'data',
- 'data_type': None
- },
- 'non_zero': {'kind': 'op', 'op': 'NonZero', 'output_type': np.int64},
- 'non_zero_data': {'kind': 'data'},
- 'transpose': {'kind': 'op', 'op': 'Transpose'},
- 'transpose_data': {'kind': 'data'},
- 'perm_const': {'kind': 'op', 'op': 'Const', 'shape': [2], 'value': int64_array([1, 0])},
- 'perm_const_data': {'kind': 'data', 'shape': [2], 'value': int64_array([1, 0])},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-ref_graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'non_zero'),
- ('non_zero', 'non_zero_data'),
- ('non_zero_data', 'transpose', {'in': 0}),
- ('perm_const', 'perm_const_data'),
- ('perm_const_data', 'transpose', {'in': 1}),
- ('transpose', 'transpose_data'),
- ('transpose_data', 'output'),
-]
-
-
-class TestTFWhereDecompositionTest():
- @pytest.mark.parametrize("input_shape",[[1, 100, 120, 150], [16, 125, 14]])
- def test_1(self, input_shape):
- in_shape = int64_array(input_shape)
- graph = build_graph(graph_node_attrs,
- graph_edges,
- update_attributes={
- 'placeholder_data': {'shape': in_shape}
- })
- WhereDecomposition().find_and_replace_pattern(graph)
- ref_graph = build_graph(ref_graph_node_attrs,
- ref_graph_edges,
- update_attributes={
- 'placeholder_data': {'shape': in_shape}
- })
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- assert flag,resp
diff --git a/tools/mo/unit_tests/mo/front/tf/__init__.py b/tools/mo/unit_tests/mo/front/tf/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/tf/concat_ext_test.py b/tools/mo/unit_tests/mo/front/tf/concat_ext_test.py
deleted file mode 100644
index f0b68cbdf8a3aa..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/concat_ext_test.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.tf.concat_ext import ConcatFrontExtractor
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class ConcatExtractorTest(BaseExtractorsTestingClass):
- def test_concat(self):
- node = PB({'pb': PB({'attr': {'N': PB({'i': 4})}})})
- self.expected = {
- 'N': 4,
- 'simple_concat': True,
- 'type': 'Concat',
- 'op': 'Concat',
- 'kind': 'op',
- 'axis': 1
- }
- ConcatFrontExtractor.extract(node)
- self.res = node
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/tf/concat_test.py b/tools/mo/unit_tests/mo/front/tf/concat_test.py
deleted file mode 100644
index 2655f771677e47..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/concat_test.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.concat import Concat
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-class TestConcatEdgesReshuffler(unittest.TestCase):
- def test_concat_edges_reshaffle(self):
- graph = build_graph_with_edge_attrs(
- {'axis': {},
- 'input_1': {},
- 'input_2': {},
- 'input_3': {},
- 'concat': {'op': 'Concat', 'simple_concat': True, 'axis': 1},
- },
- [('axis', 'concat', {'in': 0}),
- ('input_1', 'concat', {'in': 1}),
- ('input_2', 'concat', {'in': 2}),
- ('input_3', 'concat', {'in': 3})],
- )
- Concat().find_and_replace_pattern(graph=graph)
- for u, v, attrs in graph.in_edges('concat', data=True):
- if attrs['in'] == 0:
- self.assertEqual(u, 'input_1')
- if attrs['in'] == 1:
- self.assertEqual(u, 'input_2')
- if attrs['in'] == 2:
- self.assertEqual(u, 'input_3')
- if attrs['in'] == 3:
- self.assertEqual(u, 'axis')
- self.assertTrue('axis' not in graph.node['concat'])
diff --git a/tools/mo/unit_tests/mo/front/tf/conv_ext_test.py b/tools/mo/unit_tests/mo/front/tf/conv_ext_test.py
deleted file mode 100644
index d1a02fea225c79..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/conv_ext_test.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.conv_ext import Conv2DFrontExtractor, DepthwiseConv2dNativeFrontExtractor
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class ConvExtractorTest(BaseExtractorsTestingClass):
- @classmethod
- def setUpClass(cls):
- cls.strides = [1, 2, 3, 4]
- cls.dilations = [1, 1, 1, 1]
-
- def test_conv_2d_defaults(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NHWC"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides})
- }),
- 'padding': PB({
- 's': b'VALID'
- }),
- 'dilations': PB({
- 'list': PB({"i": [1, 1, 1, 1]})
- })
- }})})
- self.expected = {
- 'bias_addable': True,
- 'dilation': np.array([1, 1, 1, 1], dtype=np.int8),
- 'type': 'Convolution',
- 'layout': 'NHWC',
- }
- Conv2DFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, False)
- self.compare()
-
- def test_conv2d_nhwc(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NHWC"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides})
- }),
- 'padding': PB({
- 's': b'VALID'
- }),
- 'dilations': PB({
- 'list': PB({"i": [1, 1, 1, 1]})
- })
- }})})
- self.expected = {
- # spatial_dims = [1, 2] will be detected in infer function
- "channel_dims": [3],
- "batch_dims": [0],
- "input_feature_channel": 2,
- "output_feature_channel": 3,
- 'dilation': np.array([1, 1, 1, 1], dtype=np.int8),
- 'stride': np.array(self.strides, dtype=np.int8),
- }
- Conv2DFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, False)
- self.compare()
-
- def test_conv2d_nchw(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NCHW"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides})
- }),
- 'padding': PB({
- 's': b'VALID'
- }),
- 'dilations': PB({
- 'list': PB({"i": [1, 1, 1, 1]})
- })
- }})})
- self.expected = {
- # spatial_dims = [2, 3] will be detected in infer function
- "channel_dims": [1],
- "batch_dims": [0],
- "input_feature_channel": 2,
- "output_feature_channel": 3,
- 'dilation': np.array([1, 1, 1, 1], dtype=np.int8),
- 'stride': np.array(self.strides, dtype=np.int8),
- }
- Conv2DFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, False)
- self.compare()
-
- def test_conv2d_depthwise(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NHWC"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides}),
- }),
- 'dilations': PB({
- 'list': PB({"i": self.dilations}),
- }),
- 'padding': PB({
- 's': b'VALID'
- })
- }})})
- self.expected = {
- # spatial_dims = [1, 2] will be detected in infer function
- "channel_dims": [3],
- "batch_dims": [0],
- "input_feature_channel": 2,
- "output_feature_channel": 2,
- 'dilation': np.array([1, 1, 1, 1], dtype=np.int8),
- 'stride': np.array(self.strides, dtype=np.int8),
- }
- DepthwiseConv2dNativeFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, True)
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/tf/deconv_ext_test.py b/tools/mo/unit_tests/mo/front/tf/deconv_ext_test.py
deleted file mode 100644
index 5b43b0ebb6044b..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/deconv_ext_test.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.deconv_ext import Conv2DBackpropInputFrontExtractor
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class DeconvolutionExtractorTest(BaseExtractorsTestingClass):
- @classmethod
- def setUpClass(cls):
- cls.strides = [1, 2, 3, 4]
-
- def test_deconv2d_defaults(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NHWC"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides})
- }),
- 'padding': PB({
- 's': b'VALID'
- })
- }})})
- self.expected = {
- 'bias_addable': True,
- 'pad': None, # will be inferred when input shape is known
- 'pad_spatial_shape': None,
- 'output_spatial_shape': None,
- 'output_shape': None,
- 'group': None,
- }
- Conv2DBackpropInputFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, False)
- self.compare()
-
- def test_deconv2d_nhwc(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NHWC"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides})
- }),
- 'padding': PB({
- 's': b'VALID'
- })
- }})})
-
- self.expected = {
- "spatial_dims": [1, 2],
- "channel_dims": [3],
- "batch_dims": [0],
- 'stride': np.array(self.strides, dtype=np.int8),
- }
-
- Conv2DBackpropInputFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, False)
- self.compare()
-
- def test_deconv2d_nchw(self):
- node = PB({'pb': PB({'attr': {
- 'data_format': PB({
- 's': b"NCHW"
- }),
- 'strides': PB({
- 'list': PB({"i": self.strides})
- }),
- 'padding': PB({
- 's': b'VALID'
- })
- }})})
- self.expected = {
- "spatial_dims": [2, 3],
- "channel_dims": [1],
- "batch_dims": [0],
- 'stride': np.array(self.strides, dtype=np.int8),
- }
-
- Conv2DBackpropInputFrontExtractor.extract(node)
- self.res = node
- self.expected_call_args = (None, False)
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/tf/embedding_segments_operation_fusing_test.py b/tools/mo/unit_tests/mo/front/tf/embedding_segments_operation_fusing_test.py
deleted file mode 100644
index 88ec471742dbcc..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/embedding_segments_operation_fusing_test.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.embedding_segments_operation_fusing import \
- EmbeddingSegmentsOperationMultipleFeaturesFusing, \
- EmbeddingSegmentsOperationSingleFeatureFusing
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-class EmbeddingSegmentsOperationFusingTest(unittest.TestCase):
- def test1(self):
- nodes_attributes = {
- 'input_indices': {'shape': int64_array([5, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_values': {'shape': int64_array([5]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_dense_shape': {'shape': int64_array([2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_params_table': {'shape': int64_array([10, 3, 4]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_default_value': {'shape': int64_array([]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
-
- 'identity_spw': {'kind': 'op', 'op': 'Identity'},
- 'gather0_1': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'gather0_2': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'reshape0': {'kind': 'op', 'op': 'Reshape'},
- 'where0': {'kind': 'op', 'op': 'Where'},
- 'greaterequal0': {'kind': 'op', 'op': 'GreaterEqual'},
- 'sparse_fill_empty_rows': {'kind': 'op', 'op': 'SparseFillEmptyRows'},
- 'unique': {'kind': 'op', 'op': 'Unique'},
- 'strided_slice': {'kind': 'op', 'op': 'StridedSlice'},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'gather': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'sparse_segment_sum': {'kind': 'op', 'op': 'SparseSegmentSum'},
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'tile': {'kind': 'op', 'op': 'Tile', 'type': 'Tile'},
- 'select': {'kind': 'op', 'op': 'Select'},
-
- 'split_for_indices': {'kind': 'op', 'op': 'Split'},
- 'squeeze_for_indices': {'kind': 'op', 'op': 'Squeeze'},
- 'split_for_dense_shape': {'kind': 'op', 'op': 'Split'},
- 'squeeze_to_scalar': {'kind': 'op', 'op': 'Squeeze'},
- 'cast_indices': {'kind': 'op', 'op': 'Cast'},
- 'cast_segment_ids': {'kind': 'op', 'op': 'Cast'},
- 'cast_default_value': {'kind': 'op', 'op': 'Cast'},
- 'cast_number_segments': {'kind': 'op', 'op': 'Cast'},
- 'embedding_segments_sum': {'kind': 'op', 'op': 'EmbeddingSegmentsSum'},
-
- **const('split_for_indices_axis', int64_array(1)),
- **const('split_for_dense_shape_axis', int64_array(0)),
- **const('squeeze_axis', int64_array([0])),
- **const('squeeze_for_indices_axis', int64_array([1])),
-
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- }
-
- graph = build_graph(nodes_attributes,
- [('input_indices', 'gather0_1', {'out': 0, 'in': 0}),
- ('input_dense_shape', 'identity_spw', {'out': 0, 'in': 0}),
- ('input_values', 'greaterequal0', {'out': 0, 'in': 0}),
- ('input_values', 'gather0_2', {'out': 0, 'in': 0}),
- ('input_params_table', 'gather', {'out': 0, 'in': 0}),
- ('input_default_value', 'sparse_fill_empty_rows', {'out': 0, 'in': 3}),
-
- ('gather0_1', 'sparse_fill_empty_rows', {'out': 0, 'in': 0}),
- ('gather0_2', 'sparse_fill_empty_rows', {'out': 0, 'in': 1}),
- ('identity_spw', 'sparse_fill_empty_rows', {'out': 0, 'in': 2}),
- ('reshape0', 'gather0_1', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_2', {'out': 0, 'in': 1}),
- ('where0', 'reshape0', {'out': 0, 'in': 0}),
- ('greaterequal0', 'where0', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'unique', {'out': 1, 'in': 0}),
- ('sparse_fill_empty_rows', 'strided_slice', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'reshape', {'out': 2, 'in': 0}),
- ('unique', 'sparse_segment_sum', {'out': 1, 'in': 1}),
- ('unique', 'gather', {'out': 0, 'in': 1}),
- ('strided_slice', 'cast', {'out': 0, 'in': 0}),
- ('gather', 'sparse_segment_sum', {'out': 0, 'in': 0}),
- ('cast', 'sparse_segment_sum', {'out': 0, 'in': 2}),
- ('sparse_segment_sum', 'select', {'out': 0, 'in': 2}),
- ('reshape', 'tile', {'out': 0, 'in': 0}),
- ('tile', 'select', {'out': 0, 'in': 0}),
- ('select', 'last', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- EmbeddingSegmentsOperationSingleFeatureFusing().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input_indices', 'split_for_indices', {'in': 0}),
- ('split_for_indices_axis', 'split_for_indices', {'in': 1}),
- ('split_for_indices', 'squeeze_for_indices', {'in': 0}),
- ('squeeze_for_indices_axis', 'squeeze_for_indices', {'in': 1}),
- ('squeeze_for_indices', 'cast_segment_ids', {'in': 0}),
- ('cast_segment_ids', 'embedding_segments_sum', {'in': 2, 'out': 0}),
- ('input_values', 'cast_indices', {'in': 0}),
- ('cast_indices', 'embedding_segments_sum', {'in': 1}),
- ('input_dense_shape', 'split_for_dense_shape', {'in': 0}),
- ('split_for_dense_shape_axis', 'split_for_dense_shape', {'in': 1}),
- ('split_for_dense_shape', 'squeeze_to_scalar', {'in': 0}),
- ('squeeze_axis', 'squeeze_to_scalar', {'in': 1}),
- ('squeeze_to_scalar', 'cast_number_segments', {'in': 0}),
- ('cast_number_segments', 'embedding_segments_sum', {'in': 3, 'out': 0}),
- ('input_params_table', 'embedding_segments_sum', {'in': 0}),
- ('input_default_value', 'cast_default_value', {'in': 0}),
- ('cast_default_value', 'embedding_segments_sum', {'in': 4}),
- ('embedding_segments_sum', 'last', {'in': 0}), ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test2(self):
- nodes_attributes = {
- 'input_indices': {'shape': int64_array([5, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_values': {'shape': int64_array([5]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_dense_shape': {'shape': int64_array([2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_params_table': {'shape': int64_array([10, 3, 4]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_default_value': {'shape': int64_array([]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
-
- 'identity_spw': {'kind': 'op', 'op': 'Identity'},
- 'gather0_1': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'gather0_2': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'reshape0': {'kind': 'op', 'op': 'Reshape'},
- 'where0': {'kind': 'op', 'op': 'Where'},
- 'greaterequal0': {'kind': 'op', 'op': 'GreaterEqual'},
- 'sparse_fill_empty_rows': {'kind': 'op', 'op': 'SparseFillEmptyRows'},
- 'unique': {'kind': 'op', 'op': 'Unique'},
- 'strided_slice': {'kind': 'op', 'op': 'StridedSlice'},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'gather': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'identity': {'kind': 'op', 'op': 'Identity'},
- 'identity_1': {'kind': 'op', 'op': 'Identity'},
- 'sparse_segment_mean': {'kind': 'op', 'op': 'SparseSegmentMean'},
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'tile': {'kind': 'op', 'op': 'Tile', 'type': 'Tile'},
- 'select': {'kind': 'op', 'op': 'Select'},
-
- 'split_for_indices': {'kind': 'op', 'op': 'Split'},
- 'squeeze_for_indices': {'kind': 'op', 'op': 'Squeeze'},
- 'split_for_dense_shape': {'kind': 'op', 'op': 'Split'},
- 'squeeze_to_scalar': {'kind': 'op', 'op': 'Squeeze'},
- 'cast_indices': {'kind': 'op', 'op': 'Cast'},
- 'cast_segment_ids': {'kind': 'op', 'op': 'Cast'},
- 'cast_default_value': {'kind': 'op', 'op': 'Cast'},
- 'cast_number_segments': {'kind': 'op', 'op': 'Cast'},
- 'embedding_segments_mean': {'kind': 'op', 'op': 'EmbeddingSegmentsMean'},
-
- **const('split_for_indices_axis', int64_array(1)),
- **const('split_for_dense_shape_axis', int64_array(0)),
- **const('squeeze_axis', int64_array([0])),
- **const('squeeze_for_indices_axis', int64_array([1])),
-
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- }
-
- graph = build_graph(nodes_attributes,
- [('input_indices', 'gather0_1', {'out': 0, 'in': 0}),
- ('input_dense_shape', 'identity_spw', {'out': 0, 'in': 0}),
- ('input_values', 'greaterequal0', {'out': 0, 'in': 0}),
- ('input_values', 'gather0_2', {'out': 0, 'in': 0}),
- ('input_params_table', 'gather', {'out': 0, 'in': 0}),
- ('input_default_value', 'sparse_fill_empty_rows', {'out': 0, 'in': 3}),
-
- ('identity_spw', 'sparse_fill_empty_rows', {'out': 0, 'in': 2}),
- ('gather0_1', 'sparse_fill_empty_rows', {'out': 0, 'in': 0}),
- ('gather0_2', 'sparse_fill_empty_rows', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_1', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_2', {'out': 0, 'in': 1}),
- ('where0', 'reshape0', {'out': 0, 'in': 0}),
- ('greaterequal0', 'where0', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'unique', {'out': 1, 'in': 0}),
- ('sparse_fill_empty_rows', 'strided_slice', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'reshape', {'out': 2, 'in': 0}),
- ('unique', 'sparse_segment_mean', {'out': 1, 'in': 1}),
- ('unique', 'gather', {'out': 0, 'in': 1}),
- ('strided_slice', 'cast', {'out': 0, 'in': 0}),
- ('gather', 'identity', {'out': 0, 'in': 0}),
- ('identity', 'identity_1', {'out': 0, 'in': 0}),
- ('identity_1', 'sparse_segment_mean', {'out': 0, 'in': 0}),
- ('cast', 'sparse_segment_mean', {'out': 0, 'in': 2}),
- ('sparse_segment_mean', 'select', {'out': 0, 'in': 2}),
- ('reshape', 'tile', {'out': 0, 'in': 0}),
- ('tile', 'select', {'out': 0, 'in': 0}),
- ('select', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
- graph.stage = 'front'
- EmbeddingSegmentsOperationMultipleFeaturesFusing().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input_indices', 'split_for_indices', {'in': 0}),
- ('split_for_indices_axis', 'split_for_indices', {'in': 1}),
- ('split_for_indices', 'squeeze_for_indices', {'in': 0}),
- ('squeeze_for_indices_axis', 'squeeze_for_indices', {'in': 1}),
- ('squeeze_for_indices', 'cast_segment_ids', {'in': 0}),
- ('cast_segment_ids', 'embedding_segments_mean', {'in': 2, 'out': 0}),
- ('input_values', 'cast_indices', {'in': 0}),
- ('cast_indices', 'embedding_segments_mean', {'in': 1}),
- ('input_dense_shape', 'split_for_dense_shape', {'in': 0}),
- ('split_for_dense_shape_axis', 'split_for_dense_shape', {'in': 1}),
- ('split_for_dense_shape', 'squeeze_to_scalar', {'in': 0}),
- ('squeeze_axis', 'squeeze_to_scalar', {'in': 1}),
- ('squeeze_to_scalar', 'cast_number_segments', {'in': 0}),
- ('cast_number_segments', 'embedding_segments_mean', {'in': 3, 'out': 0}),
- ('input_params_table', 'embedding_segments_mean', {'in': 0}),
- ('input_default_value', 'cast_default_value', {'in': 0}),
- ('cast_default_value', 'embedding_segments_mean', {'in': 4}),
- ('embedding_segments_mean', 'last', {'in': 0}), ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/embedding_segments_sum_test.py b/tools/mo/unit_tests/mo/front/tf/embedding_segments_sum_test.py
deleted file mode 100644
index 88ec471742dbcc..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/embedding_segments_sum_test.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.embedding_segments_operation_fusing import \
- EmbeddingSegmentsOperationMultipleFeaturesFusing, \
- EmbeddingSegmentsOperationSingleFeatureFusing
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-class EmbeddingSegmentsOperationFusingTest(unittest.TestCase):
- def test1(self):
- nodes_attributes = {
- 'input_indices': {'shape': int64_array([5, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_values': {'shape': int64_array([5]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_dense_shape': {'shape': int64_array([2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_params_table': {'shape': int64_array([10, 3, 4]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_default_value': {'shape': int64_array([]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
-
- 'identity_spw': {'kind': 'op', 'op': 'Identity'},
- 'gather0_1': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'gather0_2': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'reshape0': {'kind': 'op', 'op': 'Reshape'},
- 'where0': {'kind': 'op', 'op': 'Where'},
- 'greaterequal0': {'kind': 'op', 'op': 'GreaterEqual'},
- 'sparse_fill_empty_rows': {'kind': 'op', 'op': 'SparseFillEmptyRows'},
- 'unique': {'kind': 'op', 'op': 'Unique'},
- 'strided_slice': {'kind': 'op', 'op': 'StridedSlice'},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'gather': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'sparse_segment_sum': {'kind': 'op', 'op': 'SparseSegmentSum'},
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'tile': {'kind': 'op', 'op': 'Tile', 'type': 'Tile'},
- 'select': {'kind': 'op', 'op': 'Select'},
-
- 'split_for_indices': {'kind': 'op', 'op': 'Split'},
- 'squeeze_for_indices': {'kind': 'op', 'op': 'Squeeze'},
- 'split_for_dense_shape': {'kind': 'op', 'op': 'Split'},
- 'squeeze_to_scalar': {'kind': 'op', 'op': 'Squeeze'},
- 'cast_indices': {'kind': 'op', 'op': 'Cast'},
- 'cast_segment_ids': {'kind': 'op', 'op': 'Cast'},
- 'cast_default_value': {'kind': 'op', 'op': 'Cast'},
- 'cast_number_segments': {'kind': 'op', 'op': 'Cast'},
- 'embedding_segments_sum': {'kind': 'op', 'op': 'EmbeddingSegmentsSum'},
-
- **const('split_for_indices_axis', int64_array(1)),
- **const('split_for_dense_shape_axis', int64_array(0)),
- **const('squeeze_axis', int64_array([0])),
- **const('squeeze_for_indices_axis', int64_array([1])),
-
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- }
-
- graph = build_graph(nodes_attributes,
- [('input_indices', 'gather0_1', {'out': 0, 'in': 0}),
- ('input_dense_shape', 'identity_spw', {'out': 0, 'in': 0}),
- ('input_values', 'greaterequal0', {'out': 0, 'in': 0}),
- ('input_values', 'gather0_2', {'out': 0, 'in': 0}),
- ('input_params_table', 'gather', {'out': 0, 'in': 0}),
- ('input_default_value', 'sparse_fill_empty_rows', {'out': 0, 'in': 3}),
-
- ('gather0_1', 'sparse_fill_empty_rows', {'out': 0, 'in': 0}),
- ('gather0_2', 'sparse_fill_empty_rows', {'out': 0, 'in': 1}),
- ('identity_spw', 'sparse_fill_empty_rows', {'out': 0, 'in': 2}),
- ('reshape0', 'gather0_1', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_2', {'out': 0, 'in': 1}),
- ('where0', 'reshape0', {'out': 0, 'in': 0}),
- ('greaterequal0', 'where0', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'unique', {'out': 1, 'in': 0}),
- ('sparse_fill_empty_rows', 'strided_slice', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'reshape', {'out': 2, 'in': 0}),
- ('unique', 'sparse_segment_sum', {'out': 1, 'in': 1}),
- ('unique', 'gather', {'out': 0, 'in': 1}),
- ('strided_slice', 'cast', {'out': 0, 'in': 0}),
- ('gather', 'sparse_segment_sum', {'out': 0, 'in': 0}),
- ('cast', 'sparse_segment_sum', {'out': 0, 'in': 2}),
- ('sparse_segment_sum', 'select', {'out': 0, 'in': 2}),
- ('reshape', 'tile', {'out': 0, 'in': 0}),
- ('tile', 'select', {'out': 0, 'in': 0}),
- ('select', 'last', {'out': 0, 'in': 0}),
- ], nodes_with_edges_only=True)
- graph.stage = 'front'
- EmbeddingSegmentsOperationSingleFeatureFusing().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input_indices', 'split_for_indices', {'in': 0}),
- ('split_for_indices_axis', 'split_for_indices', {'in': 1}),
- ('split_for_indices', 'squeeze_for_indices', {'in': 0}),
- ('squeeze_for_indices_axis', 'squeeze_for_indices', {'in': 1}),
- ('squeeze_for_indices', 'cast_segment_ids', {'in': 0}),
- ('cast_segment_ids', 'embedding_segments_sum', {'in': 2, 'out': 0}),
- ('input_values', 'cast_indices', {'in': 0}),
- ('cast_indices', 'embedding_segments_sum', {'in': 1}),
- ('input_dense_shape', 'split_for_dense_shape', {'in': 0}),
- ('split_for_dense_shape_axis', 'split_for_dense_shape', {'in': 1}),
- ('split_for_dense_shape', 'squeeze_to_scalar', {'in': 0}),
- ('squeeze_axis', 'squeeze_to_scalar', {'in': 1}),
- ('squeeze_to_scalar', 'cast_number_segments', {'in': 0}),
- ('cast_number_segments', 'embedding_segments_sum', {'in': 3, 'out': 0}),
- ('input_params_table', 'embedding_segments_sum', {'in': 0}),
- ('input_default_value', 'cast_default_value', {'in': 0}),
- ('cast_default_value', 'embedding_segments_sum', {'in': 4}),
- ('embedding_segments_sum', 'last', {'in': 0}), ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test2(self):
- nodes_attributes = {
- 'input_indices': {'shape': int64_array([5, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_values': {'shape': int64_array([5]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_dense_shape': {'shape': int64_array([2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_params_table': {'shape': int64_array([10, 3, 4]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_default_value': {'shape': int64_array([]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
-
- 'identity_spw': {'kind': 'op', 'op': 'Identity'},
- 'gather0_1': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'gather0_2': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'reshape0': {'kind': 'op', 'op': 'Reshape'},
- 'where0': {'kind': 'op', 'op': 'Where'},
- 'greaterequal0': {'kind': 'op', 'op': 'GreaterEqual'},
- 'sparse_fill_empty_rows': {'kind': 'op', 'op': 'SparseFillEmptyRows'},
- 'unique': {'kind': 'op', 'op': 'Unique'},
- 'strided_slice': {'kind': 'op', 'op': 'StridedSlice'},
- 'cast': {'kind': 'op', 'op': 'Cast'},
- 'gather': {'kind': 'op', 'op': 'Gather', 'type': 'Gather'},
- 'identity': {'kind': 'op', 'op': 'Identity'},
- 'identity_1': {'kind': 'op', 'op': 'Identity'},
- 'sparse_segment_mean': {'kind': 'op', 'op': 'SparseSegmentMean'},
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'tile': {'kind': 'op', 'op': 'Tile', 'type': 'Tile'},
- 'select': {'kind': 'op', 'op': 'Select'},
-
- 'split_for_indices': {'kind': 'op', 'op': 'Split'},
- 'squeeze_for_indices': {'kind': 'op', 'op': 'Squeeze'},
- 'split_for_dense_shape': {'kind': 'op', 'op': 'Split'},
- 'squeeze_to_scalar': {'kind': 'op', 'op': 'Squeeze'},
- 'cast_indices': {'kind': 'op', 'op': 'Cast'},
- 'cast_segment_ids': {'kind': 'op', 'op': 'Cast'},
- 'cast_default_value': {'kind': 'op', 'op': 'Cast'},
- 'cast_number_segments': {'kind': 'op', 'op': 'Cast'},
- 'embedding_segments_mean': {'kind': 'op', 'op': 'EmbeddingSegmentsMean'},
-
- **const('split_for_indices_axis', int64_array(1)),
- **const('split_for_dense_shape_axis', int64_array(0)),
- **const('squeeze_axis', int64_array([0])),
- **const('squeeze_for_indices_axis', int64_array([1])),
-
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
- }
-
- graph = build_graph(nodes_attributes,
- [('input_indices', 'gather0_1', {'out': 0, 'in': 0}),
- ('input_dense_shape', 'identity_spw', {'out': 0, 'in': 0}),
- ('input_values', 'greaterequal0', {'out': 0, 'in': 0}),
- ('input_values', 'gather0_2', {'out': 0, 'in': 0}),
- ('input_params_table', 'gather', {'out': 0, 'in': 0}),
- ('input_default_value', 'sparse_fill_empty_rows', {'out': 0, 'in': 3}),
-
- ('identity_spw', 'sparse_fill_empty_rows', {'out': 0, 'in': 2}),
- ('gather0_1', 'sparse_fill_empty_rows', {'out': 0, 'in': 0}),
- ('gather0_2', 'sparse_fill_empty_rows', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_1', {'out': 0, 'in': 1}),
- ('reshape0', 'gather0_2', {'out': 0, 'in': 1}),
- ('where0', 'reshape0', {'out': 0, 'in': 0}),
- ('greaterequal0', 'where0', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'unique', {'out': 1, 'in': 0}),
- ('sparse_fill_empty_rows', 'strided_slice', {'out': 0, 'in': 0}),
- ('sparse_fill_empty_rows', 'reshape', {'out': 2, 'in': 0}),
- ('unique', 'sparse_segment_mean', {'out': 1, 'in': 1}),
- ('unique', 'gather', {'out': 0, 'in': 1}),
- ('strided_slice', 'cast', {'out': 0, 'in': 0}),
- ('gather', 'identity', {'out': 0, 'in': 0}),
- ('identity', 'identity_1', {'out': 0, 'in': 0}),
- ('identity_1', 'sparse_segment_mean', {'out': 0, 'in': 0}),
- ('cast', 'sparse_segment_mean', {'out': 0, 'in': 2}),
- ('sparse_segment_mean', 'select', {'out': 0, 'in': 2}),
- ('reshape', 'tile', {'out': 0, 'in': 0}),
- ('tile', 'select', {'out': 0, 'in': 0}),
- ('select', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
- graph.stage = 'front'
- EmbeddingSegmentsOperationMultipleFeaturesFusing().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input_indices', 'split_for_indices', {'in': 0}),
- ('split_for_indices_axis', 'split_for_indices', {'in': 1}),
- ('split_for_indices', 'squeeze_for_indices', {'in': 0}),
- ('squeeze_for_indices_axis', 'squeeze_for_indices', {'in': 1}),
- ('squeeze_for_indices', 'cast_segment_ids', {'in': 0}),
- ('cast_segment_ids', 'embedding_segments_mean', {'in': 2, 'out': 0}),
- ('input_values', 'cast_indices', {'in': 0}),
- ('cast_indices', 'embedding_segments_mean', {'in': 1}),
- ('input_dense_shape', 'split_for_dense_shape', {'in': 0}),
- ('split_for_dense_shape_axis', 'split_for_dense_shape', {'in': 1}),
- ('split_for_dense_shape', 'squeeze_to_scalar', {'in': 0}),
- ('squeeze_axis', 'squeeze_to_scalar', {'in': 1}),
- ('squeeze_to_scalar', 'cast_number_segments', {'in': 0}),
- ('cast_number_segments', 'embedding_segments_mean', {'in': 3, 'out': 0}),
- ('input_params_table', 'embedding_segments_mean', {'in': 0}),
- ('input_default_value', 'cast_default_value', {'in': 0}),
- ('cast_default_value', 'embedding_segments_mean', {'in': 4}),
- ('embedding_segments_mean', 'last', {'in': 0}), ],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/extractors/__init__.py b/tools/mo/unit_tests/mo/front/tf/extractors/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/front/tf/extractors/concat_test.py b/tools/mo/unit_tests/mo/front/tf/extractors/concat_test.py
deleted file mode 100644
index 90bbff25949711..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/extractors/concat_test.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.tf.extractors.concat import tf_concat_ext
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class ConcatExtractorTest(BaseExtractorsTestingClass):
- @classmethod
- def setUpClass(cls):
- cls.patcher = 'openvino.tools.mo.front.tf.extractors.concat.concat_infer'
-
- def test_concat(self):
- pb = PB({'attr': {
- 'N': PB({'i': 3}),
- }})
- self.expected = {
- 'type': 'Concat',
- 'N': 3,
- }
- self.res = tf_concat_ext(pb=pb)
- self.res["infer"](None)
- self.call_args = self.infer_mock.call_args
- self.expected_call_args = (None)
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/tf/extractors/identity_test.py b/tools/mo/unit_tests/mo/front/tf/extractors/identity_test.py
deleted file mode 100644
index fab7dd045ec225..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/extractors/identity_test.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.tf.extractors.identity import tf_identity_ext
-from unit_tests.utils.extractors import BaseExtractorsTestingClass
-
-
-class IdentityExtractorTest(BaseExtractorsTestingClass):
- @classmethod
- def setUpClass(cls):
- cls.patcher = 'openvino.tools.mo.front.tf.extractors.identity.copy_shape_infer'
-
- def test_identity(self):
- self.expected = {}
- self.res = tf_identity_ext(pb=None)
- self.res["infer"](None)
- self.call_args = self.infer_mock.call_args
- self.expected_call_args = None
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/tf/extractors/utils_test.py b/tools/mo/unit_tests/mo/front/tf/extractors/utils_test.py
deleted file mode 100644
index ddb8acfe07e5e9..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/extractors/utils_test.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.extractors.utils import collect_tf_attrs, tf_tensor_content
-from unit_tests.utils.extractors import PB
-
-
-class AttrParsingTest(unittest.TestCase):
- def test_simple_check(self):
- pb = PB({'attr': {
- 'str': PB({'s': "aaaa"}),
- 'int': PB({'i': 7}),
- 'float': PB({'f': 2.0}),
- 'bool': PB({'b': True}),
- 'lisint': PB({'list': PB({'i': 5, 'i': 6})})}
- })
-
- res = collect_tf_attrs(pb.attr)
-
- # Reference results for given parameters
- ref = {
- 'str': pb.attr['str'].s,
- 'int': pb.attr['int'].i,
- 'float': pb.attr['float'].f,
- 'bool': pb.attr['bool'].b,
- 'lisint': pb.attr['lisint'].list.i
- }
- for attr in ref:
- self.assertEqual(res[attr], ref[attr])
-
-
-class TensorContentParsing(unittest.TestCase):
- def test_list_not_type_no_shape(self):
- pb_tensor = PB(dict(
- dtype=3,
- tensor_content=b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00'
- ))
- tf_dtype = pb_tensor.dtype
- shape = np.array([5])
- ref = [1, 2, 3, 4, 5]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_list_type_no_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': np.array([1, 2, 3, 4, 5], dtype=np.int32)
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([5])
- ref = [1, 2, 3, 4, 5]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_list_not_type_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'tensor_content': b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00'
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([10])
- ref = [1, 2, 3, 4, 5, 5, 5, 5, 5, 5]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_list_type_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': np.array([1, 2, 3, 4, 5], dtype=np.int32)
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([10])
- ref = [1, 2, 3, 4, 5, 5, 5, 5, 5, 5]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_0d_not_type_no_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'tensor_content': b'\x01\x00\x00\x00',
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([])
- ref = 1
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(res == ref)
-
- def test_0d_type_no_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': [5],
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([])
- ref = 5
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(res == ref)
-
- def test_0d_not_type_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'tensor_content': b'\x01\x00\x00\x00',
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([3])
- ref = [1, 1, 1]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_0d_type_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': [5],
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([3])
- ref = [5, 5, 5]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_0d_type_shape_1(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': [5],
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([1])
- ref = [5]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_nd_not_type_no_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'tensor_content':
- b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00',
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([2, 3])
- ref = [[1, 2, 3], [4, 5, 6]]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_nd_type_no_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': [[1, 2, 3], [4, 5, 6]],
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([2, 3])
- ref = [[1, 2, 3], [4, 5, 6]]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_nd_not_type_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'tensor_content':
- b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00',
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([2, 5, 2])
- ref = [[[1, 2], [3, 4], [5, 6], [6, 6], [6, 6]],
- [[6, 6], [6, 6], [6, 6], [6, 6], [6, 6]]]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_nd_type_shape(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': [[1, 2, 3], [4, 5, 6]],
- })
- tf_dtype = pb_tensor.dtype
- shape = np.array([2, 5, 2])
- ref = [[[1, 2], [3, 4], [5, 6], [6, 6], [6, 6]],
- [[6, 6], [6, 6], [6, 6], [6, 6], [6, 6]]]
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertTrue(np.all(res == ref))
-
- def test_str_decode(self):
- pb_tensor = PB({
- 'dtype': 7,
- 'string_val': [b"\037\000\036\000\002\000\303\237\035\000\002"]
- })
- tf_dtype = pb_tensor.dtype
- shape = int64_array([1])
- warning_message = 'ERROR:root:Failed to parse a tensor with Unicode characters. Note that OpenVINO ' \
- 'does not support string literals, so the string constant should be eliminated from the ' \
- 'graph.'
- ref_val = np.array([b'\x1f\x00\x1e\x00\x02\x00\xc3\x9f\x1d\x00\x02'])
- with self.assertLogs(log.getLogger(), level="ERROR") as cm:
- result = tf_tensor_content(tf_dtype, shape, pb_tensor)
- self.assertEqual([warning_message], cm.output)
- self.assertEqual(ref_val, result)
-
- def test_str_decode_list(self):
- pb_tensor = PB({
- 'dtype': 7,
- 'string_val': [b'\377\330\377\377\330\377'],
- })
- shape = int64_array([])
- warning_message = 'ERROR:root:Failed to parse a tensor with Unicode characters. Note that OpenVINO ' \
- 'does not support string literals, so the string constant should be eliminated from the ' \
- 'graph.'
- with self.assertLogs(log.getLogger(), level="ERROR") as cm:
- result = tf_tensor_content(pb_tensor.dtype, shape, pb_tensor)
- self.assertEqual([warning_message, warning_message], cm.output)
-
- def test_empty_value(self):
- pb_tensor = PB({
- 'dtype': 1,
- 'float_val': []
- })
-
- shape = int64_array([1, 1, 0])
- tf_dtype = pb_tensor.dtype
- ref = np.array([[[]]], dtype=np.float32)
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
-
- self.assertEqual(res.shape, ref.shape)
- self.assertTrue(np.all(res == ref))
-
- def test_scalar_value(self):
- pb_tensor = PB({
- 'dtype': 3,
- 'int_val': 4
- })
-
- shape = int64_array([])
- tf_dtype = pb_tensor.dtype
- ref = np.array(4, dtype=np.int32)
- res = tf_tensor_content(tf_dtype, shape, pb_tensor)
-
- self.assertEqual(ref, res)
diff --git a/tools/mo/unit_tests/mo/front/tf/fifo_replacer_test.py b/tools/mo/unit_tests/mo/front/tf/fifo_replacer_test.py
deleted file mode 100644
index 04d29d4b89acab..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/fifo_replacer_test.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array
-from openvino.tools.mo.front.tf.fifo_replacer import FIFOQueue, FIFOQueueDequeueCut
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-def create_fifo_queue_graph(batch_size_shape: np.ndarray):
- nodes = {
- 'placeholder': {'op': 'Parameter', 'data_type': np.int32, 'kind': 'op', 'shape': batch_size_shape},
- 'batch_join/fifo_queue': {'op': 'FIFOQueueV2', 'name': 'batch_join/fifo_queue',
- 'shapes': np.array([[1, 2, 3]]), 'types': np.array([np.float32]), 'kind': 'op'},
- 'batch_join': {'op': 'QueueDequeueUpToV2', 'kind': 'op'},
- 'image_batch': {'op': 'Identity', 'data_type': np.float32, 'kind': 'op'},
- 'label_batch': {'op': 'Identity', 'kind': 'op'},
- 'label_batch_op_output': {'op': 'Result', 'kind': 'op'},
- }
- edges = [
- ('placeholder', 'batch_join', {'out': 0, 'in': 0}),
- ('batch_join/fifo_queue', 'batch_join', {'out': 0, 'in': 1}),
- ('batch_join', 'image_batch', {'out': 0, 'in': 0}),
- ('batch_join', 'label_batch', {'out': 1, 'in': 0}),
- ('label_batch', 'label_batch_op_output', {'out': 0, 'in': 0})
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- return graph
-
-
-class TestFIFOQueueReplacement(unittest.TestCase):
- def test_fifo_with_label_batch(self):
- graph = create_fifo_queue_graph(shape_array([1]))
- tested_class = FIFOQueue()
- tested_class.find_and_replace_pattern(graph=graph)
- after_pattern = graph.nodes()
- self.assertEqual(2, len(after_pattern))
- try:
- new_ph_dict = graph.node[[u for u, v in graph.in_edges('image_batch')][0]]
- except Exception as e:
- self.fail("Can't get new placeholder. Broken edge. Additional information: {}".format(e))
- self.assertEqual(new_ph_dict['name'], 'batch_join/fifo_queue')
- self.assertTrue(np.array_equal(new_ph_dict['shape'], [1, 2, 3]))
-
- def test_fifo_with_undefined_batch_size(self):
- graph = create_fifo_queue_graph(None)
- tested_class = FIFOQueue()
- tested_class.find_and_replace_pattern(graph=graph)
- after_pattern = graph.nodes()
- self.assertEqual(2, len(after_pattern))
- try:
- new_ph_dict = graph.node[[u for u, v in graph.in_edges('image_batch')][0]]
- except Exception as e:
- self.fail("Can't get new placeholder. Broken edge. Additional information: {}".format(e))
- self.assertEqual(new_ph_dict['name'], 'batch_join/fifo_queue')
- self.assertTrue(np.array_equal(new_ph_dict['shape'], [1, 2, 3]))
-
- def test_fifo_with_out_label_batch(self):
- nodes_no_label = {
- 'placeholder': {'op': 'Parameter', 'data_type': np.int32, 'kind': 'op', 'shape': np.array(0)},
- 'batch_join/fifo_queue': {'op': 'FIFOQueueV2', 'name': 'batch_join/fifo_queue',
- 'shapes': np.array([[1, 2, 3]]), 'types': np.array([np.float32]), 'kind': 'op'},
- 'batch_join': {'op': 'QueueDequeueUpToV2', 'kind': 'op'},
- 'image_batch': {'op': 'Identity', 'data_type': np.float32, 'kind': 'op'},
- }
- edges_no_label = [
- ('placeholder', 'batch_join', {'out': 0, 'in': 0}),
- ('batch_join/fifo_queue', 'batch_join', {'out': 0, 'in': 1}),
- ('batch_join', 'image_batch', {'out': 0, 'in': 0})
- ]
-
- graph = build_graph_with_edge_attrs(nodes_no_label, edges_no_label)
- tested_class = FIFOQueue()
- tested_class.find_and_replace_pattern(graph=graph)
- after_pattern = graph.nodes()
- self.assertEqual(2, len(after_pattern))
- try:
- new_ph_dict = graph.node[[u for u, v in graph.in_edges('image_batch')][0]]
- except Exception as e:
- self.fail("Can't get new placeholder. Broken edge. Additional information: {}".format(e))
- self.assertEqual(new_ph_dict['name'], 'batch_join/fifo_queue')
- self.assertTrue(np.array_equal(new_ph_dict['shape'], np.array([1, 2, 3])))
-
-
-class FIFOQueueDequeueCutTest(unittest.TestCase):
- def test_one_output_v1(self):
- graph = build_graph_with_edge_attrs(
- {
- 'queue_dequeue': {'kind': 'op', 'op': 'QueueDequeue', 'shapes': shape_array([[2, 2]]),
- 'types': [np.int32]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- },
- [
- ('queue_dequeue', 'sub', {'out': 0, 'in': 0}),
- ]
- )
-
- graph_ref = build_graph_with_edge_attrs(
- {
- 'parameter_1': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([2, 2]), 'type': np.int32},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- },
- [
- ('parameter_1', 'sub', {'out': 0, 'in': 0}),
- ]
- )
-
- FIFOQueueDequeueCut().find_and_replace_pattern(graph)
-
- flag, msg = compare_graphs(graph, graph_ref, last_node='sub')
- self.assertTrue(flag, msg)
-
- def test_one_output_v2(self):
- graph = build_graph_with_edge_attrs(
- {
- 'queue_dequeue': {'kind': 'op', 'op': 'QueueDequeueV2', 'shapes': shape_array([[2, 2]]),
- 'types': [np.int32]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- },
- [
- ('queue_dequeue', 'sub', {'out': 0, 'in': 0}),
- ]
- )
-
- graph_ref = build_graph_with_edge_attrs(
- {
- 'parameter_1': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([2, 2]), 'type': np.int32},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- },
- [
- ('parameter_1', 'sub', {'out': 0, 'in': 0}),
- ]
- )
-
- FIFOQueueDequeueCut().find_and_replace_pattern(graph)
-
- flag, msg = compare_graphs(graph, graph_ref, last_node='sub')
- self.assertTrue(flag, msg)
-
- def test_two_outputs_v1(self):
- graph = build_graph_with_edge_attrs(
- {
- 'queue_dequeue': {'kind': 'op', 'op': 'QueueDequeue', 'shapes': [shape_array([2, 2]),
- shape_array([1, 1])],
- 'types': [np.int32, np.float32]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'concat': {'kind': 'op', 'op': 'Concat'}
- },
- [
- ('queue_dequeue', 'sub', {'out': 0, 'in': 0}),
- ('queue_dequeue', 'add', {'out': 1, 'in': 0}),
- ('sub', 'concat', {'out': 0, 'in': 0}),
- ('add', 'concat', {'out': 0, 'in': 1})
- ]
- )
-
- graph_ref = build_graph_with_edge_attrs(
- {
- 'parameter_1': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([2, 2]), 'data_type': np.int32},
- 'parameter_2': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([1, 1]), 'data_type': np.float32},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'concat': {'kind': 'op', 'op': 'Concat'}
- },
- [
- ('parameter_1', 'sub', {'out': 0, 'in': 0}),
- ('parameter_2', 'add', {'out': 0, 'in': 0}),
- ('sub', 'concat', {'out': 0, 'in': 0}),
- ('add', 'concat', {'out': 0, 'in': 1})
- ]
- )
-
- FIFOQueueDequeueCut().find_and_replace_pattern(graph)
-
- flag, msg = compare_graphs(graph, graph_ref, last_node='concat', check_op_attrs=True)
- self.assertTrue(flag, msg)
-
- def test_two_outputs_v2(self):
- graph = build_graph_with_edge_attrs(
- {
- 'queue_dequeue': {'kind': 'op', 'op': 'QueueDequeueV2', 'shapes': [shape_array([2, 2]),
- shape_array([1, 1])],
- 'types': [np.int32, np.float32]},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'concat': {'kind': 'op', 'op': 'Concat'}
- },
- [
- ('queue_dequeue', 'sub', {'out': 0, 'in': 0}),
- ('queue_dequeue', 'add', {'out': 1, 'in': 0}),
- ('sub', 'concat', {'out': 0, 'in': 0}),
- ('add', 'concat', {'out': 0, 'in': 1})
- ]
- )
-
- graph_ref = build_graph_with_edge_attrs(
- {
- 'parameter_1': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([2, 2]), 'data_type': np.int32},
- 'parameter_2': {'kind': 'op', 'op': 'Parameter', 'shape': shape_array([1, 1]), 'data_type': np.float32},
- 'sub': {'kind': 'op', 'op': 'Sub'},
- 'add': {'kind': 'op', 'op': 'Add'},
- 'concat': {'kind': 'op', 'op': 'Concat'}
- },
- [
- ('parameter_1', 'sub', {'out': 0, 'in': 0}),
- ('parameter_2', 'add', {'out': 0, 'in': 0}),
- ('sub', 'concat', {'out': 0, 'in': 0}),
- ('add', 'concat', {'out': 0, 'in': 1})
- ]
- )
-
- FIFOQueueDequeueCut().find_and_replace_pattern(graph)
-
- flag, msg = compare_graphs(graph, graph_ref, last_node='concat', check_op_attrs=True)
- self.assertTrue(flag, msg)
diff --git a/tools/mo/unit_tests/mo/front/tf/floor_div_test.py b/tools/mo/unit_tests/mo/front/tf/floor_div_test.py
deleted file mode 100644
index 9c9a2c43f40d29..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/floor_div_test.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.floor_div_decomposition import FloorDivDecomposition
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, \
- connect_data, regular_op_with_empty_data
-
-nodes = {
- **regular_op_with_empty_data('placeholder_1', {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_empty_data('placeholder_2', {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_empty_data('floor_div', {'op': 'FloorDiv', 'type': None, 'name': 'my_floor_div'}),
-
- **regular_op_with_empty_data('div', {'type': 'Divide', 'op': 'Div'}),
- **regular_op_with_empty_data('floor', {'type': 'Floor', 'op': 'Floor'}),
-
- **result(),
-}
-
-
-class TestFloorDiv(unittest.TestCase):
- def test_floor_div_test_1(self):
- # Test with two different inputs from two placeholders
- graph = build_graph(nodes, [
- *connect('placeholder_1:0', '0:floor_div'),
- *connect('placeholder_2:0', '1:floor_div'),
- *connect('floor_div:0', '0:output'),
- ], nodes_with_edges_only=True)
- FloorDivDecomposition().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_1:0', '0:div'),
- *connect('placeholder_2:0', '1:div'),
- *connect('div:0', '0:floor'),
- *connect('floor:0', '0:output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='Floor')[0]]['name'] == 'my_floor_div')
-
- def test_floor_div_test_2(self):
- # Test with two same inputs from one placeholder
- graph = build_graph(nodes, [
- *connect('placeholder_1:0', '0:floor_div'),
- *connect_data('placeholder_1:0', '1:floor_div'),
- *connect('floor_div', 'output'),
- ], nodes_with_edges_only=True)
- FloorDivDecomposition().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_1:0', '0:div'),
- *connect_data('placeholder_1:0', '1:div'),
- *connect('div', 'floor'),
- *connect('floor', 'output'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(type='Floor')[0]]['name'] == 'my_floor_div')
diff --git a/tools/mo/unit_tests/mo/front/tf/identityN_to_identity_test.py b/tools/mo/unit_tests/mo/front/tf/identityN_to_identity_test.py
deleted file mode 100644
index 4f67edce9da954..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/identityN_to_identity_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.identityN_to_identity import IdentityN_to_Identity
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import result, regular_op_with_shaped_data, \
- regular_op_with_empty_data, build_graph, connect, empty_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder_0', [1, 227, 227, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('placeholder_1', [1, 227, 227, 3], {'type': 'Parameter'}),
-
- **regular_op_with_empty_data('identityN', {'op': 'IdentityN', 'type': None, 'data_types': [np.int32, np.float32],
- 'name': 'my_identity'}),
- **empty_data('identityN_1_d'),
- **regular_op_with_empty_data('identity0', {'op': 'Identity', 'type': None, 'data_type': np.int32,
- 'name': 'my_identity/0_port'}),
- **regular_op_with_empty_data('identity1', {'op': 'Identity', 'type': None, 'data_type': np.float32,
- 'name': 'my_identity/1_port'}),
-
- **result('output0'),
- **result('output1'),
-}
-
-
-class TestIdentityN(unittest.TestCase):
- def test_identityN(self):
- graph = build_graph(nodes, [
- *connect('placeholder_0', '0:identityN'),
- *connect('placeholder_1', '1:identityN'),
- *connect('identityN:0', 'output0'),
- ('identityN', 'identityN_1_d', {'out': 1}),
- ('identityN_1_d', 'output1', {'out': 1}),
- ], nodes_with_edges_only=True)
-
- IdentityN_to_Identity().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_0', 'identity0'),
- *connect('placeholder_1', 'identity1'),
- *connect('identity0', 'output0'),
- *connect('identity1', 'output1'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_identityN_unused_ports(self):
- graph = build_graph(nodes, [
- *connect('placeholder_0', '0:identityN'),
- *connect('placeholder_1', '1:identityN'),
- *connect('identityN:0', 'output0'),
- ], nodes_with_edges_only=True)
-
- IdentityN_to_Identity().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, [
- *connect('placeholder_0', 'identity0'),
- *connect('identity0', 'output0'),
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output0', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/loader_test.py b/tools/mo/unit_tests/mo/front/tf/loader_test.py
deleted file mode 100644
index dd02b83e6a02d3..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/loader_test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest.mock
-from io import StringIO
-from openvino.tools.mo.front.tf.loader import load_tf_graph_def
-from unittest.mock import Mock, MagicMock
-
-
-class TestLoader(unittest.TestCase):
- @unittest.mock.patch('sys.stdout', new_callable=StringIO)
- def test_helper_print_ckpt(self, out):
- for path in ['/path/to/somewhere/my_checkpoint.ckpt', '/path/to/somewhere/my_meta_graph.meta']:
- mock = Mock(__bool__=MagicMock(side_effect=Exception()))
- self.assertRaises(Exception, load_tf_graph_def, path, meta_graph_file=mock)
- self.assertRegex(out.getvalue(),
- r'\[ WARNING ] The value for the --input_model command line parameter ends with "\.ckpt"')
diff --git a/tools/mo/unit_tests/mo/front/tf/mvn_unrolled_test.py b/tools/mo/unit_tests/mo/front/tf/mvn_unrolled_test.py
deleted file mode 100644
index 92e6f39782b92b..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/mvn_unrolled_test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.mvn_unrolled import MVNUnrolled
-from openvino.tools.mo.ops.mvn import MVN
-from openvino.tools.mo.ops.op import Op
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class MVNUnrolledMatchingTests(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- Op.registered_ops['MVN'] = MVN
-
- def test(self):
- pattern_matcher = MVNUnrolled()
- pattern = pattern_matcher.pattern()
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'], update_edge_attrs=None,
- new_nodes_with_attrs=[('reduction_indicies', {'kind': 'data'}),
- ('conv2d', {'kind': 'op'}),
- ('variance_reduction', {'kind': 'data'}),
- ('pow2', {'kind': 'data'}),
- ('eps', {'kind': 'data'}),
- ('next_op', {'kind': 'op'})],
- new_edges_with_attrs=[('reduction_indicies', 'mean', {'in': 1}),
- ('conv2d', 'mean',{'in': 0, 'out': 1}),
- ('variance_reduction', 'variance', {'in': 1}),
- ('pow2', 'pow', {'in': 1}),
- ('eps', 'add'), ('truediv', 'next_op')])
- graph.graph['layout'] = 'NHWC'
- pattern_matcher.find_and_replace_pattern(graph)
-
- graph_ref = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'][:-1],
- edges_with_attrs=pattern['edges'][:-2], update_edge_attrs=None,
- new_nodes_with_attrs=[('reduction_indicies', {'kind':'data'}),
- ('conv2d', {'kind':'op'}),
- ('variance_reduction', {'kind':'data'}),
- ('pow2', {'kind': 'data'}),
- ('eps', {'kind': 'data'}),
- ('mvn', {'kind': 'op', 'op': 'MVN'}),
- ('next_op', {'kind': 'op'})],
- new_edges_with_attrs=[('reduction_indicies', 'mean', {'in':1}),
- ('conv2d', 'mean', {'in': 0}),
- ('variance_reduction', 'variance',{'in': 1}),
- ('pow2', 'pow', {'in': 1}),
- ('eps', 'add'),
- ('conv2d', 'mvn',{'in': 0}),
- ('reduction_indicies', 'mvn', {'in': 1}),
- ('variance_reduction', 'mvn',{'in': 2}),
- ('pow2', 'mvn', {'in': 3}),
- ('eps', 'mvn',{'in': 4}),
- ('mvn', 'next_op')])
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'next_op', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/next_iteration_ext_test.py b/tools/mo/unit_tests/mo/front/tf/next_iteration_ext_test.py
deleted file mode 100644
index abbb6bfc6c2cb8..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/next_iteration_ext_test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.front.tf.next_iteration_ext import NextIterationExtractor
-from unit_tests.utils.extractors import PB, BaseExtractorsTestingClass
-
-
-class TestNextIteration(BaseExtractorsTestingClass):
- def test_is_cyclic(self):
- pb = PB({})
- node = PB({'pb': pb})
- NextIterationExtractor.extract(node)
- self.expected = {
- 'is_cyclic': True,
- }
- self.res = node
- self.compare()
diff --git a/tools/mo/unit_tests/mo/front/tf/pad_tf_to_pad_test.py b/tools/mo/unit_tests/mo/front/tf/pad_tf_to_pad_test.py
deleted file mode 100644
index 9c3179a1ea2c55..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/pad_tf_to_pad_test.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.tf.pad_tf_to_pad import PadTFToPad
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-nodes_attributes = {
- 'placeholder': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'tfpad': {'type': None, 'kind': 'op', 'op': 'TFPad', 'mode': 'constant', 'name': 'tfpad_name'},
- **const('paddings', int64_array([1, 2, 3, 4, 5, 6]).reshape([3, 2])),
- **const('fill', float_array(5.75)),
- 'result': {'type': 'Result', 'value': None, 'kind': 'op', 'op': 'Result'},
-
- # new Pad layer and sub-graph
- 'pad': {'type': 'Pad', 'kind': 'op', 'op': 'Pad', 'mode': 'constant'},
- 'transpose': {'type': 'Transpose', 'kind': 'op', 'op': 'Transpose'},
- **const('transpose_order', int64_array([1, 0])),
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 2},
- **const('split_axis', int64_array(0)),
- 'squeeze_1': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- **const('squeeze_1_axis', int64_array([0])),
- 'squeeze_2': {'type': 'Squeeze', 'kind': 'op', 'op': 'Squeeze'},
- **const('squeeze_2_axis', int64_array([0])),
- 'convert_like': {'type': 'ConvertLike', 'kind': 'op', 'op': 'ConvertLike'},
-
- **const('pad_fill', np.array(0.0)),
-}
-
-common_edges = [('placeholder', 'pad', {'in': 0, 'out': 0}),
-
- ('paddings', 'transpose', {'in': 0, 'out': 0}),
- ('transpose_order', 'transpose', {'in': 1, 'out': 0}),
-
- ('transpose', 'split', {'in': 0, 'out': 0}),
- ('split_axis', 'split', {'in': 1, 'out': 0}),
-
- ('split', 'squeeze_1', {'in': 0, 'out': 0}),
- ('squeeze_1_axis', 'squeeze_1', {'in': 1, 'out': 0}),
-
- ('split', 'squeeze_2', {'in': 0, 'out': 1}),
- ('squeeze_2_axis', 'squeeze_2', {'in': 1, 'out': 0}),
-
- ('squeeze_1', 'pad', {'in': 1, 'out': 0}),
- ('squeeze_2', 'pad', {'in': 2, 'out': 0}),
-
- ('pad', 'result')
- ]
-
-
-class PadTFToPadTest(unittest.TestCase):
- def _run_test(self, graph, graph_ref):
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'front'
-
- replacer = PadTFToPad()
- replacer.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Pad')[0]]['name'] == 'tfpad_name')
- self.assertTrue(flag, resp)
-
- def test_2_inputs(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'tfpad', {'in': 0, 'out': 0}),
- ('paddings', 'tfpad', {'in': 1, 'out': 0}),
- ('tfpad', 'result', {'in': 0, 'out': 0}),
- ],
- {}, nodes_with_edges_only=True)
- graph.get_op_nodes(op='TFPad')[0].add_input_port(2)
-
- graph_ref = build_graph(nodes_attributes, common_edges,
- {}, nodes_with_edges_only=True)
- self._run_test(graph, graph_ref)
-
- def test_3_inputs(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'tfpad', {'in': 0, 'out': 0}),
- ('paddings', 'tfpad', {'in': 1, 'out': 0}),
- ('fill', 'tfpad', {'in': 2, 'out': 0}),
- ('tfpad', 'result', {'in': 0, 'out': 0}),
- ],
- {}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes, common_edges + [('fill', 'pad', {'in': 3, 'out': 0})],
- {}, nodes_with_edges_only=True)
-
- self._run_test(graph, graph_ref)
-
- def test_3_inputs_with_non_constant_pad(self):
- updated_paddings_attrs = {'type': 'Parameter', 'op': 'Parameter', 'value': None}
- graph = build_graph(nodes_attributes,
- [('placeholder', 'tfpad', {'in': 0, 'out': 0}),
- ('paddings', 'tfpad', {'in': 1, 'out': 0}),
- ('fill', 'tfpad', {'in': 2, 'out': 0}),
- ('tfpad', 'result', {'in': 0, 'out': 0}),
- ],
- {'paddings': updated_paddings_attrs}, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes, common_edges + [('fill', 'pad', {'in': 3, 'out': 0})],
- {'paddings': updated_paddings_attrs}, nodes_with_edges_only=True)
-
- self._run_test(graph, graph_ref)
-
- def test_2_inputs_non_constant_mode(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'tfpad', {'in': 0, 'out': 0}),
- ('paddings', 'tfpad', {'in': 1, 'out': 0}),
- ('tfpad', 'result', {'in': 0, 'out': 0}),
- ],
- {'tfpad': {'mode': 'reflect'}}, nodes_with_edges_only=True)
- graph.get_op_nodes(op='TFPad')[0].add_input_port(2)
-
- graph_ref = build_graph(nodes_attributes, common_edges,
- {'pad': {'mode': 'reflect'}}, nodes_with_edges_only=True)
- self._run_test(graph, graph_ref)
diff --git a/tools/mo/unit_tests/mo/front/tf/sparse_to_dense_replacer_test.py b/tools/mo/unit_tests/mo/front/tf/sparse_to_dense_replacer_test.py
deleted file mode 100644
index 1a340b2b92d84b..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/sparse_to_dense_replacer_test.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.tf.sparse_to_dense_replacer import SparseToDenseReplacer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, const
-
-
-class SparseToDenseFrontReplacersTest(unittest.TestCase):
- def test1(self):
- nodes_attributes = {
- 'input_indices': {'shape': int64_array([5, 2]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'input_values': {'shape': int64_array([5]), 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
-
- 'sparse_to_dense': {'kind': 'op', 'op': 'SparseToDense'},
- 'broadcast': {'kind': 'op', 'op': 'Broadcast'},
- 'scatternd': {'kind': 'op', 'op': 'ScatterNDUpdate'},
-
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': 'Result'},
-
- **const('input_dense_shape', int64_array([50, 40])),
- **const('input_default_value', int64_array(0))}
-
- graph = build_graph(nodes_attributes,
- [('input_indices', 'sparse_to_dense', {'out': 0, 'in': 0}),
- ('input_dense_shape', 'sparse_to_dense', {'out': 0, 'in': 1}),
- ('input_values', 'sparse_to_dense', {'out': 0, 'in': 2}),
- ('input_default_value', 'sparse_to_dense', {'out': 0, 'in': 3}),
- ('sparse_to_dense', 'last', {'out': 0, 'in': 0})],
- nodes_with_edges_only=True)
- graph.stage = 'front'
- SparseToDenseReplacer().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes_attributes,
- [('input_default_value', 'broadcast', {'in': 0}),
- ('input_dense_shape', 'broadcast', {'in': 1}),
- ('broadcast', 'scatternd', {'in': 0}),
- ('input_indices', 'scatternd', {'in': 1}),
- ('input_values', 'scatternd', {'in': 2}),
- ('scatternd', 'last', {'in': 0})],
- nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'last', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/front/tf/test_configs/config1.config b/tools/mo/unit_tests/mo/front/tf/test_configs/config1.config
deleted file mode 100755
index 22a47732c22de9..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/test_configs/config1.config
+++ /dev/null
@@ -1,17 +0,0 @@
-model {
- ssd {
- num_classes: 90
- image_resizer {
- fixed_shape_resizer {
- height: 300
- width: 300
- }
- }
- anchor_generator {
- ssd_anchor_generator {
- num_layers: 6
- }
- }
- }
-}
-
diff --git a/tools/mo/unit_tests/mo/front/tf/test_configs/config2.config b/tools/mo/unit_tests/mo/front/tf/test_configs/config2.config
deleted file mode 100755
index 0e837a7139129c..00000000000000
--- a/tools/mo/unit_tests/mo/front/tf/test_configs/config2.config
+++ /dev/null
@@ -1,11 +0,0 @@
-model {
- ssd {
- num_classes: 10
- image_resizer {
- fixed_shape_resizer {
- height: 640
- width: 640
- }
- }
- }
-}
diff --git a/tools/mo/unit_tests/mo/frontend_ngraph_test.py b/tools/mo/unit_tests/mo/frontend_ngraph_test.py
deleted file mode 100644
index d7571bc36c7169..00000000000000
--- a/tools/mo/unit_tests/mo/frontend_ngraph_test.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import os
-import subprocess
-import sys
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.subprocess_main import setup_env, subprocess_main
-
-import pytest
-
-
-class TestNoInferenceEngine(unittest.TestCase):
- @patch('openvino.tools.mo.utils.find_ie_version.find_ie_version')
- def test_no_ie_ngraph(self, mock_find):
- mock_find.return_value = False
- with pytest.raises(SystemExit) as e, self.assertLogs(log.getLogger(), level="ERROR") as cm:
- subprocess_main()
- assert e.value.code == 1
- res = [i for i in cm.output if
- 'Consider building the OpenVINO and Python APIs from sources' in i]
- assert res
-
-@pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == 'true', reason="Ticket - 113358")
-def test_frontends():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'frontend_ngraph_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-@pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == 'true', reason="Ticket - 113358")
-def test_moc_extractor():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'moc_frontend/moc_extractor_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-
-def test_moc_preprocessing():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'back/moc_preprocessing_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-
-def test_main_test():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'main_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-
-@pytest.mark.xfail(reason="Mismatched error messages due to namespace redesign.")
-def test_main_error_log():
- setup_env()
- args = [sys.executable,
- os.path.join(os.path.dirname(__file__), 'main_test_error_log.py')]
-
- status = subprocess.run(args, env=os.environ, capture_output=True)
- test_log = status.stderr.decode("utf-8").replace("\r\n", "\n")
-
- # Check that log has exactly one warning from parse_args and
- # exactly one error message "FW ERROR"
- ref_log = "[ WARNING ] warning\n[ FRAMEWORK ERROR ] FW ERROR MESSAGE\n"
-
- assert test_log == ref_log
-
-
-def test_mo_convert_logger():
- setup_env()
- args = [sys.executable,
- os.path.join(os.path.dirname(__file__), 'convert/logger_test_actual.py')]
-
- status = subprocess.run(args, env=os.environ, capture_output=True)
- test_log = status.stdout.decode("utf-8").replace("\r\n", "\n")
-
- assert "test message 1" in test_log
- assert "test message 2" in test_log
- assert "test message 3" in test_log
-
- assert test_log.count("[ SUCCESS ] Total execution time") == 2
-
-
-@pytest.mark.skipif(os.getenv("GITHUB_ACTIONS") == 'true', reason="Ticket - 115084")
-def test_rt_info():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'convert/meta_data_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ, capture_output=True)
- assert not status.returncode
-
-
-def test_mo_extensions_test():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'extensions_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-
-@pytest.mark.skipif(sys.version_info > (3, 10), reason="Ticket: 95904")
-def test_mo_fallback_test():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'utils/mo_fallback_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-
-def test_mo_model_analysis():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'utils/test_mo_model_analysis_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
-
-
-def test_convert_impl_tmp_irs_cleanup():
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(__file__), 'utils', 'convert_impl_tmp_irs_cleanup_test_actual.py')]
-
- status = subprocess.run(args, env=os.environ)
- assert not status.returncode
diff --git a/tools/mo/unit_tests/mo/frontend_ngraph_test_actual.py b/tools/mo/unit_tests/mo/frontend_ngraph_test_actual.py
deleted file mode 100644
index 759acb3984f883..00000000000000
--- a/tools/mo/unit_tests/mo/frontend_ngraph_test_actual.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import io
-import re
-import unittest
-from contextlib import redirect_stdout
-from unittest.mock import patch
-
-import numpy as np
-
-import pytest
-
-
-mock_available = True
-try:
- # pylint: disable=no-name-in-module,import-error
- from openvino.tools.mo.main import main
-
- # pylint: disable=no-name-in-module,import-error
- from mock_mo_python_api import get_frontend_statistic, get_model_statistic, \
- clear_frontend_statistic, clear_model_statistic, clear_place_statistic, \
- mock_return_partial_shape
-
- # pylint: disable=no-name-in-module,import-error
- from openvino.runtime import PartialShape
- from openvino.frontend import FrontEndManager
- from openvino.runtime.utils.types import get_element_type
-
-except Exception:
- print("No mock frontend API available, "
- "ensure to use -DENABLE_TESTS=ON option when running these tests")
- mock_available = False
-
-# FrontEndManager shall be initialized and destroyed after all tests finished
-# This is because destroy of FrontEndManager will unload all plugins,
-# no objects shall exist after this
-if mock_available:
- fem = FrontEndManager()
-
-mock_needed = pytest.mark.skipif(not mock_available,
- reason="mock MO fe is not available")
-
-
-def replaceArgsHelper(log_level='DEBUG',
- silent=False,
- model_name='abc',
- input_model='abc.test_mo_mock_mdl',
- transform=[],
- scale=None,
- output=None,
- _input=None,
- input_shape=None,
- batch=None,
- mean_values=None,
- scale_values=None,
- layout=None,
- source_layout=None,
- target_layout=None,
- output_dir='.',
- freeze_placeholder_with_value=None):
- return argparse.Namespace(
- log_level=log_level,
- silent=silent,
- model_name=model_name,
- input_model=input_model,
- transform=transform,
- scale=scale,
- output=output,
- input=_input,
- input_shape=input_shape,
- batch=batch,
- mean_values=mean_values,
- scale_values=scale_values,
- layout=layout,
- source_layout=source_layout,
- target_layout=target_layout,
- output_dir=output_dir,
- freeze_placeholder_with_value=freeze_placeholder_with_value,
- use_legacy_frontend=None,
- use_new_frontend=None,
- framework=None)
-
-
-class TestMainFrontend(unittest.TestCase):
- def setUp(self):
- clear_frontend_statistic()
- clear_model_statistic()
- clear_place_statistic()
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper())
- def test_simple_convert(self, mock_argparse):
- f = io.StringIO()
- with redirect_stdout(f):
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- out = f.getvalue()
-
- xml_file = re.search(r'\[ SUCCESS \] XML file: (.*)', out).\
- group(1).replace("\r", "")
- bin_file = re.search(r'\[ SUCCESS \] BIN file: (.*)', out).\
- group(1).replace("\r", "")
- assert xml_file and bin_file
-
- # verify that 'convert' was called, and 'supported' was not
- stat = get_frontend_statistic()
- assert stat.convert_model == 1
- assert stat.supported == 0
- # verify that meta info is added to XML file
- with open(xml_file) as file:
- assert 'openvino_mock_mo_frontend' in file.read()
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper())
- def test_convert_framework_discover(self, mock_argparse):
- f = io.StringIO()
- with redirect_stdout(f):
- main(argparse.ArgumentParser(), fem, None)
- out = f.getvalue()
-
- xml_file = re.search(r'\[ SUCCESS \] XML file: (.*)', out). \
- group(1).replace("\r", "")
- bin_file = re.search(r'\[ SUCCESS \] BIN file: (.*)', out). \
- group(1).replace("\r", "")
- assert xml_file and bin_file
-
- # verify that 'convert', 'supported' and 'get_name' were called
- stat = get_frontend_statistic()
- assert stat.convert_model == 1
- assert stat.supported == 1
- assert stat.get_name > 0
-
- # verify that meta info is added to XML file
- with open(xml_file) as file:
- assert 'openvino_mock_mo_frontend' in file.read()
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(_input='newInput1,mock_input2'))
- def test_override_inputs(self, mock_argparse):
-
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'override_all_inputs' was called
- assert stat.override_all_inputs == 1
- assert stat.override_all_outputs == 0
- assert stat.extract_subgraph == 0
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(output='newOut1,mock_output2'))
- def test_override_outputs(self, mock_argparse):
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'override_all_outputs' was called
- assert stat.override_all_inputs == 0
- assert stat.override_all_outputs == 1
- assert stat.extract_subgraph == 0
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(_input='newIn1,newIn2',
- output='newOut1,newOut2'))
- def test_extract_subgraph(self, mock_argparse):
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'extract_subgraph' was called
- assert stat.override_all_inputs == 0
- assert stat.override_all_outputs == 0
- assert stat.extract_subgraph == 1
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(_input='mock_input2,mock_input1',
- output='new_output2,mock_output1'))
- def test_override_same_inputs(self, mock_argparse):
-
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'override_all_outputs' was called
- # because inputs were not changed
- assert stat.override_all_inputs == 0
- assert stat.override_all_outputs == 1
- assert stat.extract_subgraph == 0
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(_input='newInput1,mock_input2',
- output='mock_output2,mock_output1'))
- def test_override_same_outputs(self, mock_argparse):
-
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'override_all_inputs' was called
- # because outputs were not changed
- assert stat.override_all_inputs == 1
- assert stat.override_all_outputs == 0
- assert stat.extract_subgraph == 0
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(_input='newIn1',
- input_shape='[1,2,3,4]'))
- @pytest.mark.skip(reason="Unskip as 8301 will be merged")
- def test_input_shape(self, mock_argparse):
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'set_partial_shape' was called
- assert stat.set_partial_shape == 1
- assert stat.lastArgPartialShape == PartialShape([1, 2, 3, 4])
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(_input='newIn1{i8}'))
- @pytest.mark.skip(reason="Unskip as 8301 will be merged")
- def test_element_type(self, mock_argparse):
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'set_element_type' was called
- assert stat.set_element_type == 1
- assert stat.lastArgElementType == get_element_type(np.int8)
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(batch=123))
- @pytest.mark.skip(reason="Unskip as 8301 will be merged")
- def test_set_batch_size(self, mock_argparse):
- mock_return_partial_shape(PartialShape([-1, 2, 3, 4]))
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
- stat = get_model_statistic()
-
- # verify that 'set_element_type' was called
- # 2 is because mock model has 2 inputs
- assert stat.get_partial_shape == 2
- assert stat.set_partial_shape == 2
- assert stat.lastArgPartialShape == PartialShape([123, 2, 3, 4])
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(batch=123))
- def test_error_batch(self, mock_argparse):
- # First dimension doesn't look like a batch,
- # so MO shall not convert anything and produce specified error
- mock_return_partial_shape(PartialShape([122, 2, 3, 4]))
- with self.assertLogs() as logger:
- main(argparse.ArgumentParser(), fem, 'openvino_mock_mo_frontend')
-
- stat = get_model_statistic()
-
- assert [s for s in logger.output if 'question=39' in s]
-
- # verify that 'get_element_type' was called
- assert stat.get_partial_shape == 1
- # verify that 'set_element_type' was not called
- assert stat.set_partial_shape == 0
-
- @mock_needed
- @patch('argparse.ArgumentParser.parse_args',
- return_value=replaceArgsHelper(input_model='abc.qwerty'))
- def test_error_input_model_no_framework(self, mock_argparse):
- # Framework is not specified and 'abc.qwerty' is not supported
- # so MO shall not convert anything and produce specified error
- with self.assertLogs() as logger:
- main(argparse.ArgumentParser(), fem, None)
-
- stat = get_frontend_statistic()
-
- assert [s for s in logger.output if 'can not be deduced' in s]
-
- # verify that 'supported' was called
- assert stat.supported == 1
diff --git a/tools/mo/unit_tests/mo/graph/__init__.py b/tools/mo/unit_tests/mo/graph/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/graph/connection_test.py b/tools/mo/unit_tests/mo/graph/connection_test.py
deleted file mode 100644
index 03c94cacd6833a..00000000000000
--- a/tools/mo/unit_tests/mo/graph/connection_test.py
+++ /dev/null
@@ -1,621 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.graph.graph import Node, Graph
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op
-
-nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('Op1', {'type': 'Op1', 'kind': 'op', 'op': 'Op1'}),
- **regular_op('Op2', {'type': 'Op2', 'kind': 'op', 'op': 'Op2'}),
- **regular_op('NewOp', {'type': 'NewOp', 'kind': 'op', 'op': 'NewOp'}),
-
- 'input_data': {'kind': 'data', 'fw_tensor_debug_info': [('input', 'input')]},
- 'Op1_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op1', 'Op1')]},
- 'Op2_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op2', 'Op2')]},
- 'NewOp_data': {'kind': 'data'},
-}
-
-
-class TestsFront(unittest.TestCase):
- def check_graph_attrs_front(self, graph: Graph, graph_ref: Graph):
- for node in graph_ref.get_op_nodes():
- if len(node.out_edges()) > 0:
- out_edge_ref = node.out_edge(0)
- out_edge = Node(graph, node.id).out_edge(0)
- if 'fw_tensor_debug_info' in out_edge_ref:
- self.assertTrue(out_edge['fw_tensor_debug_info'] == out_edge_ref['fw_tensor_debug_info'])
- else:
- self.assertFalse('fw_tensor_debug_info' in out_edge)
-
- def test_case1_merge(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'NewOp', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- input_node = Node(graph, 'input')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
-
- graph.stage = 'front'
- new_node.in_port(0).get_connection().set_source(input_node.out_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case1_source(self):
- graph = build_graph(nodes, [
- ('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'NewOp', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- input_node = Node(graph, 'input')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
-
- graph.stage = 'front'
- new_node.in_port(0).get_connection().set_source(input_node.out_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case1_dest(self):
- graph = build_graph(nodes, [
- ('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'NewOp', {'in': 0, 'out': 0})])
-
- input_node = Node(graph, 'input')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
-
- graph.stage = 'front'
- new_node.in_port(0).get_connection().set_source(input_node.out_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case2_merge(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'NewOp', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_destination(new_node.in_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case2_source(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'NewOp', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_destination(new_node.in_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case2_dest(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [('input', 'NewOp', {'in': 0, 'out': 0})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_destination(new_node.in_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case3_merge(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('NewOp', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_source(new_node.out_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case3_source(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [('NewOp', 'Op1', {'in': 0, 'out': 0})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_source(new_node.out_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case3_dest(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('NewOp', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_source(new_node.out_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case4_merge(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
- graph_ref = build_graph(nodes, [
- ('NewOp', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input')]})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
-
- graph.stage = 'front'
- new_node.out_port(0).get_connection().set_destination(op1_node.in_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case4_source(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]})])
- graph_ref = build_graph(nodes, [('NewOp', 'Op1', {'in': 0, 'out': 0})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
-
- graph.stage = 'front'
- new_node.out_port(0).get_connection().set_destination(op1_node.in_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case4_dest(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]})])
- graph_ref = build_graph(nodes, [
- ('NewOp', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]})])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
-
- graph.stage = 'front'
- new_node.out_port(0).get_connection().set_destination(op1_node.in_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case5_merge(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]}),
- ('Op1', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input'), ('Op1', 0, 'Op1')]})])
- op1_node = Node(graph, 'Op1')
-
- inp_node = Node(graph, 'input')
- op2_node = Node(graph, 'Op2')
- graph.stage = 'front'
- op1_node.out_port(0).get_connection().set_source(op1_node.in_port(0).get_source(), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case5_source(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]}),
- ('Op1', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]})])
- op1_node = Node(graph, 'Op1')
-
- graph.stage = 'front'
- op1_node.out_port(0).get_connection().set_source(op1_node.in_port(0).get_source(), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case5_dest(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]}),
- ('Op1', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- graph_ref = build_graph(nodes,
- [('input', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- op1_node = Node(graph, 'Op1')
-
- graph.stage = 'front'
- op1_node.out_port(0).get_connection().set_source(op1_node.in_port(0).get_source(), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case6_merge(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]}),
- ('Op1', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input'), ('Op1', 0, 'Op1')]})])
- op1_node = Node(graph, 'Op1')
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_destination(op1_node.out_port(0).get_destination(), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case6_source(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]}),
- ('Op1', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- graph_ref = build_graph(nodes, [
- ('input', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]})])
- op1_node = Node(graph, 'Op1')
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_destination(op1_node.out_port(0).get_destination(), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
- def test_case6_dest(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 0, 'input')]}),
- ('Op1', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- graph_ref = build_graph(nodes,
- [('input', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 0, 'Op1')]})])
- op1_node = Node(graph, 'Op1')
-
- graph.stage = 'front'
- op1_node.in_port(0).get_connection().set_destination(op1_node.out_port(0).get_destination(), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_front(graph, graph_ref)
-
-
-class TestsMiddle(unittest.TestCase):
- def check_graph_attrs_middle(self, graph: Graph, graph_ref: Graph):
- for node in graph_ref.get_op_nodes():
- if len(node.out_nodes()) > 0:
- data_node_ref = node.out_node(0)
- data_node = Node(graph, node.id).out_node(0)
- if 'fw_tensor_debug_info' in data_node_ref:
- self.assertTrue(data_node_ref['fw_tensor_debug_info'] == data_node['fw_tensor_debug_info'])
- else:
- self.assertFalse('fw_tensor_debug_info' in data_node)
-
- def test_case1_merge(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('input_data', 'NewOp')])
- input_node = Node(graph, 'input')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
- new_node.in_port(0).get_connection().set_source(input_node.out_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case1_source(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('input_data', 'NewOp')])
- input_node = Node(graph, 'input')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
- new_node.in_port(0).get_connection().set_source(input_node.out_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case1_dest(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('input_data', 'NewOp')])
-
- input_node_data = Node(graph_ref, 'input_data')
- del input_node_data['fw_tensor_debug_info']
-
- input_node = Node(graph, 'input')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
- new_node.in_port(0).get_connection().set_source(input_node.out_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case2_merge(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'),
- ('input_data', 'NewOp')])
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
- op1_node.in_port(0).get_connection().set_destination(new_node.in_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case2_source(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'),
- ('input_data', 'NewOp')])
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
- op1_node.in_port(0).get_connection().set_destination(new_node.in_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case2_dest(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'),
- ('input_data', 'NewOp')])
-
- input_node_data = Node(graph_ref, 'input_data')
- del input_node_data['fw_tensor_debug_info']
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_input_port(0)
- op1_node.in_port(0).get_connection().set_destination(new_node.in_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'NewOp', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case3_merge(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('NewOp', 'NewOp_data'), ('NewOp_data', 'Op1')])
-
- new_op_data = Node(graph_ref, 'NewOp_data')
- new_op_data['fw_tensor_debug_info'] = [('input', 'input')]
-
- input_data = Node(graph_ref, 'input_data')
- del input_data['fw_tensor_debug_info']
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
- op1_node.in_port(0).get_connection().set_source(new_node.out_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case3_source(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('NewOp', 'NewOp_data'), ('NewOp_data', 'Op1')])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
- op1_node.in_port(0).get_connection().set_source(new_node.out_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case3_dest(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('NewOp', 'NewOp_data'), ('NewOp_data', 'Op1')])
-
- new_op_data = Node(graph_ref, 'NewOp_data')
- new_op_data['fw_tensor_debug_info'] = [('input', 'input')]
-
- input_data = Node(graph_ref, 'input_data')
- del input_data['fw_tensor_debug_info']
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
- op1_node.in_port(0).get_connection().set_source(new_node.out_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case4_merge(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('NewOp', 'NewOp_data'), ('NewOp_data', 'Op1')])
-
- new_op_data = Node(graph_ref, 'NewOp_data')
- new_op_data['fw_tensor_debug_info'] = [('input', 'input')]
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
- new_node.out_port(0).get_connection().set_destination(op1_node.in_port(0), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case4_source(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('NewOp', 'NewOp_data'), ('NewOp_data', 'Op1')])
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
- new_node.out_port(0).get_connection().set_destination(op1_node.in_port(0), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case4_dest(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('NewOp', 'NewOp_data'), ('NewOp_data', 'Op1')])
-
- new_op_data = Node(graph_ref, 'NewOp_data')
- new_op_data['fw_tensor_debug_info'] = [('input', 'input')]
-
- op1_node = Node(graph, 'Op1')
- new_node = Node(graph, 'NewOp')
- new_node.add_output_port(0)
- new_node.out_port(0).get_connection().set_destination(op1_node.in_port(0), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op1', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case5_merge(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('input_data', 'Op2')])
-
- input_data = Node(graph_ref, 'input_data')
- input_data['fw_tensor_debug_info'] = [('input', 'input'), ('Op1', 'Op1')]
-
- op1_data = Node(graph_ref, 'Op1_data')
- del op1_data['fw_tensor_debug_info']
-
- op1_node = Node(graph, 'Op1')
- op1_node.out_port(0).get_connection().set_source(op1_node.in_port(0).get_source(), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case5_source(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('input_data', 'Op2')])
-
- input_data = Node(graph_ref, 'input_data')
- input_data['fw_tensor_debug_info'] = [('input', 'input')]
-
- op1_node = Node(graph, 'Op1')
- op1_node.out_port(0).get_connection().set_source(op1_node.in_port(0).get_source(), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case5_dest(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('input_data', 'Op2')])
-
- input_data = Node(graph_ref, 'input_data')
- input_data['fw_tensor_debug_info'] = [('Op1', 'Op1')]
-
- op1_data = Node(graph_ref, 'Op1_data')
- del op1_data['fw_tensor_debug_info']
-
- op1_node = Node(graph, 'Op1')
- op1_node.out_port(0).get_connection().set_source(op1_node.in_port(0).get_source(), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case6_merge(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op2'),
- ('Op1', 'Op1_data')])
-
- input_data = Node(graph_ref, 'input_data')
- input_data['fw_tensor_debug_info'] = [('input', 'input'), ('Op1', 'Op1')]
-
- op1_node = Node(graph, 'Op1')
- op1_node.in_port(0).get_connection().set_destination(op1_node.out_port(0).get_destination(), "merge")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case6_source(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op2'),
- ('Op1', 'Op1_data')])
-
- input_data = Node(graph_ref, 'input_data')
- input_data['fw_tensor_debug_info'] = [('input', 'input')]
-
- op1_node = Node(graph, 'Op1')
- op1_node.in_port(0).get_connection().set_destination(op1_node.out_port(0).get_destination(), "source")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
-
- def test_case6_dest(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2')])
- graph_ref = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op2'),
- ('Op1', 'Op1_data')])
-
- input_data = Node(graph_ref, 'input_data')
- input_data['fw_tensor_debug_info'] = [('Op1', 'Op1')]
-
- op1_node = Node(graph, 'Op1')
- op1_node.in_port(0).get_connection().set_destination(op1_node.out_port(0).get_destination(), "dest")
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'Op2', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.check_graph_attrs_middle(graph, graph_ref)
diff --git a/tools/mo/unit_tests/mo/graph/graph_test.py b/tools/mo/unit_tests/mo/graph/graph_test.py
deleted file mode 100644
index 6aa770b5994ed3..00000000000000
--- a/tools/mo/unit_tests/mo/graph/graph_test.py
+++ /dev/null
@@ -1,1867 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.graph.graph import Node, Graph, add_opoutput, dict_includes_compare_attrs, get_edge_attribute_between_nodes, \
- set_edge_attribute_between_nodes
-from openvino.tools.mo.ops.const import Const
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import build_graph, build_graph_with_edge_attrs
-
-nodes = {
- '0': {'name': 'input1', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '1': {'name': 'input2', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '2': {'name': 'node_1', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'NotPlaceholder'},
- '3': {'name': 'node_2', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'NotPlaceholder'},
- '4': {'name': 'node_3', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'NotPlaceholder'},
- '5': {'name': 'node_4', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'NotPlaceholder'},
- '6': {'name': 'output', 'value': None, 'kind': 'op', 'op': 'Result'},
- 'input_3': {'name': 'input_3', 'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Parameter'}
-}
-edges = {
- ('0', '2'),
- ('2', '3'),
- ('4', '6'),
- ('1', '5'),
- ('5', '6'),
- ('input_3', '6')
-}
-
-
-class TestGetNodeById(UnitTestWithMockedTelemetry):
- def setUp(self):
- super().setUp()
- self.graph = build_graph(nodes, edges)
-
- def test_get_node_id_by_name(self):
- self.assertEqual(self.graph.get_node_id_by_name('input1'), '0')
-
- def test_get_node_id_by_name_1(self):
- self.assertEqual(self.graph.get_node_id_by_name('input2'), '1')
-
- def test_get_node_id_by_name_2(self):
- self.assertEqual(self.graph.get_node_id_by_name('node_1'), '2')
-
- def test_get_node_id_by_name_3(self):
- self.assertEqual(self.graph.get_node_id_by_name('node_2'), '3')
-
- def test_get_node_id_by_name_4(self):
- self.assertEqual(self.graph.get_node_id_by_name('node_3'), '4')
-
- def test_get_node_id_by_name_5(self):
- self.assertEqual(self.graph.get_node_id_by_name('node_4'), '5')
-
- def test_get_node_id_by_name_6(self):
- self.assertEqual(self.graph.get_node_id_by_name('output'), '6')
-
- def test_get_node_id_by_name_7(self):
- self.assertEqual(self.graph.get_node_id_by_name('input_3'), 'input_3')
-
- def test_get_node_id_by_name_8(self):
- self.assertRaises(Error, self.graph.get_node_id_by_name, '1')
-
-
-class TestEraseNode(unittest.TestCase):
- def test_remove_noop_nodes_middle(self):
- graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'},
- 'output': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input', 'noop'),
- ('noop', 'output')])
-
- self.assertEqual(len(graph.nodes()), 3)
- self.assertEqual(len(graph.edges()), 2)
- self.assertListEqual(list(graph.out_edges('input')), [('input', 'noop')])
-
- graph.erase_node(Node(graph, 'noop'))
-
- self.assertEqual(len(graph.nodes()), 2)
- self.assertEqual(len(graph.edges()), 1)
- self.assertListEqual(list(graph.out_edges('input')), [('input', 'output')])
-
- def test_remove_noop_nodes_middle_2(self):
- graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input', 'noop'),
- ('noop', 'output_1', {'in': 4, 'out': 0}),
- ('noop', 'output_2', {'in': 2, 'out': 0}),
- ('noop', 'output_3', {'in': 10, 'out': 0})])
-
- ref_graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input', 'output_1', {'in': 4, 'out': 0}),
- ('input', 'output_2', {'in': 2, 'out': 0}),
- ('input', 'output_3', {'in': 10, 'out': 0})],
- nodes_with_edges_only=True)
-
- graph.erase_node(Node(graph, 'noop'))
-
- compare_graphs(graph, ref_graph, 'output_1')
-
- def test_remove_noop_nodes_check_out_port(self):
- graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input', 'noop'),
- ('noop', 'output_1', {'in': 4, 'out': 1}),
- ('noop', 'output_2', {'in': 2, 'out': 1}),
- ('noop', 'output_3', {'in': 10, 'out': 1})])
-
- ref_graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input', 'output_1', {'in': 4, 'out': 0}),
- ('input', 'output_2', {'in': 2, 'out': 0}),
- ('input', 'output_3', {'in': 10, 'out': 0})],
- nodes_with_edges_only=True)
-
- graph.erase_node(Node(graph, 'noop'))
-
- compare_graphs(graph, ref_graph, 'output_1')
-
- def test_remove_noop_nodes_too_many_outputs(self):
- graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input', 'noop'),
- ('noop', 'output_1', {'in': 4, 'out': 0}),
- ('noop', 'output_2', {'in': 2, 'out': 1}),
- ('noop', 'output_3', {'in': 10, 'out': 0})])
-
- self.assertRaises(AssertionError, graph.erase_node, Node(graph, 'noop'))
-
- def test_remove_noop_nodes_front(self):
- graph = build_graph(
- {
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'},
- 'output': {'type': 'Identity', 'value': None, 'kind': 'op'}
- },
- [('noop', 'output')]
- )
-
- self.assertEqual(len(graph.nodes()), 2)
- self.assertEqual(len(graph.edges()), 1)
- self.assertListEqual(list(graph.out_edges('noop')), [('noop', 'output')])
-
- graph.erase_node(Node(graph, 'noop'))
-
- self.assertEqual(len(graph.nodes()), 1)
- self.assertEqual(len(graph.edges()), 0)
- self.assertEqual(len(graph.in_edges('output')), 0)
-
- def test_remove_noop_nodes_back(self):
- graph = build_graph(
- {
- 'input': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'}
- },
- [('input', 'noop')]
- )
-
- self.assertEqual(len(graph.nodes()), 2)
- self.assertEqual(len(graph.edges()), 1)
- self.assertListEqual(list(graph.in_edges('noop')), [('input', 'noop')])
-
- graph.erase_node(Node(graph, 'noop'))
-
- self.assertEqual(len(graph.nodes()), 1)
- self.assertEqual(len(graph.edges()), 0)
- self.assertEqual(len(graph.in_edges('input')), 0)
-
- def test_remove_noop_nodes_noop_only(self):
- graph = Graph()
- graph.add_node('noop', **{'type': 'NoOp', 'value': None, 'kind': 'op'})
-
- self.assertEqual(len(graph.nodes()), 1)
- self.assertEqual(len(graph.edges()), 0)
-
- graph.erase_node(Node(graph, 'noop'))
-
- self.assertEqual(len(graph.nodes()), 0)
- self.assertEqual(len(graph.edges()), 0)
-
- def test_remove_noop_error(self):
- graph = build_graph(
- {
- 'input_1': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'input_2': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'input_3': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'noop': {'type': 'NoOp', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input_1', 'noop'),
- ('input_2', 'noop'),
- ('input_3', 'noop'),
- ('noop', 'output_1'),
- ('noop', 'output_2'),
- ('noop', 'output_3')])
- self.assertRaises(AssertionError, graph.erase_node, Node(graph, 'noop'))
-
-
-class TestReplaceNode(unittest.TestCase):
- def test_replace_node_one_consumer(self):
- graph = build_graph(
- {
- 'input_1': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'input_2': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'old': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output': {'op': 'Result', 'value': None, 'kind': 'op'},
- },
- [('input_1', 'old'),
- ('input_2', 'old'),
- ('old', 'output')])
-
- new_node = Const(graph, {'name': 'new'}).create_node([Node(graph, 'input_1'), Node(graph, 'input_2')])
-
- old_node = Node(graph, 'old')
- old_node.replace_node(new_node)
-
- self.assertEqual(len(graph.nodes()), 4)
- self.assertEqual(len(graph.edges()), 3)
- self.assertEqual(new_node.out_node().op, 'Result')
- self.assertEqual(len(graph.out_edges('new')), 1)
-
- def test_replace_node_several_consumers(self):
- graph = build_graph(
- {
- 'input_1': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'input_2': {'type': 'Parameter', 'value': None, 'kind': 'op'},
- 'old': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'output_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- },
- [('input_1', 'old'),
- ('input_2', 'old'),
- ('old', 'output_3'),
- ('old', 'output_2'),
- ('old', 'output_1'),
- ])
-
- new_node = Const(graph, {'name': 'new'}).create_node([Node(graph, 'input_1'), Node(graph, 'input_2')])
- Node(graph, 'old').replace_node(new_node)
-
- self.assertEqual(len(graph.nodes()), 6)
- self.assertEqual(len(graph.edges()), 5)
- self.assertListEqual(sorted(graph.out_edges('new')), [('new', 'output_1'), ('new', 'output_2'),
- ('new', 'output_3')])
- expected_result = [('new', 'output_1', {'in': 0, 'out': 2, 'name': 'old'}),
- ('new', 'output_2', {'in': 0, 'out': 1, 'name': 'old'}),
- ('new', 'output_3', {'in': 0, 'out': 0, 'name': 'old'})]
- self.assertListEqual(sorted(graph.out_edges('new', data=True)), expected_result)
-
-
-class GetNodesWithPorts(unittest.TestCase):
- def test_get_nodes_with_ports(self):
- nodes = {
- 'one': {},
- 'two': {},
- 'three': {},
- 'four': {},
- 'five': {}
- }
- edges = [
- ('one', 'two', {'in': 0, 'out': 0}),
- ('two', 'three', {'in': 0, 'out': 0}),
- ('two', 'four', {'in': 0, 'out': 1}),
- ('two', 'five', {'in': 0, 'out': 2}),
- ('three', 'five', {'in': 1, 'out': 0})
- ]
- graph = build_graph(nodes, edges)
- match = {
- 'one': Node(graph, 'one'),
- 'two': Node(graph, 'two'),
- 'three': Node(graph, 'three'),
- 'four': Node(graph, 'four'),
- 'five': Node(graph, 'five'),
-
- }
- input_names_in_pattern = ['one', 'three']
- result = graph.get_inputs_with_ports(match=match, pattern_edges=edges,
- input_names_in_pattern=input_names_in_pattern)
- self.assertListEqual([(match['one'], 0), (match['three'], 0)], result)
-
-
-class TestGraphShapeChecker(unittest.TestCase):
- nodes = {
- '0': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '0_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '1': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '2': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '2_data': {'value': None, 'shape': None, 'kind': 'data'},
- }
-
- def test_check_shape_consistency_1(self):
- # No shape attr in data node
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
-
- del graph.node['2_data']['shape']
-
- with self.assertRaisesRegex(Error, r"Graph contains data nodes \(1\) with inconsistent shapes:.*"):
- graph.check_shapes_consistency()
-
- def test_check_shape_consistency_2(self):
- # No shape attr in data node
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
-
- graph.node['1_data']['shape'] = (1, 2, 3)
- graph.node['2_data']['shape'] = (1, 2, 3)
-
- with self.assertRaisesRegex(Error, r"Graph contains data nodes \(2\) with inconsistent shapes:.*"):
- graph.check_shapes_consistency()
-
-
-class TestGraphPortsChecker():
- nodes = {
- '0': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '0_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '1': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '2': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '2_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '3': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '3_data': {'value': None, 'shape': None, 'kind': 'data'},
- }
-
- @pytest.mark.parametrize("node_id, port_type, port_idx",[('0', 'in', 1), ('0', 'out', 2), ('1', 'in', 2), ('3', 'out', 2)])
- def test_check_shape_consistency_1(self, node_id: str, port_type: str, port_idx: int):
- #
- # ,->2-->2_data---,->3-->3_data
- # 0-->0_data-/-->1-->1_data--/
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ('1_data', '3'),
- ('2_data', '3'),
- ])
-
- node = Node(graph, node_id)
- if port_type == 'in':
- node.add_input_port(idx=port_idx)
- else:
- node.add_output_port(idx=port_idx)
-
- with pytest.raises (Error, match= "Node {} has not consecutive {} ports indexes:.*".format(node_id,
- port_type)):
- graph.check_nodes_ports_are_consecutive()
-
-
-class TestNewGraphAPIMiddle(unittest.TestCase):
-
- nodes = {
- '0': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '0_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '1': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '2': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '2_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '3': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '3_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- '4': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '4_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'const_1': {'type': 'Const', 'value': None, 'kind': 'op', 'op': 'Const'},
- 'const_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- }
-
- nodes_10_in_10_out = {
- 'op_concat': {'type': 'Concat', 'value': None, 'kind': 'op', 'op': 'Concat'},
- 'op_concat_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'op_split': {'type': 'Split', 'value': None, 'kind': 'op', 'op': 'Split'},
- }
-
- # Filling nodes list
- for idx in range(11):
- nodes_10_in_10_out.update({'in_{}'.format(idx): {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'}})
- nodes_10_in_10_out.update({'in_{}_data'.format(idx): {'value': None, 'shape': None, 'kind': 'data'}})
- nodes_10_in_10_out.update({'out_{}'.format(idx): {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'}})
- nodes_10_in_10_out.update({'op_split_{}_data'.format(idx): {'value': None, 'shape': None, 'kind': 'data'}})
-
- ###########################################
- ###### TESTS FOR PORT CLASS METHODS #######
- ###########################################
-
- def test_port_get_destinations_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
- node_2_in_port = Node(graph, '2').in_port(0)
-
- ports = node_0_out_port.get_destinations()
-
- self.assertTrue(len(ports) == 2)
- for port in ports:
- self.assertTrue(port in [node_1_in_port, node_2_in_port])
-
- def test_port_get_destination_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
- node_2_in_port = Node(graph, '2').in_port(0)
-
- with self.assertRaises(Error):
- node_0_out_port.get_destination()
-
- def test_port_get_destination_2(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('0_data', '1'),
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
-
- self.assertEqual(node_0_out_port.get_destination(), node_1_in_port)
-
- def test_port_get_source_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('0_data', '1'),
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
-
- self.assertEqual(node_1_in_port.get_source(), node_0_out_port)
-
- def test_port_get_source_2(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('0_data', '1'),
- ('2_data', '1')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- self.assertEqual(node_1.in_port(0).get_source(), node_0.out_port(0))
- self.assertEqual(node_1.in_port(1).get_source(), node_2.out_port(0))
-
- def test_port_get_source_3(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_0.add_input_port(0)
- node_1.add_input_port(0)
- node_2.add_input_port(0)
-
- self.assertEqual(node_0.in_port(0).get_source(), None)
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
- def test_port_disconnect_1(self):
- # ,-->1-->1_data 0-->0_data
- # 0-->0_data/--->2-->2_data ==> 0-->0_data 1-->1_data
- # 2-->2_data
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_0.out_port(0).disconnect()
-
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
- self.assertTrue(len(node_1.in_nodes()) == 0)
- self.assertTrue(len(node_2.in_nodes()) == 0)
-
- def test_port_disconnect_2(self):
- # ,-->1-->1_data ,-->1-->1_data
- # 0-->0_data/--->2-->2_data ==> 0-->0_data/ 2-->2_data
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_2.in_port(0).disconnect()
-
- self.assertEqual(node_0.out_port(0).get_destination(), node_1.in_port(0))
- self.assertEqual(node_1.in_port(0).get_source(), node_0.out_port(0))
- self.assertEqual(node_2.out_port(0).get_destination(), None)
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
- self.assertTrue(len(node_0.out_nodes()) == 1)
- self.assertTrue(len(node_1.in_nodes()) == 1)
- self.assertTrue(len(node_2.in_nodes()) == 0)
-
- def test_port_disconnect_3(self):
- # 1-->1_data---\ 1-->1_data
- # 0-->0_data---->2-->2_data ==> 0-->0_data-->2-->2_data
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('0_data', '2'),
- ('1_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_2.in_port(1).disconnect()
-
- self.assertEqual(node_0.out_port(0).get_destination(), node_2.in_port(0))
- self.assertEqual(node_2.in_port(0).get_source(), node_0.out_port(0))
- self.assertEqual(node_1.out_port(0).get_destination(), None)
-
- self.assertTrue(len(node_0.out_nodes()) == 1)
- self.assertTrue(len(node_1.in_nodes()) == 0)
- self.assertTrue(len(node_2.in_nodes()) == 1)
-
- def test_port_disconnect_4(self):
- # 1-->1_data---\ 0-->0_data
- # 0-->0_data---->2-->2_data ==> 1-->1_data-->2-->2_data
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('0_data', '2'),
- ('1_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_2.in_port(0).disconnect()
-
- self.assertEqual(node_1.out_port(0).get_destination(), node_2.in_port(1))
- self.assertEqual(node_2.in_port(1).get_source(), node_1.out_port(0))
- self.assertEqual(node_2.in_port(0).get_source(), None)
- self.assertEqual(node_0.out_port(0).get_destination(), None)
- #
- # self.assertTrue(len(node_0.out_nodes()) == 1)
- # self.assertTrue(len(node_1.in_nodes()) == 0)
- # self.assertTrue(len(node_2.in_nodes()) == 1)
-
- ###########################################
- ### TESTS FOR CONNECTION CLASS METHODS ####
- ###########################################
-
- def test_connection_set_source_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
- ('4', '4_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ('3_data', '4'),
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_3 = Node(graph, '3')
- node_4 = Node(graph, '4')
-
- c = node_0.out_port(0).get_connection()
- c.set_source(node_3.out_port(0))
-
- self.assertTrue(node_0.out_node().kind == 'data')
-
- self.assertEqual(node_0.out_port(0).get_destinations(), [])
- destinations = node_3.out_port(0).get_destinations()
- for port in destinations:
- self.assertTrue(port in [node_1.in_port(0), node_2.in_port(0), node_4.in_port(0)])
-
- def test_connection_set_source_2(self):
- # 2-->2_data ,->2-->2_data
- # 0-->0_data-->1-->1_data ==> 0-->0_data/-->1-->1_data
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_2 = Node(graph, '2')
- node_2.add_input_port(0)
-
- node_2.in_port(0).get_connection().set_source(node_0.out_port(0))
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ])
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_source_3(self):
- # ,->2-->2_data 0-->0_data-->1-->1_data
- # 0-->0_data/-->1-->1_data => 3-->3_data-->2-->2_data
- # 3-->3_data
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_2 = Node(graph, '2')
- node_3 = Node(graph, '3')
-
- node_2.in_port(0).get_connection().set_source(node_3.out_port(0))
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('3_data', '2'),
- ])
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- (flag, resp) = compare_graphs(graph, graph_ref, '2', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_source_4(self):
- # 0 1 ==> 0-->1
- graph = build_graph(self.nodes, [])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
-
- node_0.add_output_port(0)
- node_1.add_input_port(0)
-
- node_1.in_port(0).get_connection().set_source(node_0.out_port(0))
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('0_data', '1'),
- ])
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_destination(self):
- # ,->2-->2_data-->3-->3_data ,->2-->2_data
- # 0-->0_data/-->1-->1_data ==> 0-->0_data/-->3-->3_data
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ('2_data', '3'),
- ])
- graph.__setattr__('stage', 'middle')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '3'),
- ('0_data', '2'),
- ])
-
- node_1 = Node(graph, '1')
- node_3 = Node(graph, '3')
-
- node_3.in_port(0).disconnect()
- node_1.in_port(0).get_connection().set_destination(node_3.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_destination_1(self):
- # 2
- # ,->1-->1_data ,->2
- # 0-->0_data/-->1-->1_data ==> 0-->0_data/-->1
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
-
- ('0_data', '1'),
- ('0_data', '1'),
- ])
- graph.__setattr__('stage', 'middle')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ])
-
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_2.add_input_port(0)
-
- node_1.in_port(1).get_connection().set_destination(node_2.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_destination_2(self):
- # 2
- # ,->1 ,->1
- # 0-->0_data/-->1 ==> 0-->0_data/-->2
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
-
- ('0_data', '1'),
- ('0_data', '1'),
- ])
- graph.__setattr__('stage', 'middle')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
-
- ('0_data', '1', {'in': 1}),
- ('0_data', '2'),
- ])
-
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_2.add_input_port(0)
-
- node_1.in_port(0).get_connection().set_destination(node_2.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_add_destination_1(self):
- # 3-->3_data ,-->3-->3_data
- # ,->2-->2_data ,-->2-->2_data
- # 0-->0_data/-->1-->1_data ==> 0-->0_data/-->1-->1_data
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ])
- graph.__setattr__('stage', 'middle')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ('0_data', '3'),
- ])
-
- node_0 = Node(graph, '0')
- node_3 = Node(graph, '3')
- node_3.add_input_port(idx=0)
-
- node_0.out_port(0).get_connection().add_destination(node_3.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_add_destination_2(self):
- # 0
- # 1-->1_data ==> 0-->0_data-->1-->1_data
- graph = build_graph(self.nodes, [
- ('1', '1_data'),
- ])
- graph.__setattr__('stage', 'middle')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('0_data', '1'),
- ])
-
- node_0 = Node(graph, '0')
- node_0.add_output_port(idx=0)
-
- node_1 = Node(graph, '1')
- node_1.add_input_port(idx=0)
-
- node_0.out_port(0).get_connection().add_destination(node_1.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_get_source_destinations_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- source = node_0.out_port(0).get_connection().get_source()
- destinations = node_0.out_port(0).get_connection().get_destinations()
-
- self.assertEqual(source, node_0.out_port(0))
- for port in destinations:
- self.assertTrue(port in [node_1.in_port(0), node_2.in_port(0)])
-
- self.assertEqual(node_1.out_port(0).get_connection().get_destination(), None)
- self.assertEqual(node_1.out_port(0).get_destination(), None)
-
- self.assertEqual(node_2.out_port(0).get_connection().get_destination(), None)
- self.assertEqual(node_2.out_port(0).get_destination(), None)
-
- def test_connection_remove_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_1.in_port(0).get_connection().remove()
-
- self.assertEqual(node_0.out_port(0).get_destinations(), [node_2.in_port(0)])
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), node_0.out_port(0))
-
- def test_connection_remove_2(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ])
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_0.out_port(0).get_connection().remove()
-
- self.assertEqual(node_0.out_port(0).get_destinations(), [])
- self.assertEqual(node_1.out_port(0).get_destinations(), [])
- self.assertEqual(node_2.out_port(0).get_destinations(), [])
-
- def test_connection_data_1(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
-
- ('0_data', '1'),
- ('0_data', '2')
- ], {'0_data': {'value': np.ones((1,3,64,64)), 'shape': np.array([1, 3, 64, 64])}})
-
- graph.__setattr__('stage', 'middle')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- self.assertTrue(np.array_equal(node_0.out_port(0).get_connection().data.get_shape(), (1, 3, 64, 64)))
- self.assertTrue(np.array_equal(node_0.out_port(0).get_connection().data.get_value(), np.ones((1, 3, 64, 64))))
-
- self.assertEqual(node_1.out_port(0).get_connection().data.get_shape(), None)
- self.assertEqual(node_1.out_port(0).get_connection().data.get_value(), None)
-
- self.assertEqual(node_2.out_port(0).get_connection().data.get_shape(), None)
- self.assertEqual(node_2.out_port(0).get_connection().data.get_value(), None)
-
- ###########################################
- ################## OTHER ##################
- ###########################################
-
- def test_graph_cleanup_that_restores_const_operations(self):
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('2_data', '1'),
- ('3_data', '2'),
- ], {
- '3': {'shape': np.array([1, 227, 227, 3]), 'value': np.ones((1, 227, 227, 3))},
- '3_data': {'shape': np.array([1, 227, 227, 3]), 'value': np.ones((1, 227, 227, 3))},
- '2': {'shape': np.array([1, 227, 227, 3]), 'value': np.ones((1, 227, 227, 3))},
- '2_data': {'shape': np.array([1, 227, 227, 3]), 'value': np.ones((1, 227, 227, 3))},
- }, nodes_with_edges_only=True)
- add_opoutput(graph, '1_data', 0, False)
-
- graph_ref = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('const_1', '2_data'),
-
- ('0_data', '1'),
- ('2_data', '1'),
- ], {
- 'const_1': {'shape': np.array([1, 227, 227, 3]), 'value': np.ones((1, 227, 227, 3))},
- '2_data': {'shape': np.array([1, 227, 227, 3]), 'value': np.ones((1, 227, 227, 3))},
- }, nodes_with_edges_only=True)
- add_opoutput(graph_ref, '1_data', 0, False)
-
- graph.clean_up()
- graph_ref.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, '1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_node_in_out_ports_order(self):
- #
- # ,->2-->2_data---,->3-->3_data
- # 0-->0_data-/-->1-->1_data--/
- #
- graph = build_graph(self.nodes, [
- ('0', '0_data'),
- ('1', '1_data'),
- ('2', '2_data'),
- ('3', '3_data'),
-
- ('0_data', '1'),
- ('0_data', '2'),
- ('1_data', '3'),
- ('2_data', '3'),
- ])
-
- for id in ['0', '1', '2', '3']:
- node = Node(graph, id)
- for idx in range(len(node.in_ports())):
- self.assertEqual(node.in_port(idx), node.in_ports()[idx])
- for idx in range(len(node.out_ports())):
- self.assertEqual(node.out_port(idx), node.out_ports()[idx])
-
- def test_node_in_ports_order_10_inputs(self):
- edges = [('op_concat', 'op_concat_data'),
- ('op_concat_data', 'op_split'),
- ]
-
- # Filling edges list
- for idx in range(11):
- edges.append(('in_{}'.format(idx), 'in_{}_data'.format(idx)))
- edges.append(('in_{}_data'.format(idx), 'op_concat', {'in': idx}))
- edges.append(('op_split', 'op_split_{}_data'.format(idx), {'out': idx}))
- edges.append(('op_split_{}_data'.format(idx), 'out_{}'.format(idx)))
-
- graph = build_graph(self.nodes_10_in_10_out, edges)
-
- node_concat = Node(graph, 'op_concat')
- node_split = Node(graph, 'op_split')
-
- self.assertEqual(len(node_concat.in_ports()), len(node_concat.in_nodes()))
-
- l1 = [node_concat.in_port(idx).get_source().node.name for idx in node_concat.in_ports()]
- l2 = [node_concat.in_node(idx).in_node(0).name for idx in node_concat.in_nodes()]
-
- self.assertEqual(l1, l2)
-
- l1 = [node_split.out_port(idx).get_destination().node.name for idx in node_split.out_ports()]
- l2 = [node_split.out_node(idx).out_node(0).name for idx in node_split.out_nodes()]
-
- self.assertEqual(l1, l2)
-
- def test_node_in_ports_order_10_inputs_control_flow(self):
- edges = [('op_concat', 'op_concat_data', {'out': 'control_flow_0', 'control_flow_edge': True}),
- ('op_concat_data', 'op_split', {'in': 'control_flow_0', 'control_flow_edge': True}),
- ]
-
- # Filling edges list
- for idx in range(11):
- edges.append(('in_{}'.format(idx), 'in_{}_data'.format(idx),
- {'out': 'control_flow_0', 'control_flow_edge': True}))
- edges.append(('in_{}_data'.format(idx), 'op_concat',
- {'in': 'control_flow_{}'.format(idx), 'control_flow_edge': True}))
- edges.append(('op_split', 'op_split_{}_data'.format(idx),
- {'out': 'control_flow_{}'.format(idx), 'control_flow_edge': True}))
- edges.append(('op_split_{}_data'.format(idx), 'out_{}'.format(idx),
- {'in': 'control_flow_0', 'control_flow_edge': True}))
-
- graph = build_graph(self.nodes_10_in_10_out, edges)
-
- node_concat = Node(graph, 'op_concat')
- node_split = Node(graph, 'op_split')
-
- self.assertEqual(len(node_concat.in_ports()), len(node_concat.in_nodes()))
-
- l1 = [node_concat.in_port(idx, control_flow=True).get_source().node.name
- for idx in node_concat.in_ports(control_flow=True)]
- l2 = [node_concat.in_node(idx, control_flow=True).in_node(0, control_flow=True).name
- for idx in node_concat.in_nodes(control_flow=True)]
-
- self.assertEqual(l1, l2)
-
- l1 = [node_split.out_port(idx, control_flow=True).get_destination().node.name
- for idx in node_split.out_ports(control_flow=True)]
- l2 = [node_split.out_node(idx, control_flow=True).out_node(0, control_flow=True).name for idx in
- node_split.out_nodes(control_flow=True)]
-
- self.assertEqual(l1, l2)
-
- def test_node_in_ports_order_10_inputs_mixed(self):
- edges = [('op_concat', 'op_concat_data', {'out': 'control_flow_0', 'control_flow_edge': True}),
- ('op_concat_data', 'op_split', {'in': 'control_flow_0', 'control_flow_edge': True}),
- ]
- graph = build_graph(self.nodes_10_in_10_out, edges)
-
- # Filling edges list
- for idx in range(5):
- edges.append(('in_{}'.format(idx), 'in_{}_data'.format(idx)))
- edges.append(('in_{}_data'.format(idx), 'op_concat'))
- edges.append(('op_split', 'op_split_{}_data'.format(idx)))
- edges.append(('op_split_{}_data'.format(idx), 'out_{}'.format(idx)))
- for idx in range(5, 11):
- edges.append(('in_{}'.format(idx), 'in_{}_data'.format(idx),
- {'out': 'control_flow_0', 'control_flow_edge': True}))
- edges.append(('in_{}_data'.format(idx), 'op_concat',
- {'in': 'control_flow_{}', 'control_flow_edge': True}))
- edges.append(('op_split', 'op_split_{}_data'.format(idx),
- {'out': 'control_flow_{}', 'control_flow_edge': True}))
- edges.append(('op_split_{}_data'.format(idx), 'out_{}'.format(idx),
- {'in': 'control_flow_0', 'control_flow_edge': True}))
-
- node_concat = Node(graph, 'op_concat')
- node_split = Node(graph, 'op_split')
-
- self.assertEqual(len(node_concat.in_ports()), len(node_concat.in_nodes()))
-
- l1 = [node_concat.in_port(idx, control_flow=True).get_source().node.name
- for idx in node_concat.in_ports(control_flow=True)]
- l2 = [node_concat.in_node(idx, control_flow=True).in_node(0, control_flow=True).name
- for idx in node_concat.in_nodes(control_flow=True)]
-
- self.assertEqual(l1, l2)
-
- l1 = [node_split.out_port(idx, control_flow=True).get_destination().node.name
- for idx in node_split.out_ports(control_flow=True)]
- l2 = [node_split.out_node(idx, control_flow=True).out_node(0, control_flow=True).name for idx in
- node_split.out_nodes(control_flow=True)]
-
- self.assertEqual(l1, l2)
-
-
-class TestNewGraphAPIFront(unittest.TestCase):
- nodes = {
- '0': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '1': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '2': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '3': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- '4': {'type': 'Parameter', 'value': None, 'kind': 'op', 'op': 'Parameter'},
- 'const_1': {'type': 'Const', 'value': None, 'kind': 'op', 'op': 'Const'},
- }
-
- ###########################################
- ###### TESTS FOR PORT CLASS METHODS #######
- ###########################################
-
- def test_port_get_destinations_1(self):
- # ,->2
- # /-->1
- # 0
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0}),
- ('0', '2', {'out': 0}),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
- node_2_in_port = Node(graph, '2').in_port(0)
-
- ports = node_0_out_port.get_destinations()
-
- self.assertTrue(len(ports) == 2)
- for port in ports:
- self.assertTrue(port in [node_1_in_port, node_2_in_port])
-
- def test_port_get_destination_1(self):
- # ,->2
- # /-->1
- # 0
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0}),
- ('0', '2', {'out': 0}),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
- node_2_in_port = Node(graph, '2').in_port(0)
-
- with self.assertRaises(Error):
- node_0_out_port.get_destination()
-
- def test_port_get_destination_2(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
-
- self.assertEqual(node_0_out_port.get_destination(), node_1_in_port)
-
- def test_port_get_destination_3(self):
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 0}),
- ('0', '2', {'out': 1, 'in': 0}),
- ('0', '3', {'out': 1, 'in': 0}),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0_out_port_1 = Node(graph, '0').out_port(1)
- node_2_in_port = Node(graph, '2').in_port(0)
- node_3_in_port = Node(graph, '3').in_port(0)
-
- destinations = node_0_out_port_1.get_destinations()
-
- self.assertTrue((destinations[0] == node_2_in_port and destinations[1] == node_3_in_port) or
- (destinations[1] == node_2_in_port and destinations[0] == node_3_in_port))
-
- def test_port_get_source_1(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0_out_port = Node(graph, '0').out_port(0)
-
- node_1_in_port = Node(graph, '1').in_port(0)
-
- self.assertEqual(node_1_in_port.get_source(), node_0_out_port)
-
- def test_port_get_source_2(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ('2', '1')
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- self.assertEqual(node_1.in_port(0).get_source(), node_0.out_port(0))
- self.assertEqual(node_1.in_port(1).get_source(), node_2.out_port(0))
-
- def test_port_get_source_3(self):
- graph = build_graph(self.nodes, [])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_0.add_input_port(0)
- node_1.add_input_port(0)
- node_2.add_input_port(0)
-
- self.assertEqual(node_0.in_port(0).get_source(), None)
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
- def test_port_disconnect_1(self):
- # ,-->1-->1_data 0-->0_data
- # 0-->0_data/--->2-->2_data ==> 0-->0_data 1-->1_data
- # 2-->2_data
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0}),
- ('0', '2', {'out': 0})
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_0.out_port(0).disconnect()
-
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
- self.assertTrue(len(node_1.in_nodes()) == 0)
- self.assertTrue(len(node_2.in_nodes()) == 0)
-
- def test_port_disconnect_2(self):
- # ,-->1 ,-->1
- # 0-->/--->2 ==> 0-->/ 2
- #
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0}),
- ('0', '2', {'out': 0})
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_2.in_port(0).disconnect()
-
- self.assertEqual(node_0.out_port(0).get_destination(), node_1.in_port(0))
- self.assertEqual(node_1.in_port(0).get_source(), node_0.out_port(0))
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
- self.assertTrue(len(node_0.out_nodes()) == 1)
- self.assertTrue(len(node_1.in_nodes()) == 1)
- self.assertTrue(len(node_2.in_nodes()) == 0)
-
- def test_port_disconnect_3(self):
- # 1---\ 1
- # 0---->2 ==> 0-->2
- #
- graph = build_graph(self.nodes, [
- ('0', '2'),
- ('1', '2')
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_2.in_port(1).disconnect()
-
- self.assertEqual(node_0.out_port(0).get_destination(), node_2.in_port(0))
- self.assertEqual(node_2.in_port(0).get_source(), node_0.out_port(0))
- self.assertEqual(node_1.out_port(0).get_destination(), None)
-
- self.assertTrue(len(node_0.out_nodes()) == 1)
- self.assertTrue(len(node_1.in_nodes()) == 0)
- self.assertTrue(len(node_2.in_nodes()) == 1)
-
- def test_port_disconnect_4(self):
- # 1-----\ 0
- # 0------>2 ==> 1--->2
- #
- graph = build_graph(self.nodes, [
- ('0', '2', {'out': 0}),
- ('1', '2', {'out': 0})
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_2.in_port(0).disconnect()
-
- self.assertEqual(node_1.out_port(0).get_destination(), node_2.in_port(1))
- self.assertEqual(node_2.in_port(1).get_source(), node_1.out_port(0))
- self.assertEqual(node_2.in_port(0).get_source(), None)
- self.assertEqual(node_0.out_port(0).get_destination(), None)
-
- def test_port_disconnected_1(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ('1', '2')
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_2.add_output_port(0)
- node_0.add_input_port(0)
-
- self.assertTrue(not node_0.out_port(0).disconnected())
- self.assertTrue(not node_1.out_port(0).disconnected())
- self.assertTrue(not node_1.in_port(0).disconnected())
- self.assertTrue(node_2.out_port(0).disconnected())
- self.assertTrue(node_0.in_port(0).disconnected())
-
- def test_port_get_connection_1(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ('1', '2', {'out': 0}),
- ('1', '3', {'out': 0}),
- ])
- graph.__setattr__('stage', 'front')
-
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '3')
- node_3 = Node(graph, '2')
-
- c = node_1.out_port(0).get_connection()
-
- self.assertTrue(c.get_source() == node_1.out_port(0))
- for port in c.get_destinations():
- self.assertTrue(port in [node_2.in_port(0), node_3.in_port(0)])
-
- ###########################################
- ### TESTS FOR CONNECTION CLASS METHODS ####
- ###########################################
-
- def test_connection_set_source_1(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ('0', '2'),
- ('3', '4'),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_3 = Node(graph, '3')
- node_4 = Node(graph, '4')
-
- c = node_0.out_port(0).get_connection()
- c.set_source(node_3.out_port(0))
-
- self.assertEqual(node_0.out_port(0).get_destinations(), [])
- destinations = node_3.out_port(0).get_destinations()
- for port in destinations:
- self.assertTrue(port in [node_1.in_port(0), node_2.in_port(0), node_4.in_port(0)])
-
- def test_connection_set_source_2(self):
- # 2 ,->2
- # 0-->1 ==> 0/-->1
- #
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_2 = Node(graph, '2')
- node_2.add_input_port(0)
-
- node_2.in_port(0).get_connection().set_source(node_0.out_port(0))
-
- graph_ref = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 0}),
- ('0', '2', {'out': 0, 'in': 0}),
- ])
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_source_3(self):
- # 0 1 ==> 0-->1
- graph = build_graph(self.nodes, [])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
-
- node_0.add_output_port(0)
- node_1.add_input_port(0)
-
- node_1.in_port(0).get_connection().set_source(node_0.out_port(0))
-
- graph_ref = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 0}),
- ])
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_destination(self):
- # ,->2-->2_data-->3-->3_data ,->2-->2_data
- # 0-->0_data/-->1-->1_data ==> 0-->0_data/-->3-->3_data
- #
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ('0', '2'),
- ('2', '3'),
- ])
- graph.__setattr__('stage', 'front')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '3'),
- ('0', '2'),
- ])
-
- node_1 = Node(graph, '1')
- node_3 = Node(graph, '3')
-
- node_3.in_port(0).disconnect()
- node_1.in_port(0).get_connection().set_destination(node_3.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_destination_1(self):
- # 2
- # ,->1 ,->2
- # 0-->1 ==> 0-->1
- #
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 0}),
- ('0', '1', {'out': 0, 'in': 1}),
- ])
- graph.__setattr__('stage', 'front')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 0}),
- ('0', '2', {'out': 0, 'in': 0}),
- ])
-
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_2.add_input_port(0)
-
- node_1.in_port(1).get_connection().set_destination(node_2.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_set_destination_2(self):
- # 2
- # ,->1 ,->1
- # 0-->1 ==> 0-->2
- #
- graph = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 0}),
- ('0', '1', {'out': 0, 'in': 1}),
- ])
- graph.__setattr__('stage', 'front')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '1', {'out': 0, 'in': 1}),
- ('0', '2', {'out': 0, 'in': 0}),
- ])
-
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_2.add_input_port(0)
-
- node_1.in_port(0).get_connection().set_destination(node_2.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_add_destination_1(self):
- # 3 ,-->3
- # ,->2 ,-->2
- # 0--/-->1 ==> 0--/-->1
- #
- graph = build_graph(self.nodes, [
- ('0', '1', {'in': 0, 'out': 0}),
- ('0', '2', {'in': 0, 'out': 0}),
- ])
- graph.__setattr__('stage', 'front')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '1', {'in': 0, 'out': 0}),
- ('0', '2', {'in': 0, 'out': 0}),
- ('0', '3', {'in': 0, 'out': 0}),
- ])
-
- node_0 = Node(graph, '0')
- node_3 = Node(graph, '3')
- node_3.add_input_port(idx=0)
-
- node_0.out_port(0).get_connection().add_destination(node_3.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_add_destination_2(self):
- # 0
- # 1 ==> 0-->1
- graph = build_graph(self.nodes, [])
- graph.__setattr__('stage', 'front')
-
- graph_ref = build_graph(self.nodes, [
- ('0', '1'),
- ])
-
- node_0 = Node(graph, '0')
- node_0.add_output_port(idx=0)
-
- node_1 = Node(graph, '1')
- node_1.add_input_port(idx=0)
-
- node_0.out_port(0).get_connection().add_destination(node_1.in_port(0))
-
- (flag, resp) = compare_graphs(graph, graph_ref, '0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_connection_get_source_destinations_1(self):
- graph = build_graph(self.nodes, [
- ('0', '1'),
- ('0', '2')
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
- node_1.add_output_port(idx=0)
- node_2.add_output_port(idx=0)
-
- source = node_0.out_port(0).get_connection().get_source()
- destinations = node_0.out_port(0).get_connection().get_destinations()
-
- self.assertEqual(source, node_0.out_port(0))
- for port in destinations:
- self.assertTrue(port in [node_1.in_port(0), node_2.in_port(0)])
-
- self.assertEqual(node_1.out_port(0).get_connection().get_destination(), None)
- self.assertEqual(node_1.out_port(0).get_destination(), None)
-
- self.assertEqual(node_2.out_port(0).get_connection().get_destination(), None)
- self.assertEqual(node_2.out_port(0).get_destination(), None)
-
- def test_connection_remove_1(self):
- graph = build_graph(self.nodes, [
- ('0', '1', {'in': 0, 'out': 0}),
- ('0', '2', {'in': 0, 'out': 0})
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_1.in_port(0).get_connection().remove()
-
- self.assertEqual(node_0.out_port(0).get_destinations(), [node_2.in_port(0)])
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), node_0.out_port(0))
-
- def test_connection_remove_2(self):
- graph = build_graph(self.nodes, [
- ('0', '1', {'in': 0, 'out': 0}),
- ('0', '2', {'in': 0, 'out': 0})
- ])
- graph.__setattr__('stage', 'front')
-
- node_0 = Node(graph, '0')
- node_1 = Node(graph, '1')
- node_2 = Node(graph, '2')
-
- node_0.out_port(0).get_connection().remove()
-
- self.assertEqual(node_0.out_port(0).get_destinations(), [])
- self.assertEqual(node_1.in_port(0).get_source(), None)
- self.assertEqual(node_2.in_port(0).get_source(), None)
-
-
-class TestDictIncludesCompareAttrs(unittest.TestCase):
- def test_numpy_scalar(self):
- self.assertTrue(dict_includes_compare_attrs(2.0, np.array(2.0)))
- self.assertTrue(dict_includes_compare_attrs(2, np.array(2.0)))
- self.assertTrue(dict_includes_compare_attrs(np.array(2.0), 2.0))
- self.assertTrue(dict_includes_compare_attrs(np.array(2.0), 2))
-
- self.assertFalse(dict_includes_compare_attrs(2.01, np.array(2.0)))
- self.assertFalse(dict_includes_compare_attrs(2, np.array(2.1)))
- self.assertFalse(dict_includes_compare_attrs(np.array(2.0), 2.01))
- self.assertFalse(dict_includes_compare_attrs(np.array(2.1), 2))
-
- def test_regular_scalars(self):
- self.assertTrue(dict_includes_compare_attrs(2.0, 2))
- self.assertFalse(dict_includes_compare_attrs(2, 1.99999999999999))
-
- def test_lists_numpy(self):
- self.assertTrue(dict_includes_compare_attrs([4, 2, 3], np.array([4, 2, 3])))
- self.assertFalse(dict_includes_compare_attrs([4, 2, 3], np.array([1, 2, 3])))
-
- def test_regular_lists(self):
- self.assertTrue(dict_includes_compare_attrs([4, 2, 3], [4, 2, 3]))
- self.assertFalse(dict_includes_compare_attrs([4, 2, 3], [1, 2, 3]))
- self.assertFalse(dict_includes_compare_attrs([4, 2, 3], [4, 2, 3, 5]))
-
- def test_regular_string(self):
- self.assertTrue(dict_includes_compare_attrs("abc", "abc"))
- self.assertFalse(dict_includes_compare_attrs("abc", "abd"))
-
-
-class TestGetSetAttributeBetweenNodes(unittest.TestCase):
- nodes = {
- 'A': {'id': 0, 'kind': 'op'},
- 'B': {'id': 1, 'kind': 'op'},
- 'C': {'id': 2, 'kind': 'op'},
- 'D': {'id': 3, 'kind': 'op'},
- 'E': {'id': 4, 'kind': 'op'},
- 'F': {'id': 5, 'kind': 'op'},
- }
-
- def build_test_graph(self):
- graph = build_graph(self.nodes, [
- ('A', 'D', {'in': 0, 'out': 0, 'Attr': "A-D"}),
- ('A', 'E', {'in': 0, 'out': 1, 'Attr': "A-E"}),
- ('A', 'F', {'in': 0, 'out': 2, 'Attr': "A-F"}),
- ('B', 'D', {'in': 1, 'out': 0, 'Attr': "B-D"}),
- ('B', 'F', {'in': 2, 'out': 1, 'Attr': "B-F"}),
- ])
- return graph
-
- def test_get_attribute_between_nodes(self):
- graph = self.build_test_graph()
- a_node = Node(graph, 'A')
- b_node = Node(graph, 'B')
- d_node = Node(graph, 'D')
- e_node = Node(graph, 'E')
- f_node = Node(graph, 'F')
- self.assertTrue(get_edge_attribute_between_nodes(a_node, d_node, 'Attr') == "A-D")
- self.assertTrue(get_edge_attribute_between_nodes(a_node, e_node, 'Attr') == "A-E")
- self.assertTrue(get_edge_attribute_between_nodes(a_node, f_node, 'Attr') == "A-F")
- self.assertTrue(get_edge_attribute_between_nodes(b_node, d_node, 'Attr') == "B-D")
- self.assertTrue(get_edge_attribute_between_nodes(b_node, f_node, 'Attr') == "B-F")
-
- def test_set_attribute_between_nodes(self):
- graph = self.build_test_graph()
- a_node = Node(graph, 'A')
- b_node = Node(graph, 'B')
- d_node = Node(graph, 'D')
- e_node = Node(graph, 'E')
- f_node = Node(graph, 'F')
-
- set_edge_attribute_between_nodes(a_node, d_node, 'Attr', 'new_value_1')
- set_edge_attribute_between_nodes(a_node, e_node, 'Attr', 'new_value_2')
- set_edge_attribute_between_nodes(a_node, f_node, 'Attr', 'new_value_3')
- set_edge_attribute_between_nodes(b_node, d_node, 'Attr', 'new_value_4')
- set_edge_attribute_between_nodes(b_node, f_node, 'Attr', 'new_value_5')
-
- self.assertTrue(get_edge_attribute_between_nodes(a_node, d_node, 'Attr') == "new_value_1")
- self.assertTrue(get_edge_attribute_between_nodes(a_node, e_node, 'Attr') == "new_value_2")
- self.assertTrue(get_edge_attribute_between_nodes(a_node, f_node, 'Attr') == "new_value_3")
- self.assertTrue(get_edge_attribute_between_nodes(b_node, d_node, 'Attr') == "new_value_4")
- self.assertTrue(get_edge_attribute_between_nodes(b_node, f_node, 'Attr') == "new_value_5")
-
-
-class TestTopologicalSort(unittest.TestCase):
- nodes = {
- 'A': {'id': 0, 'kind': 'op'},
- 'B': {'id': 1, 'kind': 'op'},
- 'C': {'id': 2, 'kind': 'op'},
- 'D': {'id': 3, 'kind': 'op'},
- 'E': {'id': 4, 'kind': 'op'},
- }
-
- def build_test_graph(self):
- graph = build_graph(self.nodes, [
- ('A', 'B', {'in': 0, 'out': 0}),
- ('A', 'C', {'in': 0, 'out': 1}),
- ('A', 'D', {'in': 0, 'out': 2}),
- ('A', 'E', {'in': 0, 'out': 3}),
- ('B', 'D', {'in': 1, 'out': 0}),
- ('C', 'D', {'in': 2, 'out': 0}),
- ('C', 'E', {'in': 1, 'out': 1}),
- ('D', 'E', {'in': 2, 'out': 0}),
- ])
- return graph
-
- def test_sort_with_start_node(self):
- graph = self.build_test_graph()
-
- stat_node = Node(graph, "A")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node)]
- assert nodes_names == ['A', 'C', 'B', 'D', 'E']
-
- stat_node = Node(graph, "B")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node)]
- assert nodes_names == ['B', 'D', 'E']
-
- stat_node = Node(graph, "C")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node)]
- assert nodes_names == ['C', 'D', 'E']
-
- stat_node = Node(graph, "D")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node)]
- assert nodes_names == ['D', 'E']
-
- stat_node = Node(graph, "E")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node)]
- assert nodes_names == ['E']
-
- # reverse order
- stat_node = Node(graph, "A")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node,
- reverse=True)]
- assert nodes_names == ['E', 'D', 'B', 'C', 'A']
-
- stat_node = Node(graph, "B")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node,
- reverse=True)]
- assert nodes_names == ['E', 'D', 'B']
-
- stat_node = Node(graph, "C")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node,
- reverse=True)]
- assert nodes_names == ['E', 'D', 'C']
-
- stat_node = Node(graph, "D")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node,
- reverse=True)]
- assert nodes_names == ['E', 'D']
-
- stat_node = Node(graph, "E")
- nodes_names = [node.name for node in graph.pseudo_topological_sort_with_start_node(start_node=stat_node,
- reverse=True)]
- assert nodes_names == ['E']
-
\ No newline at end of file
diff --git a/tools/mo/unit_tests/mo/graph/port_test.py b/tools/mo/unit_tests/mo/graph/port_test.py
deleted file mode 100644
index 8787bada84597d..00000000000000
--- a/tools/mo/unit_tests/mo/graph/port_test.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op, valued_const_with_data, result, connect
-
-nodes = {
- **regular_op('input', {'type': 'Parameter'}),
- **regular_op('Op1', {'type': 'Op1', 'kind': 'op', 'op': 'Op1'}),
- **regular_op('Op2', {'type': 'Op2', 'kind': 'op', 'op': 'Op2'}),
- **regular_op('Op3', {'type': 'Op3', 'kind': 'op', 'op': 'Op3'}),
-
- 'input_data': {'kind': 'data', 'fw_tensor_debug_info': [('input', 'input'), ('Op1', 'Op1,Op2')]},
- 'Op1_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op1', 'Op1,Op2')]},
- 'Op2_data': {'kind': 'data'},
- 'Op3_data': {'kind': 'data', 'fw_tensor_debug_info': [('Op3', 'Op3')]},
-}
-
-
-class TestsGetTensorNames(unittest.TestCase):
- def test_front(self):
- graph = build_graph(nodes,
- [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input'),
- ('Op1', 'Op1,Op2')]})])
- graph.stage = 'front'
- input_node = Node(graph, 'input')
- self.assertTrue(input_node.out_port(0).get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op1_node = Node(graph, 'Op1')
- op1_node.add_output_port(0)
- self.assertTrue(op1_node.out_port(0).get_tensor_names() == [])
-
- input_node.out_port(0).add_tensor_names(["A:0", "B:0", "B:1", "B:2", "C:0"])
- self.assertTrue(input_node.out_port(0).get_tensor_debug_info() ==
- [('input', 'input'), ('Op1', 'Op1,Op2'), ("input", "A:0"), ("input", "B:0"),
- ("input", "B:1"), ("input", "B:2"), ("input", "C:0")])
- self.assertTrue(input_node.out_port(0).get_tensor_names() ==
- ['A:0', 'B:0', 'B:1', 'B:2', 'C:0', 'Op1\\,Op2', 'input'])
- input_node.out_port(0).remove_tensor_names()
- self.assertTrue(input_node.out_port(0).get_tensor_debug_info() == [])
- self.assertTrue(input_node.out_port(0).get_tensor_names() == [])
-
- def test_middle(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('input_data', 'Op2')])
-
- input_node = Node(graph, 'input')
- self.assertTrue(input_node.out_port(0).get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op1_node = Node(graph, 'Op1')
- op1_node.add_output_port(0)
- self.assertTrue(op1_node.out_port(0).get_tensor_names() == [])
-
- op2_node = Node(graph, 'Op2')
- op2_node.add_output_port(0)
- self.assertTrue(op2_node.out_port(0).get_tensor_names() == [])
-
- input_node.out_port(0).add_tensor_names(["A:0", "B:0", "B:1", "B:2", "C:0"])
- self.assertTrue(input_node.out_port(0).get_tensor_debug_info() ==
- [('input', 'input'), ('Op1', 'Op1,Op2'), ("input", "A:0"), ("input", "B:0"),
- ("input", "B:1"), ("input", "B:2"), ("input", "C:0")])
- self.assertTrue(input_node.out_port(0).get_tensor_names() ==
- ['A:0', 'B:0', 'B:1', 'B:2', 'C:0', 'Op1\\,Op2', 'input'])
- input_node.out_port(0).remove_tensor_names()
- self.assertTrue(input_node.out_port(0).get_tensor_debug_info() == [])
- self.assertTrue(input_node.out_port(0).get_tensor_names() == [])
-
- def test_port_renumber(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data', {'out': 1}), ('Op1_data', 'Op2')])
- input_node = Node(graph, 'input')
- self.assertTrue(input_node.out_port(0).get_tensor_names(port_renumber=True) == ['Op1\\,Op2', 'input'])
-
- op1_node = Node(graph, 'Op1')
- op1_node.add_output_port(0)
-
- self.assertTrue(op1_node.out_port(0).get_tensor_names(port_renumber=True) == ['Op1\\,Op2'])
-
- input_node.out_port(0).add_tensor_names(["A:0", "B:0", "B:1", "B:2", "C:0"])
- self.assertTrue(input_node.out_port(0).get_tensor_debug_info() ==
- [('input', 'input'), ('Op1', 'Op1,Op2'), ("input", "A:0"), ("input", "B:0"),
- ("input", "B:1"), ("input", "B:2"), ("input", "C:0")])
- self.assertTrue(input_node.out_port(0).get_tensor_names() ==
- ['A:0', 'B:0', 'B:1', 'B:2', 'C:0', 'Op1\\,Op2', 'input'])
- input_node.out_port(0).remove_tensor_names(port_renumber=True)
- self.assertTrue(input_node.out_port(0).get_tensor_debug_info() == [])
- self.assertTrue(input_node.out_port(0).get_tensor_names() == [])
-
- def test_reconnect_middle_case1(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'), ('Op3', 'Op3_data')])
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0), "merge")
-
- self.assertTrue(input_node_out_port.get_tensor_names() is None)
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op1\\,Op2', 'Op3', 'input'])
-
- def test_reconnect_middle_case1_parameter(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'), ('Op3', 'Op3_data')])
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0))
-
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op3'])
-
- def test_reconnect_front_case1(self):
- graph = build_graph(nodes, [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input'),
- ('Op1', 'Op1,Op2')]}),
- ('Op3', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op3', 'Op3')]})])
- graph.stage = 'front'
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0), "merge")
-
- self.assertTrue(input_node_out_port.get_tensor_names() == [])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op1\\,Op2', 'Op3', 'input'])
-
- def test_reconnect_front_case1_parameter(self):
- graph = build_graph(nodes, [('input', 'Op1', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('input', 'input'),
- ('Op1', 'Op1,Op2')]}),
- ('Op3', 'Op2', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op3', 'Op3')]})])
- graph.stage = 'front'
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0))
-
- self.assertTrue(input_node_out_port.get_tensor_names() == [])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op3'])
-
- def test_reconnect_middle_case1(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'), ('Op3', 'Op3_data')])
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0), "merge")
-
- self.assertTrue(input_node_out_port.get_tensor_names() == [])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op1\\,Op2', 'Op3', 'input'])
-
- def test_reconnect_middle_case1_parameter(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'), ('Op3', 'Op3_data')])
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0))
-
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op3'])
-
- def test_reconnect_middle_case2(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1', {'out': 0}),
- ('input_data', 'Op1', {'out': 1}), ('Op3', 'Op3_data')])
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0), "merge")
-
- self.assertTrue(input_node_out_port.get_tensor_names() == [])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op1\\,Op2', 'Op3', 'input'])
-
- def test_reconnect_middle_case2(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1', {'out': 0}),
- ('input_data', 'Op1', {'out': 1}), ('Op3', 'Op3_data')])
- input_node = Node(graph, 'input')
-
- input_node_out_port = input_node.out_port(0)
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
-
- op3_node = Node(graph, 'Op3')
- input_node_out_port.get_connection().set_source(op3_node.out_port(0))
-
- self.assertTrue(input_node_out_port.get_tensor_names() == ['Op1\\,Op2', 'input'])
- self.assertTrue(op3_node.out_port(0).get_tensor_names() == ['Op3'])
-
-
-class TestPortMethods(unittest.TestCase):
-
- def test_middle_disconnect_several_edges_between_two_nodes(self):
- graph = build_graph(nodes, [('input', 'input_data'), ('input_data', 'Op1'),
- ('Op1', 'Op1_data'), ('Op1_data', 'Op2', {'in': 0}), ('Op1_data', 'Op2', {'in': 1}),
- ('Op1_data', 'Op2', {'in': 2})],
- nodes_with_edges_only=True)
- op1_node = Node(graph, 'Op1')
- op1_node.out_port(0).disconnect()
- self.assertTrue(op1_node.out_port(0).disconnected())
-
-
-class TestForceShape(unittest.TestCase):
- def test_set_value_and_shape_with_force_shape_attribute_in_op(self):
- import numpy as np
- graph = build_graph({**valued_const_with_data('const', np.array([1, 2, 3])), **result()},
- [*connect('const', 'output')])
-
- node = Node(graph, 'const')
- node['force_shape'] = np.array([2, 5, 7], dtype=np.int64)
- node.out_port(0).data.set_value(np.zeros(35))
- self.assertTrue(np.array_equal(node.out_port(0).data.get_shape(), np.array([2, 5, 7], dtype=np.int64)),
- "node.out_port(0).data.get_shape()={} != [2, 5, 7]".format(node.out_port(0).data.get_shape()))
-
- def test_set_value_and_shape_with_force_shape_attribute_in_data(self):
- import numpy as np
- graph = build_graph({**valued_const_with_data('const', np.array([1, 2, 3])), **result()},
- [*connect('const', 'output')])
-
- node = Node(graph, 'const')
- Node(graph, 'const_d')['force_shape'] = np.array([2, 5, 7], dtype=np.int64)
- node.out_port(0).data.set_value(np.zeros(30))
- self.assertTrue(np.array_equal(node.out_port(0).data.get_shape(), np.array([2, 5, 7], dtype=np.int64)),
- "node.out_port(0).data.get_shape()={} != [2, 5, 7]".format(
- node.out_port(0).data.get_shape()))
-
diff --git a/tools/mo/unit_tests/mo/load/loader_test.py b/tools/mo/unit_tests/mo/load/loader_test.py
deleted file mode 100644
index 4134400daec933..00000000000000
--- a/tools/mo/unit_tests/mo/load/loader_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.load.tf.loader import graph_or_sub_graph_has_nhwc_ops
-from unit_tests.utils.graph import build_graph, result, regular_op, const, connect_front
-
-
-class TFLoaderTest(unittest.TestCase):
- @staticmethod
- def build_conv_graph():
- nodes = {
- **const('weights', np.random.randn(1, 1, 1, 1)),
- **regular_op('input', {'op': 'Parameter'}),
- **regular_op('conv', {'op': 'Conv2D', 'layout': 'NHWC'}),
- **result('result'),
- }
- edges = [*connect_front('input', '0:conv'),
- *connect_front('weights', '1:conv'),
- *connect_front('conv:0', 'result'),
- ]
- graph = build_graph(nodes, edges)
-
- graph.stage = 'front'
- return graph
-
- @staticmethod
- def build_parameter_result_graph():
- nodes = {
- **regular_op('input', {'op': 'Parameter'}),
- **result('result'),
- }
- edges = [*connect_front('input', '0:result'),
- ]
- graph = build_graph(nodes, edges)
- graph.stage = 'front'
- return graph
-
- @staticmethod
- def build_loop_graph(body_graph):
- # create fake Loop operation
- nodes = {
- **regular_op('input', {'op': 'Parameter'}),
- **regular_op('loop', {'op': 'Loop', 'body': body_graph, 'sub_graphs': ['body']}),
- **result('result'),
- }
- edges = [*connect_front('input', '0:loop'),
- *connect_front('loop:0', 'result'),
- ]
- graph = build_graph(nodes, edges)
- graph.stage = 'front'
- return graph
-
- def test_convolution_main_graph(self):
- self.assertTrue(graph_or_sub_graph_has_nhwc_ops(self.build_conv_graph()))
-
- def test_convolution_loop_body_graph(self):
- self.assertTrue(graph_or_sub_graph_has_nhwc_ops(self.build_loop_graph(self.build_conv_graph())))
-
- def test_no_convolution_main_graph(self):
- self.assertFalse(graph_or_sub_graph_has_nhwc_ops(self.build_parameter_result_graph()))
-
- def test_no_convolution_main_and_sub_graph(self):
- self.assertFalse(graph_or_sub_graph_has_nhwc_ops(self.build_loop_graph(self.build_parameter_result_graph())))
diff --git a/tools/mo/unit_tests/mo/main_test_actual.py b/tools/mo/unit_tests/mo/main_test_actual.py
deleted file mode 100644
index 947130272ccc32..00000000000000
--- a/tools/mo/unit_tests/mo/main_test_actual.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import unittest
-from unittest.mock import patch
-
-import pytest
-
-from openvino.tools.mo.utils.error import FrameworkError
-
-ngraph_available = True
-try:
- from openvino.tools.mo.main import main
-except Exception:
- ngraph_available = False
-
-ngraph_needed = pytest.mark.skipif(not ngraph_available,
- reason="mock MO fe is not available")
-
-
-class TestMainErrors(unittest.TestCase):
- @patch('argparse.ArgumentParser.parse_args', return_value=argparse.Namespace(
- use_legacy_frontend=False,
- use_new_frontend=False,
- framework=None,
- input_model="abc.pbtxt"
- ))
- @patch('openvino.tools.mo.convert_impl.driver', side_effect=FrameworkError('FW ERROR MESSAGE'))
- @ngraph_needed
- def test_FrameworkError(self, mock_argparse, mock_driver):
- with self.assertLogs() as logger:
- main(argparse.ArgumentParser())
- self.assertEqual(logger.output, ['ERROR:root:FW ERROR MESSAGE'])
diff --git a/tools/mo/unit_tests/mo/main_test_error_log.py b/tools/mo/unit_tests/mo/main_test_error_log.py
deleted file mode 100644
index 34534ac3e750c5..00000000000000
--- a/tools/mo/unit_tests/mo/main_test_error_log.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-from unittest.mock import patch
-
-from openvino.tools.mo.utils.error import FrameworkError
-
-
-def mocked_parse_args(*argv):
- # Mock parse_args method which generates warning
- import logging as log
- log.error("warning", extra={'is_warning': True})
- argv = argparse.Namespace(use_legacy_frontend=False,
- use_new_frontend=False,
- framework=None,
- input_model="abc.pbtxt")
- return argv
-
-
-@patch('argparse.ArgumentParser.parse_args', mocked_parse_args)
-@patch('openvino.tools.mo.convert_impl.driver', side_effect=FrameworkError('FW ERROR MESSAGE'))
-def run_main(mock_driver):
- from openvino.tools.mo.main import main
- # runs main() method where driver() raises FrameworkError
- main(argparse.ArgumentParser())
-
-
-if __name__ == "__main__":
- run_main()
diff --git a/tools/mo/unit_tests/mo/middle/AddIsCyclicAttribute_test.py b/tools/mo/unit_tests/mo/middle/AddIsCyclicAttribute_test.py
deleted file mode 100644
index aa9fa1caf15773..00000000000000
--- a/tools/mo/unit_tests/mo/middle/AddIsCyclicAttribute_test.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.AddIsCyclicAttribute import AddIsCyclicAttribute
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class AddIsCyclicAttributeTest(unittest.TestCase):
- nodes = [('node_1', {}),
- ('node_2', {})]
- edges = [('node_1', 'node_2')]
-
- def test_1(self):
- """
- Acyclic case => graph.graph['is_cyclic'] should be False.
- """
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges)
- tested_pass = AddIsCyclicAttribute()
- tested_pass.find_and_replace_pattern(graph)
-
- assert graph.graph['is_cyclic'] is False
-
- def test_2(self):
- """
- Cyclic case => graph.graph['is_cyclic'] should be True.
- :return:
- """
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- new_edges_with_attrs=[('node_2', 'node_1')])
- tested_pass = AddIsCyclicAttribute()
- tested_pass.find_and_replace_pattern(graph)
-
- assert graph.graph['is_cyclic'] is True
diff --git a/tools/mo/unit_tests/mo/middle/ArgOpsToTopK_test.py b/tools/mo/unit_tests/mo/middle/ArgOpsToTopK_test.py
deleted file mode 100644
index db139419a979cb..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ArgOpsToTopK_test.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.ArgOpsToTopK import ArgOpsToTopK
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import regular_op_with_empty_data, result, build_graph, connect, \
- valued_const_with_data, regular_op, empty_data, connect_front
-
-nodes_attributes = {
- **regular_op_with_empty_data('input', {'op': 'Parameter', 'type': 'Parameter'}),
- **regular_op_with_empty_data('argmax', {'op': 'ArgMax', 'type': None, 'out_max_val': 0, 'top_k': 1, 'axis': 0,
- 'output_type': np.int32, 'remove_values_output': True}),
- **regular_op_with_empty_data('argmin', {'op': 'ArgMin', 'type': None, 'top_k': 1, 'axis': 0,
- 'output_type': np.int32, 'remove_values_output': True}),
- **result('result'),
- **valued_const_with_data('axis_const', int64_array([1])),
-
- **regular_op('topk', {'op': 'TopK', 'type': 'TopK', 'sort': 'index', 'index_element_type': np.int32}),
- **empty_data('topk_out_0_data'),
- **empty_data('topk_out_1_data'),
- **regular_op_with_empty_data('topk_scalar', {'op': 'Const', 'type': 'Const', 'value': int64_array([1]),
- 'shape': []}),
-
-
- **regular_op_with_empty_data('concat', {'op': 'Concat', 'type': 'Concat', 'axis': 1})
-}
-
-
-class ArgOpsToTopKTest(unittest.TestCase):
-
- def test_tf_argmax_to_topk(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:argmax'),
- *connect('axis_const', '1:argmax'),
- *connect('argmax', 'result')
- ],
- nodes_with_edges_only=True)
- ArgOpsToTopK().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:topk'),
- *connect('topk_scalar', '1:topk'),
- *connect_front('topk:1', 'topk_out_1_data'),
- *connect_front('topk_out_1_data', 'result'),
- ],
- update_attributes={
- 'topk': {'axis': int64_array([1]), 'mode': 'max', 'remove_values_output': True},
- },
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'input', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_tf_argmin_to_topk(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:argmin'),
- *connect('axis_const', '1:argmin'),
- *connect('argmin', 'result')
- ],
- nodes_with_edges_only=True)
- ArgOpsToTopK().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:topk'),
- *connect('topk_scalar', '1:topk'),
- *connect_front('topk:1', 'topk_out_1_data'),
- *connect_front('topk_out_1_data', 'result')
- ],
- update_attributes={
- 'topk': {'axis': int64_array([1]), 'mode': 'min', 'remove_values_output': True},
- },
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'input', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_onnx_argmax_to_topk(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', 'argmax'),
- *connect('argmax', 'result')
- ],
- nodes_with_edges_only=True)
- ArgOpsToTopK().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:topk'),
- *connect('topk_scalar', '1:topk'),
- *connect_front('topk:1', 'topk_out_1_data'),
- *connect_front('topk_out_1_data', 'result')
- ],
- update_attributes={
- 'topk': {'axis': 0, 'mode': 'max', 'remove_values_output': True},
- },
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'input', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_onnx_argmin_to_topk(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', 'argmin'),
- *connect('argmin', 'result')
- ],
- nodes_with_edges_only=True)
- ArgOpsToTopK().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:topk'),
- *connect('topk_scalar', '1:topk'),
- *connect_front('topk:1', 'topk_out_1_data'),
- *connect_front('topk_out_1_data', 'result')
- ],
- update_attributes={
- 'topk': {'axis': 0, 'mode': 'min', 'remove_values_output': True},
- },
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'input', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_caffe_argmax_to_topk(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', 'argmax'),
- *connect('argmax', 'result')
- ],
- update_attributes={
- 'argmax': {'out_max_val': 1}
- },
- nodes_with_edges_only=True)
- ArgOpsToTopK().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:topk'),
- *connect('topk_scalar', '1:topk'),
- *connect_front('topk:0','topk_out_0_data'),
- *connect_front('topk:1', 'topk_out_1_data'),
- *connect_front('topk_out_0_data', '1:concat'),
- *connect_front('topk_out_1_data', '0:concat'),
- *connect('concat', 'result')
- ],
- update_attributes={
- 'topk': {'axis': 0, 'mode': 'max', 'remove_values_output': True},
- },
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'input', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/BlockLSTMtoLSTMSequence_test.py b/tools/mo/unit_tests/mo/middle/BlockLSTMtoLSTMSequence_test.py
deleted file mode 100644
index 88422254e0917d..00000000000000
--- a/tools/mo/unit_tests/mo/middle/BlockLSTMtoLSTMSequence_test.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.BlockLSTMtoLSTMSequence import BlockLSTMtoLSTMSequenceSingleFirstOutput
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import regular_op_with_empty_data, result, build_graph, connect, \
- valued_const_with_data
-
-nodes_attributes = {
- # hidden_size = 2
- **regular_op_with_empty_data('x', {'op': 'Parameter', 'type': 'Parameter'}),
- **valued_const_with_data('weights', np.array([[1, 2, 3, 4, 5, 6, 7, 8],
- [9, 10, 11, 12, 13, 14, 15, 16]], dtype=np.float32)),
- **valued_const_with_data('bias', np.array([2, 4, 6, 8, 10, 12, 14, 16], dtype=np.float32)),
- **regular_op_with_empty_data('h_init_state', {'op': 'Parameter', 'type': 'Parameter'}),
- **regular_op_with_empty_data('c_init_state', {'op': 'Parameter', 'type': 'Parameter'}),
- **regular_op_with_empty_data('block_lstm', {'op': 'BlockLSTM', 'type': None, 'forget_bias': 1}),
- **result('result'),
-
- **valued_const_with_data('weights_normalized', np.array(
- [[5, 13], [6, 14], [1, 9], [2, 10], [3, 11],
- [4, 12], [7, 15], [8, 16]],
- dtype=np.float32)),
- **valued_const_with_data('bias_normalized', np.array([11, 13, 2, 4, 6, 8, 14, 16], dtype=np.float32)),
-}
-
-
-class BlockLSTMtoLSTMSequenceSingleFirstOutputTest(unittest.TestCase):
-
- def test_tf_block_lstm_to_lstm_seq(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('x', '0:block_lstm'),
- *connect('weights', '1:block_lstm'),
- *connect('bias', '2:block_lstm'),
- *connect('h_init_state', '3:block_lstm'),
- *connect('c_init_state', '4:block_lstm'),
- *connect('block_lstm', 'result')
- ],
- nodes_with_edges_only=True)
- BlockLSTMtoLSTMSequenceSingleFirstOutput().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('x', '0:block_lstm'),
- *connect('weights_normalized', '1:block_lstm'),
- *connect('bias_normalized', '2:block_lstm'),
- *connect('h_init_state', '4:block_lstm'),
- *connect('c_init_state', '5:block_lstm'),
- *connect('block_lstm', 'result'),
- ],
- update_attributes={
- 'block_lstm': {'sequence_dim': 0, 'batch_dim': 1, 'direction': 'forward',
- 'hidden_size': 2, 'format': 'tf', 'type': 'RNNSequence',
- 'op': 'LSTM'},
- },
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/CheckForCycle_test.py b/tools/mo/unit_tests/mo/middle/CheckForCycle_test.py
deleted file mode 100644
index 24629aa5a7ee74..00000000000000
--- a/tools/mo/unit_tests/mo/middle/CheckForCycle_test.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.middle.CheckForCycle import CheckForCycle
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_1_data': {'value': None, 'kind': 'data', 'data_type': None},
- 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'concat': {'type': 'Concat', 'value': None, 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_3_data': {'value': None, 'kind': 'data', 'data_type': None},
- # Placeholders
- 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pl_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pl_1_data': {'value': None, 'kind': 'data', 'data_type': None},
- 'pl_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pl_2_data': {'value': None, 'kind': 'data', 'data_type': None},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # ScaleShift layer
- 'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul op
- 'mul_1': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result', 'infer': lambda x: None}
- }
-
-
-class CycleTest(UnitTestWithMockedTelemetry):
- def test_check_for_cycle1(self):
- # cyclic case
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_1_data'),
- ('node_1_data', 'node_3'),
- ('node_3', 'node_3_data'),
- ('node_3_data', 'node_1')],
- nodes_with_edges_only=True)
- with self.assertRaisesRegex(Error, 'Graph contains a cycle. Can not proceed.*'):
- CheckForCycle().find_and_replace_pattern(graph)
-
- def test_check_for_cycle2(self):
- # acyclic case
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_1_data'),
- ('node_1_data', 'node_3'),
- ('node_3', 'node_3_data'),
- ('node_3_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data')
- ],
- nodes_with_edges_only=True)
- try:
- CheckForCycle().find_and_replace_pattern(graph)
- except Error:
- self.fail("Unexpected Error raised")
diff --git a/tools/mo/unit_tests/mo/middle/ConcatOptimization_test.py b/tools/mo/unit_tests/mo/middle/ConcatOptimization_test.py
deleted file mode 100644
index 81b1917ec46e28..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ConcatOptimization_test.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.ConcatOptimization import ConcatOdInputEraserAndPortsReconnect
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, shaped_const_with_data, connect
-
-
-class ConcatOdInputEraserAndPortsReconnectTest(unittest.TestCase):
- def test_deletion(self):
- nodes = {
- **shaped_const_with_data('input_0', [1]),
- **shaped_const_with_data('input_1', [1]),
- **shaped_const_with_data('input_2', [0]),
- **shaped_const_with_data('input_3', [1]),
- **regular_op_with_shaped_data('concat', [3], {'type': 'Concat'}),
- **result(),
- }
- edges_before = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_2', '2:concat'),
- *connect('input_3', '3:concat'),
- *connect('concat', 'output'),
- ]
- edges_after = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_3', '2:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges_before, nodes_with_edges_only=True)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_deletion_2(self):
- nodes = {
- **shaped_const_with_data('input_0', [5, 0]),
- **shaped_const_with_data('input_1', [5, 1]),
- **shaped_const_with_data('input_2', [5, 3]),
- **shaped_const_with_data('input_3', [5, 5]),
- **regular_op_with_shaped_data('concat', [5, 9], {'type': 'Concat', 'axis': 1}),
- **result(),
- }
- edges_before = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_2', '2:concat'),
- *connect('input_3', '3:concat'),
- *connect('concat', 'output'),
- ]
- edges_after = [
- *connect('input_1', '0:concat'),
- *connect('input_2', '1:concat'),
- *connect('input_3', '2:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges_before, nodes_with_edges_only=True)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_deletion_3(self):
- nodes = {
- **shaped_const_with_data('input_0', [5, 3]),
- **shaped_const_with_data('input_1', [5, 1]),
- **shaped_const_with_data('input_2', [5, 5]),
- **shaped_const_with_data('input_3', [5, 0]),
- **regular_op_with_shaped_data('concat', [5, 9], {'type': 'Concat', 'axis': 1}),
- **result(),
- }
- edges_before = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_2', '2:concat'),
- *connect('input_3', '3:concat'),
- *connect('concat', 'output'),
- ]
- edges_after = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_2', '2:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges_before, nodes_with_edges_only=True)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_deletion_unconnected_port_and_0d(self):
- nodes = {
- **shaped_const_with_data('input_0', [5, 3]),
- **shaped_const_with_data('input_2', [5, 1]),
- **shaped_const_with_data('input_3', [5, 0]),
- **regular_op_with_shaped_data('concat', [5, 4], {'type': 'Concat', 'axis': 1}),
- **result(),
- }
- edges_before = [
- *connect('input_0', '0:concat'),
- *connect('input_2', '2:concat'),
- *connect('input_3', '3:concat'),
- *connect('concat', 'output'),
- ]
- edges_after = [
- *connect('input_0', '0:concat'),
- *connect('input_2', '1:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges_before, nodes_with_edges_only=True)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_deletion_unconnected_ports(self):
- nodes = {
- **shaped_const_with_data('input_0', [5, 3]),
- **shaped_const_with_data('input_4', [5, 1]),
- **shaped_const_with_data('input_7', [5, 2]),
- **regular_op_with_shaped_data('concat', [5, 6], {'type': 'Concat', 'axis': 1}),
- **result(),
- }
- edges_before = [
- *connect('input_0', '0:concat'),
- *connect('input_4', '4:concat'),
- *connect('input_7', '7:concat'),
- *connect('concat', 'output'),
- ]
- edges_after = [
- *connect('input_0', '0:concat'),
- *connect('input_4', '1:concat'),
- *connect('input_7', '2:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges_before, nodes_with_edges_only=True)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_deletion_trailing_unconnected_ports(self):
- nodes = {
- **shaped_const_with_data('input_0', [5, 3]),
- **regular_op_with_shaped_data('concat', [5, 3], {'type': 'Concat', 'axis': 1}),
- **result(),
- }
- edges_before = [
- *connect('input_0', '0:concat'),
- *connect('concat', 'output'),
- ]
- edges_after = [
- *connect('input_0', '0:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges_before, nodes_with_edges_only=True)
- Node(graph, 'concat').add_input_port(1)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges_after, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- self.assertTrue(1 not in Node(graph, 'concat').in_ports())
-
- def test_negative(self):
- nodes = {
- **shaped_const_with_data('input_0', [1]),
- **shaped_const_with_data('input_1', [1]),
- **shaped_const_with_data('input_2', [1]),
- **shaped_const_with_data('input_3', [1]),
- **regular_op_with_shaped_data('concat', [4], {'type': 'Concat'}),
- **result(),
- }
- edges = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_2', '2:concat'),
- *connect('input_3', '3:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern(graph)
- graph_ref = build_graph(nodes, edges, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_assertion_error(self):
- nodes = {
- **shaped_const_with_data('input_0', [0]),
- **shaped_const_with_data('input_1', [0]),
- **shaped_const_with_data('input_2', [0]),
- **shaped_const_with_data('input_3', [0]),
- **regular_op_with_shaped_data('concat', [0], {'type': 'Concat'}),
- **result(),
- }
- edges = [
- *connect('input_0', '0:concat'),
- *connect('input_1', '1:concat'),
- *connect('input_2', '2:concat'),
- *connect('input_3', '3:concat'),
- *connect('concat', 'output'),
- ]
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- self.assertRaises(AssertionError, ConcatOdInputEraserAndPortsReconnect().find_and_replace_pattern, graph)
diff --git a/tools/mo/unit_tests/mo/middle/ConvertGroupedStridedSlice_test.py b/tools/mo/unit_tests/mo/middle/ConvertGroupedStridedSlice_test.py
deleted file mode 100644
index 2a39ac12d979ac..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ConvertGroupedStridedSlice_test.py
+++ /dev/null
@@ -1,1255 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.middle.ConvertGroupedStridedSlice import ConvertGroupedStridedSlice
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_begin_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_end_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_stride_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
-
- # StridedSlice layers
- 'sslice_1': {'type': None, 'kind': 'op', 'op': 'StridedSlice', 'slices': None,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]), 'begin_mask': int64_array([1, 1, 1, 1]),
- 'end_mask': int64_array([1, 1, 1, 1]), 'new_axis_mask': int64_array([0, 0, 0, 0]),
- 'ellipsis_mask': int64_array([0])},
- 'sslice_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'sslice_2': {'type': None, 'kind': 'op', 'op': 'StridedSlice', 'slices': None,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]), 'begin_mask': int64_array([1, 1, 1, 1]),
- 'end_mask': int64_array([1, 1, 1, 1]), 'new_axis_mask': int64_array([0, 0, 0, 0]),
- 'ellipsis_mask': int64_array([0])},
- 'sslice_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'sslice_3': {'type': None, 'kind': 'op', 'op': 'StridedSlice', 'slices': None,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]), 'begin_mask': int64_array([1, 1, 1, 1]),
- 'end_mask': int64_array([1, 1, 1, 1]), 'new_axis_mask': int64_array([0, 0, 0, 0]),
- 'ellipsis_mask': int64_array([0])},
- 'sslice_3_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'sslice_4': {'type': None, 'kind': 'op', 'op': 'StridedSlice', 'slices': None,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]), 'begin_mask': int64_array([1, 1, 1, 1]),
- 'end_mask': int64_array([1, 1, 1, 1]), 'new_axis_mask': int64_array([0, 0, 0, 0]),
- 'ellipsis_mask': int64_array([0])},
- 'sslice_4_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- # Split layer
- 'axis_const': {'kind': 'op'},
- 'axis_const_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'split_dim_const': {'kind': 'op'},
- 'split_dim_const_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'split_1': {'type': 'VariadicSplit', 'kind': 'op', 'op': 'VariadicSplit'},
- 'split_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'split_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'split_3_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'split_4_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- # Concat1 operation
- 'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'op_output': {'kind': 'op', 'op': 'Result'},
- 'op_output_1': {'kind': 'op', 'op': 'Result', 'keep_output_port': True},
- 'op_output_2': {'kind': 'op', 'op': 'Result', 'keep_output_port': True},
-
- # Squeeze layers
- 'sslice_1/Squeeze_shrink': {'type': None, 'value': None, 'kind': 'op', 'op': 'Squeeze'},
- 'sslice_1/Squeeze_shrink_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'sslice_1/squeeze_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': int64_array([2])},
- 'sslice_1/squeeze_const_data': {'kind': 'data', 'value': None, 'shape': None},
-
- 'sslice_2/Squeeze_shrink': {'type': None, 'value': None, 'kind': 'op', 'op': 'Squeeze'},
- 'sslice_2/Squeeze_shrink_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'sslice_2/squeeze_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': int64_array([2])},
- 'sslice_2/squeeze_const_data': {'kind': 'data', 'value': None, 'shape': None},
-
- # Unsqueeze layer
- 'sslice_2/Unsqueeze_new': {'type': None, 'value': None, 'kind': 'op', 'op': 'Unsqueeze'},
- 'sslice_2/Unsqueeze_new_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'sslice_2/unsqueeze_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': int64_array([2])},
- 'sslice_2/unsqueeze_const_data': {'kind': 'data', 'value': None, 'shape': None},
-
- # Activations
- 'abs': {'type': None, 'value': None, 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'relu': {'type': None, 'value': None, 'kind': 'op', 'op': 'ReLU'},
- 'relu_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'erf': {'type': None, 'value': None, 'kind': 'op', 'op': 'Erf'},
- 'erf_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'gelu': {'type': None, 'value': None, 'kind': 'op', 'op': 'Gelu'},
- 'gelu_data': {'value': None, 'shape': None, 'kind': 'data'},
-}
-
-one_strided_slice_case_node_attributes = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'sslice': {'type': None, 'kind': 'op', 'op': 'StridedSlice', 'slices': None,
- 'shrink_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
-}
-
-one_strided_slice_case_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'sslice'),
- ('sslice', 'sslice_data'),
- ('sslice_data', 'op_output'),
-]
-
-
-class TestConvertGroupedStridedSliceTests():
- def test_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 18, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(18, 36, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(36, 54, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'split_1', {'in': 0}),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('split_1', 'split_3_data'),
- ('split_1_data', 'concat_1'),
- ('split_2_data', 'concat_1'),
- ('split_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'axis_const': {'value': 3},
- 'split_1_data': {'shape': np.array([1, 227, 227, 18])},
- 'split_2_data': {'shape': np.array([1, 227, 227, 18])},
- 'split_3_data': {'shape': np.array([1, 227, 227, 18])},
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- def test_2(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 37, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 54, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 17])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 19, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 19])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'split_1'),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('split_1', 'split_3_data'),
- ('split_1_data', 'concat_1'),
- ('split_2_data', 'concat_1'),
- ('split_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'axis_const': {'value': 3},
- 'split_1_data': {'shape': np.array([1, 227, 227, 18])},
- 'split_2_data': {'shape': np.array([1, 227, 227, 17])},
- 'split_3_data': {'shape': np.array([1, 227, 227, 19])},
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # Intersection of split ranges in feature dimension
- def test_3_neg(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 39, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 20])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 54, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 17])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 19, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 19])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 39, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 20])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 54, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 17])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 19, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 19])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # Split range overflow in feature dimension
- def test_4_neg(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 37, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 55, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 19, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 19])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 37, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 55, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 19, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 19])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # Split(1,H,W,54)--->Fake_data (1,H,W,1)
- # |`---->Sslice1_out (1,H,W,18)
- # |`---->Sslice2_out (1,H,W,18)
- # `----->Sslice3_out (1,H,W,17)
- def test_5(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 37, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 54, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 17])},
-
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(1, 19, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'split_1'),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('split_1', 'split_3_data'),
- ('split_1', 'split_4_data'),
- ('split_2_data', 'concat_1'),
- ('split_3_data', 'concat_1'),
- ('split_4_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ('split_1_data', 'op_output_1'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'axis_const': {'value': 3},
- 'split_1_data': {'shape': np.array([1, 227, 227, 1])},
- 'split_2_data': {'shape': np.array([1, 227, 227, 18])},
- 'split_3_data': {'shape': np.array([1, 227, 227, 17])},
- 'split_4_data': {'shape': np.array([1, 227, 227, 18])},
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # Split(1,H,W,54)
- # |`---->Sslice1_out (1,H,W,(0,18))
- # |`---->Fake_data (1,H,W,(18,27))
- # |`---->Sslice3_out (1,H,W,(27,45))
- # `----->Fake_data (1,H,W,(45,54))
- def test_6(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 18, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(27, 45, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 18])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'split_1'),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('split_1', 'split_3_data'),
- ('split_1', 'split_4_data'),
- ('split_1_data', 'concat_1'),
- ('split_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ('split_2_data', 'op_output_1'),
- ('split_4_data', 'op_output_2'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'axis_const': {'value': 3},
- 'split_1_data': {'shape': np.array([1, 227, 227, 18])},
- 'split_2_data': {'shape': np.array([1, 227, 227, 9])},
- 'split_3_data': {'shape': np.array([1, 227, 227, 18])},
- 'split_4_data': {'shape': np.array([1, 227, 227, 9])},
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- def test_7_neg(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 10, 1), slice(0, 227, 1), slice(0, 18, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 10, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(10, 227, 1), slice(0, 227, 1), slice(27, 45, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 217, 227, 18])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 10, 1), slice(0, 227, 1), slice(0, 18, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 10, 227, 18])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(10, 227, 1), slice(0, 227, 1), slice(27, 45, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 217, 227, 18])},
-
- 'concat_1_data': {'shape': np.array([1, 227, 227, 54])},
- })
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # Split(1,54,W,C)
- # |`---->Sslice1_out (1,(0,18),W,C)
- # |`---->Sslice2_out (1,(18,36),W,C)
- # `----->Fake_data (1,(36,54),W,C)
- def test_8(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 54, 54, 3])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 18, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 18, 54, 3])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(18, 36, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 18, 54, 3])},
-
- 'concat_1_data': {'shape': np.array([1, 54, 54, 3])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'split_1'),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('split_1', 'split_3_data'),
- ('split_1_data', 'concat_1'),
- ('split_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ('split_2_data', 'op_output_1'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 54, 54, 3])},
- 'axis_const': {'value': 1},
- 'split_1_data': {'shape': np.array([1, 18, 54, 3])},
- 'split_2_data': {'shape': np.array([1, 18, 54, 3])},
- 'split_3_data': {'shape': np.array([1, 18, 54, 3])},
- 'concat_1_data': {'shape': np.array([1, 54, 54, 3])},
- })
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # Test for the case when there is only 1 StridedSlice.
- @pytest.mark.parametrize("input_shape, slices, output_shape",[(np.array([1, 227, 227, 54]),
- np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 18, 1)]),
- np.array([1, 227, 227, 18])),
- (np.array([57, 16, 100, 23]),
- np.array([slice(3, 16, 1), slice(0, 16, 1), slice(0, 100, 1), slice(0, 23, 1)]),
- np.array([13, 16, 100, 23])),
- (np.array([16, 800, 1024, 17]),
- np.array([slice(0, 16, 1), slice(0, 800, 1), slice(13, 817, 1), slice(0, 17, 1)]),
- np.array([16, 800, 804, 17]))])
- def test_9(self, input_shape, slices, output_shape):
- graph = build_graph(nodes_attrs=one_strided_slice_case_node_attributes,
- edges=one_strided_slice_case_edges,
- update_attributes={
- 'placeholder_data': {'shape': input_shape},
- 'sslice': {'slices': slices},
- 'sslice_data': {'shape': output_shape},
- })
- graph.graph['layout'] = 'NHWC'
- graph_ref = build_graph(nodes_attrs=one_strided_slice_case_node_attributes,
- edges=one_strided_slice_case_edges,
- update_attributes={
- 'placeholder_data': {'shape': input_shape},
- 'sslice': {'slices': slices},
- 'sslice_data': {'shape': output_shape},
- })
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'op_output', check_op_attrs=True)
- assert flag, resp
-
- # Test for case when
- # 1) There are 4 StridedSlice operations.
- # 2) 2 of StridedSlice have the same data.
- # 3) 2 others StridedSlice have the same data.
- # 4) All StridedSlice operations outputs are consumed by different operations.
- def test_10(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('placeholder_1_data', 'sslice_4'),
- ('sslice_4', 'sslice_4_data'),
- ('sslice_1_data', 'abs'),
- ('abs', 'abs_data'),
- ('sslice_2_data', 'relu'),
- ('relu', 'relu_data'),
- ('sslice_3_data', 'erf'),
- ('erf', 'erf_data'),
- ('sslice_4_data', 'gelu'),
- ('gelu', 'gelu_data'),
- ('abs_data', 'concat_1'),
- ('relu_data', 'concat_1'),
- ('erf_data', 'concat_1'),
- ('gelu_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 54, 54, 3])},
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 30, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 30, 54, 3])},
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(30, 54, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 24, 54, 3])},
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 30, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 30, 54, 3])},
- 'sslice_4': {'slices': np.array(
- [slice(0, 1, 1), slice(30, 54, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_4_data': {'shape': np.array([1, 24, 54, 3])},
- 'concat_1_data': {'shape': np.array([1, 108, 54, 3])},
- 'abs_data': {'shape': np.array([1, 30, 54, 3])},
- 'relu_data': {'shape': np.array([1, 24, 54, 3])},
- 'erf_data': {'shape': np.array([1, 30, 54, 3])},
- 'gelu_data': {'shape': np.array([1, 24, 54, 3])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'split_1'),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('placeholder_1_data', 'sslice_4'),
- ('sslice_4', 'sslice_4_data'),
- ('split_1_data', 'abs'),
- ('abs', 'abs_data'),
- ('split_2_data', 'relu'),
- ('relu', 'relu_data'),
- ('sslice_3_data', 'erf'),
- ('erf', 'erf_data'),
- ('sslice_4_data', 'gelu'),
- ('gelu', 'gelu_data'),
- ('abs_data', 'concat_1'),
- ('relu_data', 'concat_1'),
- ('erf_data', 'concat_1'),
- ('gelu_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
-
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 54, 54, 3])},
- 'split_1_data': {'shape': np.array([1, 30, 54, 3])},
- 'split_2_data': {'shape': np.array([1, 24, 54, 3])},
- 'sslice_3': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 30, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 30, 54, 3])},
- 'sslice_4': {'slices': np.array(
- [slice(0, 1, 1), slice(30, 54, 1), slice(0, 54, 1), slice(0, 3, 1)])},
- 'sslice_4_data': {'shape': np.array([1, 24, 54, 3])},
- 'abs_data': {'shape': np.array([1, 30, 54, 3])},
- 'relu_data': {'shape': np.array([1, 24, 54, 3])},
- 'erf_data': {'shape': np.array([1, 30, 54, 3])},
- 'gelu_data': {'shape': np.array([1, 24, 54, 3])},
- 'axis_const': {'value': 1},
- 'concat_1_data': {'shape': np.array([1, 108, 54, 3])},
- })
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # dynamic slice
- def test_11(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
-
- 'sslice_1': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(19, 39, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 20])},
-
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(37, 54, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 17])},
-
- 'sslice_3': {'slices': [slice(0, 1, 1), slice(0, 227, 1), 12, slice(0, 19, 1)]},
- 'sslice_3_data': {'shape': shape_array([1, 227, dynamic_dimension_value, 19])},
-
- 'concat_1_data': {'shape': shape_array([1, 227, dynamic_dimension_value, 54])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = graph.copy()
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- assert flag, resp
-
- # one unuque StridedSlice
- def test_12(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 511])},
-
- 'sslice_1': {'slices': np.array([slice(0, 1, 1), slice(0, 1, 1)]),
- 'begin_mask': np.array([0, 1, 0]),
- 'end_mask': np.array([0, 1, 0]),
- 'new_axis_mask': np.array([0, 0, 0]),
- 'shrink_axis_mask': np.array([0, 0, 0]),
- 'ellipsis_mask': np.array([0, 0, 0])},
- 'sslice_1_data': {'shape': np.array([1, 1, 511])},
-
- 'sslice_2': {'slices': np.array([slice(0, 1, 1), slice(0, 1, 1)]),
- 'begin_mask': np.array([0, 1, 0]),
- 'end_mask': np.array([0, 1, 0]),
- 'new_axis_mask': np.array([0, 0, 0]),
- 'shrink_axis_mask': np.array([0, 0, 0]),
- 'ellipsis_mask': np.array([0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 1, 511])},
- })
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = graph.copy()
-
- pattern = ConvertGroupedStridedSlice()
- pattern.find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_1_data', check_op_attrs=True)
- assert flag, resp
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_2_data', check_op_attrs=True)
- assert flag, resp
-
-
-class AddReshapeAfterStridedSliceTests(unittest.TestCase):
- def test_ss_1_shrink_last(self):
- slices = np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1), slice(0, 54, 1)])
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('placeholder_begin_data', 'sslice_1'),
- ('placeholder_end_data', 'sslice_1'),
- ('placeholder_stride_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('sslice_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_1': {'slices': slices,
- 'shrink_axis_mask': [0, 0, 1, 0],
- 'new_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_1_data': {'shape': np.array([1, 227, 54])},
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('placeholder_begin_data', 'sslice_1'),
- ('placeholder_end_data', 'sslice_1'),
- ('placeholder_stride_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('sslice_1_data', 'sslice_1/Squeeze_shrink'),
- ('sslice_1/squeeze_const', 'sslice_1/squeeze_const_data'),
- ('sslice_1/squeeze_const_data', 'sslice_1/Squeeze_shrink'),
- ('sslice_1/Squeeze_shrink', 'sslice_1/Squeeze_shrink_data'),
- ('sslice_1/Squeeze_shrink_data', 'op_output'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_1': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]),
- 'new_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_1_data': {'shape': np.array([1, 227, 1, 54])},
- 'sslice_1/Squeeze_shrink_data': {'shape': np.array([1, 227, 54])}
- }, nodes_with_edges_only=True)
-
- ConvertGroupedStridedSlice().add_squeeze_for_shrink(graph, Node(graph, 'sslice_1'))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ss_1_shrink(self):
- slices = np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1), slice(0, 54, 1)])
-
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2', {'out': 0}),
- ('placeholder_2', 'placeholder_2_data'),
- ('sslice_2_data', 'op_output', {'out': 0})
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': [0, 0, 1, 0],
- 'new_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227, 54])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'sslice_2/Squeeze_shrink'),
- ('sslice_2/squeeze_const', 'sslice_2/squeeze_const_data'),
- ('sslice_2/squeeze_const_data', 'sslice_2/Squeeze_shrink'),
- ('sslice_2/Squeeze_shrink', 'sslice_2/Squeeze_shrink_data'),
- ('sslice_2/Squeeze_shrink_data', 'placeholder_2', {'out': 0}),
- ('placeholder_2', 'placeholder_2_data'),
- ('sslice_2/Squeeze_shrink_data', 'op_output', {'out': 0})
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]),
- 'new_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227, 1, 54])},
- 'sslice_2/squeeze_const': {'value': np.array([2])},
- 'sslice_2/Squeeze_shrink_data': {'shape': np.array([1, 227, 54])},
- }, nodes_with_edges_only=True)
-
- ConvertGroupedStridedSlice().add_squeeze_for_shrink(graph, Node(graph, 'sslice_2'))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'op_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ss_2_shrink(self):
- slices = np.array([slice(0, 1, 1), slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1)])
-
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2', {'out': 0}),
- ('placeholder_2', 'placeholder_2_data'),
- ('sslice_2_data', 'op_output', {'out': 0})
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 1, 0, 1]),
- 'new_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'sslice_2/Squeeze_shrink'),
- ('sslice_2/squeeze_const', 'sslice_2/squeeze_const_data'),
- ('sslice_2/squeeze_const_data', 'sslice_2/Squeeze_shrink'),
- ('sslice_2/Squeeze_shrink', 'sslice_2/Squeeze_shrink_data'),
- ('sslice_2/Squeeze_shrink_data', 'placeholder_2', {'out': 0}),
- ('placeholder_2', 'placeholder_2_data'),
- ('sslice_2/Squeeze_shrink_data', 'op_output', {'out': 0})
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 0]),
- 'new_axis_mask': np.array([0, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 1, 227, 1])},
- 'sslice_2/squeeze_const': {'value': np.array([1, 3])},
- 'sslice_2/Squeeze_shrink_data': {'shape': np.array([1, 227])},
- }, nodes_with_edges_only=True)
-
- ConvertGroupedStridedSlice().add_squeeze_for_shrink(graph, Node(graph, 'sslice_2'))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'op_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ss_1_new(self):
- slices = np.array([slice(0, 1, 1), slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1), slice(0, 54, 1)])
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'), ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 0, 0]),
- 'new_axis_mask': np.array([0, 1, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 1, 227, 227, 54])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'sslice_2/Unsqueeze_new'),
- ('sslice_2/unsqueeze_const', 'sslice_2/unsqueeze_const_data'),
- ('sslice_2/unsqueeze_const_data', 'sslice_2/Unsqueeze_new'),
- ('sslice_2/Unsqueeze_new', 'sslice_2/Unsqueeze_new_data'),
- ('sslice_2/Unsqueeze_new_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data')],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 0, 0]),
- 'new_axis_mask': np.array([0, 0, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2/unsqueeze_const': {'value': int64_array([1])},
- 'sslice_2/Unsqueeze_new_data': {'shape': np.array([1, 1, 227, 227, 54])},
- }, nodes_with_edges_only=True)
-
- pattern = ConvertGroupedStridedSlice()
- pattern.add_unsqueeze_for_new(graph, Node(graph, 'sslice_2'))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ss_shrink_new(self):
- slices = np.array([slice(0, 1, 1), slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1), slice(0, 54, 1)])
-
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('sslice_2_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 1, 0]),
- 'new_axis_mask': np.array([0, 1, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 1, 227, 54])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'sslice_2/Unsqueeze_new'),
- ('sslice_2/unsqueeze_const', 'sslice_2/unsqueeze_const_data'),
- ('sslice_2/unsqueeze_const_data', 'sslice_2/Unsqueeze_new'),
- ('sslice_2/Unsqueeze_new', 'sslice_2/Unsqueeze_new_data'),
- ('sslice_2/Unsqueeze_new_data', 'sslice_2/Squeeze_shrink'),
- ('sslice_2/squeeze_const', 'sslice_2/squeeze_const_data'),
- ('sslice_2/squeeze_const_data', 'sslice_2/Squeeze_shrink'),
- ('sslice_2/Squeeze_shrink', 'sslice_2/Squeeze_shrink_data'),
- ('sslice_2/Squeeze_shrink_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('sslice_2/Squeeze_shrink_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_2': {'slices': slices,
- 'shrink_axis_mask': np.array([0, 0, 0, 0, 0]),
- 'new_axis_mask': np.array([0, 0, 0, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227, 1, 54])},
- 'sslice_2/unsqueeze_const': {'value': int64_array([1])},
- 'sslice_2/Unsqueeze_new_data': {'shape': np.array([1, 1, 227, 1, 54])},
- 'sslice_2/squeeze_const': {'value': np.array([3])},
- 'sslice_2/Squeeze_shrink_data': {'shape': np.array([1, 1, 227, 54])},
- }, nodes_with_edges_only=True)
-
- pattern = ConvertGroupedStridedSlice()
- pattern.add_squeeze_for_shrink(graph, Node(graph, 'sslice_2'))
- pattern.add_unsqueeze_for_new(graph, Node(graph, 'sslice_2'))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'op_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # test case for strided slice that only shrinks dimension
- def test_ss_shrink_only(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 1, 54])},
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1), slice(0, 54, 1)]),
- 'shrink_axis_mask': np.array([0, 0, 1, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227, 54])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = graph.copy()
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ss_shrink_only_short(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 1, 54])},
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1), slice(0, 54, 1)]),
- 'shrink_axis_mask': np.array([0, 0, 1])},
- 'sslice_2_data': {'shape': np.array([1, 227, 54])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = graph.copy()
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ss_shrink_only_long(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('placeholder_begin_data', 'sslice_2'),
- ('placeholder_end_data', 'sslice_2'),
- ('placeholder_stride_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('sslice_2_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 1, 54])},
- 'sslice_2': {'slices': np.array(
- [slice(0, 1, 1), slice(0, 227, 1), slice(0, 1, 1), slice(0, 54, 1)]),
- 'shrink_axis_mask': np.array([0, 0, 1, 0, 0])},
- 'sslice_2_data': {'shape': np.array([1, 227, 54])}
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = graph.copy()
-
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'sslice_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # test case when
- # 1) There are 3 StridedSlice operations;
- # 2) 2 of StridedSlice have the same attributes;
- # 3) other StridedSlice have different attributes;
- # 4) pair (some StridedSlice from the item 2, StridedSlice from the item 3) can be replaced by VariadicSplit.
- def test_1(self):
- graph = build_graph(nodes_attributes,
- [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_1'),
- ('sslice_1', 'sslice_1_data'),
- ('placeholder_1_data', 'sslice_2'),
- ('sslice_2', 'sslice_2_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('sslice_1_data', 'concat_1'),
- ('sslice_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ],
- {
- 'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_1': {'slices': np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1),
- slice(0, 27, 1)])},
- 'sslice_1_data': {'shape': np.array([1, 227, 227, 27])},
- 'sslice_2': {'slices': np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1),
- slice(27, 54, 1)])},
- 'sslice_2_data': {'shape': np.array([1, 227, 227, 27])},
- 'sslice_3': {'slices': np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1),
- slice(0, 27, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 27])},
- 'concat_1': {'axis': 3},
- 'concat_1_data': {'shape': np.array([1, 227, 227, 81])},
- })
- graph.graph['layout'] = 'NHWC'
- graph_ref = build_graph(nodes_attributes,
- [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'sslice_3'),
- ('sslice_3', 'sslice_3_data'),
- ('placeholder_1_data', 'split_1'),
- ('split_1', 'split_1_data'),
- ('split_1', 'split_2_data'),
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split_1', {'in': 1}),
- ('split_dim_const_data', 'split_1', {'in': 2}),
- ('split_1_data', 'concat_1'),
- ('split_2_data', 'concat_1'),
- ('sslice_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {
- 'placeholder_1_data': {'shape': np.array([1, 227, 227, 54])},
- 'sslice_3': {'slices': np.array([slice(0, 1, 1), slice(0, 227, 1), slice(0, 227, 1),
- slice(0, 27, 1)])},
- 'sslice_3_data': {'shape': np.array([1, 227, 227, 27])},
- 'split_1_data': {'shape': np.array([1, 227, 227, 27])},
- 'split_2_data': {'shape': np.array([1, 227, 227, 27])},
- 'axis_const': {'op': 'Const', 'type': 'Const', 'value': 3, 'shape': []},
- 'axis_const_data': {'value': 3, 'shape': []},
- 'split_dim_const': {'op': 'Const', 'type': 'Const', 'value': np.array([27, 27])},
- 'split_dim_const_data': {'value': np.array([27, 27])},
- 'concat_1': {'axis': 3},
- 'concat_1_data': {'shape': np.array([1, 227, 227, 81])}
- })
- ConvertGroupedStridedSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tools/mo/unit_tests/mo/middle/CutInputHavingZeroDimFromConcat_test.py b/tools/mo/unit_tests/mo/middle/CutInputHavingZeroDimFromConcat_test.py
deleted file mode 100644
index e9f3b46c73be2d..00000000000000
--- a/tools/mo/unit_tests/mo/middle/CutInputHavingZeroDimFromConcat_test.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.CutInputHavingZeroDimFromConcat import CutInputHavingZeroDimFromConcat
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-node_attrs_for_the_case_when_there_are_no_zero_shape_constants = {
- 'const0': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([1, 2, 5]),
- 'value': np.zeros((1, 2, 5))
- },
- 'const0_data': {'kind': 'data', 'shape': int64_array([1, 2, 5]), 'value': None},
- 'const1': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([1, 2, 7]),
- 'value': np.zeros((1, 2, 7))
- },
- 'const1_data': {'kind': 'data', 'shape': int64_array([1, 2, 7]), 'value': None},
- 'placeholder': {'kind': 'op', 'type': 'Parameter', 'op': 'Parameter'},
- 'placeholder_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': int64_array([1, 2, 8]),
- 'data_type': None
- },
- 'concat': {'kind': 'op', 'type': 'Concat', 'op': 'Concat', 'axis': 2},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 2, 20]), 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-
-edges_for_the_case_when_there_are_no_zero_shape_constants = [
- ('const0', 'const0_data'),
- ('const1', 'const1_data'),
- ('placeholder', 'placeholder_data'),
- ('const0_data', 'concat', {'in': 0}),
- ('const1_data', 'concat', {'in': 1}),
- ('placeholder_data', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'output')
-]
-
-
-class CutInputHavingZeroDimFromConcatTest(unittest.TestCase):
- """
- This class tests deleting of inputs of Concat having zeros in their shapes, if not all inputs have such shapes.
- """
- def test_when_need_to_do_nothing(self):
- graph = build_graph(
- nodes_attrs=node_attrs_for_the_case_when_there_are_no_zero_shape_constants,
- edges=edges_for_the_case_when_there_are_no_zero_shape_constants
- )
- ref_graph = build_graph(
- nodes_attrs=node_attrs_for_the_case_when_there_are_no_zero_shape_constants,
- edges=edges_for_the_case_when_there_are_no_zero_shape_constants
- )
- CutInputHavingZeroDimFromConcat().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_when_there_are_three_inputs_and_middle_constant_has_zero_in_shape(self):
- graph = build_graph(
- nodes_attrs={
- 'const0': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([1, 2, 5]),
- 'value': np.zeros((1, 2, 5))
- },
- 'const0_data': {'kind': 'data', 'shape': int64_array([1, 2, 5]), 'value': None},
- 'const1': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([1, 2, 0]),
- 'value': np.zeros((1, 2, 0))
- },
- 'const1_data': {'kind': 'data', 'shape': int64_array([1, 2, 0]), 'value': None},
- 'placeholder': {'kind': 'op', 'type': 'Parameter', 'op': 'Parameter'},
- 'placeholder_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': int64_array([1, 2, 17]),
- 'data_type': None
- },
- 'concat': {'kind': 'op', 'type': 'Concat', 'op': 'Concat', 'axis': 2},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 2, 22]), 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
- },
- edges=[
- ('const0', 'const0_data'),
- ('const1', 'const1_data'),
- ('placeholder', 'placeholder_data'),
- ('const0_data', 'concat', {'in': 0}),
- ('const1_data', 'concat', {'in': 1}),
- ('placeholder_data', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'output')
- ]
- )
- ref_graph = build_graph(
- nodes_attrs={
- 'const0': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([1, 2, 5]),
- 'value': np.zeros((1, 2, 5))
- },
- 'const0_data': {'kind': 'data', 'shape': int64_array([1, 2, 5]), 'value': None},
- 'placeholder': {'kind': 'op', 'type': 'Parameter', 'op': 'Parameter'},
- 'placeholder_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': int64_array([1, 2, 17]),
- 'data_type': None
- },
- 'concat': {'kind': 'op', 'type': 'Concat', 'op': 'Concat', 'axis': 2},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 2, 22]), 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
- },
- edges=[
- ('const0', 'const0_data'),
- ('placeholder', 'placeholder_data'),
- ('const0_data', 'concat', {'in': 0}),
- ('placeholder_data', 'concat', {'in': 1}),
- ('concat', 'concat_data'),
- ('concat_data', 'output')
- ]
- )
- CutInputHavingZeroDimFromConcat().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_there_are_four_inputs_and_first_and_third_input_have_zero_in_their_shapes(self):
- graph = build_graph(
- nodes_attrs={
- 'const0': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([5, 0]),
- 'value': np.zeros((5, 0))
- },
- 'const0_data': {'kind': 'data', 'shape': int64_array([5, 0]), 'value': None},
- 'placeholder': {'kind': 'op', 'type': 'Parameter', 'op': 'Parameter'},
- 'placeholder_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': int64_array([5, 17]),
- 'data_type': None
- },
- 'const2': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([5, 0]),
- 'value': np.zeros((5, 0))
- },
- 'const2_data': {'kind': 'data', 'shape': int64_array([5, 0]), 'value': None},
- 'const3': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([5, 23]),
- 'value': np.zeros((5, 23))
- },
- 'const3_data': {'kind': 'data', 'shape': int64_array([5, 23]), 'value': None},
- 'concat': {'kind': 'op', 'type': 'Concat', 'op': 'Concat', 'axis': 1},
- 'concat_data': {'kind': 'data', 'shape': int64_array([5, 40]), 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
- },
- edges=[
- ('const0', 'const0_data'),
- ('placeholder', 'placeholder_data'),
- ('const2', 'const2_data'),
- ('const3', 'const3_data'),
- ('const0_data', 'concat', {'in': 0}),
- ('placeholder_data', 'concat', {'in': 1}),
- ('const2_data', 'concat', {'in': 2}),
- ('const3_data', 'concat', {'in': 3}),
- ('concat', 'concat_data'),
- ('concat_data', 'output')
- ]
- )
- ref_graph = build_graph(
- nodes_attrs={
- 'placeholder': {'kind': 'op', 'type': 'Parameter', 'op': 'Parameter'},
- 'placeholder_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': int64_array([5, 17]),
- 'data_type': None
- },
- 'const3': {
- 'kind': 'op',
- 'type': 'Const',
- 'op': 'Const',
- 'shape': int64_array([5, 23]),
- 'value': np.zeros((5, 23))
- },
- 'const3_data': {'kind': 'data', 'shape': int64_array([5, 23]), 'value': None},
- 'concat': {'kind': 'op', 'type': 'Concat', 'op': 'Concat', 'axis': 1},
- 'concat_data': {'kind': 'data', 'shape': int64_array([5, 40]), 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
- },
- edges=[
- ('placeholder', 'placeholder_data'),
- ('const3', 'const3_data'),
- ('placeholder_data', 'concat', {'in': 0}),
- ('const3_data', 'concat', {'in': 1}),
- ('concat', 'concat_data'),
- ('concat_data', 'output')
- ]
- )
- CutInputHavingZeroDimFromConcat().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/DilatedConvolution_test.py b/tools/mo/unit_tests/mo/middle/DilatedConvolution_test.py
deleted file mode 100644
index e9563ec60302da..00000000000000
--- a/tools/mo/unit_tests/mo/middle/DilatedConvolution_test.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.DilatedConvolution import DilatedConvolutionConverter
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, \
- regular_op_with_shaped_data, valued_const_with_data
-
-shape = int64_array([1, 375, 500, 24])
-nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('stb_bs', int64_array([1, 32, 32, 1])),
- **valued_const_with_data('stb_pad_begin', int64_array([0, 32, 32, 0])),
- **valued_const_with_data('stb_pad_end', int64_array([0, 41, 44, 0])),
- **regular_op_with_shaped_data('space_to_batch', int64_array([1024, 14, 18, 24]),
- {'op': 'SpaceToBatch', 'name': 'stb'}),
- **regular_op_with_shaped_data('conv', int64_array([1024, 12, 16, 24]),
- {'op': 'Conv2D', 'name': 'conv', 'spatial_dims': int64_array([1, 2]),
- 'dilation': int64_array([1, 1, 1, 1]),
- 'pad': int64_array([[0, 0], [0, 0], [0, 0], [0, 0]])}),
- **valued_const_with_data('bts_bs', int64_array([1, 32, 32, 1])),
- **valued_const_with_data('bts_crop_begin', int64_array([0, 0, 0, 0])),
- **valued_const_with_data('bts_crop_end', int64_array([0, 9, 12, 0])),
- **regular_op_with_shaped_data('batch_to_space', shape, {'op': 'BatchToSpace', 'name': 'bts'}),
- **result('result')
- }
-
-edges = [*connect('input', '0:space_to_batch'),
- *connect('stb_bs', '1:space_to_batch'),
- *connect('stb_pad_begin', '2:space_to_batch'),
- *connect('stb_pad_end', '3:space_to_batch'),
- *connect('space_to_batch', '0:conv'),
- *connect('conv', '0:batch_to_space'),
- *connect('bts_bs', '1:batch_to_space'),
- *connect('bts_crop_begin', '2:batch_to_space'),
- *connect('bts_crop_end', '3:batch_to_space'),
- *connect('batch_to_space', 'result')
- ]
-
-ref_nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('conv', shape,
- {'op': 'Conv2D', 'name': 'conv', 'spatial_dims': int64_array([1, 2]),
- 'dilation': int64_array([1, 32, 32, 1]), 'auto_pad': None,
- 'pad': int64_array([[0, 0], [32, 32], [32, 32], [0, 0]])}),
- **result('result')
- }
-ref_edges = [*connect('input', '0:conv'),
- *connect('conv', 'result')
- ]
-
-
-class DilatedConvolutionTest(unittest.TestCase):
- def test_dilated_conv_1(self):
- graph = build_graph(nodes, edges)
-
- graph_ref = build_graph(ref_nodes, ref_edges)
-
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- DilatedConvolutionConverter().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/EltwiseInputReshape_test.py b/tools/mo/unit_tests/mo/middle/EltwiseInputReshape_test.py
deleted file mode 100644
index b906e4f0edcac1..00000000000000
--- a/tools/mo/unit_tests/mo/middle/EltwiseInputReshape_test.py
+++ /dev/null
@@ -1,531 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.EltwiseInputReshape import normalize_eltwise_inputs
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-# 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': {'value': None, 'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2': {'value': None, 'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3': {'value': None, 'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_4_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
-
- # Reshape layers
- 'reshape_1': {'type': 'Unsqueeze', 'value': None, 'kind': 'op', 'op': 'Unsqueeze'},
- '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': 'Unsqueeze', 'value': None, 'kind': 'op', 'op': 'Unsqueeze'},
- '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},
-
- # Eltwise consumes layers
- 'eltwise_1': {'kind': 'op', 'is_eltwise': True},
- 'eltwise_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'eltwise_2': {'kind': 'op', 'is_eltwise': True},
- 'eltwise_2_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'eltwise_3': {'kind': 'op', 'is_eltwise': True},
- 'eltwise_3_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'eltwise_4': {'kind': 'op', 'is_eltwise': True},
- 'eltwise_4_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- # Concat
- 'concat': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
-}
-
-
-class EltwiseInputNormalizationTest(unittest.TestCase):
- def test1_not_constant(self):
- #
- # data1(1,3,64,64)----. data(1,3,64,64)-------.
- # data2(1,64,1)-------->Eltwise-->data(1,3,64,64) => data(1,64,1)->Reshape->data(1,1,64,1)-->Eltwise->...
- # data3(64,1)------' data(64,1)->Reshape->data(1,1,64,1)-'
- #
- graph = build_graph(nodes_attributes, [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1', 'placeholder_2_data'),
- ('placeholder_1', 'placeholder_3_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_2_data', 'eltwise_1'),
- ('placeholder_3_data', 'eltwise_1'),
- ('eltwise_1', 'eltwise_1_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'placeholder_2_data': {'shape': np.array([1, 64, 1])},
- 'placeholder_3_data': {'shape': np.array([64, 1])},
- 'eltwise_1_data': {'shape': np.array([1, 3, 64, 64])}
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1', 'placeholder_2_data'),
- ('placeholder_1', 'placeholder_3_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_2_data', 'reshape_1'),
- ('reshape_1_const', 'reshape_1_const_data'),
- ('reshape_1_const_data', 'reshape_1'),
- ('placeholder_3_data', 'reshape_2'),
- ('reshape_2_const', 'reshape_2_const_data'),
- ('reshape_2_const_data', 'reshape_2'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_2', 'reshape_2_data'),
- ('reshape_1_data', 'eltwise_1'),
- ('reshape_2_data', 'eltwise_1'),
- ('eltwise_1', 'eltwise_1_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'reshape_1_const': {'value': int64_array([0]), 'shape': int64_array([1])},
- 'reshape_1_const_data': {'value': int64_array([0]),
- 'shape': int64_array([1])},
- 'reshape_1_data': {'shape': np.array([1, 1, 64, 1])},
- 'reshape_2_const': {'value': int64_array([0, 1]), 'shape': int64_array([2])},
- 'reshape_2_const_data': {'value': int64_array([0, 1]),
- 'shape': int64_array([2])},
- 'reshape_2_data': {'shape': np.array([1, 1, 64, 1])},
- 'eltwise_1_data': {'shape': np.array([1, 3, 64, 64])}
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'eltwise_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_mega_hardcore(self):
- # ORIGINAL GRAPH
- #
- # data1(1,3,64,64)---,->Eltwise1->data(1,3,64,64)-----,->Eltwise2->data(1,3,64,64)---,->Eltwise4->data(1,3,64,64)
- # /\ /\ /\
- # data2(64,1)-----,-'--------------------------------'------------------------------'
- # \/ /
- # data3(64,1)----`-->Eltwise3->data(64,1)----------'
- #
- # REFERENCE GRAPH AFTER TRANSFORMATION
- #
- # data1(1,3,64,64)---------------------,->Eltwise1->data(1,3,64,64)-----,->Eltwise2->data(1,3,64,64)---,->Eltwise4->data(1,3,64,64)
- # /\ /\ /\
- # data2(64,1)-,- Reshape1(1,1,64,64)--'--------------------------------o-------------------------------'
- # | |
- # | Reshape(1,1,64,1)
- # \/ |
- # data3(64,1)----------->Eltwise3->data(64,1)--------------------------'
- #
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_2_data', 'eltwise_1'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_1_data', 'eltwise_2'),
- ('placeholder_2_data', 'eltwise_3'),
- ('placeholder_3_data', 'eltwise_3'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_3_data', 'eltwise_2'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_2_data', 'eltwise_4'),
- ('placeholder_2_data', 'eltwise_4'),
- ('eltwise_4', 'eltwise_4_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'placeholder_2_data': {'shape': np.array([64, 1]), 'value': np.ones([64, 1])},
- 'placeholder_3_data': {'shape': np.array([64, 1])},
- 'eltwise_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'eltwise_2_data': {'shape': np.array([1, 3, 64, 64])},
- 'eltwise_3_data': {'shape': np.array([64, 1])},
- 'eltwise_4_data': {'shape': np.array([1, 3, 64, 64])}
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_2_data', 'reshape_1'),
- ('reshape_1_const', 'reshape_1_const_data'),
- ('reshape_1_const_data', 'reshape_1'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_1_data', 'eltwise_1'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_1_data', 'eltwise_2'),
- ('placeholder_2_data', 'eltwise_3'),
- ('placeholder_3_data', 'eltwise_3'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_3_data', 'reshape_2'),
- ('reshape_2_const', 'reshape_2_const_data'),
- ('reshape_2_const_data', 'reshape_2'),
- ('reshape_2', 'reshape_2_data'),
- ('reshape_2_data', 'eltwise_2'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_2_data', 'eltwise_4'),
- ('reshape_1_data', 'eltwise_4'),
- ('eltwise_4', 'eltwise_4_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'placeholder_2_data': {'shape': np.array([64, 1]),
- 'value': np.ones([64, 1])},
- 'placeholder_3_data': {'shape': np.array([64, 1])},
- 'reshape_1_const': {'value': int64_array([0, 1]), 'shape': int64_array([2])},
- 'reshape_1_const_data': {'value': int64_array([0, 1]),
- 'shape': int64_array([2])},
- 'reshape_1_data': {'shape': np.array([1, 1, 64, 1])},
-
- 'reshape_2_const': {'value': int64_array([0, 1]), 'shape': int64_array([2])},
- 'reshape_2_const_data': {'value': int64_array([0, 1]),
- 'shape': int64_array([2])},
- 'reshape_2_data': {'shape': np.array([1, 1, 64, 1])},
- 'eltwise_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'eltwise_2_data': {'shape': np.array([1, 3, 64, 64])},
- 'eltwise_3_data': {'shape': np.array([64, 1])},
- 'eltwise_4_data': {'shape': np.array([1, 3, 64, 64])}
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'eltwise_4', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test2_not_constant(self):
- # ,-------------->consumer3 ,------------>consumer3
- # data---(new_shape1)-->consumer1 => data---->Reshape-->consumer1
- # `-(new_shape2)-->consumer2 `-->Reshape-->consumer2
- #
- graph = build_graph(nodes_attributes, [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_1_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3])},
- 'eltwise_1_data': {'shape': int64_array([1, 1, 1, 3])},
- 'eltwise_2_data': {'shape': int64_array([1, 1, 3])},
- 'eltwise_3_data': {'shape': int64_array([1, 3])},
- },
- nodes_with_edges_only=True)
-
- 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'),
- ('placeholder_1_data', 'reshape_2'),
- ('reshape_2_const', 'reshape_2_const_data'),
- ('reshape_2_const_data', 'reshape_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_2', 'reshape_2_data'),
- ('reshape_1_data', 'eltwise_1'),
- ('reshape_2_data', 'eltwise_2'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3])},
- 'reshape_1_const': {'value': int64_array([0, 1]), 'shape': int64_array([2])},
- 'reshape_1_const_data': {'value': int64_array([0, 1]),
- 'shape': int64_array([2])},
- 'reshape_1_data': {'shape': int64_array([1, 1, 1, 3])},
- '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([1, 1, 3])},
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test3_not_constant(self):
- # ,--------------->consumer3 ,----------->consumer3
- # data---(new_shape1)-->consumer1 => data-->Reshape-->consumer1
- # `-(new_shape1)-->consumer2 `-->consumer2
- #
- graph = build_graph(nodes_attributes,
- [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_1_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3])},
- 'eltwise_1_data': {'shape': int64_array([1, 1, 1, 3])},
- 'eltwise_2_data': {'shape': int64_array([1, 1, 1, 3])},
- 'eltwise_3_data': {'shape': int64_array([1, 3])},
- },
- nodes_with_edges_only=True)
-
- 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'),
- ('placeholder_1_data', 'eltwise_3'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_1_data', 'eltwise_1'),
- ('reshape_1_data', 'eltwise_2'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3])},
- 'reshape_1_const': {'value': int64_array([0, 1]), 'shape': int64_array([2])},
- 'reshape_1_const_data': {'value': int64_array([0, 1]),
- 'shape': int64_array([2])},
- 'reshape_1_data': {'shape': int64_array([1, 1, 1, 3])},
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test4_constant(self):
- # ,--------------->consumer3 ,------------>consumer3
- # data---(new_shape1)-->consumer1 => data--->reshape1-->consumer1
- # `-(new_shape2)-->consumer2 `->reshape2-->consumer2
- #
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_1_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3]), 'value': np.ones([1, 3])},
- 'eltwise_1_data': {'shape': int64_array([1, 1, 1, 3])},
- 'eltwise_2_data': {'shape': int64_array([1, 1, 3])},
- 'eltwise_3_data': {'shape': int64_array([1, 3])},
- },
- nodes_with_edges_only=True)
-
- 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', 'eltwise_1'),
- ('placeholder_1_data', 'reshape_2'),
- ('reshape_2_const', 'reshape_2_const_data'),
- ('reshape_2_const_data', 'reshape_2'),
- ('reshape_2', 'reshape_2_data'),
- ('reshape_2_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3]), 'value': np.ones([1, 3])},
- 'reshape_1_const': {'value': int64_array([0, 1]), 'shape': int64_array([2])},
- 'reshape_1_const_data': {'value': int64_array([0, 1]),
- 'shape': int64_array([2])},
- 'reshape_1_data': {'shape': int64_array([1, 1, 1, 3])},
-
- '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([1, 1, 3])},
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test5_constant(self):
- # ,-(new_shape)-->consumer3 ,-->consumer3
- # data---(new_shape)-->consumer1 => data-->reshape---->consumer1
- # `-(new_shape)-->consumer2 `-->consumer2
- #
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_1_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3]), 'value': np.ones([1, 3])},
- 'eltwise_1_data': {'shape': int64_array([1, 1, 3])},
- 'eltwise_2_data': {'shape': int64_array([1, 1, 3])},
- 'eltwise_3_data': {'shape': int64_array([1, 1, 3])},
- },
- nodes_with_edges_only=True)
-
- 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', 'eltwise_1'),
- ('reshape_1_data', 'eltwise_2'),
- ('reshape_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3]), 'value': np.ones([1, 3])},
- 'reshape_1_const': {'value': int64_array([0]), 'shape': int64_array([1])},
- 'reshape_1_const_data': {'value': int64_array([0]),
- 'shape': int64_array([1])},
- 'reshape_1_data': {'shape': int64_array([1, 1, 3])},
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test6_not_constant(self):
- # ,--------------->consumer3 ,->consumer3
- # data---(new_shape1)-->consumer1 => data----->consumer1
- # `-(new_shape1)-->consumer2 `-->consumer2
- #
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_1_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3])},
- 'eltwise_1_data': {'shape': int64_array([1, 3])},
- 'eltwise_2_data': {'shape': int64_array([1, 3])},
- 'eltwise_3_data': {'shape': int64_array([1, 3])},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_1_data', 'eltwise_2'),
- ('placeholder_1_data', 'eltwise_3'),
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_2', 'eltwise_2_data'),
- ('eltwise_3', 'eltwise_3_data'),
- ('eltwise_1_data', 'concat'),
- ('eltwise_2_data', 'concat'),
- ('eltwise_3_data', 'concat'),
- ],
- {'placeholder_1_data': {'shape': int64_array([1, 3])}}, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test7_axis1_not_constant(self):
- #
- # data1(1,3,64,64)----. data(1,3,64,64)-------.
- # data2(3,64,1)-------->Eltwise-->data(1,3,64,64)=> data(3,64,1)->Unsqueeze(0)->data(1,3,64,1)-->Eltwise->...
- # data3(3,1)------' data(3,1)->Unsqueeze(2, 0)->data(1,3,1,1)-'
- #
- graph = build_graph(nodes_attributes, [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_2_data', 'eltwise_1'),
- ('placeholder_3_data', 'eltwise_1'),
- ('eltwise_1', 'eltwise_1_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'placeholder_2_data': {'shape': np.array([3, 64, 1])},
- 'placeholder_3_data': {'shape': np.array([3, 1])},
- 'eltwise_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'eltwise_1' : {'axis': 1}
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [
- ('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_1_data', 'eltwise_1'),
- ('placeholder_2_data', 'reshape_1'),
- ('reshape_1_const', 'reshape_1_const_data'),
- ('reshape_1_const_data', 'reshape_1'),
- ('placeholder_3_data', 'reshape_2'),
- ('reshape_2_const', 'reshape_2_const_data'),
- ('reshape_2_const_data', 'reshape_2'),
- ('reshape_1', 'reshape_1_data'),
- ('reshape_2', 'reshape_2_data'),
- ('reshape_1_data', 'eltwise_1'),
- ('reshape_2_data', 'eltwise_1'),
- ('eltwise_1', 'eltwise_1_data')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 64, 64])},
- 'placeholder_2_data': {'shape': np.array([3, 64, 1])},
- 'placeholder_3_data': {'shape': np.array([3, 1])},
- 'reshape_1_const': {'value': int64_array([0]), 'shape': int64_array([1])},
- 'reshape_1_const_data': {'value': int64_array([0]),
- 'shape': int64_array([1])},
- 'reshape_1_data': {'shape': np.array([1, 3, 64, 1])},
- 'reshape_2_const': {'value': int64_array([2, 0]), 'shape': int64_array([2])},
- 'reshape_2_const_data': {'value': int64_array([2, 0]),
- 'shape': int64_array([2])},
- 'reshape_2_data': {'shape': np.array([1, 3, 1, 1])},
- 'eltwise_1_data': {'shape': np.array([1, 3, 64, 64])}
- }, nodes_with_edges_only=True)
-
- normalize_eltwise_inputs(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'eltwise_1', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/FakeSplitOutputs_test.py b/tools/mo/unit_tests/mo/middle/FakeSplitOutputs_test.py
deleted file mode 100644
index cb14ca53234db1..00000000000000
--- a/tools/mo/unit_tests/mo/middle/FakeSplitOutputs_test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.FakeSplitOutputs import AddFakeOutputsToSplit, AddFakeOutputsToVariadicSplit
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.eliminate import graph_clean_up
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter', 'shape': np.array([1, 227, 227, 3])},
- # VariadicSplit operation
- 'variadic_split': {'type': 'VariadicSplit', 'kind': 'op', 'op': 'VariadicSplit'},
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3, 'axis': 3},
- # Test operation
- 'last': {'type': None, 'value': None, 'kind': 'op', 'op': None, 'infer': copy_shape_infer},
- 'res': {'type': 'Result', 'kind': 'op', 'op': 'Result'},
- # Data nodes
- 'placeholder_data': {'kind': 'data', 'value': None, 'shape': np.array([1, 227, 227, 3])},
- 'variadic_split_data_1': {'kind': 'data', 'value': None, 'shape': np.array([1, 2, 227, 3])},
- 'split_data_1': {'kind': 'data', 'value': None, 'shape': np.array([1, 227, 227, 1])},
- 'last_data': {'kind': 'data', 'value': None, 'shape': np.array([1, 227, 227, 3])},
-
- 'axis_const': {'kind': 'op', 'op': 'Const'},
- 'axis_const_data': {'value': np.int64(1), 'shape': None, 'kind': 'data'},
- 'split_dim_const': {'kind': 'op', 'op': 'Const'},
- 'split_dim_const_data': {'value': np.array([1, 2, 3]), 'shape': None, 'kind': 'data'},
-
-}
-
-
-class SplitSaveEmptyBranchesTest(unittest.TestCase):
- def test_variadic_split_non_zero(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_data'), ('placeholder_data', 'variadic_split'),
- ('variadic_split', 'variadic_split_data_1'), ('variadic_split_data_1', 'last'),
- ('last', 'last_data'), ('last_data', 'res'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'variadic_split', {'in': 1}),
- ('split_dim_const_data', 'variadic_split', {'in': 2}),
- ], nodes_with_edges_only=True)
- node = Node(graph, 'variadic_split')
-
- # extractor should do it
- node['out_ports_count'] = 3
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- replacer = AddFakeOutputsToVariadicSplit()
- replacer.find_and_replace_pattern(graph)
-
- for n in graph.get_op_nodes():
- n['need_shape_inference'] = False
- graph_clean_up(graph)
-
- self.assertTrue(len(node.out_edges()) == 3)
-
- def test_split(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_data'), ('placeholder_data', 'split'),
- ('split', 'split_data_1'), ('split_data_1', 'last'),
- ('last', 'last_data'), ('last_data', 'res'),
- ], nodes_with_edges_only=True)
- node = Node(graph, 'split')
-
- # extractor should do it
- node['out_ports_count'] = node.num_splits
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- replacer = AddFakeOutputsToSplit()
- replacer.find_and_replace_pattern(graph)
-
- for n in graph.get_op_nodes():
- n['need_shape_inference'] = False
- graph_clean_up(graph)
-
- self.assertTrue(len(node.out_edges()) == node.num_splits)
diff --git a/tools/mo/unit_tests/mo/middle/FuseReshapeSequenceKaldi_test.py b/tools/mo/unit_tests/mo/middle/FuseReshapeSequenceKaldi_test.py
deleted file mode 100644
index 525ecd9185e894..00000000000000
--- a/tools/mo/unit_tests/mo/middle/FuseReshapeSequenceKaldi_test.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.FuseReshapesSequence import FuseReshapesSequenceKaldi
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, valued_const_with_data, connect, regular_op_with_shaped_data
-
-
-class FuseReshapesKaldiTests(unittest.TestCase):
- ref_nodes = {
- **regular_op_with_shaped_data('conv', [1, 128, 1, 9], {'kind': 'op', 'op': 'Convolution',
- 'kernel': [1, 11, 1, 5], 'patch_stride': 5,
- 'kernel_spatial': [1, 5]}),
- **valued_const_with_data('transpose_out_order', int64_array([0, 2, 3, 1])),
- **regular_op_with_shaped_data('transpose_out', [1, 1, 9, 128], {'op': 'Transpose', 'type': 'Transpose'}),
- **valued_const_with_data('transpose_in_order', int64_array([0, 3, 1, 2])),
- **regular_op_with_shaped_data('transpose_in', [1, 128, 1, 9], {'op': 'Transpose', 'type': 'Transpose'}),
- **regular_op_with_shaped_data('pool', [1, 128, 1, 3], {'kind': 'op', 'op': 'Pooling',
- 'pool_stride': 3, 'pool_step': [1, 1, 1, 1]}),
- }
-
- nodes = {
- **regular_op_with_shaped_data('conv', [1, 128, 1, 9], {'kind': 'op', 'op': 'Convolution',
- 'kernel': [1, 1, 11, 5]}),
- **valued_const_with_data('transpose_out_order', int64_array([0, 2, 3, 1])),
- **regular_op_with_shaped_data('transpose_out', [1, 1, 9, 128], {'op': 'Transpose', 'type': 'Transpose'}),
- **valued_const_with_data('reshape_out_shape', int64_array([0, -1])),
- **regular_op_with_shaped_data('reshape_out', [1, 1152], {'op': 'Reshape', 'type': 'Reshape',
- 'special_zero': True}),
-
- **regular_op_with_shaped_data('shapeof', [4], {'op': 'ShapeOf', 'type': 'ShapeOf'}),
- **valued_const_with_data('ind', int64_array([0])),
- **valued_const_with_data('axis', int64_array(0)),
- **regular_op_with_shaped_data('gather_batch', [], {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('t', int64_array([1])),
- **valued_const_with_data('h', int64_array([9])),
- **valued_const_with_data('ind_h', int64_array([1])),
- **regular_op_with_shaped_data('gather_h', [], {'op': "Gather", 'type': 'Gather'}),
- **valued_const_with_data('th', int64_array([9])),
- **regular_op_with_shaped_data('div', [], {'op': 'Div', 'type': 'Divide'}),
- **regular_op_with_shaped_data('concat', [4], {'op': 'Concat', 'type': 'Concat'}),
-
- **regular_op_with_shaped_data('reshape_in', [1, 1, 9, 128], {'op': 'Reshape', 'type': 'Reshape'}),
- **valued_const_with_data('transpose_in_order', int64_array([0, 3, 1, 2])),
- **regular_op_with_shaped_data('transpose_in', [1, 128, 1, 9], {'op': 'Transpose', 'type': 'Transpose'}),
- **regular_op_with_shaped_data('pool', [1, 128, 1, 3], {'kind': 'op', 'op': 'Pooling', 'pool_stride': 3,
- 'pool_step': [1, 1, 1, 1]}),
- }
-
- def test_conv_reshape_pool(self):
- graph = build_graph(self.nodes, [
- *connect('conv', '0:transpose_out'),
- *connect('transpose_out_order', '1:transpose_out'),
- *connect('transpose_out', '0:reshape_out'),
- *connect('reshape_out_shape', '1:reshape_out'),
- *connect('reshape_out', 'shapeof'),
-
- *connect('shapeof', '0:gather_batch'),
- *connect('ind', '1:gather_batch'),
- *connect('axis', '2:gather_batch'),
- *connect('shapeof', '0:gather_h', skip_data=True),
- *connect('ind_h', '1:gather_h'),
- *connect('axis', '2:gather_h', skip_data=True),
- *connect('gather_h', '0:div'),
- *connect('th', '1:div'),
- *connect('gather_batch', '0:concat'),
- *connect('t', '1:concat'),
- *connect('h', '2:concat'),
- *connect('div', '3:concat'),
- *connect('concat', '1:reshape_in'),
-
- *connect('reshape_out', '0:reshape_in', skip_data=True),
- *connect('reshape_in', '0:transpose_in'),
- *connect('transpose_in_order', "1:transpose_in"),
- *connect('transpose_in', 'pool'),
- ], nodes_with_edges_only=True)
-
- FuseReshapesSequenceKaldi().find_and_replace_pattern(graph)
-
- ref_graph = build_graph(self.ref_nodes,
- [
- *connect('conv', '0:transpose_out'),
- *connect('transpose_out_order', '1:transpose_out'),
- *connect('transpose_out', '0:transpose_in'),
- *connect('transpose_in_order', "1:transpose_in"),
- *connect('transpose_in', 'pool'),
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'pool')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/FusedBatchNormTraining_test.py b/tools/mo/unit_tests/mo/middle/FusedBatchNormTraining_test.py
deleted file mode 100644
index 5a46980eb69400..00000000000000
--- a/tools/mo/unit_tests/mo/middle/FusedBatchNormTraining_test.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.middle.FusedBatchNormTraining import FusedBatchNormTraining
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.passes.eliminate import shape_inference
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder': {'value': None, 'shape': int64_array([3, 10, 11, 5]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'placeholder_data': {'shape': int64_array([3, 10, 11, 5]), 'value': None, 'kind': 'data'},
-
- 'scale': {'value': np.array([2, 3.5, 4.5, 5.1, 2.6], dtype=np.float32), 'shape': int64_array([5]), 'kind': 'op',
- 'op': 'Const'},
- 'scale_data': {'value': np.array([2, 3.5, 4.5, 5.1, 2.6], dtype=np.float32), 'shape': int64_array([5]),
- 'kind': 'data'},
-
- 'offset': {'value': np.array([1, 2.5, 3.5, 4.1, 5.6], dtype=np.float32), 'shape': int64_array([5]), 'kind': 'op',
- 'op': 'Const'},
- 'offset_data': {'value': np.array([1, 2.5, 3.5, 4.1, 5.6], dtype=np.float32), 'shape': int64_array([5]),
- 'kind': 'data'},
-
- 'mean': {'value': None, 'shape': int64_array([]), 'kind': 'op', 'op': 'Const'},
- 'mean_data': {'value': None, 'shape': int64_array([]), 'kind': 'data'},
-
- 'variance': {'value': None, 'shape': int64_array([]), 'kind': 'op', 'op': 'Const'},
- 'variance_data': {'value': None, 'shape': int64_array([]), 'kind': 'data'},
-
- 'batchnorm': {'value': None, 'shape': int64_array([3, 10, 11, 5]), 'type': None, 'kind': 'op',
- 'op': 'FusedBatchNorm', 'is_training': True, 'eps': 1e-3},
- 'batchnorm_data': {'value': None, 'shape': int64_array([3, 10, 11, 5]), 'kind': 'data'},
-
- 'result': {'kind': 'op', 'op': 'Result'},
-
- # nodes after transformation
- 'bn_mean': {'value': np.zeros([5]), 'shape': int64_array([5]), 'kind': 'op', 'op': 'Const'},
- 'bn_mean_data': {'value': np.zeros([5]), 'shape': int64_array([5]), 'kind': 'data'},
-
- 'bn_variance': {'value': np.ones([5]), 'shape': int64_array([5]), 'kind': 'op', 'op': 'Const'},
- 'bn_variance_data': {'value': np.ones([5]), 'shape': int64_array([5]), 'kind': 'data'},
-
- 'shapeof': {'type': 'ShapeOf', 'value': None, 'kind': 'op', 'op': 'ShapeOf'},
- 'shapeof_data': {'value': int64_array([3, 10, 11, 5]), 'shape': int64_array([4]), 'kind': 'data'},
-
- 'reshape_to_orig': {'type': 'Reshape', 'value': None, 'kind': 'op', 'op': 'Reshape'},
- 'reshape_to_orig_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'start': {'kind': 'op', 'op': 'Const', 'value': int64_array(1)},
- 'start_data': {'value': None, 'shape': None, 'kind': 'data', 'value': int64_array(1)},
- 'stop': {'kind': 'op', 'op': 'Const', 'value': int64_array(3)},
- 'stop_data': {'value': None, 'shape': None, 'kind': 'data', 'value': int64_array(3)},
- 'step': {'kind': 'op', 'op': 'Const', 'value': int64_array(1)},
- 'step_data': {'value': None, 'shape': None, 'kind': 'data', 'value': int64_array(1)},
- 'mvn_axes': {'kind': 'op', 'op': 'Range'},
- 'mvn_axes_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'mvn': {'type': 'MVN', 'value': None, 'kind': 'op', 'op': 'MVN', 'eps': 1e-3, 'eps_mode': 'inside_sqrt'},
- 'mvn_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'reshape_1': {'type': 'Reshape', 'value': None, 'kind': 'op', 'op': 'Reshape'},
- 'reshape_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'reshape_1_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': int64_array([1, -1, 0, 0])},
- 'reshape_1_const_data': {'kind': 'data', 'value': None, 'shape': None},
-}
-
-
-class TestFusedBatchNormTrainingTest():
- @pytest.mark.parametrize("op",[
- 'FusedBatchNorm', 'FusedBatchNormV2', 'FusedBatchNormV3',
- ])
- def test_transformation(self, op: str):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'placeholder_data', {}),
- ('scale', 'scale_data'),
- ('offset', 'offset_data'),
- ('mean', 'mean_data'),
- ('variance', 'variance_data'),
- ('placeholder_data', 'batchnorm', {'in': 0}),
- ('scale_data', 'batchnorm', {'in': 1}),
- ('offset_data', 'batchnorm', {'in': 2}),
- ('mean_data', 'batchnorm', {'in': 3}),
- ('variance_data', 'batchnorm', {'in': 4}),
- ('batchnorm', 'batchnorm_data'),
- ('batchnorm_data', 'result'),
- ],
- {}, nodes_with_edges_only=True)
- graph.nodes['batchnorm']['op'] = op
- graph_ref = build_graph(nodes_attributes,
- [('placeholder', 'placeholder_data', {}),
- ('scale', 'scale_data'),
- ('offset', 'offset_data'),
- ('bn_mean', 'bn_mean_data'),
- ('bn_variance', 'bn_variance_data'),
- ('scale_data', 'batchnorm', {'in': 1}),
- ('offset_data', 'batchnorm', {'in': 2}),
- ('bn_mean_data', 'batchnorm', {'in': 3}),
- ('bn_variance_data', 'batchnorm', {'in': 4}),
-
- ('placeholder_data', 'reshape_1', {'in': 0}),
- ('reshape_1_const', 'reshape_1_const_data'),
- ('reshape_1_const_data', 'reshape_1', {'in': 1}),
- ('reshape_1', 'reshape_1_data', {}),
- ('reshape_1_data', 'mvn', {'in': 0}),
- ('mvn', 'mvn_data'),
- ('mvn_data', 'reshape_to_orig', {'in': 0}),
- ('start', 'start_data'),
- ('start_data', 'mvn_axes'),
- ('stop', 'stop_data'),
- ('stop_data', 'mvn_axes'),
- ('step', 'step_data'),
- ('step_data', 'mvn_axes'),
- ('mvn_axes', 'mvn_axes_data'),
- ('mvn_axes_data', 'mvn'),
- ('placeholder_data', 'shapeof', {'in': 0}),
- ('shapeof', 'shapeof_data'),
- ('shapeof_data', 'reshape_to_orig', {'in': 1}),
- ('reshape_to_orig', 'reshape_to_orig_data'),
- ('reshape_to_orig_data', 'batchnorm', {'in': 0}),
-
- ('batchnorm', 'batchnorm_data'),
- ('batchnorm_data', 'result'),
- ],
- {'batchnorm': {'is_training': False},
-
- }, nodes_with_edges_only=True)
- FusedBatchNormTraining().find_and_replace_pattern(graph)
- shape_inference(graph)
-
- graph_ref.nodes['batchnorm']['op'] = op
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- assert flag, resp
-
- def test_non_training(self):
- graph = build_graph(nodes_attributes,
- [('placeholder', 'placeholder_data', {}),
- ('scale', 'scale_data'),
- ('offset', 'offset_data'),
- ('mean', 'mean_data'),
- ('variance', 'variance_data'),
- ('placeholder_data', 'batchnorm', {'in': 0}),
- ('scale_data', 'batchnorm', {'in': 1}),
- ('offset_data', 'batchnorm', {'in': 2}),
- ('mean_data', 'batchnorm', {'in': 3}),
- ('variance_data', 'batchnorm', {'in': 4}),
- ('batchnorm', 'batchnorm_data'),
- ('batchnorm_data', 'result'),
- ],
- {'batchnorm': {'is_training': False}}, nodes_with_edges_only=True)
- graph_ref = graph.copy()
-
- FusedBatchNormTraining().find_and_replace_pattern(graph)
- shape_inference(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/middle/GatherNDDecomposition_test.py b/tools/mo/unit_tests/mo/middle/GatherNDDecomposition_test.py
deleted file mode 100644
index bc6c15ec832a67..00000000000000
--- a/tools/mo/unit_tests/mo/middle/GatherNDDecomposition_test.py
+++ /dev/null
@@ -1,395 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-import numpy as np
-
-from openvino.tools.mo.middle.GatherNDDecomposition import GatherNDDecomposition
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-nodes = {
- 'input': {'kind': 'op', 'op': 'Const'},
- 'input_data': {'kind': 'data'},
-
- 'indices_input': {'kind': 'op', 'op': 'Const'},
- 'indices_input_data': {'kind': 'data'},
-
- 'gathernd': {'kind': 'op', 'op': 'GatherND'},
- 'gathernd_data': {'kind': 'data'},
-
- 'result': {'kind': 'op', 'op': 'Result'},
-}
-
-edges = [
- ('input', 'input_data'),
- ('input_data', 'gathernd', {'in': 0}),
-
- ('indices_input', 'indices_input_data'),
- ('indices_input_data', 'gathernd', {'in': 1}),
-
- ('gathernd', 'gathernd_data'),
- ('gathernd_data', 'result'),
-]
-
-nodes_expected = {
- 'input': {'kind': 'op', 'op': 'Const'},
- 'input_data': {'kind': 'data'},
-
- 'reshape_shape': {'kind': 'op', 'op': 'Const'},
- 'reshape_shape_data': {'kind': 'data'},
-
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'reshape_data': {'kind': 'data'},
-
- 'axis': {'kind': 'op', 'op': 'Const'},
- 'axis_data': {'kind': 'data'},
-
- 'indices': {'kind': 'op', 'op': 'Const'},
- 'indices_data': {'kind': 'data'},
-
- 'gather': {'kind': 'op', 'op': 'Gather'},
- 'gather_data': {'kind': 'data'},
-
- 'result': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_expected = [
- ('input', 'input_data'),
- ('input_data', 'reshape', {'in': 0}),
-
- ('reshape_shape', 'reshape_shape_data'),
- ('reshape_shape_data', 'reshape', {'in': 1}),
-
- ('reshape', 'reshape_data'),
- ('reshape_data', 'gather', {'in': 0}),
-
- ('indices', 'indices_data'),
- ('indices_data', 'gather', {'in': 1}),
-
- ('axis', 'axis_data'),
- ('axis_data', 'gather', {'in': 2}),
-
- ('gather', 'gather_data'),
- ('gather_data', 'result'),
-]
-
-
-class GatherNDDecompositionTest(unittest.TestCase):
-
- def test_GatherNDDecomposition_2by2indices_validinputs(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 2]).reshape([2, 1])},
- 'indices_input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 0, 0, 0]).reshape([2, 2])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 2]).reshape([2, 1])},
- 'indices': {'shape': np.array([2]), 'value': np.array([1, 0])},
- 'reshape_shape': {'shape': np.array([1]), 'value': np.array([-1])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_2by2indices_invalidinputs(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices_input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 0, 0, 0]).reshape([2, 2])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = graph
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_2by1indices_validinputs(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices_input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 0]).reshape([2, 1])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices': {'shape': np.array([2]), 'value': np.array([1, 0])},
- 'reshape_shape': {'shape': np.array([2]), 'value': np.array([-1, 2])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_2by0indices_invalidinputs(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([1, 2]), 'value': np.array([1, 2]).reshape([1, 2])},
- 'indices_input_data': {'shape': np.array([2]), 'value': np.array([1, 0])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = graph
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_2by0indices_validinputs(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 2])},
- 'indices_input_data': {'shape': np.array([2]), 'value': np.array([1, 0])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 2])},
- 'indices': {'shape': np.array([]), 'value': np.array([1])},
- 'reshape_shape': {'shape': np.array([1]), 'value': np.array([-1])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_1leadingdim(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices_input_data': {'shape': np.array([2, 1, 1]), 'value': np.array([1, 0]).reshape([2, 1, 1])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices': {'shape': np.array([2, 1]), 'value': np.array([1, 0]).reshape([2, 1])},
- 'reshape_shape': {'shape': np.array([2]), 'value': np.array([-1, 2])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_3leadingdims(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices_input_data': {'shape': np.array([2, 1, 1, 1, 1]), 'value': np.array([1, 0]).reshape([2, 1, 1, 1, 1])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices': {'shape': np.array([2, 1, 1, 1]), 'value': np.array([1, 0]).reshape([2, 1, 1, 1])},
- 'reshape_shape': {'shape': np.array([2]), 'value': np.array([-1, 2])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_nonzerobatchdim(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 2]), 'value': np.array([1, 2, 3, 4]).reshape([2, 2])},
- 'indices_input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 0]).reshape([2, 1])},
- 'gathernd': {'batch_dims': 1}
- },
- nodes_with_edges_only=True)
- graph_ref = graph
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_complexexample1_nonzerobatchdim(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 3, 4]), 'value': np.array([i for i in range(24)]).reshape([2, 3, 4])},
- 'indices_input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 0]).reshape([2, 1])},
- 'gathernd': {'batch_dims': 1}
- },
- nodes_with_edges_only=True)
- graph_ref = graph
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_complexexample2(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([2, 3, 4]), 'value': np.array([i for i in range(24)]).reshape([2, 3, 4])},
- 'indices_input_data': {'shape': np.array([2, 1]), 'value': np.array([1, 0]).reshape([2, 1])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([2, 3, 4]), 'value': np.array([i for i in range(24)]).reshape([2, 3, 4])},
- 'indices': {'shape': np.array([2]), 'value': np.array([1, 0]).reshape([2])},
- 'reshape_shape': {'shape': np.array([3]), 'value': np.array([-1, 3, 4])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_complexexample3(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([1, 1, 5]), 'value': np.array([1, 2, 3, 4, 5]).reshape([1, 1, 5])},
- 'indices_input_data': {'shape': np.array([2, 2, 3]), 'value': np.array([0, 0, 3, 0, 0, 1, 0, 0, 4, 0, 0, 2]).reshape([2, 2, 3])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([1, 1, 5]), 'value': np.array([1, 2, 3, 4, 5]).reshape([1, 1, 5])},
- 'indices': {'shape': np.array([2, 2]), 'value': np.array([3, 1, 4, 2]).reshape([2, 2])},
- 'reshape_shape': {'shape': np.array([1]), 'value': np.array([-1])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_complexexample4(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([1, 4, 1]), 'value': np.array([1, 2, 3, 4]).reshape([1, 4, 1])},
- 'indices_input_data': {'shape': np.array([2, 2, 2]), 'value': np.array([0, 1, 0, 3, 0, 2, 0, 0]).reshape([2, 2, 2])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = build_graph(nodes_expected,
- edges_expected,
- update_attributes={
- 'input_data': {'shape': np.array([1, 4, 1]), 'value': np.array([1, 2, 3, 4]).reshape([1, 4, 1])},
- 'indices': {'shape': np.array([2, 2]), 'value': np.array([1, 3, 2, 0]).reshape([2, 2])},
- 'reshape_shape': {'shape': np.array([2]), 'value': np.array([-1, 1])},
- 'axis': {'shape': np.array([]), 'value': 0}
- },
- nodes_with_edges_only=True)
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_dynamic_data_shape(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([1, -1, 1]), 'value': np.array([1, 2, 3, 4]).reshape([1, 4, 1])},
- 'indices_input_data': {'shape': np.array([2, 2, 2]), 'value': np.array([0, 1, 0, 3, 0, 2, 0, 0]).reshape([2, 2, 2])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = graph
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_GatherNDDecomposition_dynamic_indices_shape(self):
-
- graph = build_graph(nodes,
- edges,
- update_attributes={
- 'input_data': {'shape': np.array([1, 4, 1]), 'value': np.array([1, 2, 3, 4]).reshape([1, 4, 1])},
- 'indices_input_data': {'shape': np.array([2, -1, 2]), 'value': np.array([0, 1, 0, 3, 0, 2, 0, 0]).reshape([2, 2, 2])},
- 'gathernd': {'batch_dims': 0}
- },
- nodes_with_edges_only=True)
- graph_ref = graph
-
- GatherNDDecomposition().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(
- graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/GroupNorm_test.py b/tools/mo/unit_tests/mo/middle/GroupNorm_test.py
deleted file mode 100644
index 905289e06b61dd..00000000000000
--- a/tools/mo/unit_tests/mo/middle/GroupNorm_test.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.GroupNorm import GroupNormToMVN
-from openvino.tools.mo.front.common.partial_infer.utils import float_array, int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, \
- regular_op_with_shaped_data, valued_const_with_data
-
-shape = int64_array([1, 3, 5, 2])
-nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('gamma', float_array([0.5])),
- **valued_const_with_data('beta', float_array([0.5])),
- **regular_op_with_shaped_data('group_norm', shape,
- {'op': 'GroupNorm', 'name': 'group_norm', 'num_groups': 3, 'eps': 1e-9}),
- **result('result')
- }
-
-edges = [*connect('input:0', '0:group_norm'),
- *connect('gamma', '1:group_norm'),
- *connect('beta', '2:group_norm'),
- *connect('group_norm:0', 'result'),
- ]
-
-ref_nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('shape1', int64_array([4]), {'op': 'ShapeOf'}),
- **regular_op_with_shaped_data('shape2', int64_array([4]), {'op': 'ShapeOf'}),
- **regular_op_with_shaped_data('shape3', int64_array([1]), {'op': 'ShapeOf'}),
- **regular_op_with_shaped_data('hcast1', int64_array([4]), {'op': 'Cast'}),
- **regular_op_with_shaped_data('cast2', int64_array([2]), {'op': 'Cast'}),
- **regular_op_with_shaped_data('cast3', int64_array([4]), {'op': 'Cast'}),
- **regular_op_with_shaped_data('gather1', int64_array([2]), {'op': 'Gather'}),
- **regular_op_with_shaped_data('gather2', int64_array([1]), {'op': 'Gather'}),
- **regular_op_with_shaped_data('gather3', int64_array([1]), {'op': 'Gather'}),
- **regular_op_with_shaped_data('mul1', int64_array([1]), {'op': 'Mul'}),
- **regular_op_with_shaped_data('mul2', int64_array([1]), {'op': 'Mul'}),
- **regular_op_with_shaped_data('mul3', shape, {'op': 'Mul'}),
- **regular_op_with_shaped_data('concat', int64_array([4]), {'op': 'Concat'}),
- **regular_op_with_shaped_data('reshape1', int64_array([3, 1, 5, 2]), {'op': 'Reshape'}),
- **regular_op_with_shaped_data('reshape2', shape, {'op': 'Reshape'}),
- **regular_op_with_shaped_data('squeeze', int64_array([]), {'op': 'Squeeze'}),
- **regular_op_with_shaped_data('range', int64_array([3]), {'op': 'Range'}),
- **regular_op_with_shaped_data('mvn', int64_array([3, 1, 5, 2]), {'op': 'MVN'}),
- **regular_op_with_shaped_data('add', shape, {'op': 'Add'}),
- **valued_const_with_data('shape/axis1', int64_array(0)),
- **valued_const_with_data('shape/ind1', int64_array([2, 3])),
- **valued_const_with_data('shape/axis2', int64_array(0)),
- **valued_const_with_data('shape/ind2', int64_array([0])),
- **valued_const_with_data('shape/axis3', int64_array(0)),
- **valued_const_with_data('shape/ind3', int64_array([1])),
- **valued_const_with_data('gn/rec', float_array([1./3])),
- **valued_const_with_data('group', int64_array([3])),
- **valued_const_with_data('squeeze/axis', int64_array([0])),
- **valued_const_with_data('range/start', int64_array(1)),
- **valued_const_with_data('range/step', int64_array(1)),
- **valued_const_with_data('gamma', float_array([[[[0.5]]]])),
- **valued_const_with_data('beta', float_array([[[[0.5]]]])),
- **result('result')
- }
-ref_edges = [*connect('input', '0:reshape1'),
- *connect('input', 'shape1', skip_data=True),
- *connect('shape1:0', '0:gather1'),
- *connect('shape1:0', 'hcast1', skip_data=True),
- *connect('shape/ind1', '1:gather1'),
- *connect('shape/axis1', '2:gather1'),
- *connect('gather1', 'cast2'),
- *connect('hcast1', '0:gather3'),
- *connect('hcast1', '0:gather2', skip_data=True),
- *connect('shape/ind2', '1:gather2'),
- *connect('shape/axis2', '2:gather2'),
- *connect('gather2', '0:mul2'),
- *connect('group', '1:mul2'),
- *connect('shape/ind3', '1:gather3'),
- *connect('shape/axis3', '2:gather3'),
- *connect('gather3', '0:mul1'),
- *connect('gn/rec', '1:mul1'),
- *connect('mul2', '0:concat'),
- *connect('mul1', '1:concat'),
- *connect('cast2', '2:concat'),
- *connect('concat', 'cast3'),
- *connect('cast3', '1:reshape1'),
- *connect('reshape1', 'shape2'),
- *connect('shape2', 'shape3'),
- *connect('shape3', '0:squeeze'),
- *connect('squeeze/axis', '1:squeeze'),
- *connect('range/start', '0:range'),
- *connect('squeeze', '1:range'),
- *connect('range/step', '2:range'),
- *connect('reshape1', '0:mvn', skip_data=True),
- *connect('range', '1:mvn'),
- *connect('mvn', '0:reshape2'),
- *connect('shape1:0', '1:reshape2', skip_data=True),
- *connect('reshape2', '0:mul3'),
- *connect('gamma', '1:mul3'),
- *connect('mul3', '0:add'),
- *connect('beta', '1:add'),
- *connect('add', 'result')
- ]
-
-
-class GroupNormToMVNTest(unittest.TestCase):
- def test_group_norm_1(self):
- graph = build_graph(nodes, edges)
-
- graph_ref = build_graph(ref_nodes, ref_edges)
-
- graph.graph['layout'] = 'NCHW'
-
- GroupNormToMVN().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/InsertSelect_test.py b/tools/mo/unit_tests/mo/middle/InsertSelect_test.py
deleted file mode 100644
index 31f1ffd5cf167b..00000000000000
--- a/tools/mo/unit_tests/mo/middle/InsertSelect_test.py
+++ /dev/null
@@ -1,446 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.InsertSelect import AddSelectBeforeMemoryNodePattern
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class InsertSelectTests(unittest.TestCase):
-
- # graph have no splices - selects should not be inserted
- def test_insert_select_0(self):
- graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'memory': {'kind': 'op', 'op': 'Assign'},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'memory')
- ],
- nodes_with_edges_only=True)
- ref_graph = graph.copy()
- AddSelectBeforeMemoryNodePattern().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'memory')
- self.assertTrue(flag, resp)
-
- # graph contains 1 splice with context length 5, should be inserted select with memory as counter with length 5
- def test_insert_select_1(self):
- graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': np.array([-2, -1, 0, 1, 2])},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'placeholder_2': {'kind': 'op', 'op': None},
- 'placeholder_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'memory': {'kind': 'op', 'op': 'Assign', 'index': 0},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'splice_1'), ('splice_1', 'splice_data_1'),
- ('splice_data_1', 'placeholder_2'), ('placeholder_2', 'placeholder_data_2'),
- ('placeholder_data_2', 'memory')
- ],
- nodes_with_edges_only=True)
- AddSelectBeforeMemoryNodePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': np.array([-2, -1, 0, 1, 2])},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'placeholder_2': {'kind': 'op', 'op': None},
-
- 'second_dim_mem_1': {'kind': 'op', 'op': 'Const', 'value': int64_array([5])},
- 'second_dim_data_mem_1': {'kind': 'data'},
- 'gather_shape_mem_1': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data_mem_1': {'kind': 'data'},
- 'fill_value': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data': {'kind': 'data'},
- 'broadcast_mem_1': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data_mem_1': {'kind': 'data'},
-
- 'shape': {'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data'},
- 'crop_batch': {'kind': 'op', 'op': 'Crop', 'offset': int64_array([0])},
- 'crop_batch_data': {'kind': 'data'},
- 'crop_batch_dim': {'kind': 'op', 'op': 'Const', 'value': int64_array([1])},
- 'crop_batch_dim_data': {'kind': 'data'},
- 'second_dim': {'kind': 'op', 'op': 'Const', 'value': int64_array([5])},
- 'second_dim_data': {'kind': 'data'},
- 'gather_shape': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data': {'kind': 'data'},
- 'fill_value_ones': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data_ones': {'kind': 'data'},
- 'broadcast': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data': {'kind': 'data'},
-
- 'second_dim_mem_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([26])},
- 'second_dim_data_mem_2': {'kind': 'data'},
- 'gather_shape_mem_2': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data_mem_2': {'kind': 'data'},
- 'fill_value_ones_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data_ones_2': {'kind': 'data'},
- 'broadcast_mem_2': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data_mem_2': {'kind': 'data'},
-
- 'memory_in': {'kind': 'op', 'op': 'ReadValue', 'shape': int64_array([5])},
- 'memory_in_data': {'kind': 'data'},
- 'memory_out': {'kind': 'op', 'op': 'Assign', 'shape': int64_array([5])},
- 'memory_out_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result'},
- 'crop_in': {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 1, 'dim': 4},
- 'crop_in_data': {'kind': 'data'},
- 'crop_out': {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 0, 'dim': 1},
- 'crop_out_data': {'kind': 'data'},
- 'equal': {'kind': 'op', 'op': 'Equal'},
- 'equal_data': {'kind': 'data'},
- 'select': {'kind': 'op', 'op': 'Select'},
- 'select_out_data': {'kind': 'data', 'shape': [1, 26]},
- 'const_0': {'kind': 'op', 'op': 'Const'},
- 'const_0_data': {'kind': 'data'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data'},
-
- 'placeholder_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'memory': {'kind': 'op', 'op': 'Assign'},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'splice_1'), ('splice_1', 'splice_data_1'),
- ('splice_data_1', 'placeholder_2'), ('placeholder_2', 'placeholder_data_2'),
- ('placeholder_data_2', 'select', {'in': 1}),
-
- ('second_dim_mem_1', 'second_dim_data_mem_1'),
- ('second_dim_data_mem_1', 'gather_shape_mem_1', {'in': 1}),
- ('crop_batch_data', 'gather_shape_mem_1', {'in': 0}),
- ('gather_shape_mem_1', 'gather_shape_data_mem_1'),
- ('fill_value', 'fill_value_data'),
- ('fill_value_data', 'broadcast_mem_1', {'in': 0}),
- ('gather_shape_data_mem_1', 'broadcast_mem_1', {'in': 1}),
- ('broadcast_mem_1', 'broadcast_data_mem_1'),
- ('broadcast_data_mem_1', 'memory_in'),
-
- ('memory_in', 'memory_in_data'), ('memory_in_data', 'crop_in'),
- ('crop_in', 'crop_in_data'), ('crop_in_data', 'concat', {'in': 0}),
-
- ('second_dim_mem_2', 'second_dim_data_mem_2'),
- ('second_dim_data_mem_2', 'gather_shape_mem_2', {'in': 1}),
- ('crop_batch_data', 'gather_shape_mem_2', {'in': 0}),
- ('gather_shape_mem_2', 'gather_shape_data_mem_2'),
- ('fill_value_ones_2', 'fill_value_data_ones_2'),
- ('fill_value_data_ones_2', 'broadcast_mem_2', {'in': 0}),
- ('gather_shape_data_mem_2', 'broadcast_mem_2', {'in': 1}),
- ('broadcast_mem_2', 'broadcast_data_mem_2'),
- ('broadcast_data_mem_2', 'concat', {'in': 1}),
-
- ('concat', 'concat_data'), ('concat_data', 'memory_out'),
- ('memory_out', 'memory_out_data'), ('memory_out_data', 'result'),
- ('concat_data', 'crop_out'), ('crop_out', 'crop_out_data'),
- ('crop_out_data', 'equal', {'in': 1}), ('broadcast_data_mem_2', 'equal', {'in': 0}),
- ('equal', 'equal_data'),
- ('equal_data', 'select', {'in': 0}),
-
- ('placeholder_data_2', 'shape'), ('shape', 'shape_data'),
- ('shape_data', 'crop_batch'), ('crop_batch', 'crop_batch_data'),
- ('crop_batch_dim', 'crop_batch_dim_data'),
- ('crop_batch_dim_data', 'crop_batch', {'in': 1}),
- ('second_dim', 'second_dim_data'), ('second_dim_data', 'gather_shape', {'in': 1}),
- ('crop_batch_data', 'gather_shape', {'in': 0}), ('gather_shape', 'gather_shape_data'),
- ('fill_value_ones', 'fill_value_data_ones'),
- ('fill_value_data_ones', 'broadcast', {'in': 0}),
- ('gather_shape_data', 'broadcast', {'in': 1}), ('broadcast', 'broadcast_data'),
- ('broadcast_data', 'select', {'in': 2}),
-
- ('select', 'select_out_data'),
- ('select_out_data', 'memory')
- ],
- nodes_with_edges_only=True
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'memory')
- self.assertTrue(flag, resp)
-
- # graph contains 1 splice with context length 5 on the path to memory and 1 out of path,
- # should be inserted select with memory as counter with length 5
- def test_insert_select_2(self):
- graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': np.array([-2, -1, 0, 1, 2])},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 65]},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': np.array([-1, 0, 1])},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'placeholder_2': {'kind': 'op', 'op': None},
- 'placeholder_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'memory': {'kind': 'op', 'op': 'Assign'},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'splice_1'), ('splice_1', 'splice_data_1'),
- ('placeholder_data_1', 'splice_2'), ('splice_2', 'splice_data_2'),
- ('splice_data_1', 'placeholder_2'), ('placeholder_2', 'placeholder_data_2'),
- ('placeholder_data_2', 'memory')
- ],
- nodes_with_edges_only=True)
- AddSelectBeforeMemoryNodePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': np.array([-2, -1, 0, 1, 2])},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 65]},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': np.array([-1, 0, 1])},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'placeholder_2': {'kind': 'op', 'op': None},
-
- 'second_dim_mem_1': {'kind': 'op', 'op': 'Const', 'value': int64_array([5])},
- 'second_dim_data_mem_1': {'kind': 'data'},
- 'gather_shape_mem_1': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data_mem_1': {'kind': 'data'},
- 'fill_value': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data': {'kind': 'data'},
- 'broadcast_mem_1': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data_mem_1': {'kind': 'data'},
-
- 'shape': {'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data'},
- 'crop_batch': {'kind': 'op', 'op': 'Crop', 'offset': int64_array([0])},
- 'crop_batch_data': {'kind': 'data'},
- 'crop_batch_dim': {'kind': 'op', 'op': 'Const', 'value': int64_array([1])},
- 'crop_batch_dim_data': {'kind': 'data'},
- 'second_dim': {'kind': 'op', 'op': 'Const', 'value': int64_array([5])},
- 'second_dim_data': {'kind': 'data'},
- 'gather_shape': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data': {'kind': 'data'},
- 'fill_value_ones': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data_ones': {'kind': 'data'},
- 'broadcast': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data': {'kind': 'data'},
-
- 'second_dim_mem_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([26])},
- 'second_dim_data_mem_2': {'kind': 'data'},
- 'gather_shape_mem_2': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data_mem_2': {'kind': 'data'},
- 'fill_value_ones_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data_ones_2': {'kind': 'data'},
- 'broadcast_mem_2': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data_mem_2': {'kind': 'data'},
-
- 'memory_in': {'kind': 'op', 'op': 'ReadValue', 'shape': int64_array([5])},
- 'memory_in_data': {'kind': 'data'},
- 'memory_out': {'kind': 'op', 'op': 'Assign', 'shape': int64_array([5])},
- 'memory_out_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result'},
- 'crop_in': {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 1, 'dim': 4},
- 'crop_in_data': {'kind': 'data'},
- 'crop_out': {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 0, 'dim': 1},
- 'crop_out_data': {'kind': 'data'},
- 'equal': {'kind': 'op', 'op': 'Equal'},
- 'equal_data': {'kind': 'data'},
- 'select': {'kind': 'op', 'op': 'Select'},
- 'select_out_data': {'kind': 'data', 'shape': [1, 26]},
- 'const_0': {'kind': 'op', 'op': 'Const'},
- 'const_0_data': {'kind': 'data'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data'},
-
- 'placeholder_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'memory': {'kind': 'op', 'op': 'Assign'},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'splice_1'), ('splice_1', 'splice_data_1'),
- ('placeholder_data_1', 'splice_2'), ('splice_2', 'splice_data_2'),
- ('splice_data_1', 'placeholder_2'), ('placeholder_2', 'placeholder_data_2'),
- ('placeholder_data_2', 'select', {'in': 1}),
-
- ('second_dim_mem_1', 'second_dim_data_mem_1'),
- ('second_dim_data_mem_1', 'gather_shape_mem_1', {'in': 1}),
- ('crop_batch_data', 'gather_shape_mem_1', {'in': 0}),
- ('gather_shape_mem_1', 'gather_shape_data_mem_1'),
- ('fill_value', 'fill_value_data'),
- ('fill_value_data', 'broadcast_mem_1', {'in': 0}),
- ('gather_shape_data_mem_1', 'broadcast_mem_1', {'in': 1}),
- ('broadcast_mem_1', 'broadcast_data_mem_1'),
- ('broadcast_data_mem_1', 'memory_in'),
-
- ('memory_in', 'memory_in_data'), ('memory_in_data', 'crop_in'),
- ('crop_in', 'crop_in_data'), ('crop_in_data', 'concat', {'in': 0}),
-
- ('second_dim_mem_2', 'second_dim_data_mem_2'),
- ('second_dim_data_mem_2', 'gather_shape_mem_2', {'in': 1}),
- ('crop_batch_data', 'gather_shape_mem_2', {'in': 0}),
- ('gather_shape_mem_2', 'gather_shape_data_mem_2'),
- ('fill_value_ones_2', 'fill_value_data_ones_2'),
- ('fill_value_data_ones_2', 'broadcast_mem_2', {'in': 0}),
- ('gather_shape_data_mem_2', 'broadcast_mem_2', {'in': 1}),
- ('broadcast_mem_2', 'broadcast_data_mem_2'),
- ('broadcast_data_mem_2', 'concat', {'in': 1}),
-
- ('concat', 'concat_data'), ('concat_data', 'memory_out'),
- ('memory_out', 'memory_out_data'), ('memory_out_data', 'result'),
- ('concat_data', 'crop_out'), ('crop_out', 'crop_out_data'),
- ('crop_out_data', 'equal', {'in': 1}), ('broadcast_data_mem_2', 'equal', {'in': 0}),
- ('equal', 'equal_data'),
- ('equal_data', 'select', {'in': 0}),
-
- ('placeholder_data_2', 'shape'), ('shape', 'shape_data'),
- ('shape_data', 'crop_batch'), ('crop_batch', 'crop_batch_data'),
- ('crop_batch_dim', 'crop_batch_dim_data'),
- ('crop_batch_dim_data', 'crop_batch', {'in': 1}),
- ('second_dim', 'second_dim_data'), ('second_dim_data', 'gather_shape', {'in': 1}),
- ('crop_batch_data', 'gather_shape', {'in': 0}), ('gather_shape', 'gather_shape_data'),
- ('fill_value_ones', 'fill_value_data_ones'),
- ('fill_value_data_ones', 'broadcast', {'in': 0}),
- ('gather_shape_data', 'broadcast', {'in': 1}), ('broadcast', 'broadcast_data'),
- ('broadcast_data', 'select', {'in': 2}),
-
- ('select', 'select_out_data'),
- ('select_out_data', 'memory')
- ],
- nodes_with_edges_only=True
- )
- (flag, resp) = compare_graphs(graph, ref_graph, 'memory')
- self.assertTrue(flag, resp)
-
- # graph contains 2 splices with sum context length 8 on the path to memory,
- # should be inserted select with memory as counter with length 7
- def test_insert_select_3(self):
- graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': np.array([-2, -1, 0, 1, 2])},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 65]},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': np.array([-1, 0, 1])},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'placeholder_2': {'kind': 'op', 'op': None},
- 'placeholder_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'memory': {'kind': 'op', 'op': 'Assign', 'index': 0},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'splice_1'), ('splice_1', 'splice_data_1'),
- ('splice_data_1', 'splice_2'), ('splice_2', 'splice_data_2'),
- ('splice_data_2', 'placeholder_2'), ('placeholder_2', 'placeholder_data_2'),
- ('placeholder_data_2', 'memory')
- ],
- nodes_with_edges_only=True)
- AddSelectBeforeMemoryNodePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({
- 'input': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data_1': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': np.array([-2, -1, 0, 1, 2])},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 65]},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': np.array([-1, 0, 1])},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'placeholder_2': {'kind': 'op', 'op': None},
-
- 'second_dim_mem_1': {'kind': 'op', 'op': 'Const', 'value': int64_array([5])},
- 'second_dim_data_mem_1': {'kind': 'data'},
- 'gather_shape_mem_1': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data_mem_1': {'kind': 'data'},
- 'fill_value': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data': {'kind': 'data'},
- 'broadcast_mem_1': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data_mem_1': {'kind': 'data'},
-
- 'shape': {'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data'},
- 'crop_batch': {'kind': 'op', 'op': 'Crop', 'offset': int64_array([0])},
- 'crop_batch_data': {'kind': 'data'},
- 'crop_batch_dim': {'kind': 'op', 'op': 'Const', 'value': int64_array([1])},
- 'crop_batch_dim_data': {'kind': 'data'},
- 'second_dim': {'kind': 'op', 'op': 'Const', 'value': int64_array([5])},
- 'second_dim_data': {'kind': 'data'},
- 'gather_shape': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data': {'kind': 'data'},
- 'fill_value_ones': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data_ones': {'kind': 'data'},
- 'broadcast': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data': {'kind': 'data'},
-
- 'second_dim_mem_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([26])},
- 'second_dim_data_mem_2': {'kind': 'data'},
- 'gather_shape_mem_2': {'kind': 'op', 'op': 'Concat'},
- 'gather_shape_data_mem_2': {'kind': 'data'},
- 'fill_value_ones_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data_ones_2': {'kind': 'data'},
- 'broadcast_mem_2': {'kind': 'op', 'op': 'Broadcast'},
- 'broadcast_data_mem_2': {'kind': 'data'},
-
- 'memory_in': {'kind': 'op', 'op': 'ReadValue', 'shape': int64_array([5])},
- 'memory_in_data': {'kind': 'data'},
- 'memory_out': {'kind': 'op', 'op': 'Assign', 'shape': int64_array([5])},
- 'memory_out_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result'},
- 'crop_in': {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 1, 'dim': 4},
- 'crop_in_data': {'kind': 'data'},
- 'crop_out': {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 0, 'dim': 1},
- 'crop_out_data': {'kind': 'data'},
- 'equal': {'kind': 'op', 'op': 'Equal'},
- 'equal_data': {'kind': 'data'},
- 'select': {'kind': 'op', 'op': 'Select'},
- 'select_out_data': {'kind': 'data', 'shape': [1, 26]},
- 'const_0': {'kind': 'op', 'op': 'Const'},
- 'const_0_data': {'kind': 'data'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data'},
-
- 'placeholder_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'memory': {'kind': 'op', 'op': 'Assign', 'index': 0},
- },
- [('input', 'placeholder_data_1'),
- ('placeholder_data_1', 'splice_1'), ('splice_1', 'splice_data_1'),
- ('splice_data_1', 'splice_2'), ('splice_2', 'splice_data_2'),
- ('splice_data_2', 'placeholder_2'), ('placeholder_2', 'placeholder_data_2'),
- ('placeholder_data_2', 'select', {'in': 1}),
-
- ('second_dim_mem_1', 'second_dim_data_mem_1'),
- ('second_dim_data_mem_1', 'gather_shape_mem_1', {'in': 1}),
- ('crop_batch_data', 'gather_shape_mem_1', {'in': 0}),
- ('gather_shape_mem_1', 'gather_shape_data_mem_1'),
- ('fill_value', 'fill_value_data'),
- ('fill_value_data', 'broadcast_mem_1', {'in': 0}),
- ('gather_shape_data_mem_1', 'broadcast_mem_1', {'in': 1}),
- ('broadcast_mem_1', 'broadcast_data_mem_1'),
- ('broadcast_data_mem_1', 'memory_in'),
-
- ('memory_in', 'memory_in_data'), ('memory_in_data', 'crop_in'),
- ('crop_in', 'crop_in_data'), ('crop_in_data', 'concat', {'in': 0}),
-
- ('second_dim_mem_2', 'second_dim_data_mem_2'),
- ('second_dim_data_mem_2', 'gather_shape_mem_2', {'in': 1}),
- ('crop_batch_data', 'gather_shape_mem_2', {'in': 0}),
- ('gather_shape_mem_2', 'gather_shape_data_mem_2'),
- ('fill_value_ones_2', 'fill_value_data_ones_2'),
- ('fill_value_data_ones_2', 'broadcast_mem_2', {'in': 0}),
- ('gather_shape_data_mem_2', 'broadcast_mem_2', {'in': 1}),
- ('broadcast_mem_2', 'broadcast_data_mem_2'),
- ('broadcast_data_mem_2', 'concat', {'in': 1}),
-
- ('concat', 'concat_data'), ('concat_data', 'memory_out'),
- ('memory_out', 'memory_out_data'), ('memory_out_data', 'result'),
- ('concat_data', 'crop_out'), ('crop_out', 'crop_out_data'),
- ('crop_out_data', 'equal', {'in': 1}), ('broadcast_data_mem_2', 'equal', {'in': 0}),
- ('equal', 'equal_data'),
- ('equal_data', 'select', {'in': 0}),
-
- ('placeholder_data_2', 'shape'), ('shape', 'shape_data'),
- ('shape_data', 'crop_batch'), ('crop_batch', 'crop_batch_data'),
- ('crop_batch_dim', 'crop_batch_dim_data'),
- ('crop_batch_dim_data', 'crop_batch', {'in': 1}),
- ('second_dim', 'second_dim_data'), ('second_dim_data', 'gather_shape', {'in': 1}),
- ('crop_batch_data', 'gather_shape', {'in': 0}), ('gather_shape', 'gather_shape_data'),
- ('fill_value_ones', 'fill_value_data_ones'),
- ('fill_value_data_ones', 'broadcast', {'in': 0}),
- ('gather_shape_data', 'broadcast', {'in': 1}), ('broadcast', 'broadcast_data'),
- ('broadcast_data', 'select', {'in': 2}),
-
- ('select', 'select_out_data'),
- ('select_out_data', 'memory')
- ],
- nodes_with_edges_only=True
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'memory')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/InterpolateSequenceToInterpolate_test.py b/tools/mo/unit_tests/mo/middle/InterpolateSequenceToInterpolate_test.py
deleted file mode 100644
index 6eebb89c1ee2bb..00000000000000
--- a/tools/mo/unit_tests/mo/middle/InterpolateSequenceToInterpolate_test.py
+++ /dev/null
@@ -1,1584 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import unittest
-
-from openvino.tools.mo.middle.InterpolateSequenceToInterpolate import InterpolateSequenceToInterpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-graph_node_attrs_for_2d_case_1_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([660])
- },
- 'size_1_data': {'value': int64_array([660]), 'shape': [1], 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([3.0])
- },
- 'scale_1_data': {'value': np.array([3.0]), 'shape': [1], 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2])
- },
- 'axes_1_data': {'value': int64_array([2]), 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 660, 350]), 'kind': 'data'},
- 'size_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([700])
- },
- 'size_2_data': {'value': int64_array([700]), 'shape': [1], 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([2.0])
- },
- 'scale_2_data': {'value': np.array([2.0]), 'shape': [1], 'kind': 'data'},
- 'axes_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([3])
- },
- 'axes_2_data': {'value': int64_array([3]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 660, 700]), 'kind': 'data'},
- 'size_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1320])
- },
- 'size_3_data': {'value': int64_array([1320]), 'shape': [1], 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([2.0])
- },
- 'scale_3_data': {'value': np.array([2.0]), 'shape': [1], 'kind': 'data'},
- 'axes_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2])
- },
- 'axes_3_data': {'value': int64_array([2]), 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_1_opset4_case = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('size_1', 'size_1_data'),
- ('scale_1', 'scale_1_data'),
- ('axes_1', 'axes_1_data'),
- ('size_1_data', 'interpolate_1', {'in': 1}),
- ('scale_1_data', 'interpolate_1', {'in': 2}),
- ('axes_1_data', 'interpolate_1', {'in': 3}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('size_2', 'size_2_data'),
- ('scale_2', 'scale_2_data'),
- ('axes_2', 'axes_2_data'),
- ('size_2_data', 'interpolate_2', {'in': 1}),
- ('scale_2_data', 'interpolate_2', {'in': 2}),
- ('axes_2_data', 'interpolate_2', {'in': 3}),
- ('interpolate_2', 'interpolate_2_data'),
-
- ('interpolate_2_data', 'interpolate_3', {'in': 0}),
- ('size_3', 'size_3_data'),
- ('scale_3', 'scale_3_data'),
- ('axes_3', 'axes_3_data'),
- ('size_3_data', 'interpolate_3', {'in': 1}),
- ('scale_3_data', 'interpolate_3', {'in': 2}),
- ('axes_3_data', 'interpolate_3', {'in': 3}),
- ('interpolate_3', 'interpolate_3_data'),
-
- ('interpolate_3_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-ref_graph_node_attrs_for_2d_case_1_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([660, 700])
- },
- 'size_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([3.0, 2.0])
- },
- 'scale_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2, 3])
- },
- 'axes_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'scales',
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 660, 700]), 'kind': 'data'},
- 'size_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1320])
- },
- 'size_3_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([2.0])
- },
- 'scale_3_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'axes_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2])
- },
- 'axes_3_data': {'value': int64_array([2]), 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-ref_edges_for_2d_case_1_opset4_case = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('size_1', 'size_1_data'),
- ('scale_1', 'scale_1_data'),
- ('axes_1', 'axes_1_data'),
- ('size_1_data', 'interpolate_1', {'in': 1}),
- ('scale_1_data', 'interpolate_1', {'in': 2}),
- ('axes_1_data', 'interpolate_1', {'in': 3}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'interpolate_3', {'in': 0}),
- ('size_3', 'size_3_data'),
- ('scale_3', 'scale_3_data'),
- ('axes_3', 'axes_3_data'),
- ('size_3_data', 'interpolate_3', {'in': 1}),
- ('scale_3_data', 'interpolate_3', {'in': 2}),
- ('axes_3_data', 'interpolate_3', {'in': 3}),
- ('interpolate_3', 'interpolate_3_data'),
-
- ('interpolate_3_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_for_2d_case_1 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([660])
- },
- 'scale_1_data': {'value': int64_array([660]), 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 660, 350]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([700])
- },
- 'scale_2_data': {'value': int64_array([700]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 660, 700]), 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1320])
- },
- 'scale_3_data': {'value': int64_array([1320]), 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_1 = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 1}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('scale_2', 'scale_2_data'),
- ('scale_2_data', 'interpolate_2', {'in': 1}),
- ('interpolate_2', 'interpolate_2_data'),
-
- ('interpolate_2_data', 'interpolate_3', {'in': 0}),
- ('scale_3', 'scale_3_data'),
- ('scale_3_data', 'interpolate_3', {'in': 1}),
- ('interpolate_3', 'interpolate_3_data'),
-
- ('interpolate_3_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_for_2d_case_2 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([660])
- },
- 'scale_1_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 660, 350]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 660, 350]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_2 = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 1}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_for_2d_case_3 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([660])
- },
- 'scale_1_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 660, 350]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([700])
- },
- 'scale_2_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'linear',
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 660, 700]), 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1320])
- },
- 'scale_3_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'cubic',
- 'version': 'opset1'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_3 = edges_for_2d_case_1
-
-
-new_graph_node_attrs_for_2d_case_4_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2200])
- },
- 'size_1_data': {'value': int64_array([2200]), 'shape': [1], 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([10.0])
- },
- 'scale_1_data': {'value': np.array([10.0]), 'shape': [1], 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2])
- },
- 'axes_1_data': {'value': int64_array([2]), 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'coordinate_transformation_mode': 'asymmetric',
- 'nearest_mode': 'simple',
- 'cube_coeff': -0.4,
- 'antialias': 1,
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 2200, 350]), 'kind': 'data'},
- 'size_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([700])
- },
- 'size_2_data': {'value': int64_array([700]), 'shape': [1], 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([2.0])
- },
- 'scale_2_data': {'value': np.array([2.0]), 'shape': [1], 'kind': 'data'},
- 'axes_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([3])
- },
- 'axes_2_data': {'value': int64_array([3]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'coordinate_transformation_mode': 'asymmetric',
- 'nearest_mode': 'simple',
- 'cube_coeff': -0.4,
- 'antialias': 1,
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-new_edges_for_2d_case_4_opset4_case = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('size_1', 'size_1_data'),
- ('size_1_data', 'interpolate_1', {'in': 1}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 2}),
- ('axes_1', 'axes_1_data'),
- ('axes_1_data', 'interpolate_1', {'in': 3}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('size_2', 'size_2_data'),
- ('size_2_data', 'interpolate_2', {'in': 1}),
- ('scale_2', 'scale_2_data'),
- ('scale_2_data', 'interpolate_2', {'in': 2}),
- ('axes_2', 'axes_2_data'),
- ('axes_2_data', 'interpolate_2', {'in': 3}),
- ('interpolate_2', 'interpolate_2_data'),
-
- ('interpolate_2_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-new_ref_graph_node_attrs_for_2d_case_4_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2200, 700])
- },
- 'size_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([10.0, 2.0])
- },
- 'scale_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2, 3])
- },
- 'axes_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'coordinate_transformation_mode': 'asymmetric',
- 'nearest_mode': 'simple',
- 'cube_coeff': -0.4,
- 'antialias': 1,
- 'shape_calculation_mode': 'scales',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-new_ref_edges_for_2d_case_4_opset4_case = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('size_1', 'size_1_data'),
- ('size_1_data', 'interpolate_1', {'in': 1}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 2}),
- ('axes_1', 'axes_1_data'),
- ('axes_1_data', 'interpolate_1', {'in': 3}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_for_2d_case_4_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2200])
- },
- 'scale_1_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2])
- },
- 'axes_1_data': {'value': int64_array([2]), 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'coordinate_transformation_mode': 'asymmetric',
- 'nearest_mode': 'simple',
- 'cube_coeff': -0.4,
- 'antialias': 1,
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 2200, 350]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([700])
- },
- 'scale_2_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'axes_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([3])
- },
- 'axes_2_data': {'value': int64_array([3]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'coordinate_transformation_mode': 'asymmetric',
- 'nearest_mode': 'simple',
- 'cube_coeff': -0.4,
- 'antialias': 1,
- 'version': 'opset4'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_4_opset4_case = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 1}),
- ('axes_1', 'axes_1_data'),
- ('axes_1_data', 'interpolate_1', {'in': 2}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('scale_2', 'scale_2_data'),
- ('scale_2_data', 'interpolate_2', {'in': 1}),
- ('axes_2', 'axes_2_data'),
- ('axes_2_data', 'interpolate_2', {'in': 2}),
- ('interpolate_2', 'interpolate_2_data'),
-
- ('interpolate_2_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_for_2d_case_4 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2200])
- },
- 'scale_1_data': {'value': int64_array([2200]), 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 2200, 350]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([700])
- },
- 'scale_2_data': {'value': int64_array([700]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_4 = [
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 1}),
- ('interpolate_1', 'interpolate_1_data'),
-
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('scale_2', 'scale_2_data'),
- ('scale_2_data', 'interpolate_2', {'in': 1}),
- ('interpolate_2', 'interpolate_2_data'),
-
- ('interpolate_2_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_for_2d_case_6 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([220, 350])
- },
- 'scale_1_data': {'value': None, 'shape': [2], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 3]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 220, 350]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([220])
- },
- 'scale_2_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 220, 350]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 220, 350]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_2d_case_6 = edges_for_2d_case_4
-
-
-new_ref_graph_node_attrs_for_3d_case_1_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 5, 1024, 256, 800]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4096, 1280, 2400])
- },
- 'size_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([4.0, 5.0, 3.0])
- },
- 'scale_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2, 3, 4])
- },
- 'axes_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 2400]), 'kind': 'data'},
- 'size_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([512])
- },
- 'size_3_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([512.0 / 2400.0])
- },
- 'scale_3_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'axes_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4])
- },
- 'axes_3_data': {'value': int64_array([4]), 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-new_ref_edges_for_3d_case_1_opset4_case = ref_edges_for_2d_case_1_opset4_case
-
-
-new_graph_node_attrs_for_3d_case_1_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 5, 1024, 256, 800]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4096, 2400])
- },
- 'size_1_data': {'value': int64_array([4096, 2400]), 'shape': [2], 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([4.0, 3.0])
- },
- 'scale_1_data': {'value': np.array([4.0, 3.0]), 'shape': [2], 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2, 4])
- },
- 'axes_1_data': {'value': int64_array([2, 4]), 'shape': [2], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 5, 4096, 256, 2400]), 'kind': 'data'},
- 'size_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1280])
- },
- 'size_2_data': {'value': int64_array([1280]), 'shape': [1], 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([5.0])
- },
- 'scale_2_data': {'value': np.array([5.0]), 'shape': [1], 'kind': 'data'},
- 'axes_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([3])
- },
- 'axes_2_data': {'value': int64_array([3]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 2400]), 'kind': 'data'},
- 'size_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([512])
- },
- 'size_3_data': {'value': int64_array([512]), 'shape': [1], 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([512.0 / 2400.0])
- },
- 'scale_3_data': {'value': np.array([512.0 / 2400.0]), 'shape': [1], 'kind': 'data'},
- 'axes_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4])
- },
- 'axes_3_data': {'value': int64_array([4]), 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-new_edges_for_3d_case_1_opset4_case = edges_for_2d_case_1_opset4_case
-
-
-graph_node_attrs_for_3d_case_1 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 5, 1024, 256, 800]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4096, 2400])
- },
- 'scale_1_data': {'value': int64_array([4096, 2400]), 'shape': [2], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 4]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 5, 4096, 256, 2400]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1280])
- },
- 'scale_2_data': {'value': int64_array([1280]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 2400]), 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([512])
- },
- 'scale_3_data': {'value': int64_array([512]), 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([4]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_3d_case_1 = edges_for_2d_case_1
-
-
-graph_node_attrs_for_3d_case_2 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 5, 1024, 256, 800]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4096, 1280])
- },
- 'scale_1_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 3]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 800]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 800]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_3d_case_2 = edges_for_2d_case_2
-
-
-graph_node_attrs_for_3d_case_3 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([16, 44, 512, 87, 790]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([256])
- },
- 'scale_1_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([16, 44, 256, 87, 790]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2370])
- },
- 'scale_2_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([4]),
- 'mode': 'linear',
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([16, 44, 256, 87, 2370]), 'kind': 'data'},
- 'scale_3': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([435])
- },
- 'scale_3_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_3': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'cubic',
- 'version': 'opset1'
- },
- 'interpolate_3_data': {'value': None, 'shape': int64_array([16, 44, 256, 435, 2370]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([16, 44, 256, 435, 2370]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_3d_case_3 = edges_for_2d_case_3
-
-
-new_ref_graph_node_attrs_for_3d_case_4_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([10, 64, 511, 416, 10240]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4599, 912, 133120])
- },
- 'size_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const',
- 'value': np.array([4599.0 / 511.0, 912.0 / 416.0, 133120.0 / 10240.0])
- },
- 'scale_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2, 3, 4])
- },
- 'axes_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'antialias': 1,
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-new_ref_edges_for_3d_case_4_opset4_case = new_ref_edges_for_2d_case_4_opset4_case
-
-
-new_graph_node_attrs_for_3d_case_4_opset4_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([10, 64, 511, 416, 10240]),
- 'kind': 'data',
- 'data_type': None
- },
- 'size_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4599, 133120])
- },
- 'size_1_data': {'value': int64_array([4599, 133120]), 'shape': [2], 'kind': 'data'},
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([4599.0 / 511.0, 133120.0 / 10240.0])
- },
- 'scale_1_data': {'value': np.array([4599.0 / 511.0, 133120.0 / 10240.0]), 'shape': [2], 'kind': 'data'},
- 'axes_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2, 4])
- },
- 'axes_1_data': {'value': int64_array([2, 4]), 'shape': [2], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'antialias': 1,
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([10, 64, 4599, 416, 133120]), 'kind': 'data'},
- 'size_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([912])
- },
- 'size_2_data': {'value': int64_array([912]), 'shape': [1], 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': np.array([912.0 / 416.0])
- },
- 'scale_2_data': {'value': np.array([912.0 / 416.0]), 'shape': [1], 'kind': 'data'},
- 'axes_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([3])
- },
- 'axes_2_data': {'value': int64_array([3]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'linear',
- 'antialias': 1,
- 'shape_calculation_mode': 'sizes',
- 'version': 'opset4'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-new_edges_for_3d_case_4_opset4_case = new_edges_for_2d_case_4_opset4_case
-
-
-graph_node_attrs_for_3d_case_4 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([10, 64, 511, 416, 10240]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4599, 133120])
- },
- 'scale_1_data': {'value': int64_array([4599, 133120]), 'shape': [2], 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 4]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([10, 64, 4599, 416, 133120]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([912])
- },
- 'scale_2_data': {'value': int64_array([912]), 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges_for_3d_case_4 = edges_for_2d_case_4
-
-
-class InterpolateSequenceToInterpolateTest(unittest.TestCase):
- def test_2d_interpolate_sequence_1(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_1,
- edges=edges_for_2d_case_1
- )
-
- ref_graph = build_graph(
- nodes_attrs={
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([660, 700])
- },
- 'scale_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 3]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 4, 660, 700]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1320])
- },
- 'scale_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 1320, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
- },
- edges=[
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 1}),
- ('interpolate_1', 'interpolate_1_data'),
- ('scale_2', 'scale_2_data'),
- ('interpolate_2', 'interpolate_2_data'),
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('scale_2_data', 'interpolate_2', {'in': 1}),
- ('interpolate_2_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
- ]
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_1_opset4_case(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_1_opset4_case,
- edges=edges_for_2d_case_1_opset4_case
- )
-
- ref_graph = build_graph(
- nodes_attrs=ref_graph_node_attrs_for_2d_case_1_opset4_case,
- edges=ref_edges_for_2d_case_1_opset4_case
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_2(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_2,
- edges=edges_for_2d_case_2
- )
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_2,
- edges=edges_for_2d_case_2
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_3(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_3,
- edges=edges_for_2d_case_3
- )
-
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_3,
- edges=edges_for_2d_case_3
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_4(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_4,
- edges=edges_for_2d_case_4
- )
-
- ref_graph = build_graph(
- nodes_attrs={
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 4, 220, 350]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2200, 700])
- },
- 'scale_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 3]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 4, 2200, 700]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
- },
- edges=[
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate', {'in': 0}),
- ('scale', 'scale_data'),
- ('scale_data', 'interpolate', {'in': 1}),
- ('interpolate', 'interpolate_data'),
-
- ('interpolate_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
- ]
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_4_opset4_case(self):
- graph = build_graph(
- nodes_attrs=new_graph_node_attrs_for_2d_case_4_opset4_case,
- edges=new_edges_for_2d_case_4_opset4_case
- )
-
- ref_graph = build_graph(
- nodes_attrs=new_ref_graph_node_attrs_for_2d_case_4_opset4_case,
- edges=new_ref_edges_for_2d_case_4_opset4_case
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_5(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_4,
- edges=edges_for_2d_case_4,
- update_attributes={
- 'interpolate_1': {
- 'align_corners': 1, 'antialias': 1, 'pads_begin': 3, 'pads_end': 0
- }
- }
- )
-
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_4,
- edges=edges_for_2d_case_4,
- update_attributes={
- 'interpolate_1': {
- 'align_corners': 1, 'antialias': 1, 'pads_begin': 3, 'pads_end': 0
- }
- }
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_5_opset4_case(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_4_opset4_case,
- edges=edges_for_2d_case_4_opset4_case,
- update_attributes={
- 'interpolate_1': {
- 'antialias': 0, 'cube_coeff': -0.1
- }
- }
- )
-
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_4_opset4_case,
- edges=edges_for_2d_case_4_opset4_case,
- update_attributes={
- 'interpolate_1': {
- 'antialias': 0, 'cube_coeff': -0.1
- }
- }
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d_interpolate_sequence_6(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_6,
- edges=edges_for_2d_case_6,
- )
-
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_case_6,
- edges=edges_for_2d_case_6
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_1(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_1,
- edges=edges_for_3d_case_1
- )
-
- ref_graph = build_graph(
- nodes_attrs={
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 5, 1024, 256, 800]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale_1': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4096, 1280, 2400])
- },
- 'scale_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate_1': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 3, 4]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_1_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 2400]), 'kind': 'data'},
- 'scale_2': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([512])
- },
- 'scale_2_data': {'value': None, 'shape': [1], 'kind': 'data'},
- 'interpolate_2': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([4]),
- 'mode': 'nearest',
- 'version': 'opset1'
- },
- 'interpolate_2_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 5, 4096, 1280, 512]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
- },
- edges=[
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'interpolate_1', {'in': 0}),
- ('scale_1', 'scale_1_data'),
- ('scale_1_data', 'interpolate_1', {'in': 1}),
- ('interpolate_1', 'interpolate_1_data'),
- ('scale_2', 'scale_2_data'),
- ('interpolate_2', 'interpolate_2_data'),
- ('interpolate_1_data', 'interpolate_2', {'in': 0}),
- ('scale_2_data', 'interpolate_2', {'in': 1}),
- ('interpolate_2_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
- ]
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_1_opset4_case(self):
- graph = build_graph(
- nodes_attrs=new_graph_node_attrs_for_3d_case_1_opset4_case,
- edges=new_edges_for_3d_case_1_opset4_case
- )
-
- ref_graph = build_graph(
- nodes_attrs=new_ref_graph_node_attrs_for_3d_case_1_opset4_case,
- edges=new_ref_edges_for_3d_case_1_opset4_case
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_2(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_2,
- edges=edges_for_3d_case_2
- )
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_2,
- edges=edges_for_3d_case_2
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_3(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_3,
- edges=edges_for_3d_case_3
- )
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_3,
- edges=edges_for_3d_case_3
- )
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_4(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_4,
- edges=edges_for_3d_case_4
- )
-
- ref_graph = build_graph(
- nodes_attrs={
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([10, 64, 511, 416, 10240]),
- 'kind': 'data',
- 'data_type': None
- },
- 'scale': {
- 'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4599, 912, 133120])
- },
- 'scale_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([2, 3, 4]),
- 'mode': 'linear',
- 'align_corners': 0,
- 'antialias': 1,
- 'pads_begin': 5,
- 'pads_end': 3,
- 'version': 'opset1'
- },
- 'interpolate_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([10, 64, 4599, 912, 133120]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
- },
- edges=[
- ('placeholder', 'placeholder_data'),
-
- ('placeholder_data', 'interpolate', {'in': 0}),
- ('scale', 'scale_data'),
- ('scale_data', 'interpolate', {'in': 1}),
- ('interpolate', 'interpolate_data'),
-
- ('interpolate_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
- ]
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_4_opset4_case(self):
- graph = build_graph(
- nodes_attrs=new_graph_node_attrs_for_3d_case_4_opset4_case,
- edges=new_edges_for_3d_case_4_opset4_case
- )
-
- ref_graph = build_graph(
- nodes_attrs=new_ref_graph_node_attrs_for_3d_case_4_opset4_case,
- edges=new_ref_edges_for_3d_case_4_opset4_case
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d_interpolate_sequence_5(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_4,
- edges=edges_for_3d_case_4,
- update_attributes={
- 'interpolate_1': {
- 'align_corners': 1, 'antialias': 1, 'pads_begin': 3, 'pads_end': 7
- }
- }
- )
-
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_case_4,
- edges=edges_for_3d_case_4,
- update_attributes={
- 'interpolate_1': {
- 'align_corners': 1, 'antialias': 1, 'pads_begin': 3, 'pads_end': 7
- }
- }
- )
-
- InterpolateSequenceToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/L2NormFusing_test.py b/tools/mo/unit_tests/mo/middle/L2NormFusing_test.py
deleted file mode 100644
index 49aaac6d84e2cf..00000000000000
--- a/tools/mo/unit_tests/mo/middle/L2NormFusing_test.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.middle.L2NormFusing import L2NormToNorm
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-# A list with nodes attributes used to build various graphs.
-nodes = [
- ('l2_normalize_mul', dict(kind='op', op='Mul', name='l2_norm_name')),
- ('l2_normalize_mul_data', dict(kind='data')),
- ('maximum', dict(kind='op', op='Maximum')),
- ('maximum_data', dict(kind='data')),
- ('maximum_y_const', dict(kind='op', op='Const', value=np.array(12.e-13, dtype=np.float32))),
- ('maximum_y_data', dict(kind='data', value=np.array(12.e-13, dtype=np.float32))),
- ('rsqrt_pow', dict(kind='data', value=-0.5)),
- ('rsqrt', dict(kind='op', op='Pow')),
- ('rsqrt_data', dict(kind='data')),
- ('square_pow', dict(kind='op', op='Const', value=2.)),
- ('square_pow_data', dict(kind='data', value=2.)),
- ('square', dict(kind='op', op='Pow')),
- ('sum', dict(kind='op', op='ReduceSum')),
- ('sum_data', dict(kind='data')),
- ('sum_axes', dict(kind='op', op='Const')),
- # nodes added after replacement
- ('normalize_node', dict(kind='op', op='NormalizeL2')),
- ('weights_node', dict(kind='op', op='Const')),
- ('result', dict(kind='op', op='Result'))
-]
-
-edges = [
- ('input', 'input_data', {'out': 0}),
- ('input_data', 'square', {'in': 0}),
- ('square_pow', 'square_pow_data', {'out': 0}),
- ('square_pow_data', 'square', {'in': 1}),
- ('square', 'square_data'),
- ('square_data', 'sum'),
- ('sum_axes', 'sum_axes_data'),
- ('sum_axes_data', 'sum'),
- ('sum', 'sum_data'),
- ('maximum_y_const', 'maximum_y_data'),
- ('maximum_y_data', 'maximum'),
- ('sum_data', 'maximum'),
- ('maximum', 'maximum_data'),
- ('maximum_data', 'rsqrt', {'in': 0}),
- ('rsqrt_pow', 'rsqrt', {'in': 1}),
- ('rsqrt', 'rsqrt_data'),
- ('rsqrt_data', 'l2_normalize_mul'),
- ('input_data', 'l2_normalize_mul'),
- ('l2_normalize_mul', 'l2_normalize_mul_data'),
- ('l2_normalize_mul_data', 'result'),
-]
-
-edges_after_replacement = [
- ('input', 'input_data', {'out': 0}),
- ('input_data', 'normalize_node'),
- ('weights_node', 'weights_node_data'),
- ('weights_node_data', 'normalize_node'),
- ('normalize_node', 'l2_normalize_mul_data'),
- ('l2_normalize_mul_data', 'result'),
-]
-
-
-class TestL2NormToNormTest():
- @pytest.mark.parametrize("input_shape, axes, layout",
- [(int64_array([2, 3]), int64_array([1]), 'NCHW'), # NC layout, normalize C dimension
- (int64_array([2, 3]), int64_array([1]), 'NHWC'), # NC layout, normalize C dimension
- (int64_array([2, 3, 5]), int64_array([1]), 'NCHW'), # NCH layout, normalize C dimension
- (int64_array([2, 3, 5]), int64_array([1]), 'NHWC'), # NCH layout, normalize C dimension
- (int64_array([2, 3, 5]), int64_array([-1, -2]), 'NHWC'), # NCH layout, normalize CH dimensions
- (int64_array([2, 3, 5]), int64_array([-1, -2]), 'NCHW'), # NCH layout, normalize CH dimensions
- (int64_array([2, 3, 5]), int64_array([1, 2]), 'NCHW'), # NCH layout, normalize CH dimensions
- (int64_array([2, 3, 5]), int64_array([1, 2]), 'NHWC'), # NCH layout, normalize CH dimensions
- (int64_array([2, 3, 5, 7]), int64_array([1]), 'NCHW'), # NCHW layout, normalize C dimension
- (int64_array([2, 3, 5, 7]), int64_array([-1]), 'NHWC'), # NHWC layout, normalize C dimension
- (int64_array([2, 3, 5, 7]), int64_array([3]), 'NHWC'), # NCHW layout, normalize C dimension
- (int64_array([2, 3, 5, 7]), int64_array([-1, 1, 2]), 'NCHW'), # NCHW layout, normalize CHW dimensions
- (int64_array([2, 3, 5, 7]), int64_array([-3, -2, -1]), 'NHWC'), # NCHW layout, normalize HWC dimensions
- ])
- def test_positive(self, input_shape, axes, layout):
- graph = build_graph_with_attrs(nodes + [
- ('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
- ('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
- ('square_data', dict(kind='data', shape=input_shape)),
- ('sum_axes_data', dict(kind='data', value=axes, shape=None)),
- ], edges, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph.graph['layout'] = layout
-
- L2NormToNorm().find_and_replace_pattern(graph)
-
- graph_ref = build_graph_with_attrs(nodes + [
- ('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
- ('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
- ('weights_node_data', dict(kind='data', value=axes.sort())),
- ], edges_after_replacement, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- assert (graph.node[graph.get_nodes_with_attributes(type='NormalizeL2')[0]]['name'] == 'l2_norm_name')
- assert flag, resp
-
- @pytest.mark.parametrize("input_shape, axes, layout",
- [(int64_array([2]), int64_array([0]), 'NCHW'),
- (int64_array([2, 3]), int64_array([0]), 'NCHW'),
- (int64_array([2, 3]), int64_array([0]), 'NHWC'),
- (int64_array([2, 3]), int64_array([0, 1]), 'NCHW'),
- (int64_array([2, 3]), int64_array([0, 1]), 'NHWC'),
- (int64_array([2, 3, 5]), int64_array([0]), 'NCHW'),
- (int64_array([2, 3, 5]), int64_array([0]), 'NHWC'),
- (int64_array([2, 3, 5]), int64_array([-1]), 'NCHW'),
- (int64_array([2, 3, 5]), int64_array([-1]), 'NHWC'),
- (int64_array([2, 3, 5]), int64_array([0, 1]), 'NCHW'),
- (int64_array([2, 3, 5]), int64_array([0, 1]), 'NHWC'),
- (int64_array([2, 3, 5]), int64_array([0, 2]), 'NCHW'),
- (int64_array([2, 3, 5]), int64_array([0, 2]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([0]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([0]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([2]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([2]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([3]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([1]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([1, 2]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([1, -1]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([1, -1]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([-2, -1]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([1, 3]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([2, 3]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([0, 1, 2]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([0, 1, 2]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([0, 2, 3]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([0, 2, 3]), 'NHWC'),
- (int64_array([2, 3, 5, 7]), int64_array([0, 1, 2, 3]), 'NCHW'),
- (int64_array([2, 3, 5, 7]), int64_array([0, 1, 2, 3]), 'NHWC'),
- (int64_array([2, 3, 5, 7, 9]), int64_array([1]), 'NCHW'),
- (int64_array([2, 3, 5, 7, 9]), int64_array([-1]), 'NHWC'),
- (int64_array([2, 3, 5, 7, 9]), int64_array([1, 2, 3, 4]), 'NCHW'),
- (int64_array([2, 3, 5, 7, 9]), int64_array([-1, -2, -3, -4]), 'NHWC'),
- ])
- def test_negative(self, input_shape, axes, layout):
- graph = build_graph_with_attrs(nodes + [
- ('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
- ('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
- ('square_data', dict(kind='data', shape=input_shape)),
- ('sum_axes_data', dict(kind='data', value=axes, shape=None)),
- ], edges, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph.graph['layout'] = layout
-
- L2NormToNorm().find_and_replace_pattern(graph)
-
- graph_ref = build_graph_with_attrs(nodes + [
- ('input', dict(kind='op', shape=input_shape, op='Parameter', data_type=np.float32)),
- ('input_data', dict(kind='data', shape=input_shape, data_type=np.float32)),
- ('square_data', dict(kind='data', shape=input_shape)),
- ('sum_axes_data', dict(kind='data', value=axes, shape=None)),
- ], edges, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/middle/LayoutChangeForEinsum_test.py b/tools/mo/unit_tests/mo/middle/LayoutChangeForEinsum_test.py
deleted file mode 100644
index 4106e9f9d35149..00000000000000
--- a/tools/mo/unit_tests/mo/middle/LayoutChangeForEinsum_test.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.LayoutChangeForEinsum import LayoutChangeForEinsum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, valued_const_with_data, connect
-
-nodes_attributes = {
- # Parameter layers
- **regular_op_with_shaped_data('placeholder_1', None, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('placeholder_2', None, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('placeholder_3', None, {'type': 'Parameter', 'op': 'Parameter'}),
-
- # Einsum layer
- **regular_op_with_shaped_data('einsum', None, {'type': 'Einsum', 'op': 'Einsum'}),
-
- # Result layer
- **result(),
-
- # Transpose layers
- **regular_op_with_shaped_data('transpose_1', None,
- {'type': 'Transpose', 'op': 'Transpose', 'need_shape_inference': True}),
- **regular_op_with_shaped_data('transpose_3', None,
- {'type': 'Transpose', 'op': 'Transpose', 'need_shape_inference': True}),
-
- # Const layers
- **valued_const_with_data('axis_1_const', int64_array([0, 2, 3, 1])),
- **valued_const_with_data('axis_3_const', int64_array([0, 4, 1, 2, 3])),
-}
-
-
-class LayoutChangeForEinsumTests(unittest.TestCase):
- def test_layout_change_einsum(self):
- graph = build_graph(nodes_attributes,
- [*connect('placeholder_1', '0:einsum'),
- *connect('placeholder_2', '1:einsum'),
- *connect('placeholder_3', '2:einsum'),
- *connect('einsum', 'output')],
- { # this input stays as is since it is of a rank equal to 3
- 'placeholder_1_d': {'shape': np.array([2, 3, 5])},
- # [3, 5, 7, 8] - NHWC, [3, 8, 5, 7] - NCHW
- # this input does not require additional transpose
- # since the corresponding subscript can be adjusted
- 'placeholder_2_d': {'shape': np.array([3, 8, 5, 7])},
- # [3, 8, 10, 12] - NHWC, [3, 12, 8, 10] - NCHW
- # the third input must be transposed to NHWC layout
- # since ellipsis covers multiple dimensions in the end
- # the corresponding subscript is not changed
- 'placeholder_3_d': {'shape': np.array([3, 12, 8, 10])},
- # equation is still for NHWC layout
- 'einsum': {'equation': "abc,bcde,bc...->ade..."},
- # [2, 7, 8, 10, 12] - NHWC, [2, 12, 7, 8, 10] - NCHW
- # the output is in NCHW layout but its shape will be re-inferred since
- # the output stays in NHWC layout due to ellipsis in the end
- # and additional transpose to NCHW will be inserted
- 'einsum_d': {'shape': np.array([2, 12, 7, 8, 10])},
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [*connect('placeholder_3', '0:transpose_1'),
- *connect('axis_1_const', '1:transpose_1'),
- *connect('placeholder_1', '0:einsum'),
- *connect('placeholder_2', '1:einsum'),
- *connect('transpose_1', '2:einsum'),
- *connect('einsum', '0:transpose_3'),
- *connect('axis_3_const', '1:transpose_3'),
- *connect('transpose_3', 'output')],
- {'placeholder_1_d': {'shape': np.array([2, 3, 5])},
- 'placeholder_2_d': {'shape': np.array([3, 8, 5, 7])},
- 'einsum': {'equation': "abc,becd,bc...->ade..."},
- 'einsum_d': {'shape': np.array([2, 12, 7, 8, 10])}
- })
-
- LayoutChangeForEinsum().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_no_adjustment_layout_einsum(self):
- graph = build_graph(nodes_attributes,
- [*connect('placeholder_1', '0:einsum'),
- *connect('placeholder_2', '1:einsum'),
- *connect('placeholder_3', '2:einsum'),
- *connect('einsum', 'output')],
- { # this input stays as is since it is of a rank equal to 3
- 'placeholder_1_d': {'shape': np.array([2, 3, 5])},
- # [3, 5, 7, 8] - NHWC
- # this input does not require additional transpose
- # since the corresponding layout is correct
- 'placeholder_2_d': {'shape': np.array([3, 5, 7, 8])},
- # [3, 8, 10, 12] - NHWC
- # this input does not require additional transpose
- # since the corresponding layout is correct
- 'placeholder_3_d': {'shape': np.array([3, 8, 10, 12])},
- # equation is still for NHWC layout
- 'einsum': {'equation': "abc,bcde,bc...->ade...",
- 'correct_in_data_layout': [0, 1, 2],
- 'correct_out_data_layout': [0]},
- # [2, 7, 8, 10, 12] - NHWC
- # this output does not require additional transpose
- # since the corresponding layout is correct
- 'einsum_d': {'shape': np.array([2, 7, 8, 10, 12])},
- }, nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
-
- graph_ref = build_graph(nodes_attributes,
- [*connect('placeholder_1', '0:einsum'),
- *connect('placeholder_2', '1:einsum'),
- *connect('placeholder_3', '2:einsum'),
- *connect('einsum', 'output')],
- {'placeholder_1_d': {'shape': np.array([2, 3, 5])},
- 'placeholder_2_d': {'shape': np.array([3, 5, 7, 8])},
- 'placeholder_3_d': {'shape': np.array([3, 8, 10, 12])},
- 'einsum': {'equation': "abc,bcde,bc...->ade..."},
- 'einsum_d': {'shape': np.array([2, 7, 8, 10, 12])}
- })
-
- LayoutChangeForEinsum().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/LeakyReluPattern_test.py b/tools/mo/unit_tests/mo/middle/LeakyReluPattern_test.py
deleted file mode 100644
index 9b29af71f0054a..00000000000000
--- a/tools/mo/unit_tests/mo/middle/LeakyReluPattern_test.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.LeakyReluPattern import LeakyReLUFusion
-from openvino.tools.mo.front.common.partial_infer.utils import float_array, int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.result import Result
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, build_graph_with_edge_attrs, connect, \
- regular_op_with_shaped_data, valued_const_with_data, connect_data
-
-shape = int64_array([1, 3, 5, 2])
-nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('mul', shape, {'type': 'Multiply', 'name': 'mul'}),
- **regular_op_with_shaped_data('max', shape, {'type': 'Maximum', 'name': 'final_max'}),
- **valued_const_with_data('const', float_array([0.5])),
- **result('result')
- }
-
-edges = [*connect('input:0', '0:mul'),
- *connect('const', '1:mul'),
- *connect_data('input', '0:max'),
- *connect('mul:0', '1:max'),
- *connect('max:0', 'result'),
- ]
-
-ref_nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('leaky_relu', shape, {'type': 'LeakyReLU', 'name': 'max_final',
- 'negative_slope': None}),
- **result('result')
- }
-ref_edges = [*connect('input:0', 'leaky_relu'), *connect('leaky_relu', 'result')]
-
-
-class LeakyReluFusionTest(unittest.TestCase):
- def test_leaky_relu_data_port_0(self):
- graph = build_graph_with_edge_attrs(nodes, edges, {})
- graph_ref = build_graph(ref_nodes, ref_edges)
- Node(graph_ref, 'leaky_relu')['negative_slope'] = 0.5
-
- LeakyReLUFusion().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
- self.assertTrue(len(graph.get_op_nodes(name='final_max')) == 1 and
- graph.get_op_nodes(name='final_max')[0].op == 'LeakyReLU')
-
- def test_leaky_relu_not_applicable_non_scalar_const(self):
- # const value is not a scalar or 1D tensor with 1 element so the transformation is not applicable
- graph = build_graph_with_edge_attrs(nodes, edges, {})
- Node(graph, 'const')['value'] = float_array([0.5, 0.7])
- Node(graph, 'const_d')['value'] = float_array([0.5, 0.7])
- graph_ref = graph.copy()
-
- LeakyReLUFusion().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- def test_leaky_relu_mul_multiple_consumers(self):
- # multiple consumers of Mul operation
- graph = build_graph_with_edge_attrs(nodes, edges, {})
- additional_result = Result(graph, {'name': 'result_2'}).create_node()
- Node(graph, 'mul').out_port(0).connect(additional_result.in_port(0))
-
- ref_nodes = {**regular_op_with_shaped_data('input', shape, {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('mul', shape, {'type': 'Multiply', 'name': 'mul'}),
- **regular_op_with_shaped_data('max', shape, {'type': 'Maximum', 'name': 'final_max'}),
- **valued_const_with_data('const', float_array([0.5])),
- **regular_op_with_shaped_data('leaky_relu', shape, {'type': 'LeakyReLU', 'name': 'max_final',
- 'negative_slope': None}),
- **result('result'),
- **result('result_2')
- }
- ref_edges = [*connect('input:0', '0:mul'),
- *connect('const', '1:mul'),
- *connect('max:0', 'result'),
- *connect('mul:0', 'result_2'),
- *connect_data('input', 'leaky_relu'),
- *connect('leaky_relu', 'result')
- ]
- graph_ref = build_graph_with_edge_attrs(ref_nodes, ref_edges)
-
- LeakyReLUFusion().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result_2')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/MXTileReplacer_test.py b/tools/mo/unit_tests/mo/middle/MXTileReplacer_test.py
deleted file mode 100644
index 7eebae8395e33a..00000000000000
--- a/tools/mo/unit_tests/mo/middle/MXTileReplacer_test.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.MXTileReplacer import MXTileReplacer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {'kind': 'data'},
- 'tile': {'kind': 'op', 'op': 'Tile'},
- 'tile_data': {'kind': 'data', 'shape': int64_array([1, 1, 1, 1])},
- 'result': {'kind': 'op', 'op': 'Result'},
-
- 'unsqueeze_1': {'kind': 'op', 'op': 'Unsqueeze'},
- 'unsqueeze_1_data': {'kind': 'data'},
- 'unsqueeze_1_const': {'kind': 'op', 'op': 'Const'},
- 'unsqueeze_1_const_data': {'kind': 'data'},
-}
-
-
-class MXTileReplacerTest(unittest.TestCase):
-
- def test_insert_one_unsqueeze(self):
- graph = build_graph(
- nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'tile'),
- ('tile', 'tile_data'),
- ('tile_data', 'result')
- ],
- {
- 'placeholder_data': {'shape': int64_array([1, 1, 1])}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'unsqueeze_1', {'in': 0}),
- ('unsqueeze_1_const', 'unsqueeze_1_const_data'),
- ('unsqueeze_1_const_data', 'unsqueeze_1', {'in': 1}),
- ('unsqueeze_1', 'unsqueeze_1_data'),
- ('unsqueeze_1_data', 'tile'),
- ('tile', 'tile_data'),
- ('tile_data', 'result')
- ],
- {
- 'placeholder_data': {'shape': int64_array([1, 1, 1])},
- 'unsqueeze_1_const_data': {'value': int64_array([0])}
- },
- nodes_with_edges_only=True
- )
-
- MXTileReplacer().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_insert_two_unsqueezes(self):
- graph = build_graph(
- nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'tile'),
- ('tile', 'tile_data'),
- ('tile_data', 'result')
- ],
- {
- 'placeholder_data': {'shape': int64_array([1, 1])}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attributes,
- [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'unsqueeze_1', {'in': 0}),
- ('unsqueeze_1_const', 'unsqueeze_1_const_data'),
- ('unsqueeze_1_const_data', 'unsqueeze_1', {'in': 1}),
- ('unsqueeze_1', 'unsqueeze_1_data'),
- ('unsqueeze_1_data', 'tile'),
- ('tile', 'tile_data'),
- ('tile_data', 'result')
- ],
- {
- 'placeholder_data': {'shape': int64_array([1, 1])},
- 'unsqueeze_1_const_data': {'value': int64_array([0, 1])}
- },
- nodes_with_edges_only=True
- )
-
- MXTileReplacer().find_and_replace_pattern(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/MakeKaldiConstReshapable_test.py b/tools/mo/unit_tests/mo/middle/MakeKaldiConstReshapable_test.py
deleted file mode 100644
index 15afc8ac796015..00000000000000
--- a/tools/mo/unit_tests/mo/middle/MakeKaldiConstReshapable_test.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.MakeKaldiConstReshapable import MakeKaldiConstReshapable
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, regular_op_with_shaped_data, connect
-
-nodes = {
- **regular_op_with_shaped_data('placeholder_1', [1, 13], {'kind': 'op', 'op': 'Parameter', 'shape': [1, 13]}),
- **regular_op_with_shaped_data('splice_1', [1, 13], {'kind': 'op', 'op': 'Splice',
- 'context': np.array([-2, -1, 0, 1, 2])}),
- **regular_op_with_shaped_data('placeholder_2', [1, 26], {'kind': 'op', 'op': None}),
- **regular_op_with_shaped_data('memory_in', [1, 5], {'kind': 'op', 'op': 'ReadValue',
- 'shape': int64_array([1, 5])}),
- **regular_op_with_shaped_data('memory_out', [1, 5], {'kind': 'op', 'op': 'Assign', 'shape': int64_array([1, 5])}),
- **result('result'),
- **regular_op_with_shaped_data('crop_in', [1, 4], {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 1, 'dim': 4}),
- **regular_op_with_shaped_data('crop_out', [1, 1], {'kind': 'op', 'op': 'Crop', 'axis': 1, 'offset': 0, 'dim': 1}),
- **regular_op_with_shaped_data('equal', [1, 1], {'kind': 'op', 'op': 'Equal'}),
- **regular_op_with_shaped_data('select', [1, 26], {'kind': 'op', 'op': 'Select'}),
- **regular_op_with_shaped_data('const_0', [1, 1], {'kind': 'op', 'op': 'Const', 'shape': [1, 1],
- 'value': [0], 'data_type': np.float32}),
- **regular_op_with_shaped_data('const_1', [1, 1], {'kind': 'op', 'op': 'Const', 'shape': [1, 1],
- 'value': [0], 'data_type': np.float32}),
- **regular_op_with_shaped_data('concat', [1, 5], {'kind': 'op', 'op': 'Concat'}),
- **regular_op_with_shaped_data('memory', [1, 26], {'kind': 'op', 'op': 'Assign'}),
-
- **regular_op_with_shaped_data('shape', None, {'kind': 'op', 'op': 'ShapeOf'}),
- **regular_op_with_shaped_data('crop_batch', None, {'kind': 'op', 'op': 'Crop', 'offset': int64_array([0])}),
- **regular_op_with_shaped_data('crop_batch_dim', None, {'kind': 'op', 'op': 'Const', 'shape': [1],
- 'value': [1], 'data_type': np.int64}),
- **regular_op_with_shaped_data('second_dim', None, {'kind': 'op', 'op': 'Const', 'shape': [1],
- 'value': [5], 'data_type': np.int64}),
- **regular_op_with_shaped_data('gather_shape', None, {'kind': 'op', 'op': 'Concat'}),
- **regular_op_with_shaped_data('fill_value', [1, 5], {'kind': 'op', 'op': 'Const', 'shape': [1, 5],
- 'value': np.zeros([1, 5]), 'data_type': np.float32}),
- **regular_op_with_shaped_data('fill_value_2', None, {'kind': 'op', 'op': 'Const', 'shape': [1],
- 'value': [0], 'data_type': np.float32}),
- **regular_op_with_shaped_data('broadcast', [1, 5], {'kind': 'op', 'op': 'Broadcast'}),
-
- **regular_op_with_shaped_data('fill_value_ones', [1, 26], {'kind': 'op', 'op': 'Const', 'shape': [1, 26],
- 'value': np.zeros([1, 26]), 'data_type': np.int64}),
- **regular_op_with_shaped_data('fill_value_ones_2', [1, 1], {'kind': 'op', 'op': 'Const', 'shape': [1, 1],
- 'value': [1], 'data_type': np.int64}),
-}
-
-
-class MakeKaldiConstReshapableTests(unittest.TestCase):
-
- # graph contains 1 splice with context length 5, should be inserted select with memory as counter with length 5
- def test_reshapable_const(self):
- graph = build_graph(nodes,
- [*connect('placeholder_1', 'splice_1'),
- *connect('splice_1', 'placeholder_2'),
- *connect('placeholder_2', '1:select'),
- *connect('fill_value', 'memory_in'),
- *connect('memory_in', 'crop_in'),
- *connect('crop_in', '0:concat'),
- *connect('fill_value_ones_2:0', '1:concat'),
- *connect('concat', 'memory_out'),
- *connect('memory_out', 'result'),
- *connect('concat', 'crop_out'),
- *connect('crop_out', '1:equal'),
- *connect('fill_value_ones_2:0', '0:equal'),
- *connect('equal', '0:select'),
- *connect('fill_value_ones', '2:select'),
- *connect('select', 'memory')
- ],
- nodes_with_edges_only=True)
- graph.strict_mode = False
- MakeKaldiConstReshapable().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes,
- [*connect('placeholder_1:0', 'splice_1'),
- *connect('splice_1', 'placeholder_2'),
- *connect('placeholder_2', '1:select'),
- *connect('placeholder_1:0', 'shape', skip_data=True),
- *connect('shape', '0:crop_batch'),
- *connect('crop_batch_dim', '1:crop_batch'),
- *connect('second_dim', '1:gather_shape'),
- *connect('crop_batch', '0:gather_shape'),
- *connect('fill_value_2', '0:broadcast'),
- *connect('gather_shape', '1:broadcast'),
- *connect('broadcast', 'memory_in'),
- *connect('memory_in', 'crop_in'),
- *connect('crop_in', '0:concat'),
- *connect('fill_value_ones_2', '1:concat'),
- *connect('concat', 'memory_out'),
- *connect('memory_out', 'result'),
- *connect('concat', 'crop_out'),
- *connect('crop_out', '1:equal'),
- *connect('fill_value_ones_2', '0:equal'),
- *connect('equal', '0:select'),
- *connect('const_0', '2:select'),
- *connect('fill_value_ones', '2:select'),
- *connect('select', 'memory')
- ], nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'memory')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/MulQuantizeFuse_test.py b/tools/mo/unit_tests/mo/middle/MulQuantizeFuse_test.py
deleted file mode 100644
index 62ca58619bd422..00000000000000
--- a/tools/mo/unit_tests/mo/middle/MulQuantizeFuse_test.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.MulFakeQuantizeFuse import MulFakeQuantizeFuse
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-# 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 = {
- 'x': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'x_data': {'value': None, 'shape': np.array([1, 64, 56, 56]), 'kind': 'data'},
-
- 'mul_const': {'op': 'Const', 'type': 'Const', 'kind': 'op', 'value': None, 'shape': None},
- 'mul_const_data': {'value': np.array([]), 'shape': np.array([]), 'kind': 'data'},
-
- 'mul': {'op': 'Mul', 'kind': 'op'},
- 'mul_data': {'value': np.array([]), 'shape': np.array([]), 'kind': 'data'},
-
- 'mi_i': {'op': 'Const', 'type': 'Const', 'kind': 'op', 'value': None, 'shape': None},
- 'mi_i_data': {'value': np.array([-10]), 'shape': np.array([]), 'kind': 'data'},
-
- 'ma_i': {'op': 'Const', 'type': 'Const', 'kind': 'op', 'value': None, 'shape': None},
- 'ma_i_data': {'value': np.array([10]), 'shape': np.array([]), 'kind': 'data'},
-
- 'mi_o': {'op': 'Const', 'type': 'Const', 'kind': 'op', 'value': None, 'shape': None},
- 'mi_o_data': {'value': np.array([]), 'shape': np.array([]), 'kind': 'data'},
-
- '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},
- 'quantize_data': {'value': None, 'shape': np.array([1, 64, 56, 56]), 'kind': 'data'},
-
- 'output': {'op': 'Result', 'kind': 'op'},
-}
-
-edges = [
- ('x', 'x_data'),
- ('mul_const', 'mul_const_data'),
- ('mul', 'mul_data'),
- ('mi_i', 'mi_i_data'),
- ('ma_i', 'ma_i_data'),
- ('mi_o', 'mi_o_data'),
- ('ma_o', 'ma_o_data'),
- ('quantize', 'quantize_data'),
- ('quantize_data', 'output'),
-
- ('x_data', 'mul', {'in': 0}),
- ('mul_const_data', 'mul', {'in': 1}),
-
- ('mul_data', 'quantize', {'in': 0}),
- ('mi_i_data', 'quantize', {'in': 1}),
- ('ma_i_data', 'quantize', {'in': 2}),
- ('mi_o_data', 'quantize', {'in': 3}),
- ('ma_o_data', 'quantize', {'in': 4}),
-]
-
-edges_ref = [
- ('x', 'x_data'),
- ('mul_const', 'mul_const_data'),
- ('mul', 'mul_data'),
- ('mi_i', 'mi_i_data'),
- ('ma_i', 'ma_i_data'),
- ('mi_o', 'mi_o_data'),
- ('ma_o', 'ma_o_data'),
- ('quantize', 'quantize_data'),
- ('quantize_data', 'output'),
-
- ('x_data', 'quantize', {'in': 0}),
- ('mi_i_data', 'quantize', {'in': 1}),
- ('ma_i_data', 'quantize', {'in': 2}),
- ('mi_o_data', 'quantize', {'in': 3}),
- ('ma_o_data', 'quantize', {'in': 4}),
-
- ('x_data', 'mul', {'in': 0}),
- ('mul_const_data', 'mul', {'in': 1}),
-]
-
-
-class MulQuantizeFuseTest(unittest.TestCase):
- def test_1(self):
- graph = build_graph(nodes, edges, {
- 'mul': {'can_be_fused': True},
- 'mul_const_data': {'shape': np.array([3, 1, 1]), 'value': np.broadcast_to(np.array([1]), (3, 1, 1))},
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mi_o_data': {'shape': np.array([1, 1, 1, 1]), 'value': np.broadcast_to(np.array([0]), (1, 1, 1, 1))},
- 'ma_o_data': {'shape': np.array([1, 3, 1, 1]), 'value': np.broadcast_to(np.array([1]), (1, 3, 1, 1))},
- }, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = build_graph(nodes, edges_ref, {
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mul_const_data': {'shape': np.array([3, 1, 1]), 'value': np.broadcast_to(np.array([1]), (3, 1, 1))},
- 'mi_o_data': {'shape': np.array([1, 1, 1, 1]), 'value': np.broadcast_to(np.array([0]), (1, 1, 1, 1))},
- 'ma_o_data': {'shape': np.array([1, 3, 1, 1]), 'value': np.broadcast_to(np.array([1]), (1, 3, 1, 1))},
- 'mi_i_data': {'shape': np.array([3, 1, 1]), 'value': np.broadcast_to(np.array([-10]), (3, 1, 1))},
- 'ma_i_data': {'shape': np.array([3, 1, 1]), 'value': np.broadcast_to(np.array([10]), (3, 1, 1))},
- }, nodes_with_edges_only=True)
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
-
- def test_2(self):
- graph = build_graph(nodes, edges, {
- 'mul': {'can_be_fused': True},
- 'mul_const_data': {'shape': np.array([1]), 'value': np.array([2])},
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mi_o_data': {'shape': np.array([1]), 'value': np.array([0])},
- 'ma_o_data': {'shape': np.array([1]), 'value': np.array([1])},
- }, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = build_graph(nodes, edges_ref, {
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mul_const_data': {'shape': np.array([1]), 'value': np.array([2])},
- 'mi_o_data': {'shape': np.array([1]), 'value': np.array([0])},
- 'ma_o_data': {'shape': np.array([1]), 'value': np.array([1])},
- 'mi_i_data': {'shape': np.array([1]), 'value': np.array([-5])},
- 'ma_i_data': {'shape': np.array([1]), 'value': np.array([5])},
- }, nodes_with_edges_only=True)
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
-
- def test_negative_1(self):
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = build_graph(nodes, edges, nodes_with_edges_only=True)
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
-
- def test_negative_2(self):
- graph = build_graph(nodes, edges, {'mul': {'can_be_fused': False}}, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = build_graph(nodes, edges, {'mul': {'can_be_fused': False}}, nodes_with_edges_only=True)
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
-
- def test_negative_3(self):
- graph = build_graph(nodes, edges, {
- 'mul': {'can_be_fused': True},
- 'mul_const_data': {'shape': np.array([1]), 'value': np.array([-1])},
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mi_o_data': {'shape': np.array([1]), 'value': np.array([0])},
- 'ma_o_data': {'shape': np.array([1]), 'value': np.array([1])},
- }, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = graph.copy()
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
-
- def test_negative_4(self):
- graph = build_graph(nodes, edges, {
- 'mul': {'can_be_fused': True},
- 'mul_const_data': {'shape': np.array([3, 1, 1]), 'value': np.array([[[-1]], [[1]], [[-1]]])},
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mi_o_data': {'shape': np.array([1, 1, 1, 1]), 'value': np.broadcast_to(np.array([0]), (1, 1, 1, 1))},
- 'ma_o_data': {'shape': np.array([1, 1, 1, 1]), 'value': np.broadcast_to(np.array([1]), (1, 1, 1, 1))},
- }, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = graph.copy()
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
-
- def test_negative_5(self):
- graph = build_graph(nodes, edges, {
- 'mul': {'can_be_fused': True},
- 'mul_const_data': {'shape': np.array([3, 1, 1]), 'value': np.array([[[0]], [[1]], [[2]]])},
- 'quantize_data': {'shape': np.array([2, 3, 4, 4])},
- 'mi_o_data': {'shape': np.array([1, 1, 1, 1]), 'value': np.broadcast_to(np.array([0]), (1, 1, 1, 1))},
- 'ma_o_data': {'shape': np.array([1, 1, 1, 1]), 'value': np.broadcast_to(np.array([1]), (1, 1, 1, 1))},
- }, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref = graph.copy()
-
- MulFakeQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
-
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/PoolV2ToAttributedPool_test.py b/tools/mo/unit_tests/mo/middle/PoolV2ToAttributedPool_test.py
deleted file mode 100644
index b4d3bde8ab94e0..00000000000000
--- a/tools/mo/unit_tests/mo/middle/PoolV2ToAttributedPool_test.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.PoolV2ToAttributedPool import PoolV2ToAttributedPool
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from openvino.tools.mo.utils.shape import int64_array
-from unit_tests.utils.graph import build_graph, valued_const_with_data, regular_op_with_empty_data, \
- connect, shaped_const_with_data, result
-
-
-class TestPoolV2ToAttributedPool(unittest.TestCase):
-
- def test_pool_v2_to_attributed_pool(self):
- nodes = {
- **shaped_const_with_data('input', int64_array([200, 200])),
- **valued_const_with_data('windows', int64_array([4, 4])),
- **valued_const_with_data('strides', int64_array([4, 4])),
-
- **regular_op_with_empty_data('pool_v2', {'op': 'PoolingV2',
- 'pad': [2, 2],
- 'spatial_dims': [1, 2],
- 'auto_pad': 'same_upper',
- 'output_spatial_shape': [2, 3],
- 'pad_spatial_shape': [1, 2],
- 'pool_method': 'max',
- 'permute_attrs': None}),
-
- **regular_op_with_empty_data('pool_v1', {'type': 'Pooling',
- 'pad': [2, 2],
- 'spatial_dims': [1, 2],
- 'auto_pad': 'same_upper',
- 'output_spatial_shape': [2, 3],
- 'pad_spatial_shape': [1, 2],
- 'pool_method': 'max'}),
-
- **result('output')
- }
-
- edges = [
- *connect('input', 'pool_v2:0'),
- *connect('windows', 'pool_v2:1'),
- *connect('strides', 'pool_v2:2'),
- *connect('pool_v2', 'output'),
- ]
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- PoolV2ToAttributedPool().find_and_replace_pattern(graph)
-
- ref_graph = build_graph(nodes, [*connect('input', 'pool_v1'), *connect('pool_v1', 'output')],
- nodes_with_edges_only=True)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/PreserveRuntimeInfo_test.py b/tools/mo/unit_tests/mo/middle/PreserveRuntimeInfo_test.py
deleted file mode 100644
index 1237d37f6f409e..00000000000000
--- a/tools/mo/unit_tests/mo/middle/PreserveRuntimeInfo_test.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.PreserveRuntimeInfo import PreserveRuntimeInfo
-from openvino.tools.mo.ops.op import PermuteAttrs
-from openvino.tools.mo.ops.transpose import Transpose
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from openvino.tools.mo.utils.runtime_info import RTInfo
-from unit_tests.utils.graph import build_graph, connect, valued_const_with_data, regular_op_with_empty_data, \
- regular_op_with_shaped_data
-
-nodes = {
- **regular_op_with_empty_data('placeholder2', {'type': 'Parameter'}),
- **regular_op_with_empty_data('transpose_parameter',
- {'type': 'Transpose', 'op': 'Transpose', 'infer': Transpose.infer}),
- **regular_op_with_empty_data('transpose_result',
- {'type': 'Transpose', 'op': 'Transpose', 'infer': Transpose.infer}),
-}
-
-edges = [*connect('placeholder1', '0:add'), *connect('placeholder2', '1:add'), *connect('add', 'result')]
-edges_with_transpose = [*connect('placeholder1', '0:transpose_parameter'),
- *connect('transpose_parameter_order', '1:transpose_parameter'),
- *connect('transpose_parameter', '0:add'),
- *connect('placeholder2', '1:add'),
- *connect('add', '0:transpose_result'),
- *connect('transpose_result_order', '1:transpose_result'),
- *connect('transpose_result', 'result')]
-
-
-nodes_for_case_with_two_results = {
- 'placeholder1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'placeholder2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'add': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'infer': copy_shape_infer},
- 'add_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'result1': {'kind': 'op', 'op': 'Result'},
- 'result2': {'kind': 'op', 'op': 'Result'},
- 'fft': {'kind': 'op', 'op': 'IDFT', 'type': 'IDFT', 'infer': copy_shape_infer},
- 'fft_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'fft_axes': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': int64_array([1]), 'value': int64_array([-1])
- },
- 'fft_axes_data': {'value': int64_array([-1]), 'shape': int64_array([1]), 'kind': 'data', 'data_type': np.int64},
- 'transpose_parameter_order': {
- 'type': 'Const', 'kind': 'op', 'op': 'Const', 'shape': None, 'value': None
- },
- 'transpose_parameter_order_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.int64},
- 'transpose_parameter': {'type': 'Transpose', 'kind': 'op', 'op': 'Transpose', 'infer': Transpose.infer},
- 'transpose_parameter_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
-}
-
-edges_for_case_with_two_results = [
- ('transpose_parameter_order', 'transpose_parameter_order_data'),
- ('transpose_parameter_order_data', 'transpose_parameter', {'in': 1}),
- ('transpose_parameter', 'transpose_parameter_data'),
- ('placeholder1', 'placeholder1_data'),
- ('placeholder2', 'placeholder2_data'),
- ('placeholder1_data', 'add', {'in': 0}),
- ('placeholder2_data', 'add', {'in': 1}),
- ('add', 'add_data'),
- ('add_data', 'result1', {'out': 0, 'in': 0}),
- ('add_data', 'fft', {'out': 0, 'in': 0}),
- ('fft_axes', 'fft_axes_data'),
- ('fft_axes_data', 'fft', {'in': 1}),
- ('fft', 'fft_data'),
- ('fft_data', 'result2'),
-]
-
-edges_with_transpose_for_case_with_two_results = [
- ('transpose_parameter_order', 'transpose_parameter_order_data'),
- ('placeholder1_data', 'transpose_parameter', {'in': 0}),
- ('transpose_parameter_order_data', 'transpose_parameter', {'in': 1}),
- ('transpose_parameter', 'transpose_parameter_data'),
- ('placeholder1', 'placeholder1_data'),
- ('placeholder2', 'placeholder2_data'),
- ('transpose_parameter_data', 'add', {'in': 0}),
- ('placeholder2_data', 'add', {'in': 1}),
- ('add', 'add_data'),
- ('add_data', 'result1', {'out': 0, 'in': 0}),
- ('add_data', 'fft', {'out': 0, 'in': 0}),
- ('fft_axes', 'fft_axes_data'),
- ('fft_axes_data', 'fft', {'in': 1}),
- ('fft', 'fft_data'),
- ('fft_data', 'result2'),
-]
-
-
-class TestPreserveRuntimeInfoTest():
- @pytest.mark.parametrize("nhwc_to_nchw_order, nchw_to_nhwc_order, add_permutation_attrs",[
- ([0, 3, 1, 2], [0, 2, 3, 1], True),
- ([0, 4, 1, 2, 3], [0, 2, 3, 4, 1], True),
- (None, None, False),
- ])
- def test_transpose_insert(self, nhwc_to_nchw_order, nchw_to_nhwc_order, add_permutation_attrs):
- graph_nodes = {
- **valued_const_with_data('transpose_parameter_order', np.array(nhwc_to_nchw_order)),
- **valued_const_with_data('transpose_result_order', np.array(nchw_to_nhwc_order))
- }
- graph_nodes.update(nodes)
- shape_len = len(nhwc_to_nchw_order) if add_permutation_attrs else 3
- shape = np.array(range(shape_len))
- add_shape = shape if nhwc_to_nchw_order is None else shape[nhwc_to_nchw_order]
- graph_nodes.update(
- {
- **regular_op_with_shaped_data('placeholder1', shape,
- {'type': 'Parameter', 'rt_info': RTInfo(), 'shape': shape}),
- **regular_op_with_shaped_data('result', shape, {'type': 'Result', 'rt_info': RTInfo(), 'shape': shape}),
- **regular_op_with_shaped_data('add', add_shape,
- {'type': 'Add', 'op': 'Add', 'infer': copy_shape_infer}),
- }
- )
-
- graph = build_graph(graph_nodes, edges)
- graph_ref = build_graph(graph_nodes, edges_with_transpose if add_permutation_attrs else edges)
-
- param_node = Node(graph, 'placeholder1')
- result_node = Node(graph, 'result')
-
- if add_permutation_attrs:
- shape_len = len(nhwc_to_nchw_order)
- param_node['permute_attrs'] = PermuteAttrs().update_attrs(attrs=[('shape', 'output:0')])
- param_node.out_node(0)['permutation'] = PermuteAttrs().get_nhwc_to_nchw_permutation(shape_len)
- result_node.in_node(0)['permutation'] = PermuteAttrs().get_nhwc_to_nchw_permutation(shape_len)
-
- PreserveRuntimeInfo().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- assert flag, resp
-
- assert not param_node.has_valid('permute_attrs')
- assert not param_node.out_node(0).has_valid('permutation')
-
- if add_permutation_attrs:
- rt_info = param_node.rt_info.info
- old_api_map = rt_info[('old_api_map_order', 0)].info
- assert np.array_equal(old_api_map['inverse_order'], nchw_to_nhwc_order)
-
- rt_info = result_node.rt_info.info
- old_api_map = rt_info[('old_api_map_order', 0)].info
- assert np.array_equal(old_api_map['order'], nhwc_to_nchw_order)
-
- def test_auto_disable_nhwc_to_nchw(self):
- shape_len = 4
- shape = np.array(range(shape_len))
- add_shape = shape
- graph_nodes = {
- **regular_op_with_shaped_data('placeholder1', shape,
- {'type': 'Parameter', 'rt_info': RTInfo(), 'shape': shape}),
- **regular_op_with_shaped_data('placeholder2', shape,
- {'type': 'Parameter', 'rt_info': RTInfo(), 'shape': shape}),
- **regular_op_with_shaped_data('result', shape, {'type': 'Result', 'rt_info': RTInfo(), 'shape': shape}),
- **regular_op_with_shaped_data('add', add_shape,
- {'type': 'Add', 'op': 'Add', 'infer': copy_shape_infer}),
- }
-
- graph = build_graph(graph_nodes, edges)
- graph.graph['cmd_params'].auto_disable_nhwc_to_nchw = True
- graph_ref = build_graph(graph_nodes, edges)
-
- param_node = Node(graph, 'placeholder1')
- result_node = Node(graph, 'result')
-
- PreserveRuntimeInfo().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- assert flag, resp
-
- rt_info = param_node.rt_info.info
- old_api_map = rt_info[('old_api_map_order', 0)].info
- assert np.array_equal(old_api_map['inverse_order'], [0, 2, 3, 1])
-
- rt_info = result_node.rt_info.info
- old_api_map = rt_info[('old_api_map_order', 0)].info
- assert np.array_equal(old_api_map['order'], [0, 3, 1, 2])
-
- @pytest.mark.parametrize("nhwc_to_nchw_order, nchw_to_nhwc_order,add_permutation_attrs, fft_kind",
- [([0, 3, 1, 2], [0, 2, 3, 1], True, 'DFT'),
- ([0, 3, 1, 2], [0, 2, 3, 1], True, 'IDFT'),
- (None, None, False, 'DFT'),
- (None, None, False, 'IDFT'),
- ([0, 4, 1, 2, 3], [0, 2, 3, 4, 1], True, 'DFT'),
- ([0, 4, 1, 2, 3], [0, 2, 3, 4, 1], True, 'IDFT'),
- ])
- def test_transpose_insert_with_two_result_nodes(self, nhwc_to_nchw_order, nchw_to_nhwc_order,
- add_permutation_attrs, fft_kind):
- shape_len = len(nhwc_to_nchw_order) if add_permutation_attrs else 3
- shape = np.array(range(shape_len))
- add_shape = shape if nhwc_to_nchw_order is None else shape[nhwc_to_nchw_order]
- graph = build_graph(nodes_attrs=nodes_for_case_with_two_results,
- edges=edges_for_case_with_two_results,
- update_attributes={
- 'placeholder1_data': {'shape': int64_array(shape)},
- 'placeholder1': {'shape': int64_array(shape), 'rt_info': RTInfo()},
- 'transpose_parameter_order': {
- 'value': np.array(nhwc_to_nchw_order),
- 'shape': int64_array(np.array(nhwc_to_nchw_order).shape)
- },
- 'transpose_parameter_order_data': {
- 'value': np.array(nhwc_to_nchw_order),
- 'shape': int64_array(np.array(nhwc_to_nchw_order).shape)
- },
- 'fft': {'op': fft_kind, 'type': fft_kind},
- 'add_data': {'shape': add_shape},
- 'fft_data': {'shape': add_shape},
- 'result1': {'shape': shape, 'rt_info': RTInfo()},
- 'result2': {'shape': shape, 'rt_info': RTInfo()},
- })
-
- if add_permutation_attrs:
- graph_ref = build_graph(nodes_for_case_with_two_results, edges_with_transpose_for_case_with_two_results)
- else:
- graph_ref = build_graph(nodes_for_case_with_two_results, edges_for_case_with_two_results)
-
- param1_node = Node(graph, 'placeholder1')
- result1_node = Node(graph, 'result1')
- result2_node = Node(graph, 'result2')
-
- if add_permutation_attrs:
- shape_len = len(nhwc_to_nchw_order)
- param1_node['permute_attrs'] = PermuteAttrs().update_attrs(attrs=[('shape', 'output:0')])
- param1_node.out_node(0)['permutation'] = PermuteAttrs().get_nhwc_to_nchw_permutation(shape_len)
- result1_node.in_node(0)['permutation'] = PermuteAttrs().get_nhwc_to_nchw_permutation(shape_len)
- result2_node.in_node(0)['permutation'] = PermuteAttrs().get_nhwc_to_nchw_permutation(shape_len)
-
- PreserveRuntimeInfo().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result1')
- assert flag, resp
-
- assert not param1_node.has_valid('permute_attrs')
- assert not param1_node.out_node(0).has_valid('permutation')
-
- if add_permutation_attrs:
- rt_info = param1_node.rt_info.info
- old_api_map = rt_info[('old_api_map_order', 0)].info
- assert np.array_equal(old_api_map['inverse_order'], nchw_to_nhwc_order)
diff --git a/tools/mo/unit_tests/mo/middle/ReluQuantizeFuse_test.py b/tools/mo/unit_tests/mo/middle/ReluQuantizeFuse_test.py
deleted file mode 100644
index 1ccd9e76ea503b..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ReluQuantizeFuse_test.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.ReluQuantizeFuse import ReluQuantizeFuse, ReluFakeQuantizeMark
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes = {
- # input
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_d': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
-
- # Relu
- 'relu': {'kind': 'op', 'op': 'ReLU'},
- 'relu_d': {'value': None, 'shape': None, 'kind': 'data'},
-
- # Quantize
- 'const_1': {'op': 'Const', 'kind': 'op'},
- 'const_1_d': {'kind': 'data', 'value': None},
- 'const_2': {'op': 'Const', 'kind': 'op'},
- 'const_2_d': {'kind': 'data', 'value': None},
- 'const_3': {'op': 'Const', 'kind': 'op'},
- 'const_3_d': {'kind': 'data', 'value': None},
- 'const_4': {'op': 'Const', 'kind': 'op'},
- 'const_4_d': {'kind': 'data', 'value': None},
-
- 'quantize': {'kind': 'op', 'op': 'FakeQuantize'},
- 'quantize_d': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'quantize_1': {'kind': 'op', 'op': 'FakeQuantize'},
- 'quantize_1_d': {'value': None, 'shape': None, 'kind': 'data'},
-
- # Result
- 'output': {'kind': 'op', 'op': 'Result'},
- 'output_1': {'kind': 'op', 'op': 'Result'},
-
- # Ops for extra connection expressing
- 'extra_op': {'kind': 'op', 'op': 'SomeOp'},
- 'extra_data': {'kind': 'data'},
-}
-
-i8_edges = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('relu', 'relu_d', {'out': 0}),
- ('const_1', 'const_1_d'),
- ('const_2', 'const_2_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
-
- # data to op connections
- ('placeholder_d', 'relu'),
- ('relu_d', 'quantize', {'in': 0}),
- ('const_1_d', 'quantize', {'in': 1}),
- ('const_2_d', 'quantize', {'in': 2}),
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('quantize_d', 'output'),
-]
-
-ref_i8_edges = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('const_1', 'const_1_d'),
- ('const_2', 'const_2_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
-
- # data to op connections
- ('placeholder_d', 'quantize', {'in': 0}),
- ('const_1_d', 'quantize', {'in': 1}),
- ('const_2_d', 'quantize', {'in': 2}),
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('quantize_d', 'output'),
-
- ('placeholder_d', 'relu', {'out': 0}),
- ('relu', 'relu_d', {'out': 0}),
-]
-
-i1_edges = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('relu', 'relu_d', {'out': 0}),
- ('const_1', 'const_1_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
-
- # data to op connections
- ('placeholder_d', 'relu'),
- ('relu_d', 'quantize', {'in': 0}),
- ('const_1_d', 'quantize', {'in': 1}),
- ('const_1_d', 'quantize', {'in': 2}),
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('quantize_d', 'output'),
-]
-
-ref_i1_edges = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('const_1', 'const_1_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
-
- # data to op connections
- ('placeholder_d', 'quantize', {'in': 0}),
- ('const_1_d', 'quantize', {'in': 1}),
- ('const_1_d', 'quantize', {'in': 2}),
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('quantize_d', 'output'),
-
- ('placeholder_d', 'relu', {'out': 0}),
- ('relu', 'relu_d', {'out': 0}),
-
-]
-
-relu_extra_output = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('relu', 'relu_d', {'out': 0}),
-
- ('const_1', 'const_1_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
-
- # data to op connections
- ('placeholder_d', 'relu'),
- ('relu_d', 'quantize', {'in': 0}),
- ('const_1_d', 'quantize', {'in': 1}),
- ('const_1_d', 'quantize', {'in': 2}),
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('quantize_d', 'output'),
-
- # extra output of relu
- ('relu_d', 'extra_op'),
- ('extra_op', 'extra_data'),
- ('extra_data', 'output_1'),
-]
-
-const_extra = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('relu', 'relu_d', {'out': 0}),
-
- ('const_1', 'const_1_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
- ('quantize_1', 'quantize_1_d'),
-
- # data to op connections
- ('placeholder_d', 'relu', {'out': 0}),
- ('relu_d', 'quantize', {'in': 0}),
- ('relu_d', 'quantize_1', {'in': 0}),
-
- ('const_1_d', 'quantize', {'in': 1}),
- ('const_1_d', 'quantize', {'in': 2}),
- ('const_1_d', 'quantize_1', {'in': 1}),
- ('const_1_d', 'quantize_1', {'in': 2}),
-
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_3_d', 'quantize_1', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('const_4_d', 'quantize_1', {'in': 4}),
- ('quantize_d', 'output'),
- ('quantize_1_d', 'output_1'),
-]
-
-ref_const_extra = [
- # op to data connections
- ('placeholder', 'placeholder_d'),
- ('const_1', 'const_1_d'),
- ('const_2', 'const_2_d'),
- ('const_3', 'const_3_d'),
- ('const_4', 'const_4_d'),
- ('quantize', 'quantize_d'),
- ('quantize_1', 'quantize_1_d'),
-
- # data to op connections
- ('placeholder_d', 'quantize', {'in': 0, 'out': 0}),
- ('placeholder_d', 'quantize_1', {'in': 0, 'out': 0}),
-
- ('const_1_d', 'quantize', {'out': 0, 'in': 1}),
- ('const_1_d', 'quantize', {'out': 0, 'in': 2}),
- ('const_2_d', 'quantize_1', {'out': 0, 'in': 1}),
- ('const_2_d', 'quantize_1', {'out': 0, 'in': 2}),
-
- ('const_3_d', 'quantize', {'in': 3}),
- ('const_3_d', 'quantize_1', {'in': 3}),
- ('const_4_d', 'quantize', {'in': 4}),
- ('const_4_d', 'quantize_1', {'in': 4}),
- ('quantize_d', 'output'),
- ('quantize_1_d', 'output_1'),
-
- ('placeholder_d', 'relu', {'out': 0}),
- ('relu', 'relu_d', {'out': 0}),
-]
-
-
-class ReluQuantizeFuseTests(unittest.TestCase):
- def test_classic_i8_positive_case(self):
- graph = build_graph(nodes, i8_edges,
- {'const_1_d': {'value': np.zeros([1, 2, 3, 4])}, 'quantize': {'levels': 256}},
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- graph_ref = build_graph(nodes, ref_i8_edges, nodes_with_edges_only=True)
-
- ReluFakeQuantizeMark().find_and_replace_pattern(graph)
- ReluQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_classic_i8_negative_case(self):
- graph = build_graph(nodes, i8_edges,
- {'const_1_d': {'value': np.full([1, 2, 3, 4], -1)}, 'quantize': {'levels': 256}},
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- graph_ref = build_graph(nodes, i8_edges, nodes_with_edges_only=True)
-
- ReluFakeQuantizeMark().find_and_replace_pattern(graph)
- ReluQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_classic_i1_positive_case(self):
- graph = build_graph(nodes, i1_edges,
- {'const_1_d': {'value': np.zeros([1, 2, 3, 4], dtype=np.float32)},
- 'quantize': {'levels': 2}},
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- graph_ref = build_graph(nodes, ref_i1_edges, nodes_with_edges_only=True)
-
- ReluFakeQuantizeMark().find_and_replace_pattern(graph)
- ReluQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_classic_i1_negative_case(self):
- graph = build_graph(nodes, i1_edges,
- {'const_1_d': {'value': np.full([1, 2, 3, 4], -1, dtype=np.float32)},
- 'quantize': {'levels': 2}},
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- graph_ref = build_graph(nodes, ref_i1_edges, nodes_with_edges_only=True)
-
- ReluFakeQuantizeMark().find_and_replace_pattern(graph)
- ReluQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
- np.array_equal(np.full([1, 2, 3, 4], float('-inf'), dtype=np.float32), graph_ref.node['const_1_d']['value'])
-
- def test_relu_extra_outputs_i1_case(self):
- graph = build_graph(nodes, relu_extra_output,
- {'const_1_d': {'value': np.full([1, 2, 3, 4], -1, dtype=np.float32)},
- 'quantize': {'levels': 2}},
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- graph_ref = build_graph(nodes, relu_extra_output, nodes_with_edges_only=True)
-
- ReluFakeQuantizeMark().find_and_replace_pattern(graph)
- ReluQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'relu', check_op_attrs=True)
- self.assertTrue(flag, resp)
- np.array_equal(np.full([1, 2, 3, 4], float('-inf'), dtype=np.float32), graph_ref.node['const_1_d']['value'])
-
- def test_const_extra_outputs_i1_case(self):
- graph = build_graph(nodes, const_extra,
- {'const_1_d': {'value': np.full([1, 2, 3, 4], -1, dtype=np.float32)},
- 'quantize': {'levels': 2}, 'quantize_1': {'levels': 2}},
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- graph.stage = 'middle'
-
- graph_ref = build_graph(nodes, ref_const_extra, nodes_with_edges_only=True)
-
- ReluFakeQuantizeMark().find_and_replace_pattern(graph)
- ReluQuantizeFuse().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'relu', check_op_attrs=True)
- self.assertTrue(flag, resp)
- np.array_equal(np.full([1, 2, 3, 4], float('-inf'), dtype=np.float32), graph_ref.node['const_1_d']['value'])
diff --git a/tools/mo/unit_tests/mo/middle/RemoveDuplicationMemory_test.py b/tools/mo/unit_tests/mo/middle/RemoveDuplicationMemory_test.py
deleted file mode 100644
index e08aef013ab987..00000000000000
--- a/tools/mo/unit_tests/mo/middle/RemoveDuplicationMemory_test.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.RemoveDuplicationMemory import RemoveMemoryDuplicationPattern, MergeNeighborSplicePattern
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class RemoveMemoryDuplicationPatternTests(unittest.TestCase):
-
- def test_remove_duplication(self):
- graph = build_graph({'input': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 6)},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 143]},
- 'placeholder_1': {'kind': 'op', 'op': None},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': range(-1, 2)},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'placeholder_2': {'kind': 'op', 'op': None},
- },
- [('input', 'in_node'), ('in_node', 'splice_1'),
- ('splice_1', 'splice_data_1'), ('splice_data_1', 'placeholder_1'),
- ('in_node', 'splice_2'), ('splice_2', 'splice_data_2'), ('splice_data_2', 'placeholder_2'),
- ],
- nodes_with_edges_only=True)
- RemoveMemoryDuplicationPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'input': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 6)},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 143]},
- 'placeholder_1': {'kind': 'op'},
- 'crop_2': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 39, 'axis': -1},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'placeholder_2': {'kind': 'op'},
- },
- [
- ('input', 'in_node'), ('in_node', 'splice_1'),
- ('splice_1', 'splice_data_1'), ('splice_data_1', 'placeholder_1'),
- ('splice_data_1', 'crop_2'), ('crop_2', 'splice_data_2'),
- ('splice_data_2', 'placeholder_2'),
- ],
- nodes_with_edges_only=True
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_2')
- self.assertTrue(flag, resp)
-
- def test_remove_duplication_with_crops(self):
- graph = build_graph({'input': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 6)},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 143]},
- 'crop_1': {'kind': 'op', 'op': 'Crop', 'offset': 13, 'dim': 13, 'axis': -1},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': range(-1, 2)},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 39]},
- 'crop_2': {'kind': 'op', 'op': 'Crop', 'offset': 13, 'dim': 13, 'axis': -1},
- },
- [('input', 'in_node'), ('in_node', 'splice_1'),
- ('splice_1', 'splice_data_1'), ('splice_data_1', 'crop_1'),
- ('in_node', 'splice_2'), ('splice_2', 'splice_data_2'), ('splice_data_2', 'crop_2'),
- ],
- nodes_with_edges_only=True)
- RemoveMemoryDuplicationPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'input': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 6)},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 143]},
- 'crop_1': {'kind': 'op', 'op': 'Crop', 'offset': 13, 'dim': 13},
- 'crop_2': {'kind': 'op', 'op': 'Crop', 'offset': 65, 'dim': 13, 'axis': -1},
- },
- [
- ('input', 'in_node'), ('in_node', 'splice_1'),
- ('splice_1', 'splice_data_1'),
- ('splice_data_1', 'crop_1'), ('splice_data_1', 'crop_2'),
- ],
- nodes_with_edges_only=True
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'crop_2')
- self.assertTrue(flag, resp)
-
- def test_remove_duplication_neibor(self):
- graph = build_graph({'input': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 1)},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 78], 'value': None},
- 'placeholder_1': {'kind': 'op', 'op': None},
- 'splice_2': {'kind': 'op', 'op': 'Splice', 'context': range(0, 2)},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 26], 'value': None},
- 'placeholder_2': {'kind': 'op', 'op': None},
- },
- [('input', 'in_node'), ('in_node', 'splice_1'),
- ('splice_1', 'splice_data_1'), ('splice_data_1', 'placeholder_1'),
- ('in_node', 'splice_2'), ('splice_2', 'splice_data_2'), ('splice_data_2', 'placeholder_2'),
- ],
- nodes_with_edges_only=True)
- MergeNeighborSplicePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'input': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice_1': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 2)},
- 'splice_data_1': {'kind': 'data', 'shape': [1, 91], 'value': None},
- 'crop_1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 78, 'axis': -1},
- 'crop_1_data': {'kind': 'data', 'shape': [1, 78]},
- 'placeholder_1': {'kind': 'op'},
- 'crop_2': {'kind': 'op', 'op': 'Crop', 'offset': 65, 'dim': 26, 'axis': -1},
- 'splice_data_2': {'kind': 'data', 'shape': [1, 26], 'value': None},
- 'placeholder_2': {'kind': 'op'},
- },
- [
- ('input', 'in_node'), ('in_node', 'splice_1'),
- ('splice_1', 'splice_data_1'), ('splice_data_1', 'crop_1'),
- ('crop_1', 'crop_1_data'), ('crop_1_data', 'placeholder_1'),
- ('splice_data_1', 'crop_2'), ('crop_2', 'splice_data_2'),
- ('splice_data_2', 'placeholder_2'),
- ],
- nodes_with_edges_only=True
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder_2')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/RemoveUselessConcatSplit_test.py b/tools/mo/unit_tests/mo/middle/RemoveUselessConcatSplit_test.py
deleted file mode 100644
index d5c8c94687d909..00000000000000
--- a/tools/mo/unit_tests/mo/middle/RemoveUselessConcatSplit_test.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.RemoveUselessConcatSplit import RemoveUselessConcatSplitPattern
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class RemoveUselessConcatSplitTests(unittest.TestCase):
-
- def test_useless_concat_split(self):
- graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 108])},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br3': {'kind': 'op', 'op': None},
- },
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'concat', {'in': 0}),
- ('br_data_2', 'concat', {'in': 1}),
- ('br_data_3', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'split'),
- ('split', 'split_data_1', {'out': 0}),
- ('split', 'split_data_2', {'out': 1}),
- ('split', 'split_data_3', {'out': 2}),
- ('split_data_1', 'split_br1'),
- ('split_data_2', 'split_br2'),
- ('split_data_3', 'split_br3')])
- RemoveUselessConcatSplitPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_br3': {'kind': 'op', 'op': None}},
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'split_br1'),
- ('br_data_2', 'split_br2'),
- ('br_data_3', 'split_br3'),
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'split_br3')
- self.assertTrue(flag, resp)
-
- def test_usefull_concat_split(self):
- graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 108])},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_1': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_data_2': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br3': {'kind': 'op', 'op': None},
- },
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'concat', {'in': 0}),
- ('br_data_2', 'concat', {'in': 1}),
- ('br_data_3', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'split'),
- ('split', 'split_data_1', {'out': 0}),
- ('split', 'split_data_2', {'out': 1}),
- ('split', 'split_data_3', {'out': 2}),
- ('split_data_1', 'split_br1'),
- ('split_data_2', 'split_br2'),
- ('split_data_3', 'split_br3')])
- RemoveUselessConcatSplitPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 108])},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_1': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_data_2': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br3': {'kind': 'op', 'op': None},
- },
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'concat', {'in': 0}),
- ('br_data_2', 'concat', {'in': 1}),
- ('br_data_3', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'split'),
- ('split', 'split_data_1', {'out': 0}),
- ('split', 'split_data_2', {'out': 1}),
- ('split', 'split_data_3', {'out': 2}),
- ('split_data_1', 'split_br1'),
- ('split_data_2', 'split_br2'),
- ('split_data_3', 'split_br3')])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'split_br3')
- self.assertTrue(flag, resp)
-
- def test_useful_concat_2_outputs_split(self):
- graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 108])},
- 'placeholder': {'kind': 'op', 'op': None},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br3': {'kind': 'op', 'op': None},
- },
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'concat', {'in': 0}),
- ('br_data_2', 'concat', {'in': 1}),
- ('br_data_3', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'split'),
- ('concat_data', 'placeholder'),
- ('split', 'split_data_1', {'out': 0}),
- ('split', 'split_data_2', {'out': 1}),
- ('split', 'split_data_3', {'out': 2}),
- ('split_data_1', 'split_br1'),
- ('split_data_2', 'split_br2'),
- ('split_data_3', 'split_br3')])
- RemoveUselessConcatSplitPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 108])},
- 'placeholder': {'kind': 'op', 'op': None},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br3': {'kind': 'op', 'op': None},
- },
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'concat', {'in': 0}),
- ('br_data_2', 'concat', {'in': 1}),
- ('br_data_3', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'split'),
- ('concat_data', 'placeholder'),
- ('split', 'split_data_1', {'out': 0}),
- ('split', 'split_data_2', {'out': 1}),
- ('split', 'split_data_3', {'out': 2}),
- ('split_data_1', 'split_br1'),
- ('split_data_2', 'split_br2'),
- ('split_data_3', 'split_br3')])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'split_br3')
- self.assertTrue(flag, resp)
-
- def test_useless_concat_split_2_outputs(self):
- graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': int64_array([1, 108])},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_br1_1': {'kind': 'op', 'op': None},
- 'split_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br3': {'kind': 'op', 'op': None},
- },
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'concat', {'in': 0}),
- ('br_data_2', 'concat', {'in': 1}),
- ('br_data_3', 'concat', {'in': 2}),
- ('concat', 'concat_data'),
- ('concat_data', 'split'),
- ('split', 'split_data_1', {'out': 0}),
- ('split', 'split_data_2', {'out': 1}),
- ('split', 'split_data_3', {'out': 2}),
- ('split_data_1', 'split_br1'),
- ('split_data_1', 'split_br1_1'),
- ('split_data_2', 'split_br2'),
- ('split_data_3', 'split_br3')])
- RemoveUselessConcatSplitPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'br1': {'kind': 'op', 'op': None},
- 'br_data_1': {'kind': 'data', 'shape': int64_array([1, 26])},
- 'br2': {'kind': 'op', 'op': None},
- 'br_data_2': {'kind': 'data', 'shape': int64_array([1, 36])},
- 'br3': {'kind': 'op', 'op': None},
- 'br_data_3': {'kind': 'data', 'shape': int64_array([1, 46])},
- 'split_br1': {'kind': 'op', 'op': None},
- 'split_br1_1': {'kind': 'op', 'op': None},
- 'split_br2': {'kind': 'op', 'op': None},
- 'split_br3': {'kind': 'op', 'op': None}},
- [('br1', 'br_data_1'), ('br2', 'br_data_2'), ('br3', 'br_data_3'),
- ('br_data_1', 'split_br1'),
- ('br_data_1', 'split_br1_1'),
- ('br_data_2', 'split_br2'),
- ('br_data_3', 'split_br3'),
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'split_br3')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/RemoveUselessCrops_test.py b/tools/mo/unit_tests/mo/middle/RemoveUselessCrops_test.py
deleted file mode 100644
index fc52faf6d9ebf3..00000000000000
--- a/tools/mo/unit_tests/mo/middle/RemoveUselessCrops_test.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.RemoveUselessCrops import RemoveUselessCropsPattern
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class RemoveUselessCropsPatternTests(unittest.TestCase):
-
- def test_useless_crops(self):
- graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 130]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('crop_data_1', 'concat'),
- ('crop_data_2', 'concat'),
- ('crop_data_3', 'concat'),
- ('crop_data_4', 'concat'),
- ('crop_data_5', 'concat'),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')])
- RemoveUselessCropsPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 130]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [
- ('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('concat', 'concat_data'),
- ('in_node', 'placeholder')
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder')
- self.assertTrue(flag, resp)
-
- def test_useless_crops_type2(self):
- graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'const_26': {'kind': 'op', 'op': 'Const', 'value': 26},
- 'const_26_data': {'kind': 'data', 'value': 26},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 130]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2', {'in': 0}), ('const_26', 'const_26_data'),
- ('const_26_data', 'crop2', {'in': 1}), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('crop_data_1', 'concat'),
- ('crop_data_2', 'concat'),
- ('crop_data_3', 'concat'),
- ('crop_data_4', 'concat'),
- ('crop_data_5', 'concat'),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')])
- RemoveUselessCropsPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'const_26': {'kind': 'op', 'op': 'Const', 'value': 26},
- 'const_26_data': {'kind': 'data', 'value': 26},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 130]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [
- ('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2', {'in': 0}), ('const_26', 'const_26_data'),
- ('const_26_data', 'crop2', {'in': 1}), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('concat', 'concat_data'),
- ('in_node', 'placeholder')
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder')
- self.assertTrue(flag, resp)
-
- def test_useless_crops_type3(self):
- graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'crop_begin': 26, 'crop_end': 52, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 130]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('crop_data_1', 'concat'),
- ('crop_data_2', 'concat'),
- ('crop_data_3', 'concat'),
- ('crop_data_4', 'concat'),
- ('crop_data_5', 'concat'),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')])
- RemoveUselessCropsPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'crop_begin': 26, 'crop_end': 52, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 130]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [
- ('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('concat', 'concat_data'),
- ('in_node', 'placeholder')
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder')
- self.assertTrue(flag, resp)
-
- def test_useful_crops(self):
- graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 104]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('crop_data_1', 'concat'),
- ('crop_data_2', 'concat'),
- ('crop_data_4', 'concat'),
- ('crop_data_5', 'concat'),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')])
-
- RemoveUselessCropsPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Placeholder'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 104]},
- 'placeholder': {'kind': 'op', 'op': 'Placeholder'},
- },
- [('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('crop_data_1', 'concat'),
- ('crop_data_2', 'concat'),
- ('crop_data_4', 'concat'),
- ('crop_data_5', 'concat'),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')]
- )
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder')
- self.assertTrue(flag, resp)
-
- def test_useless_crops_without_concat(self):
- graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'placeholder_concat': {'kind': 'op', 'op': None},
- 'placeholder_concat_data': {'kind': 'data', 'shape': [1, 100]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 230]},
- 'placeholder': {'kind': 'op', 'op': None},
- },
- [('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('placeholder_concat', 'placeholder_concat_data'),
- ('crop_data_1', 'concat', {'in': 0}),
- ('crop_data_2', 'concat', {'in': 1}),
- ('crop_data_3', 'concat', {'in': 2}),
- ('crop_data_4', 'concat', {'in': 3}),
- ('crop_data_5', 'concat', {'in': 4}),
- ('placeholder_concat_data', 'concat', {'in': 5}),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')])
- RemoveUselessCropsPattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'placeholder_in': {'kind': 'op', 'op': 'Parameter'},
- 'in_node': {'kind': 'data', 'shape': [1, 130]},
- 'crop1': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 26, 'axis': -1},
- 'crop_data_1': {'kind': 'data', 'shape': [1, 26]},
- 'crop2': {'kind': 'op', 'op': 'Crop', 'offset': 26, 'dim': 26, 'axis': -1},
- 'crop_data_2': {'kind': 'data', 'shape': [1, 26]},
- 'crop3': {'kind': 'op', 'op': 'Crop', 'offset': 52, 'dim': 26, 'axis': -1},
- 'crop_data_3': {'kind': 'data', 'shape': [1, 26]},
- 'crop4': {'kind': 'op', 'op': 'Crop', 'offset': 78, 'dim': 26, 'axis': -1},
- 'crop_data_4': {'kind': 'data', 'shape': [1, 26]},
- 'crop5': {'kind': 'op', 'op': 'Crop', 'offset': 104, 'dim': 26, 'axis': -1},
- 'crop_data_5': {'kind': 'data', 'shape': [1, 26]},
- 'placeholder_concat': {'kind': 'op', 'op': None},
- 'placeholder_concat_data': {'kind': 'data', 'shape': [1, 100]},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 230]},
- 'placeholder': {'kind': 'op', 'op': 'Parameter'},
- },
- [
- ('placeholder_in', 'in_node'),
- ('in_node', 'crop1'), ('crop1', 'crop_data_1'),
- ('in_node', 'crop2'), ('crop2', 'crop_data_2'),
- ('in_node', 'crop3'), ('crop3', 'crop_data_3'),
- ('in_node', 'crop4'), ('crop4', 'crop_data_4'),
- ('in_node', 'crop5'), ('crop5', 'crop_data_5'),
- ('placeholder_concat', 'placeholder_concat_data'),
- ('in_node', 'concat', {'in': 4}),
- ('placeholder_concat_data', 'concat', {'in': 5}),
- ('concat', 'concat_data'),
- ('concat_data', 'placeholder')])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'placeholder')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/RemoveUselessPad_test.py b/tools/mo/unit_tests/mo/middle/RemoveUselessPad_test.py
deleted file mode 100644
index a99a663a5dc7c0..00000000000000
--- a/tools/mo/unit_tests/mo/middle/RemoveUselessPad_test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.RemoveUselessPad import RemoveUselessPad
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect, \
- connect_data
-
-
-class RemoveUselessPadTests(unittest.TestCase):
- def test_useless_pad_constant_input(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 10, 20, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('pad', [1, 10, 20, 3], {'type': 'Pad', 'op': 'Pad'}),
- **valued_const_with_data('pads_begin', int64_array([0, 0, 0, 0])),
- **valued_const_with_data('pads_end', int64_array([0, 0, 0, 0])),
- **valued_const_with_data('fill_value', np.array(1)),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:pad'),
- *connect('pads_begin', '1:pad'),
- *connect('pads_end', '2:pad'),
- *connect('fill_value', '3:pad'),
- *connect('pad', 'result'),
- ]
- graph = build_graph(nodes, edges)
- RemoveUselessPad().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, [*connect('placeholder', 'result')])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_not_useless_pad_constant_input(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [1, 10, 20, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('pad', [1, 10, 20, 3], {'type': 'Pad', 'op': 'Pad'}),
- **valued_const_with_data('pads_begin', int64_array([0, 0, 0, 0])),
- **valued_const_with_data('pads_end', int64_array([0, 1, 0, 0])),
- **valued_const_with_data('fill_value', np.array(1)),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:pad'),
- *connect('pads_begin', '1:pad'),
- *connect('pads_end', '2:pad'),
- *connect('fill_value', '3:pad'),
- *connect('pad', 'result'),
- ]
- graph = build_graph(nodes, edges)
- RemoveUselessPad().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, edges)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_not_useless_pad_non_constant_input(self):
- nodes = {
- **regular_op_with_shaped_data('placeholder', [10, 20, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('shape_of_1', [3], {'type': 'ShapeOf'}),
- **regular_op_with_shaped_data('sub', [3], {'type': 'Subtract', 'op': 'Sub'}),
- **valued_const_with_data('desired_output_size', int64_array([10, 20, 3])),
- **regular_op_with_shaped_data('pad', [10, 20, 3], {'type': 'Pad', 'op': 'Pad'}),
- **valued_const_with_data('fill_value', np.array(1)),
- **result('result'),
- }
- edges = [*connect('placeholder', '0:pad'),
- *connect('placeholder', 'shape_of_1'),
- *connect('shape_of_1', '0:sub'),
- *connect('desired_output_size', '1:sub'),
- *connect('sub', '1:pad'),
- *connect_data('sub', '2:pad'),
- *connect('fill_value', '3:pad'),
- *connect('pad', 'result'),
- ]
- graph = build_graph(nodes, edges)
- RemoveUselessPad().find_and_replace_pattern(graph)
- ref_graph = build_graph(nodes, edges)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/ReplaceMemoryOffsetWithSplice_test.py b/tools/mo/unit_tests/mo/middle/ReplaceMemoryOffsetWithSplice_test.py
deleted file mode 100644
index e40fc71479a2c3..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ReplaceMemoryOffsetWithSplice_test.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.ReplaceMemoryOffsetWithSplice import ReplaceMemoryOffsetNodePattern
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class ReplaceMemoryOffsetNodePatternTests(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- cls.nodes_attributes = {
- 'in_placeholder': {'kind': 'op', 'op': 'placeholder'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'memoryoffset': {'kind': 'op', 'op': 'MemoryOffset', 't': -5,
- 'pair_name': 'memoryoffset_2', 'has_default': False},
- 'memoryoffset_data': {'kind': 'data', 'shape': [1, 13]},
- 'memoryoffset_2': {'kind': 'op', 'op': 'MemoryOffset', 't': -5,
- 'pair_name': 'memoryoffset', 'has_default': False,
- 'in_ports_count': 1},
- 'memoryoffset_2_data': {'kind': 'data', 'shape': [1, 13]},
- 'crop_data': {'kind': 'data', 'shape': [1, 13]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- 'opoutput': {'kind': 'op', 'op': 'OpOutput'},
- }
-
- def test_memoryoffset_pos(self):
- graph = build_graph(self.nodes_attributes,
- [('in_placeholder', 'in_node'),
- ('in_node', 'memoryoffset'),
- ('memoryoffset', 'memoryoffset_data'),
- ('memoryoffset_data', 'opoutput'),
- ('memoryoffset_2', 'memoryoffset_2_data'),
- ('memoryoffset_2_data', 'out_placeholder')])
- memoryoffset_node = Node(graph, 'memoryoffset')
- memoryoffset_node['t'] = 5
- ReplaceMemoryOffsetNodePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'in_placeholder': {'kind': 'op', 'op': 'placeholder'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice': {'kind': 'op', 'op': 'Splice', 'context': range(0, 6)},
- 'splice_data': {'kind': 'data', 'shape': [1, 78]},
- 'crop': {'kind': 'op', 'op': 'Crop', 'offset': 130, 'dim': 13},
- 'crop_data': {'kind': 'data', 'shape': [1, 13]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- },
- [
- ('in_placeholder', 'in_node'),
- ('in_node', 'splice'),
- ('splice', 'splice_data'),
- ('splice_data', 'crop'),
- ('crop', 'crop_data'),
- ('crop_data', 'out_placeholder')
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_placeholder')
- self.assertTrue(flag, resp)
-
- def test_memoryoffset_neg(self):
- graph = build_graph(self.nodes_attributes,
- [('in_placeholder', 'in_node'),
- ('in_node', 'memoryoffset'),
- ('memoryoffset', 'memoryoffset_data'),
- ('memoryoffset_data', 'opoutput'),
- ('memoryoffset_2', 'memoryoffset_2_data'),
- ('memoryoffset_2_data', 'out_placeholder')])
- memoryoffset_node = Node(graph, 'memoryoffset')
- memoryoffset_node['t'] = -5
- ReplaceMemoryOffsetNodePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'in_placeholder': {'kind': 'op', 'op': 'placeholder'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 1)},
- 'splice_data': {'kind': 'data', 'shape': [1, 78]},
- 'crop': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 13},
- 'memoryoffset_2_data': {'kind': 'data', 'shape': [1, 13]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- },
- [
- ('in_placeholder', 'in_node'),
- ('in_node', 'splice'),
- ('splice', 'splice_data'),
- ('splice_data', 'crop'),
- ('crop', 'memoryoffset_2_data'),
- ('memoryoffset_2_data', 'out_placeholder')
- ]
- )
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_placeholder')
- self.assertTrue(flag, resp)
-
- def test_memoryoffset_neg_0(self):
- graph = build_graph(self.nodes_attributes,
- [('in_placeholder', 'in_node'),
- ('in_node', 'memoryoffset'),
- ('memoryoffset', 'memoryoffset_data'),
- ('memoryoffset_data', 'opoutput'),
- ('memoryoffset_2', 'memoryoffset_2_data'),
- ('memoryoffset_2_data', 'out_placeholder'),
- ('in_node', 'out_placeholder')])
- memoryoffset_node = Node(graph, 'memoryoffset')
- memoryoffset_node['t'] = -5
- ReplaceMemoryOffsetNodePattern().find_and_replace_pattern(graph)
- ref_graph = build_graph({'in_placeholder': {'kind': 'op', 'op': 'placeholder'},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 1)},
- 'splice_data': {'kind': 'data', 'shape': [1, 78]},
- 'crop': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 13},
- 'memoryoffset_2_data': {'kind': 'data', 'shape': [1, 13]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- },
- [
- ('in_placeholder', 'in_node'),
- ('in_node', 'splice'),
- ('splice', 'splice_data'),
- ('splice_data', 'crop'),
- ('crop', 'memoryoffset_2_data'),
- ('memoryoffset_2_data', 'out_placeholder'),
- ('in_node', 'out_placeholder')
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_placeholder')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/ReplacePNormNodePattern_test.py b/tools/mo/unit_tests/mo/middle/ReplacePNormNodePattern_test.py
deleted file mode 100644
index 5e83fa2e946b55..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ReplacePNormNodePattern_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.ReplacePNorm import ReplacePNormNodePattern
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class ReplacePNormNodePatternTests(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- cls.nodes_attributes = {
- 'placeholder': {'kind': 'op', 'op': None},
- 'in_node': {'kind': 'data', 'shape': [1, 3500]},
- 'pnorm': {'kind': 'op', 'op': 'pnorm', 'group': 10, 'p': 2.0},
- 'pnorm_data': {'kind': 'data', 'shape': [1, 350]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- }
-
- def test_pnorm(self):
- graph = build_graph(self.nodes_attributes,
- [('placeholder', 'in_node'),
- ('in_node', 'pnorm'),
- ('pnorm', 'pnorm_data'),
- ('pnorm_data', 'out_placeholder')])
- ReplacePNormNodePattern().find_and_replace_pattern(graph)
-
- ref_graph = build_graph({'in_placeholder': {'kind': 'op', 'op': None},
- 'in_node': {'kind': 'data', 'shape': [1, 3500]},
- 'pow_const': {'kind': 'op', 'value': 2.0},
- 'pow_const_d': {'kind': 'data'},
- 'pow': {'kind': 'op', 'op': 'Pow'},
- 'pow_data': {'kind': 'data'},
- 'reshape': {'kind': 'op', 'op': 'Reshape'},
- 'reshape_data': {'kind': 'data'},
- 'const': {'kind': 'op', 'op': 'Const', 'value': [1, 350, 10]},
- 'const_data': {'kind': 'data'},
- 'reduce': {'kind': 'op', 'op': 'ReduceSum'},
- 'reduce_data': {'kind': 'data'},
- 'const_1': {'kind': 'op', 'op': 'Const', 'value': 2},
- 'const_data_1': {'kind': 'data'},
-
- 'invpow_const': {'kind': 'op', 'value': 0.5},
- 'invpow_const_d': {'kind': 'data'},
- 'invpow': {'kind': 'op', 'op': 'Pow'},
- 'invpow_data': {'kind': 'data'},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- },
- [
- ('in_placeholder', 'in_node'),
- ('in_node', 'pow', {'in': 0}),
- ('pow', 'pow_data'),
- ('pow_data', 'reshape', {'in': 0}),
- ('reshape', 'reshape_data'),
- ('const', 'const_data'),
- ('const_data', 'reshape', {'in': 1}),
- ('reshape_data', 'reduce', {'in': 0}),
- ('const_1', 'const_data_1'),
- ('const_data_1', 'reduce', {'in': 1}),
- ('reduce', 'reduce_data'),
- ('reduce_data', 'invpow', {'in': 0}),
- ('invpow', 'invpow_data'),
- ('invpow_data', 'out_placeholder'),
-
- ('pow_const', 'pow_const_d'),
- ('invpow_const', 'invpow_const_d'),
- ('pow_const_d', 'pow', {'in': 1}),
- ('invpow_const_d', 'invpow', {'in': 1}),
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_placeholder', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/ReplaceSpliceNodePattern_test.py b/tools/mo/unit_tests/mo/middle/ReplaceSpliceNodePattern_test.py
deleted file mode 100644
index e8831b82741862..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ReplaceSpliceNodePattern_test.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.ReplaceSpliceNodePattern import ReplaceSpliceNodePattern
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class ReplaceSpliceNodePatternTests(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- cls.nodes_attributes = {
- 'placeholder': {'kind': 'op', 'op': None},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'splice': {'kind': 'op', 'op': 'Splice', 'context': range(-5, 6), 'const_dim': 0},
- 'splice_data': {'kind': 'data', 'shape': [1, 143]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- }
-
- def test_splice(self):
- graph = build_graph(self.nodes_attributes,
- [('placeholder', 'in_node'),
- ('in_node', 'splice'),
- ('splice', 'splice_data'),
- ('splice_data', 'out_placeholder')])
- ReplaceSpliceNodePattern().find_and_replace_pattern(graph)
-
- ref_graph = build_graph({'in_placeholder': {'kind': 'op', 'op': None},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
-
- 'fill_value': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data': {'kind': 'data'},
-
- 'memory_in': {'kind': 'op', 'op': 'ReadValue'},
- 'memory_in_data': {'kind': 'data'},
- 'crop_mem': {'kind': 'op', 'op': 'Crop', 'offset': 13, 'dim': 130},
- 'crop_mem_data': {'kind': 'data'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data', 'shape': [1, 143]},
- 'memory_out': {'kind': 'op', 'op': 'Assign'},
- 'memory_out_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result'},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
- },
- [
- ('in_placeholder', 'in_node'),
-
- ('fill_value', 'fill_value_data'), ('fill_value_data', 'memory_in'),
-
- ('memory_in', 'memory_in_data'),
- ('memory_in_data', 'crop_mem'),
- ('crop_mem', 'crop_mem_data'),
- ('crop_mem_data', 'concat', {'in': 0}),
- ('in_node', 'concat', {'in': 1}),
- ('concat', 'concat_data'),
- ('concat_data', 'memory_out'),
- ('memory_out', 'memory_out_data'),
- ('memory_out_data', 'result'),
- ('concat_data', 'out_placeholder'),
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_placeholder')
- self.assertTrue(flag, resp)
-
- def test_splice_with_constdim(self):
- graph = build_graph(self.nodes_attributes,
- [('placeholder', 'in_node'),
- ('in_node', 'splice'),
- ('splice', 'splice_data'),
- ('splice_data', 'out_placeholder')])
- Node(graph, 'splice')['const_dim'] = 10
- Node(graph, 'splice_data')['shape'] = [1, 43]
- ReplaceSpliceNodePattern().find_and_replace_pattern(graph)
-
- ref_graph = build_graph({'in_placeholder': {'kind': 'op', 'op': None},
- 'in_node': {'kind': 'data', 'shape': [1, 13]},
- 'split': {'kind': 'op', 'op': 'Split'},
- 'split_data_0': {'kind': 'data'},
- 'split_data_1': {'kind': 'data'},
-
- 'fill_value': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_data': {'kind': 'data'},
-
- 'memory_in': {'kind': 'op', 'op': 'ReadValue'},
- 'memory_in_data': {'kind': 'data'},
- 'crop_mem': {'kind': 'op', 'op': 'Crop', 'offset': 3, 'dim': 30},
- 'crop_mem_data': {'kind': 'data'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data'},
- 'memory_out': {'kind': 'op', 'op': 'Assign'},
- 'memory_out_data': {'kind': 'data'},
- 'result': {'kind': 'op', 'op': 'Result'},
-
-
- 'fill_value_2': {'kind': 'op', 'op': 'Const', 'value': int64_array([0])},
- 'fill_value_2_data': {'kind': 'data'},
-\
- 'memory_in_constdims': {'kind': 'op', 'op': 'ReadValue'},
- 'memory_in_constdims_data': {'kind': 'data'},
- 'crop_mem_constdims': {'kind': 'op', 'op': 'Crop', 'offset': 10, 'dim': 100},
- 'crop_mem_constdims_data': {'kind': 'data'},
- 'concat_constdims': {'kind': 'op', 'op': 'Concat'},
- 'concat_constdims_data': {'kind': 'data'},
- 'memory_out_constdims': {'kind': 'op', 'op': 'Assign'},
- 'memory_out_constdims_data': {'kind': 'data'},
- 'result_constdims': {'kind': 'op', 'op': 'Result'},
- 'crop_first_constdims': {'kind': 'op', 'op': 'Crop', 'offset': 0, 'dim': 10},
- 'crop_first_constdims_data': {'kind': 'data'},
- 'concat_all': {'kind': 'op', 'op': 'Concat'},
- 'concat_all_data': {'kind': 'data', 'shape': [1, 43]},
- 'out_placeholder': {'kind': 'op', 'op': 'placeholder'},
-
- 'axis_const': {'kind': 'op'},
- 'axis_const_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'split_dim_const': {'kind': 'op'},
- 'split_dim_const_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- },
- [
- ('in_placeholder', 'in_node'),
- ('in_node', 'split', {'in': 0}),
- ('split', 'split_data_0', {'out': 0}),
- ('split', 'split_data_1', {'out': 1}),
-
- ('fill_value', 'fill_value_data'), ('fill_value_data', 'memory_in'),
-
- ('memory_in', 'memory_in_data'),
- ('memory_in_data', 'crop_mem'),
- ('crop_mem', 'crop_mem_data'),
- ('crop_mem_data', 'concat', {'in': 0}),
- ('split_data_0', 'concat', {'in': 1}),
- ('concat', 'concat_data'),
- ('concat_data', 'memory_out'),
- ('memory_out', 'memory_out_data'),
- ('memory_out_data', 'result'),
-
- ('fill_value_2', 'fill_value_2_data'), ('fill_value_2_data', 'memory_in_constdims'),
-
- ('memory_in_constdims', 'memory_in_constdims_data'),
- ('memory_in_constdims_data', 'crop_mem_constdims'),
- ('crop_mem_constdims', 'crop_mem_constdims_data'),
- ('crop_mem_constdims_data', 'concat_constdims', {'in': 0}),
- ('split_data_1', 'concat_constdims', {'in': 1}),
- ('concat_constdims', 'concat_constdims_data'),
- ('concat_constdims_data', 'memory_out_constdims'),
- ('memory_out_constdims', 'memory_out_constdims_data'),
- ('memory_out_constdims_data', 'result_constdims'),
- ('concat_constdims_data', 'crop_first_constdims'),
- ('crop_first_constdims', 'crop_first_constdims_data'),
- ('crop_first_constdims_data', 'concat_all', {'in': 1}),
- ('concat_data', 'concat_all', {'in': 0}),
- ('concat_all', 'concat_all_data'),
- ('concat_all_data', 'out_placeholder'),
-
- ('axis_const', 'axis_const_data'),
- ('split_dim_const', 'split_dim_const_data'),
- ('axis_const_data', 'split', {'in': 1}),
- ('split_dim_const_data', 'split', {'in': 2}),
-
- ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'out_placeholder')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/ReverseTransposeNormalization_test.py b/tools/mo/unit_tests/mo/middle/ReverseTransposeNormalization_test.py
deleted file mode 100644
index ed3272b9587a39..00000000000000
--- a/tools/mo/unit_tests/mo/middle/ReverseTransposeNormalization_test.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.ReverseTransposeNormalization import ReverseTransposeNormalization
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect
-
-
-class ReverseTransposeNormalizationTests(unittest.TestCase):
- @classmethod
- def setUpClass(cls):
- cls.nodes_attributes = {
- **regular_op_with_shaped_data('placeholder', [1, 10, 20, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('transpose', [3, 20, 10, 1],
- {'type': 'Transpose', 'op': 'Transpose', 'reverse_order': True}),
- **result('result'),
- }
-
- cls.ref_nodes_attributes = {
- **regular_op_with_shaped_data('placeholder', [1, 10, 20, 3], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('transpose', [3, 20, 10, 1],
- {'type': 'Transpose', 'op': 'Transpose'}),
- **valued_const_with_data('transpose_order', np.array([3, 2, 1, 0])),
- **result('result'),
- }
-
- def test_splice(self):
- graph = build_graph(self.nodes_attributes,
- [*connect('placeholder', '0:transpose'),
- *connect('transpose', 'result'), ])
- ReverseTransposeNormalization().find_and_replace_pattern(graph)
- graph.clean_up()
-
- ref_graph = build_graph(self.ref_nodes_attributes,
- [*connect('placeholder', '0:transpose'),
- *connect('transpose_order', '1:transpose'),
- *connect('transpose', 'result'), ]
- )
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/SSliceComplex_test.py b/tools/mo/unit_tests/mo/middle/SSliceComplex_test.py
deleted file mode 100644
index 0b26541ef4b407..00000000000000
--- a/tools/mo/unit_tests/mo/middle/SSliceComplex_test.py
+++ /dev/null
@@ -1,297 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.SSliceComplex import SSliceComplex
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, \
- regular_op_with_shaped_data, valued_const_with_data
-
-graph_node_attrs = {
- **regular_op_with_shaped_data('placeholder', int64_array([3, 100, 100, 2]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('strided_slice_real', int64_array([3, 100, 100]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice', 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]), 'ellipsis_mask': int64_array([1]), 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0, 1]),
- 'slices': np.array([Ellipsis, 0])
- }),
- **regular_op_with_shaped_data('strided_slice_imag', int64_array([3, 100, 100]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice', 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]), 'ellipsis_mask': int64_array([1]), 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0, 1]),
- 'slices': np.array([Ellipsis, 1])
- }),
- **regular_op_with_shaped_data('complex', int64_array([3, 100, 100, 2]), {'op': 'Complex'}),
- **valued_const_with_data('real_begin', int64_array([0, 0])),
- **valued_const_with_data('imag_begin', int64_array([0, 1])),
- **valued_const_with_data('real_end', int64_array([0, 1])),
- **valued_const_with_data('imag_end', int64_array([0, 2])),
- **valued_const_with_data('real_strides', int64_array([1, 1])),
- **valued_const_with_data('imag_strides', int64_array([1, 1])),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 100, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **result('output'),
-}
-
-graph_edges = [
- ('placeholder', 'placeholder_d', {'out': 0}),
- ('placeholder_d', 'strided_slice_real', {'out': 0, 'in': 0}),
- ('placeholder_d', 'strided_slice_imag', {'out': 0, 'in': 0}),
- *connect('strided_slice_real:0', '0:complex'),
- *connect('strided_slice_imag:0', '1:complex'),
- *connect('real_begin:0', '1:strided_slice_real'),
- *connect('imag_begin:0', '1:strided_slice_imag'),
- *connect('real_end:0', '2:strided_slice_real'),
- *connect('imag_end:0', '2:strided_slice_imag'),
- *connect('real_strides:0', '3:strided_slice_real'),
- *connect('imag_strides:0', '3:strided_slice_imag'),
- *connect('complex:0', '0:abs'),
- *connect('abs:0', 'output'),
-]
-
-
-ref_graph_node_attrs = {
- **regular_op_with_shaped_data('placeholder', int64_array([3, 100, 100, 2]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 100, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **result('output'),
-}
-
-ref_graph_edges = [
- *connect('placeholder:0', '0:abs'),
- *connect('abs:0', 'output'),
-]
-
-
-non_transformed_graph_node_attrs = {
- **regular_op_with_shaped_data('placeholder_0', int64_array([3, 100, 100, 2]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('placeholder_1', int64_array([3, 100, 100, 2]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('strided_slice_real', int64_array([3, 100, 100]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice', 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]), 'ellipsis_mask': int64_array([1]), 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0, 1]),
- 'slices': np.array([Ellipsis, 0])
- }),
- **regular_op_with_shaped_data('strided_slice_imag', int64_array([3, 100, 100]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice', 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]), 'ellipsis_mask': int64_array([1]), 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0, 1]),
- 'slices': np.array([Ellipsis, 1])
- }),
- **regular_op_with_shaped_data('complex', int64_array([3, 100, 100, 2]), {'op': 'Complex'}),
- **valued_const_with_data('real_begin', int64_array([0, 0])),
- **valued_const_with_data('imag_begin', int64_array([0, 1])),
- **valued_const_with_data('real_end', int64_array([0, 1])),
- **valued_const_with_data('imag_end', int64_array([0, 2])),
- **valued_const_with_data('real_strides', int64_array([1, 1])),
- **valued_const_with_data('imag_strides', int64_array([1, 1])),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 100, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **result('output'),
-}
-
-non_transformed_graph_edges = [
- *connect('placeholder_0:0', '0:strided_slice_real'),
- *connect('placeholder_1:0', '0:strided_slice_imag'),
- *connect('strided_slice_real:0', '0:complex'),
- *connect('strided_slice_imag:0', '1:complex'),
- *connect('real_begin:0', '1:strided_slice_real'),
- *connect('imag_begin:0', '1:strided_slice_imag'),
- *connect('real_end:0', '2:strided_slice_real'),
- *connect('imag_end:0', '2:strided_slice_imag'),
- *connect('real_strides:0', '3:strided_slice_real'),
- *connect('imag_strides:0', '3:strided_slice_imag'),
- *connect('complex:0', '0:abs'),
- *connect('abs:0', 'output'),
-]
-
-
-graph_node_attrs_2 = {
- **regular_op_with_shaped_data('placeholder', int64_array([3, 100, 2, 66, 34]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('strided_slice_real', int64_array([3, 100, 66, 34]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice',
- 'begin_mask': int64_array([0, 0, 1, 0, 0]),
- 'end_mask': int64_array([0, 0, 1, 0, 0]),
- 'ellipsis_mask': int64_array([0, 0, 0, 0, 0]),
- 'new_axis_mask': int64_array([0, 0, 0, 0, 0]),
- 'shrink_axis_mask': int64_array([0, 0, 1, 0, 0]),
- 'slices': np.array([slice(None, None, 1),
- slice(None, None, 1),
- 0,
- slice(None, None, 1),
- slice(None, None, 1)])
- }),
- **regular_op_with_shaped_data('strided_slice_imag', int64_array([3, 100, 66, 34]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice',
- 'begin_mask': int64_array([0, 0, 1, 0, 0]),
- 'end_mask': int64_array([0, 0, 1, 0, 0]),
- 'ellipsis_mask': int64_array([0, 0, 0, 0, 0]),
- 'new_axis_mask': int64_array([0, 0, 0, 0, 0]),
- 'shrink_axis_mask': int64_array([0, 0, 1, 0, 0]),
- 'slices': np.array([slice(None, None, 1),
- slice(None, None, 1),
- 1,
- slice(None, None, 1),
- slice(None, None, 1)])
- }),
- **regular_op_with_shaped_data('complex', int64_array([3, 100, 66, 34, 2]), {'op': 'Complex'}),
- **valued_const_with_data('real_begin', int64_array([0, 0, 0, 0, 0])),
- **valued_const_with_data('imag_begin', int64_array([0, 0, 1, 0, 0])),
- **valued_const_with_data('real_end', int64_array([0, 0, 1, 0, 0])),
- **valued_const_with_data('imag_end', int64_array([0, 0, 2, 0, 0])),
- **valued_const_with_data('real_strides', int64_array([1, 1, 1, 1, 1])),
- **valued_const_with_data('imag_strides', int64_array([1, 1, 1, 1, 1])),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 66, 34, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **result('output'),
-}
-
-
-ref_graph_node_attrs_2 = {
- **regular_op_with_shaped_data('placeholder', int64_array([3, 100, 2, 66, 34]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('perm', int64_array([0, 1, 3, 4, 2])),
- **regular_op_with_shaped_data('transpose', int64_array([3, 100, 66, 34, 2]),
- {'type': 'Transpose', 'op': 'Transpose'}),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 66, 34, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **result('output'),
-}
-
-ref_graph_edges_2 = [
- *connect('placeholder:0', '0:transpose'),
- *connect('perm:0', '1:transpose'),
- *connect('transpose:0', '0:abs'),
- *connect('abs:0', 'output'),
-]
-
-
-graph_node_attrs_3 = {
- **regular_op_with_shaped_data('placeholder', int64_array([3, 100, 2, 66, 34]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_shaped_data('strided_slice_real', int64_array([3, 100, 66, 34]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice',
- 'begin_mask': int64_array([0, 0, 1, 0, 0]),
- 'end_mask': int64_array([0, 0, 1, 0, 0]),
- 'ellipsis_mask': int64_array([0, 0, 0, 0, 0]),
- 'new_axis_mask': int64_array([0, 0, 0, 0, 0]),
- 'shrink_axis_mask': int64_array([0, 0, 1, 0, 0]),
- 'slices': np.array([slice(None, None, 1),
- slice(None, None, 1),
- 0,
- slice(None, None, 1),
- slice(None, None, 1)])
- }),
- **regular_op_with_shaped_data('strided_slice_imag', int64_array([3, 100, 66, 34]),
- {
- 'type': 'StridedSlice', 'op': 'StridedSlice',
- 'begin_mask': int64_array([0, 0, 1, 0, 0]),
- 'end_mask': int64_array([0, 0, 1, 0, 0]),
- 'ellipsis_mask': int64_array([0, 0, 0, 0, 0]),
- 'new_axis_mask': int64_array([0, 0, 0, 0, 0]),
- 'shrink_axis_mask': int64_array([0, 0, 1, 0, 0]),
- 'slices': np.array([slice(None, None, 1),
- slice(None, None, 1),
- 1,
- slice(None, None, 1),
- slice(None, None, 1)])
- }),
- **regular_op_with_shaped_data('complex', int64_array([3, 100, 66, 34, 2]), {'op': 'Complex'}),
- **regular_op_with_shaped_data('roll', int64_array([3, 100, 66, 34, 2]), {'type': 'Roll', 'op': 'Roll'}),
- **valued_const_with_data('real_begin', int64_array([0, 0, 0, 0, 0])),
- **valued_const_with_data('imag_begin', int64_array([0, 0, 1, 0, 0])),
- **valued_const_with_data('real_end', int64_array([0, 0, 1, 0, 0])),
- **valued_const_with_data('imag_end', int64_array([0, 0, 2, 0, 0])),
- **valued_const_with_data('real_strides', int64_array([1, 1, 1, 1, 1])),
- **valued_const_with_data('imag_strides', int64_array([1, 1, 1, 1, 1])),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 66, 34, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **valued_const_with_data('shift', int64_array([20, 20])),
- **valued_const_with_data('axis', int64_array([1, -2, -1])),
- **result('output'),
-}
-
-graph_edges_2 = [
- ('placeholder', 'placeholder_d', {'out': 0}),
- ('placeholder_d', 'strided_slice_real', {'out': 0, 'in': 0}),
- ('placeholder_d', 'strided_slice_imag', {'out': 0, 'in': 0}),
- *connect('strided_slice_real:0', '0:complex'),
- *connect('strided_slice_imag:0', '1:complex'),
- *connect('real_begin:0', '1:strided_slice_real'),
- *connect('imag_begin:0', '1:strided_slice_imag'),
- *connect('real_end:0', '2:strided_slice_real'),
- *connect('imag_end:0', '2:strided_slice_imag'),
- *connect('real_strides:0', '3:strided_slice_real'),
- *connect('imag_strides:0', '3:strided_slice_imag'),
- *connect('complex:0', '0:roll'),
- *connect('shift:0', '1:roll'),
- *connect('axis:0', '2:roll'),
- *connect('roll:0', '0:abs'),
- *connect('abs:0', 'output'),
-]
-
-ref_graph_node_attrs_3 = {
- **regular_op_with_shaped_data('placeholder', int64_array([3, 100, 2, 66, 34]),
- {'type': 'Parameter', 'op': 'Parameter'}),
- **valued_const_with_data('perm', int64_array([0, 1, 3, 4, 2])),
- **regular_op_with_shaped_data('transpose', int64_array([3, 100, 66, 34, 2]),
- {'type': 'Transpose', 'op': 'Transpose'}),
- **regular_op_with_shaped_data('roll', int64_array([3, 100, 66, 34, 2]), {'type': 'Roll', 'op': 'Roll'}),
- **valued_const_with_data('shift', int64_array([20, 20])),
- **valued_const_with_data('axis', int64_array([1, 3, 4])),
- **regular_op_with_shaped_data('abs', int64_array([3, 100, 66, 34, 2]), {'type': 'Abs', 'op': 'Abs'}),
- **result('output'),
-}
-
-ref_graph_edges_3 = [
- *connect('placeholder:0', '0:transpose'),
- *connect('perm:0', '1:transpose'),
- *connect('transpose:0', '0:roll'),
- *connect('shift:0', '1:roll'),
- *connect('axis:0', '2:roll'),
- *connect('roll:0', '0:abs'),
- *connect('abs:0', 'output'),
-]
-
-
-class SSliceComplexMiddleStageTest(unittest.TestCase):
- def test_replacement_for_the_last_axis(self):
- graph = build_graph(nodes_attrs=graph_node_attrs, edges=graph_edges)
- SSliceComplex().find_and_replace_pattern(graph)
- graph.clean_up()
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs, edges=ref_graph_edges)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_nonreplacement_for_the_last_axis(self):
- graph = build_graph(nodes_attrs=non_transformed_graph_node_attrs, edges=non_transformed_graph_edges)
- ref_graph = build_graph(nodes_attrs=non_transformed_graph_node_attrs, edges=non_transformed_graph_edges)
- SSliceComplex().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_replacement_for_non_last_axis(self):
- graph = build_graph(nodes_attrs=graph_node_attrs_2, edges=graph_edges)
- SSliceComplex().find_and_replace_pattern(graph)
- graph.clean_up()
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs_2, edges=ref_graph_edges_2)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_replacement_with_update_roll_axes(self):
- graph = build_graph(nodes_attrs=graph_node_attrs_3, edges=graph_edges_2)
- SSliceComplex().find_and_replace_pattern(graph)
- graph.clean_up()
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs_3, edges=ref_graph_edges_3)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/SharedWeightsDuplication_test.py b/tools/mo/unit_tests/mo/middle/SharedWeightsDuplication_test.py
deleted file mode 100644
index dc80ca1b2a73c5..00000000000000
--- a/tools/mo/unit_tests/mo/middle/SharedWeightsDuplication_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.SharedWeightsDuplication import SharedWeightsDuplication
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'const': {'shape': None, 'type': 'Const', 'kind': 'op', 'op': 'Const'},
- # Mul and Add operations
- 'mul_1': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_2': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'mul_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_3': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'mul_3_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_3_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Concat1 operation
- 'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': {'op': 'Result', 'kind': 'op'}
-}
-
-
-class DuplicateSharedWeightsTests(unittest.TestCase):
- def test_duplicate_shared_weights_1(self):
- graph = build_graph(nodes_attributes,
- [('const', 'mul_1_w'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_1_w', 'mul_3'),
- ('mul_3', 'mul_3_data'),
- ('mul_1_data', 'concat_1'),
- ('mul_2_data', 'concat_1'),
- ('mul_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])}},
- nodes_with_edges_only=True
- )
-
- graph_ref = build_graph(nodes_attributes,
- [
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_3_w', 'mul_3'),
- ('mul_3', 'mul_3_data'),
- ('mul_1_data', 'concat_1'),
- ('mul_2_data', 'concat_1'),
- ('mul_3_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_3_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- }, nodes_with_edges_only=True)
-
- SharedWeightsDuplication().find_and_replace_pattern(graph)
- graph.clean_up()
- graph_ref.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/SliceConverter_test.py b/tools/mo/unit_tests/mo/middle/SliceConverter_test.py
deleted file mode 100644
index 1c29820e09df9c..00000000000000
--- a/tools/mo/unit_tests/mo/middle/SliceConverter_test.py
+++ /dev/null
@@ -1,383 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.SliceConverter import ConvertSlice
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, \
- regular_op_with_empty_data, result, connect, connect_data
-
-nodes_attributes = {
- **regular_op_with_shaped_data('input', [2, 3, 300, 300], {'type': 'Parameter', 'op': 'Parameter'}),
- **regular_op_with_empty_data('starts', {'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('ends', {'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('axes', {'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('steps', {'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('slice', {'op': 'Slice', 'type': None}),
-
- **regular_op_with_empty_data('ss_begin_cast', {'op': 'Cast', 'type': 'Convert', 'dst_type': np.int64}),
- **regular_op_with_empty_data('ss_begin_clamp', {'op': 'Clamp', 'type': None}),
- **regular_op_with_empty_data('ss_begin_clamp_min', {'value': np.iinfo(np.int32).min, 'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('ss_begin_clamp_max', {'value': np.iinfo(np.int32).max, 'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('ss_begin_gather_0', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_begin_gather_0_idx', int64_array([0])),
- **regular_op_with_shaped_data('ss_begin_gather_0_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_begin_gather_1', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_begin_gather_1_idx', int64_array([1])),
- **regular_op_with_shaped_data('ss_begin_gather_1_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_begin_gather_2', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_begin_gather_2_idx', int64_array([2])),
- **regular_op_with_shaped_data('ss_begin_gather_2_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_begin_gather_3', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_begin_gather_3_idx', int64_array([3])),
- **regular_op_with_shaped_data('ss_begin_gather_3_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_begin_const_0', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_begin_const_1', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_begin_const_2', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_begin_const_3', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_begin_concat', {'op': 'Concat', 'type': 'Concat'}),
-
- **regular_op_with_empty_data('ss_end_cast', {'op': 'Cast', 'type': 'Convert', 'dst_type': np.int64}),
- **regular_op_with_empty_data('ss_end_clamp', {'op': 'Clamp', 'type': None}),
- **regular_op_with_empty_data('ss_end_clamp_min', {'value': np.iinfo(np.int32).min, 'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('ss_end_clamp_max', {'value': np.iinfo(np.int32).max, 'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('ss_end_gather_0', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_end_gather_0_idx', int64_array([0])),
- **regular_op_with_shaped_data('ss_end_gather_0_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_end_gather_1', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_end_gather_1_idx', int64_array([1])),
- **regular_op_with_shaped_data('ss_end_gather_1_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_end_gather_2', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_end_gather_2_idx', int64_array([2])),
- **regular_op_with_shaped_data('ss_end_gather_2_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_end_gather_3', {'op': 'Gather', 'type': 'Gather'}),
- **valued_const_with_data('ss_end_gather_3_idx', int64_array([3])),
- **regular_op_with_shaped_data('ss_end_gather_3_axis', [], {'op': 'Const', 'type': 'Const', 'value': [0]}),
- **regular_op_with_empty_data('ss_end_const_0', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_end_const_1', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_end_const_2', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_end_const_3', {'op': 'Const', 'type': 'Const', 'value': int64_array([0])}),
- **regular_op_with_empty_data('ss_end_concat', {'op': 'Concat', 'type': 'Concat'}),
-
- **regular_op_with_empty_data('ss_strides', {'op': 'Const', 'type': 'Const'}),
- **regular_op_with_empty_data('ss', {'op': 'StridedSlice', 'type': 'StridedSlice',
- 'new_axis_mask': np.zeros(4, dtype=np.int64),
- 'shrink_axis_mask': np.zeros(4, dtype=np.int64),
- 'ellipsis_mask': np.zeros(4, dtype=np.int64)}),
- **result('result')
-}
-
-pattern_graph = [
- *connect('input:0', '0:slice'),
- *connect('starts:0', '1:slice'),
- *connect('ends:0', '2:slice'),
- *connect('axes:0', '3:slice'),
- *connect('steps:0', '4:slice'),
- *connect('slice:0', '0:result')
-]
-
-pattern_ref_graph = [
- *connect('input:0', '0:ss'),
- *connect('starts:0', '0:ss_begin_clamp'),
- *connect('ss_begin_clamp:0', '0:ss_begin_cast'),
- *connect('ss_begin_clamp_min:0', '1:ss_begin_clamp'),
- *connect('ss_begin_clamp_max:0', '2:ss_begin_clamp'),
- *connect('ss_begin_concat:0', '1:ss'),
- *connect('ends:0', '0:ss_end_clamp'),
- *connect('ss_end_clamp:0', '0:ss_end_cast'),
- *connect('ss_end_clamp_min:0', '1:ss_end_clamp'),
- *connect('ss_end_clamp_max:0', '2:ss_end_clamp'),
- *connect('ss_end_concat:0', '2:ss'),
- *connect('ss_strides:0', '3:ss'),
- *connect('ss:0', '0:result'),
-
- *connect('ss_begin_gather_0_idx:0', '1:ss_begin_gather_0'),
- *connect('ss_begin_gather_0_axis:0', '2:ss_begin_gather_0'),
- *connect('ss_begin_gather_1_idx:0', '1:ss_begin_gather_1'),
- *connect('ss_begin_gather_1_axis:0', '2:ss_begin_gather_1'),
- *connect('ss_begin_gather_2_idx:0', '1:ss_begin_gather_2'),
- *connect('ss_begin_gather_2_axis:0', '2:ss_begin_gather_2'),
- *connect('ss_begin_gather_3_idx:0', '1:ss_begin_gather_3'),
- *connect('ss_begin_gather_3_axis:0', '2:ss_begin_gather_3'),
-
- *connect('ss_end_gather_0_idx:0', '1:ss_end_gather_0'),
- *connect('ss_end_gather_0_axis:0', '2:ss_end_gather_0'),
- *connect('ss_end_gather_1_idx:0', '1:ss_end_gather_1'),
- *connect('ss_end_gather_1_axis:0', '2:ss_end_gather_1'),
- *connect('ss_end_gather_2_idx:0', '1:ss_end_gather_2'),
- *connect('ss_end_gather_2_axis:0', '2:ss_end_gather_2'),
- *connect('ss_end_gather_3_idx:0', '1:ss_end_gather_3'),
- *connect('ss_end_gather_3_axis:0', '2:ss_end_gather_3'),
-]
-
-
-class ConvertSliceTests(unittest.TestCase):
-
- def test_convert_slice_to_strided_slice_one_axis(self):
- graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_graph,
- update_attributes={
- 'starts': {'value': int64_array([0]), 'shape': [1]},
- 'ends': {'value': int64_array([1]), 'shape': [1]},
- 'axes': {'value': int64_array([0]), 'shape': [1]},
- 'axes_d': {'value': int64_array([0]), 'shape': [1]},
- 'steps': {'value': int64_array([1]), 'shape': [1]},
- 'steps_d': {'value': int64_array([1]), 'shape': [1]}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_ref_graph + [
- *connect('ss_begin_cast:0', '0:ss_begin_gather_0'),
- *connect('ss_begin_gather_0:0', '0:ss_begin_concat'),
- *connect('ss_begin_const_1:0', '1:ss_begin_concat'),
- *connect('ss_begin_const_2:0', '2:ss_begin_concat'),
- *connect('ss_begin_const_3:0', '3:ss_begin_concat'),
-
- *connect('ss_end_cast:0', '0:ss_end_gather_0'),
- *connect('ss_end_gather_0:0', '0:ss_end_concat'),
- *connect('ss_end_const_1:0', '1:ss_end_concat'),
- *connect('ss_end_const_2:0', '2:ss_end_concat'),
- *connect('ss_end_const_3:0', '3:ss_end_concat'),
- ],
- update_attributes={
- 'starts': {'value': int64_array([0]), 'shape': [1]},
- 'ends': {'value': int64_array([1]), 'shape': [1]},
- 'ss_strides': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]},
- 'ss': {'begin_mask': int64_array([1, 0, 0, 0]), 'end_mask': int64_array([1, 0, 0, 0])}
- }
- )
- ConvertSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_convert_slice_to_strided_slice_one_axis_steps_is_2(self):
- graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_graph,
- update_attributes={
- 'starts': {'value': int64_array([0]), 'shape': [1]},
- 'ends': {'value': int64_array([150]), 'shape': [1]},
- 'axes': {'value': int64_array([2]), 'shape': [1]},
- 'axes_d': {'value': int64_array([2]), 'shape': [1]},
- 'steps': {'value': int64_array([2]), 'shape': [1]},
- 'steps_d': {'value': int64_array([2]), 'shape': [1]}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_ref_graph + [
- *connect('ss_begin_cast:0', '0:ss_begin_gather_0'),
- *connect('ss_begin_gather_0:0', '2:ss_begin_concat'),
- *connect('ss_begin_const_0:0', '0:ss_begin_concat'),
- *connect('ss_begin_const_1:0', '1:ss_begin_concat'),
- *connect('ss_begin_const_3:0', '3:ss_begin_concat'),
-
- *connect('ss_end_cast:0', '0:ss_end_gather_0'),
- *connect('ss_end_gather_0:0', '2:ss_end_concat'),
- *connect('ss_end_const_0:0', '0:ss_end_concat'),
- *connect('ss_end_const_1:0', '1:ss_end_concat'),
- *connect('ss_end_const_3:0', '3:ss_end_concat'),
- ],
- update_attributes={
- 'starts': {'value': int64_array([0]), 'shape': [1]},
- 'ends': {'value': int64_array([150]), 'shape': [1]},
- 'ss_strides': {'value': int64_array([1, 1, 2, 1]), 'shape': [4]},
- 'ss': {'begin_mask': int64_array([0, 0, 1, 0]), 'end_mask': int64_array([0, 0, 1, 0])}
- }
- )
- ConvertSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_convert_slice_to_strided_slice_two_axes(self):
- graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_graph,
- update_attributes={
- 'starts': {'value': int64_array([0, 0]), 'shape': [2]},
- 'ends': {'value': int64_array([150, 150]), 'shape': [2]},
- 'axes': {'value': int64_array([2, 3]), 'shape': [2]},
- 'axes_d': {'value': int64_array([2, 3]), 'shape': [2]},
- 'steps': {'value': int64_array([1, 1]), 'shape': [2]},
- 'steps_d': {'value': int64_array([1, 1]), 'shape': [2]}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_ref_graph + [
- *connect('ss_begin_cast:0', '0:ss_begin_gather_0'),
- *connect('ss_begin_gather_0:0', '2:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_1'),
- *connect('ss_begin_gather_1:0', '3:ss_begin_concat'),
- *connect('ss_begin_const_0:0', '0:ss_begin_concat'),
- *connect('ss_begin_const_1:0', '1:ss_begin_concat'),
-
- *connect('ss_end_cast:0', '0:ss_end_gather_0'),
- *connect('ss_end_gather_0:0', '2:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_1'),
- *connect('ss_end_gather_1:0', '3:ss_end_concat'),
- *connect('ss_end_const_0:0', '0:ss_end_concat'),
- *connect('ss_end_const_1:0', '1:ss_end_concat'),
- ],
- update_attributes={
- 'starts': {'value': int64_array([0, 0]), 'shape': [2]},
- 'ends': {'value': int64_array([150, 150]), 'shape': [2]},
- 'ss_strides': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]},
- 'ss': {'begin_mask': int64_array([0, 0, 1, 1]), 'end_mask': int64_array([0, 0, 1, 1])}
- }
- )
- ConvertSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_convert_slice_to_strided_slice_three_axes(self):
- graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_graph,
- update_attributes={
- 'starts': {'value': int64_array([0, 0, 0]), 'shape': [3]},
- 'ends': {'value': int64_array([2, 150, 150]), 'shape': [3]},
- 'axes': {'value': int64_array([1, 2, 3]), 'shape': [3]},
- 'axes_d': {'value': int64_array([1, 2, 3]), 'shape': [3]},
- 'steps': {'value': int64_array([1, 1, 1]), 'shape': [3]},
- 'steps_d': {'value': int64_array([1, 1, 1]), 'shape': [3]}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_ref_graph + [
- *connect('ss_begin_cast:0', '0:ss_begin_gather_0'),
- *connect('ss_begin_gather_0:0', '1:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_1'),
- *connect('ss_begin_gather_1:0', '2:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_2'),
- *connect('ss_begin_gather_2:0', '3:ss_begin_concat'),
- *connect('ss_begin_const_0:0', '0:ss_begin_concat'),
-
- *connect('ss_end_cast:0', '0:ss_end_gather_0'),
- *connect('ss_end_gather_0:0', '1:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_1'),
- *connect('ss_end_gather_1:0', '2:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_2'),
- *connect('ss_end_gather_2:0', '3:ss_end_concat'),
- *connect('ss_end_const_0:0', '0:ss_end_concat'),
- ],
- update_attributes={
- 'starts': {'value': int64_array([0, 0, 0]), 'shape': [3]},
- 'ends': {'value': int64_array([2, 150, 150]), 'shape': [3]},
- 'ss_strides': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]},
- 'ss': {'begin_mask': int64_array([0, 1, 1, 1]), 'end_mask': int64_array([0, 1, 1, 1])}
- }
- )
- ConvertSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_convert_slice_to_strided_slice_not_sorted_axes(self):
- graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_graph,
- update_attributes={
- 'starts': {'value': int64_array([0, 1, 1, 0]), 'shape': [4]},
- 'ends': {'value': int64_array([1, 150, 150, 2]), 'shape': [4]},
- 'axes': {'value': int64_array([0, 2, 3, 1]), 'shape': [4]},
- 'axes_d': {'value': int64_array([0, 2, 3, 1]), 'shape': [4]},
- 'steps': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]},
- 'steps_d': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]}
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_ref_graph + [
- *connect('ss_begin_cast:0', '0:ss_begin_gather_0'),
- *connect('ss_begin_gather_0:0', '0:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_1'),
- *connect('ss_begin_gather_1:0', '2:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_2'),
- *connect('ss_begin_gather_2:0', '3:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_3'),
- *connect('ss_begin_gather_3:0', '1:ss_begin_concat'),
-
- *connect('ss_end_cast:0', '0:ss_end_gather_0'),
- *connect('ss_end_gather_0:0', '0:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_1'),
- *connect('ss_end_gather_1:0', '2:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_2'),
- *connect('ss_end_gather_2:0', '3:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_3'),
- *connect('ss_end_gather_3:0', '1:ss_end_concat'),
- ],
- update_attributes={
- 'starts': {'value': int64_array([0, 1, 1, 0]), 'shape': [4]},
- 'ends': {'value': int64_array([1, 150, 150, 2]), 'shape': [4]},
- 'ss_strides': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]},
- 'ss': {'begin_mask': int64_array([1, 1, 1, 1]), 'end_mask': int64_array([1, 1, 1, 1])}
- }
- )
- ConvertSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_convert_slice_to_strided_slice_without_axes_and_steps(self):
- graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=[
- *connect('input:0', '0:slice'),
- *connect('starts:0', '1:slice'),
- *connect('ends:0', '2:slice'),
- *connect('slice:0', '0:result')
- ],
- update_attributes={
- 'starts': {'value': int64_array([0, 0, 0, 0]), 'shape': [4]},
- 'ends': {'value': int64_array([1, 2, 150, 150]), 'shape': [4]},
- },
- nodes_with_edges_only=True
- )
-
- ref_graph = build_graph(
- nodes_attrs=nodes_attributes,
- edges=pattern_ref_graph + [
- *connect('ss_begin_cast:0', '0:ss_begin_gather_0'),
- *connect('ss_begin_gather_0:0', '0:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_1'),
- *connect('ss_begin_gather_1:0', '1:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_2'),
- *connect('ss_begin_gather_2:0', '2:ss_begin_concat'),
- *connect_data('ss_begin_cast:0', '0:ss_begin_gather_3'),
- *connect('ss_begin_gather_3:0', '3:ss_begin_concat'),
-
- *connect('ss_end_cast:0', '0:ss_end_gather_0'),
- *connect('ss_end_gather_0:0', '0:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_1'),
- *connect('ss_end_gather_1:0', '1:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_2'),
- *connect('ss_end_gather_2:0', '2:ss_end_concat'),
- *connect_data('ss_end_cast:0', '0:ss_end_gather_3'),
- *connect('ss_end_gather_3:0', '3:ss_end_concat'),
- ],
- update_attributes={
- 'starts': {'value': int64_array([0, 0, 0, 0]), 'shape': [4]},
- 'ends': {'value': int64_array([1, 2, 150, 150]), 'shape': [4]},
- 'ss_strides': {'value': int64_array([1, 1, 1, 1]), 'shape': [4]},
- 'ss': {'begin_mask': int64_array([1, 1, 1, 1]), 'end_mask': int64_array([1, 1, 1, 1])}
- }
- )
- ConvertSlice().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/SliceLikeToStridedSlice_test.py b/tools/mo/unit_tests/mo/middle/SliceLikeToStridedSlice_test.py
deleted file mode 100644
index 739055d0136bab..00000000000000
--- a/tools/mo/unit_tests/mo/middle/SliceLikeToStridedSlice_test.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.SliceLikeToStridedSlice import SliceLikeToStridedSlice
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'input': {'kind': 'op', 'op': 'Const'},
- 'input_data': {'kind': 'data'},
-
- 'shape_like_input': {'kind': 'op', 'op': 'Const'},
- 'shape_like_input_data': {'kind': 'data'},
-
- 'slice_like': {'kind': 'op', 'op': 'slice_like'},
- 'slice_like_data': {'kind': 'data', 'shape': None, 'value': None},
-
- 'result': {'kind': 'op', 'op': 'Result'},
-
- 'shape': {'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data'},
- 'rank_1_d': {'kind': 'op', 'op': 'ShapeOf'},
- 'rank_1_d_data': {'kind': 'data'},
- 'rank': {'kind': 'op', 'op': 'Squeeze'},
- 'rank_data': {'kind': 'data'},
- 'rank_const': {'kind': 'op', 'op': 'Const'},
- 'rank_const_data': {'kind': 'data'},
-
- 'shape_like': {'kind': 'op', 'op': 'ShapeOf'},
- 'shape_like_data': {'kind': 'data'},
- 'rank_like_1_d': {'kind': 'op', 'op': 'ShapeOf'},
- 'rank_like_1_d_data': {'kind': 'data'},
- 'rank_like': {'kind': 'op', 'op': 'Squeeze'},
- 'rank_like_const': {'kind': 'op', 'op': 'Const'},
- 'rank_like_const_data': {'kind': 'data'},
-
- 'begin': {'kind': 'op', 'op': 'Const'},
- 'begin_data': {'kind': 'data'},
- 'ss': {'kind': 'op', 'op': 'StridedSlice'},
-
- 'start_idx_like': {'kind': 'op', 'op': 'Const'},
- 'start_idx_like_data': {'kind': 'data'},
- 'end_idx_like': {'kind': 'op', 'op': 'Const'},
- 'end_idx_like_data': {'kind': 'data'},
- 'end_idx_like_const': {'kind': 'op', 'op': 'Const'},
- 'end_idx_like_const_data': {'kind': 'data'},
- 'end_idx_like_add': {'kind': 'op', 'op': 'Add'},
- 'end_idx_like_add_data': {'kind': 'data'},
- 'delta_like': {'kind': 'op', 'op': 'Const'},
- 'delta_like_data': {'kind': 'data'},
- 'range_like': {'kind': 'op', 'op': 'Range'},
- 'range_like_data': {'kind': 'data'},
- 'gather_like': {'kind': 'op', 'op': 't_gather'},
- 'gather_like_data': {'kind': 'data'},
- 'gather_like_axis': {'kind': 'op', 'op': 'Const'},
- 'gather_like_axis_data': {'kind': 'data'},
- 'concat': {'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'kind': 'data'},
-
- 'start_idx': {'kind': 'op', 'op': 'Const'},
- 'start_idx_data': {'kind': 'data'},
- 'start_idx_const': {'kind': 'op', 'op': 'Const'},
- 'start_idx_const_data': {'kind': 'data'},
- 'start_idx_add': {'kind': 'op', 'op': 'Add'},
- 'start_idx_add_data': {'kind': 'data'},
- 'end_idx': {'kind': 'op', 'op': 'Add'},
- 'end_idx_data': {'kind': 'data'},
- 'end_idx_axis': {'kind': 'op', 'op': 'Const'},
- 'end_idx_axis_data': {'kind': 'data'},
- 'end_idx_const': {'kind': 'op', 'op': 'Const'},
- 'end_idx_const_data': {'kind': 'data'},
- 'end_idx_add': {'kind': 'op', 'op': 'Add'},
- 'end_idx_add_data': {'kind': 'data'},
- 'delta': {'kind': 'op', 'op': 'Const'},
- 'delta_data': {'kind': 'data'},
- 'range': {'kind': 'op', 'op': 'Range'},
- 'range_data': {'kind': 'data'},
- 't_gather': {'kind': 'op', 'op': 't_gather'},
- 'gather_data': {'kind': 'data'},
- 'gather_axis': {'kind': 'op', 'op': 'Const'},
- 'gather_axis_data': {'kind': 'data'}
-
-}
-
-edges = [
- ('input', 'input_data'),
- ('input_data', 'slice_like', {'in': 0}),
- ('shape_like_input', 'shape_like_input_data'),
- ('shape_like_input_data', 'slice_like', {'in': 1}),
- ('slice_like', 'slice_like_data'),
- ('slice_like_data', 'result')
-]
-
-same_input_shapes_dims_edges = [
- ('input', 'input_data'),
- ('input_data', 'ss', {'in': 0}),
- ('ss', 'slice_like_data'),
- ('slice_like_data', 'result'),
- ('shape_like_input', 'shape_like_input_data'),
- ('shape_like_input_data', 'shape_like'),
- ('shape_like', 'shape_like_data'),
- ('shape_like_data', 'ss', {'in': 2}),
- ('begin', 'begin_data'),
- ('begin_data', 'ss', {'in': 1})
-]
-
-shape_like_sub_graph_edges = [
- ('input', 'input_data'),
- ('input_data', 'ss', {'in': 0}),
- ('ss', 'slice_like_data'),
- ('slice_like_data', 'result'),
- ('begin', 'begin_data'),
- ('begin_data', 'ss', {'in': 1}),
- ('shape_like_input', 'shape_like_input_data'),
- ('shape_like_input_data', 'shape_like'),
- ('shape_like', 'shape_like_data'),
- ('shape_like_data', 'rank_like_1_d'),
- ('rank_like_1_d', 'rank_like_1_d_data'),
- ('rank_like_1_d_data', 'rank_like', {'in': 0}),
- ('rank_like_const', 'rank_like_const_data'),
- ('rank_like_const_data', 'rank_like', {'in': 1}),
- ('end_idx_like', 'end_idx_like_data'),
- ('end_idx_like_const', 'end_idx_like_const_data'),
- ('end_idx_like_data', 'end_idx_like_add', {'in': 0}),
- ('end_idx_like_const_data', 'end_idx_like_add', {'in': 1}),
- ('end_idx_like_add', 'end_idx_like_add_data'),
- ('end_idx_like_add_data', 'range_like', {'in': 1}),
- ('start_idx_like', 'start_idx_like_data'),
- ('start_idx_like_data', 'range_like', {'in': 0}),
- ('delta_like', 'delta_like_data'),
- ('delta_like_data', 'range_like', {'in': 2}),
- ('range_like', 'range_like_data'),
- ('range_like_data', 'gather_like', {'in': 1}),
- ('shape_like_data', 'gather_like', {'in': 0}),
- ('gather_like_axis', 'gather_like_axis_data'),
- ('gather_like_axis_data', 'gather_like', {'in': 2}),
- ('gather_like', 'gather_like_data')
-]
-
-last_axis_index = shape_like_sub_graph_edges + [('gather_like_data', 'ss', {'in': 2})]
-
-input_sub_graph_edges = [
- ('input_data', 'shape'),
- ('shape', 'shape_data'),
- ('shape_data', 'rank_1_d'),
- ('rank_1_d', 'rank_1_d_data'),
- ('rank_1_d_data', 'rank', {'in': 0}),
- ('rank_const', 'rank_const_data'),
- ('rank_const_data', 'rank', {'in': 1}),
- ('rank', 'rank_data'),
- ('rank_data', 'end_idx', {'in': 0}),
- ('end_idx_axis', 'end_idx_axis_data'),
- ('end_idx_axis_data', 'end_idx', {'in': 1}),
- ('end_idx', 'end_idx_data'),
- ('end_idx_data', 'end_idx_add', {'in': 0}),
- ('end_idx_const', 'end_idx_const_data'),
- ('end_idx_const_data', 'end_idx_add', {'in': 1}),
- ('start_idx', 'start_idx_data'),
- ('start_idx_data', 'start_idx_add', {'in': 0}),
- ('start_idx_const', 'start_idx_const_data'),
- ('start_idx_const_data', 'start_idx_add', {'in': 1}),
- ('end_idx_add', 'end_idx_add_data'),
- ('start_idx_add', 'start_idx_add_data'),
- ('delta', 'delta_data'),
- ('start_idx_add_data', 'range', {'in': 0}),
- ('end_idx_add_data', 'range', {'in': 1}),
- ('delta_data', 'range', {'in': 2}),
- ('range', 'range_data'),
- ('range_data', 't_gather', {'in': 1}),
- ('shape_data', 't_gather', {'in': 0}),
- ('gather_axis', 'gather_axis_data'),
- ('gather_axis_data', 't_gather', {'in': 2}),
- ('t_gather', 'gather_data'),
- ('gather_data', 'concat', {'in': 1}),
- ('concat', 'concat_data'),
- ('concat_data', 'ss', {'in': 2}),
- ('gather_like_data', 'concat', {'in': 0})
-]
-
-input_part_shape_edges = shape_like_sub_graph_edges + input_sub_graph_edges
-
-
-class SliceLikeToStridedSliceTest(unittest.TestCase):
-
- def test_1(self):
- graph = build_graph(
- nodes_attributes,
- edges,
- update_attributes={
- 'input_data': {'shape': int64_array([1, 224, 224, 3])},
- 'shape_like_input_data': {'shape': int64_array([2, 2, 2, 2])},
- 'slice_like': {'axes': int64_array([2, 3])}
- },
- nodes_with_edges_only=True
- )
- SliceLikeToStridedSlice().find_and_replace_pattern(graph)
- ref_graph = build_graph(
- nodes_attributes,
- same_input_shapes_dims_edges,
- nodes_with_edges_only=True
- )
-
- flag, resp = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_2(self):
- graph = build_graph(
- nodes_attributes,
- edges,
- update_attributes={
- 'input_data': {'shape': int64_array([1, 224, 224, 3])},
- 'shape_like_input_data': {'shape': int64_array([2, 2, 2, 2, 2])},
- 'slice_like': {'axes': int64_array([2, 3])}
- },
- nodes_with_edges_only=True
- )
- SliceLikeToStridedSlice().find_and_replace_pattern(graph)
- ref_graph = build_graph(
- nodes_attributes,
- last_axis_index,
- nodes_with_edges_only=True
- )
-
- flag, resp = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- def test_3(self):
- graph = build_graph(
- nodes_attributes,
- edges,
- update_attributes={
- 'input_data': {'shape': int64_array([1, 224, 224, 3])},
- 'shape_like_input_data': {'shape': int64_array([2, 2, 2, 2, 2])},
- 'slice_like': {'axes': int64_array([1, 2])}
- },
- nodes_with_edges_only=True
- )
- SliceLikeToStridedSlice().find_and_replace_pattern(graph)
- ref_graph = build_graph(
- nodes_attributes,
- input_part_shape_edges,
- nodes_with_edges_only=True
- )
- flag, resp = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/SplitConcatPairToInterpolate_test.py b/tools/mo/unit_tests/mo/middle/SplitConcatPairToInterpolate_test.py
deleted file mode 100644
index a7834fa67a09e4..00000000000000
--- a/tools/mo/unit_tests/mo/middle/SplitConcatPairToInterpolate_test.py
+++ /dev/null
@@ -1,677 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.SplitConcatPairToInterpolate import SplitConcatPairToInterpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-graph_node_attrs_for_2d_spatial_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
- 'split_axis_const': {
- 'kind': 'op',
- 'value': np.array(3, dtype=np.int64),
- 'op': 'Const',
- 'type': 'Const'
- },
- 'split_axis_const_data': {
- 'value': np.array(3, dtype=np.int64),
- 'shape': np.array(3, dtype=np.int64).shape,
- 'kind': 'data'
- },
- 'concat': {'type': 'Concat', 'kind': 'op', 'axis': 3},
- 'split_data_0': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
- 'split_data_1': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
- 'split_data_2': {'value': None, 'shape': int64_array([1, 100, 120, 50]), 'kind': 'data'},
- 'concat_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-graph_node_attrs_for_3d_spatial_case = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 3, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
- 'split_axis_const': {
- 'kind': 'op',
- 'value': np.array(4, dtype=np.int64),
- 'op': 'Const',
- 'type': 'Const'
- },
- 'split_axis_const_data': {
- 'value': np.array(4, dtype=np.int64),
- 'shape': np.array(4, dtype=np.int64).shape,
- 'kind': 'data'
- },
- 'concat': {'type': 'Concat', 'kind': 'op', 'axis': 4},
- 'split_data_0': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
- 'split_data_1': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
- 'split_data_2': {'value': None, 'shape': int64_array([1, 3, 100, 120, 50]), 'kind': 'data'},
- 'concat_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'split', {'in': 0}),
- ('split_axis_const', 'split_axis_const_data'),
- ('split_axis_const_data', 'split', {'in': 1}),
- ('split', 'split_data_0', {'out': 0}),
- ('split', 'split_data_1', {'out': 1}),
- ('split', 'split_data_2', {'out': 2}),
- ('split_data_0', 'concat', {'in': 0}),
- ('split_data_0', 'concat', {'in': 1}),
- ('split_data_1', 'concat', {'in': 2}),
- ('split_data_1', 'concat', {'in': 3}),
- ('split_data_2', 'concat', {'in': 4}),
- ('split_data_2', 'concat', {'in': 5}),
- ('concat', 'concat_data'),
- ('concat_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output')
-]
-
-
-ref_graph_edges_opset4 = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'interpolate', {'in': 0}),
- ('placeholder_data', 'shape'),
- ('shape', 'shape_data'),
- ('shape_data', 'sslice', {'in': 0}),
- ('slice_begin', 'slice_begin_data'),
- ('slice_begin_data', 'sslice', {'in': 1}),
- ('slice_end', 'slice_end_data'),
- ('slice_end_data', 'sslice', {'in': 2}),
- ('sslice', 'sslice_data'),
- ('sslice_data', 'cast_shape_to_float'),
- ('cast_shape_to_float', 'cast_shape_to_float_data'),
- ('scales', 'scales_data'),
- ('axes', 'axes_data'),
- ('cast_shape_to_float_data', 'mul', {'in': 0}),
- ('scales_data', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'mul_data'),
- ('mul_data', 'floor'),
- ('floor', 'floor_data'),
- ('floor_data', 'cast_mul_to_float'),
- ('cast_mul_to_float', 'cast_mul_to_float_data'),
- ('cast_mul_to_float_data', 'interpolate', {'in': 1}),
- ('scales_data', 'interpolate', {'in': 2, 'out': 0}),
- ('axes_data', 'interpolate', {'in': 3}),
- ('interpolate', 'interpolate_data'),
- ('interpolate_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
- ]
-
-ref_graph_node_attrs_for_2d_spatial_case_1_opset4 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4',
- 'shape_calculation_mode': 'scales'
- },
- 'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_begin': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'slice_begin_data': {'kind': 'data', 'shape': int64_array([1]), 'value': int64_array([3])},
- 'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([4]), 'shape': int64_array([1])},
- 'slice_end_data': {'kind': 'data', 'value': int64_array([4]), 'shape': int64_array([1])},
- 'sslice': {
- 'kind': 'op',
- 'type': 'StridedSlice',
- 'op': 'StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0]),
- },
- 'sslice_data': {'kind': 'data', 'shape': None},
- 'scales': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1])
- },
- 'scales_data': {'kind': 'data', 'shape': None},
- 'cast_shape_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32},
- 'cast_shape_to_float_data': {'kind': 'data', 'shape': None},
- 'axes': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'axes_data': {'kind': 'data', 'shape': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None},
- 'floor': {'kind': 'op', 'op': 'Floor', 'type': 'Floor'},
- 'floor_data': {'kind': 'data', 'shape': None},
- 'cast_mul_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.int64},
- 'cast_mul_to_float_data': {'kind': 'data', 'shape': None},
- 'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-ref_graph_node_attrs_for_2d_spatial_case_1 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'axes': int64_array([3]),
- 'mode': 'nearest'
- },
- 'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_begin': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([4])},
- 'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sslice': {
- 'kind': 'op',
- 'type': 'StridedSlice',
- 'op': 'StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0]),
- },
- 'sslice_data': {'kind': 'data', 'shape': None},
- 'scales': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([2]),
- 'shape': int64_array([1])
- },
- 'scales_data': {'kind': 'data', 'shape': None},
- 'axes': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'axes_data': {'kind': 'data', 'shape': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None},
- 'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 100, 120, 300]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-ref_graph_node_attrs_for_2d_spatial_case_2 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4',
- 'shape_calculation_mode': 'scales'
- },
- 'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_begin': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([2]),
- 'shape': int64_array([1])
- },
- 'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([3])},
- 'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sslice': {
- 'kind': 'op',
- 'type': 'StridedSlice',
- 'op': 'StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0]),
- },
- 'sslice_data': {'kind': 'data', 'shape': None},
- 'scales': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1])
- },
- 'scales_data': {'kind': 'data', 'shape': None},
- 'cast_shape_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32},
- 'cast_shape_to_float_data': {'kind': 'data', 'shape': None},
- 'axes': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'axes_data': {'kind': 'data', 'shape': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None},
- 'floor': {'kind': 'op', 'op': 'Floor', 'type': 'Floor'},
- 'floor_data': {'kind': 'data', 'shape': None},
- 'cast_mul_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.int64},
- 'cast_mul_to_float_data': {'kind': 'data', 'shape': None},
- 'interpolate_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-ref_graph_node_attrs_for_3d_spatial_case_1 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 3, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4',
- 'shape_calculation_mode': 'scales'
- },
- 'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_begin': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([4]),
- 'shape': int64_array([1])
- },
- 'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([5])},
- 'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sslice': {
- 'kind': 'op',
- 'type': 'StridedSlice',
- 'op': 'StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0]),
- },
- 'sslice_data': {'kind': 'data', 'shape': None},
- 'scales': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1])
- },
- 'scales_data': {'kind': 'data', 'shape': None},
- 'cast_shape_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32},
- 'cast_shape_to_float_data': {'kind': 'data', 'shape': None},
- 'axes': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'axes_data': {'kind': 'data', 'shape': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None},
- 'floor': {'kind': 'op', 'op': 'Floor', 'type': 'Floor'},
- 'floor_data': {'kind': 'data', 'shape': None},
- 'cast_mul_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.int64},
- 'cast_mul_to_float_data': {'kind': 'data', 'shape': None},
- 'interpolate_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 120, 300]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-ref_graph_node_attrs_for_3d_spatial_case_2 = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 3, 100, 120, 150]),
- 'kind': 'data',
- 'data_type': None
- },
- 'interpolate': {
- 'type': 'Interpolate',
- 'kind': 'op',
- 'op': 'Interpolate',
- 'mode': 'nearest',
- 'antialias': 0,
- 'pads_begin': int64_array([0]),
- 'pads_end': int64_array([0]),
- 'coordinate_transformation_mode': 'half_pixel',
- 'nearest_mode': 'round_prefer_floor',
- 'cube_coeff': -0.75,
- 'version': 'opset4',
- 'shape_calculation_mode': 'scales'
- },
- 'shape': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shape_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_begin': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([4]),
- 'shape': int64_array([1])
- },
- 'slice_begin_data': {'kind': 'data', 'shape': None, 'value': None},
- 'slice_end': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'value': int64_array([5])},
- 'slice_end_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sslice': {
- 'kind': 'op',
- 'type': 'StridedSlice',
- 'op': 'StridedSlice',
- 'begin_mask': int64_array([1]),
- 'end_mask': int64_array([1]),
- 'new_axis_mask': int64_array([0]),
- 'shrink_axis_mask': int64_array([0]),
- 'ellipsis_mask': int64_array([0]),
- },
- 'sslice_data': {'kind': 'data', 'shape': None},
- 'scales': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1])
- },
- 'scales_data': {'kind': 'data', 'shape': None},
- 'cast_shape_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32},
- 'cast_shape_to_float_data': {'kind': 'data', 'shape': None},
- 'axes': {
- 'type': 'Const',
- 'op': 'Const',
- 'kind': 'op',
- 'value': int64_array([3]),
- 'shape': int64_array([1])
- },
- 'axes_data': {'kind': 'data', 'shape': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None},
- 'floor': {'kind': 'op', 'op': 'Floor', 'type': 'Floor'},
- 'floor_data': {'kind': 'data', 'shape': None},
- 'cast_mul_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.int64},
- 'cast_mul_to_float_data': {'kind': 'data', 'shape': None},
- 'interpolate_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-graph_node_attrs_when_there_are_two_splits_one_concat = {
- 'placeholder1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder1_data': {
- 'value': None,
- 'shape': int64_array([1, 13, 13, 3, 2]),
- 'kind': 'data',
- 'data_type': None
- },
- 'placeholder2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder2_data': {
- 'value': None,
- 'shape': int64_array([1, 13, 13, 3, 2]),
- 'kind': 'data',
- 'data_type': None
- },
- 'split1': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 2},
- 'split1_axis_const': {
- 'kind': 'op',
- 'value': np.array(4, dtype=np.int64),
- 'op': 'Const',
- 'type': 'Const'
- },
- 'split1_axis_const_data': {
- 'value': np.array(4, dtype=np.int64),
- 'shape': np.array(4, dtype=np.int64).shape,
- 'kind': 'data'
- },
- 'split2': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 2},
- 'split2_axis_const': {
- 'kind': 'op',
- 'value': np.array(4, dtype=np.int64),
- 'op': 'Const',
- 'type': 'Const'
- },
- 'split2_axis_const_data': {
- 'value': np.array(4, dtype=np.int64),
- 'shape': np.array(4, dtype=np.int64).shape,
- 'kind': 'data'
- },
- 'split1_data_0': {'value': None, 'shape': int64_array([1, 13, 13, 3, 1]), 'kind': 'data'},
- 'split1_data_1': {'value': None, 'shape': int64_array([1, 13, 13, 3, 1]), 'kind': 'data'},
- 'split2_data_0': {'value': None, 'shape': int64_array([1, 13, 13, 3, 1]), 'kind': 'data'},
- 'split2_data_1': {'value': None, 'shape': int64_array([1, 13, 13, 3, 1]), 'kind': 'data'},
- 'concat': {'type': 'Concat', 'kind': 'op', 'axis': 4},
- 'concat_data': {'value': None, 'shape': int64_array([1, 13, 13, 3, 4]), 'kind': 'data'},
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 13, 13, 3, 4]), 'kind': 'data'},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-graph_edges_when_there_are_two_splits_one_concat = [
- ('placeholder1', 'placeholder1_data'),
- ('placeholder2', 'placeholder2_data'),
- ('placeholder1_data', 'split1', {'in': 0}),
- ('split1_axis_const', 'split1_axis_const_data'),
- ('split1_axis_const_data', 'split1', {'in': 1}),
- ('split1', 'split1_data_0', {'out': 0}),
- ('split1', 'split1_data_1', {'out': 1}),
- ('placeholder2_data', 'split2', {'in': 0}),
- ('split2_axis_const', 'split2_axis_const_data'),
- ('split2_axis_const_data', 'split2', {'in': 1}),
- ('split2', 'split2_data_0', {'out': 0}),
- ('split2', 'split2_data_1', {'out': 1}),
- ('split1_data_0', 'concat', {'in': 0}),
- ('split1_data_1', 'concat', {'in': 1}),
- ('split2_data_0', 'concat', {'in': 2}),
- ('split2_data_1', 'concat', {'in': 3}),
- ('concat', 'concat_data'),
- ('concat_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output')
-]
-
-
-class SplitConcatPairToInterpolateTest(unittest.TestCase):
- def test_spatial_2d_split_concat_1(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_spatial_case,
- edges=graph_edges
- )
- ref_graph = build_graph(
- nodes_attrs=ref_graph_node_attrs_for_2d_spatial_case_1_opset4,
- edges=ref_graph_edges_opset4
- )
- SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_spatial_2d_split_concat_2(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_2d_spatial_case,
- edges=graph_edges,
- update_attributes={
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
- 'split_axis_const': {
- 'kind': 'op',
- 'value': np.array(2, dtype=np.int64),
- 'op': 'Const',
- 'type': 'Const'
- },
- 'split_axis_const_data': {
- 'value': np.array(2, dtype=np.int64),
- 'shape': np.array(2, dtype=np.int64).shape,
- 'kind': 'data'
- },
- 'concat': {'type': 'Concat', 'kind': 'op', 'axis': 2},
- 'split_data_0': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
- 'split_data_1': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
- 'split_data_2': {'value': None, 'shape': int64_array([1, 100, 40, 150]), 'kind': 'data'},
- 'concat_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 100, 240, 150]), 'kind': 'data'},
- }
- )
- ref_graph = build_graph(
- nodes_attrs=ref_graph_node_attrs_for_2d_spatial_case_2,
- edges=ref_graph_edges_opset4,
- update_attributes={
- 'axes': {'shape': int64_array([1]), 'value': int64_array([2])}
- }
- )
- SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_spatial_3d_split_concat_1(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_spatial_case,
- edges=graph_edges
- )
- ref_graph = build_graph(
- nodes_attrs=ref_graph_node_attrs_for_3d_spatial_case_1,
- edges=ref_graph_edges_opset4,
- update_attributes={
- 'axes': {'shape': int64_array([1]), 'value': int64_array([4])}
- }
- )
- SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_spatial_3d_split_concat_2(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_for_3d_spatial_case,
- edges=graph_edges,
- update_attributes={
- 'split': {'type': 'Split', 'kind': 'op', 'op': 'Split', 'num_splits': 3},
- 'split_axis_const': {
- 'kind': 'op',
- 'value': np.array(3, dtype=np.int64),
- 'op': 'Const',
- 'type': 'Const'
- },
- 'split_axis_const_data': {
- 'value': np.array(3, dtype=np.int64),
- 'shape': np.array(3, dtype=np.int64).shape,
- 'kind': 'data'
- },
- 'concat': {'type': 'Concat', 'kind': 'op', 'axis': 3},
- 'split_data_0': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
- 'split_data_1': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
- 'split_data_2': {'value': None, 'shape': int64_array([1, 3, 100, 40, 150]), 'kind': 'data'},
- 'concat_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
- 'abs_data': {'value': None, 'shape': int64_array([1, 3, 100, 240, 150]), 'kind': 'data'},
- }
- )
- ref_graph = build_graph(
- nodes_attrs=ref_graph_node_attrs_for_3d_spatial_case_2,
- edges=ref_graph_edges_opset4
- )
- SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_two_splits_one_concat(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_when_there_are_two_splits_one_concat,
- edges=graph_edges_when_there_are_two_splits_one_concat
- )
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_when_there_are_two_splits_one_concat,
- edges=graph_edges_when_there_are_two_splits_one_concat
- )
- SplitConcatPairToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/StridedSliceNormalizer_test.py b/tools/mo/unit_tests/mo/middle/StridedSliceNormalizer_test.py
deleted file mode 100644
index 8c81768a75b092..00000000000000
--- a/tools/mo/unit_tests/mo/middle/StridedSliceNormalizer_test.py
+++ /dev/null
@@ -1,2072 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import numpy.testing as npt
-
-from openvino.tools.mo.middle.StridedSliceNormalizer import StridedSliceNormalizer
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.ops.split import VariadicSplit
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, valued_const_with_data, regular_op_with_empty_data, \
- connect, regular_op, empty_data, regular_op_with_shaped_data
-
-edges = (
- *connect('input', '0:strided_slice'),
- *connect('begin', '1:strided_slice'),
- *connect('end', '2:strided_slice'),
- *connect('strides', '3:strided_slice'),
- *connect('strided_slice', 'res')
-)
-
-edges_without_strides = (
- *connect('input', '0:strided_slice'),
- *connect('begin', '1:strided_slice'),
- *connect('end', '2:strided_slice'),
- *connect('strided_slice', 'res')
-)
-
-
-class TestStridedSliceNormalizer(unittest.TestCase):
-
- def test_strided_slice_extend_inputs(self):
- input_shape = (16, 100, 100, 3)
- nodes = {
- **valued_const_with_data('input', np.arange(np.product(input_shape)).reshape(*input_shape)),
- **regular_op_with_empty_data('strided_slice', {'op': 'StridedSlice',
- 'type': 'StridedSlice',
- 'begin_mask': [1, 1, 1],
- 'end_mask': [1, 1, 1],
- 'shrink_axis_mask': [0, 0, 0],
- 'new_axis_mask': [0, 0, 0],
- 'ellipsis_mask': [0, 0, 0],
- 'infer': StridedSlice.infer}),
-
- **regular_op_with_empty_data('strided_slice_ref', {'op': 'StridedSlice',
- 'type': 'StridedSlice',
- 'begin_mask': [1, 1, 1, 0],
- 'end_mask': [1, 1, 1, 0],
- 'new_axis_mask': [0, 0, 0, 0],
- 'shrink_axis_mask': [0, 0, 0, 0],
- 'ellipsis_mask': [0, 0, 0, 0],
- 'infer': StridedSlice.infer}),
- **valued_const_with_data('begin', int64_array([0, 0, 0])),
- **valued_const_with_data('begin_placeholder', int64_array([0])),
- **regular_op_with_empty_data('begin_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
- **valued_const_with_data('end', int64_array([4, 25, 50])),
- **valued_const_with_data('end_placeholder', int64_array([0])),
- **regular_op_with_empty_data('end_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
- **valued_const_with_data('strides', int64_array([1, 1, 1])),
- **valued_const_with_data('strides_placeholder', int64_array([1])),
- **regular_op_with_empty_data('strides_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- edges_ref_extended_inputs = (
- *connect('input', '0:strided_slice_ref'),
-
- *connect('begin', '0:begin_concat'),
- *connect('begin_placeholder', '1:begin_concat'),
- *connect('begin_concat', '1:strided_slice_ref'),
-
- *connect('end', '0:end_concat'),
- *connect('end_placeholder', '1:end_concat'),
- *connect('end_concat', '2:strided_slice_ref'),
-
- *connect('strides', '0:strides_concat'),
- *connect('strides_placeholder', '1:strides_concat'),
- *connect('strides_concat', '3:strided_slice_ref'),
-
- *connect('strided_slice_ref', 'res')
- )
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph_ref = build_graph(nodes, edges_ref_extended_inputs, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref.stage = 'middle'
-
- graph = partial_infer(graph)
- StridedSliceNormalizer().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
- graph_ref = partial_infer(graph_ref)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=False)
- self.assertTrue(flag, 'Graphs after StridedSliceNormalizer do not match to reference: {}'.format(resp))
-
- def test_strided_slice_extend_inputs_without_strides(self):
- input_shape = (16, 100, 100, 3)
- nodes = {
- **valued_const_with_data('input', np.arange(np.product(input_shape)).reshape(*input_shape)),
- **regular_op_with_empty_data('strided_slice', {'op': 'StridedSlice',
- 'type': 'StridedSlice',
- 'begin_mask': [1, 1, 1],
- 'end_mask': [1, 1, 1],
- 'shrink_axis_mask': [1, 0, 0],
- 'new_axis_mask': [0, 0, 0],
- 'ellipsis_mask': [0, 0, 0],
- 'infer': StridedSlice.infer}),
-
- **regular_op_with_empty_data('strided_slice_ref', {'op': 'StridedSlice',
- 'type': 'StridedSlice',
- 'begin_mask': [1, 1, 1, 0],
- 'end_mask': [1, 1, 1, 0],
- 'new_axis_mask': [0, 0, 0, 0],
- 'shrink_axis_mask': [1, 0, 0, 0],
- 'ellipsis_mask': [0, 0, 0, 0],
- 'infer': StridedSlice.infer}),
- **valued_const_with_data('begin', int64_array([0, 0, 0])),
- **valued_const_with_data('begin_placeholder', int64_array([0])),
- **regular_op_with_empty_data('begin_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
- **valued_const_with_data('end', int64_array([4, 25, 50])),
- **valued_const_with_data('end_placeholder', int64_array([0])),
- **regular_op_with_empty_data('end_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- edges_ref_extended_inputs = (
- *connect('input', '0:strided_slice_ref'),
-
- *connect('begin', '0:begin_concat'),
- *connect('begin_placeholder', '1:begin_concat'),
- *connect('begin_concat', '1:strided_slice_ref'),
-
- *connect('end', '0:end_concat'),
- *connect('end_placeholder', '1:end_concat'),
- *connect('end_concat', '2:strided_slice_ref'),
-
- *connect('strided_slice_ref', 'res')
- )
-
- graph = build_graph(nodes, edges_without_strides, nodes_with_edges_only=True)
- graph_ref = build_graph(nodes, edges_ref_extended_inputs, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref.stage = 'middle'
-
- graph = partial_infer(graph)
- StridedSliceNormalizer().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
- graph_ref = partial_infer(graph_ref)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=False)
- self.assertTrue(flag, 'Graphs after StridedSliceNormalizer do not match to reference: {}'.format(resp))
-
- def test_strided_slice_unrooll_ellipsis(self):
- input_shape = (10, 10, 10, 10)
- # out = inp[1:4, ..., 0:5] -> inp[1:4, :, :, 0:5] => out_shape = (3, 10, 10, 5)
- ellipsis_start = 1
-
- nodes = {
- **valued_const_with_data('input', np.arange(np.product(input_shape)).reshape(*input_shape)),
- **regular_op_with_empty_data('strided_slice', {'op': 'StridedSlice', 'type': 'StridedSlice',
- 'begin_mask': [1, 1, 1], 'end_mask': [1, 1, 1],
- 'shrink_axis_mask': [0, 0, 0],
- 'new_axis_mask': [0, 0, 0],
- 'ellipsis_mask': [0, 1, 0],
- 'infer': StridedSlice.infer}),
-
- **regular_op_with_empty_data('strided_slice_ref', {'op': 'StridedSlice', 'begin_mask': [1, 0, 0, 1],
- 'end_mask': [1, 0, 0, 1], 'ellipsis_mask': [0, 0, 0, 0],
- 'new_axis_mask': [0, 0, 0, 0],
- 'shrink_axis_mask': [0, 0, 0, 0],
- 'infer': StridedSlice.infer}),
-
- **valued_const_with_data('begin', int64_array([1, 0, 0])),
- **valued_const_with_data('split_axis_begin', int64_array(0)),
- **valued_const_with_data('splits_lengths_begin', int64_array([ellipsis_start, -1])),
- **regular_op_with_empty_data('split_for_begin', {'op': 'VariadicSplit', 'infer': VariadicSplit.infer}),
- **empty_data('split_for_begin_data_1'),
- **valued_const_with_data('begin_placeholder', int64_array([0])),
- **regular_op_with_empty_data('begin_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
-
- **valued_const_with_data('end', int64_array([4, 0, 5])),
- **valued_const_with_data('split_axis_end', int64_array(0)),
- **valued_const_with_data('splits_lengths_end', int64_array([ellipsis_start, -1])),
- **regular_op_with_empty_data('split_for_end', {'op': 'VariadicSplit', 'infer': VariadicSplit.infer}),
- **empty_data('split_for_end_data_1'),
- **valued_const_with_data('end_placeholder', int64_array([0])),
- **regular_op_with_empty_data('end_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
-
- **valued_const_with_data('strides', int64_array([1, 1, 1])),
- **valued_const_with_data('split_axis_strides', int64_array(0)),
- **valued_const_with_data('splits_lengths_strides', int64_array([ellipsis_start, -1])),
- **regular_op_with_empty_data('split_for_strides', {'op': 'VariadicSplit', 'infer': VariadicSplit.infer}),
- **empty_data('split_for_strides_data_1'),
- **valued_const_with_data('strides_placeholder', int64_array([1])),
- **regular_op_with_empty_data('strides_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
-
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- edges_ref_ellipsis_unrolled = (
- *connect('input', '0:strided_slice_ref'),
-
- *connect('begin', '0:split_for_begin'),
- *connect('split_axis_begin', '1:split_for_begin'),
- *connect('splits_lengths_begin', '2:split_for_begin'),
- *connect('split_for_begin:0', '0:begin_concat'),
- *connect('begin_placeholder', '1:begin_concat'),
- ('split_for_begin', 'split_for_begin_data_1', {'out': 1, 'in': 2}),
- ('split_for_begin_data_1', 'begin_concat', {'out': 1, 'in': 2}),
- *connect('begin_concat', '1:strided_slice_ref'),
-
- *connect('end', '0:split_for_end'),
- *connect('split_axis_end', '1:split_for_end'),
- *connect('splits_lengths_end', '2:split_for_end'),
- *connect('split_for_end:0', '0:end_concat'),
- *connect('end_placeholder', '1:end_concat'),
- ('split_for_end', 'split_for_end_data_1', {'out': 1, 'in': 2}),
- ('split_for_end_data_1', 'end_concat', {'out': 1, 'in': 2}),
- *connect('end_concat', '2:strided_slice_ref'),
-
- *connect('strides', '0:split_for_strides'),
- *connect('split_axis_strides', '1:split_for_strides'),
- *connect('splits_lengths_strides', '2:split_for_strides'),
- *connect('split_for_strides:0', '0:strides_concat'),
- *connect('strides_placeholder', '1:strides_concat'),
- ('split_for_strides', 'split_for_strides_data_1', {'out': 1, 'in': 2}),
- ('split_for_strides_data_1', 'strides_concat', {'out': 1, 'in': 2}),
- *connect('strides_concat', '3:strided_slice_ref'),
-
- *connect('strided_slice_ref', 'res')
- )
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph_ref = build_graph(nodes, edges_ref_ellipsis_unrolled, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref.stage = 'middle'
- graph = partial_infer(graph)
- StridedSliceNormalizer().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
- graph_ref = partial_infer(graph_ref)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=False)
- self.assertTrue(flag, 'Graphs after StridedSliceNormalizer do not match to reference: {}'.format(resp))
-
- def test_strided_slice_unrooll_ellipsis_without_strides(self):
- input_shape = (10, 10, 10, 10)
- # out = inp[1:4, ..., 0:5] -> inp[1:4, :, :, 0:5] => out_shape = (3, 10, 10, 5)
- ellipsis_start = 1
-
- nodes = {
- **valued_const_with_data('input', np.arange(np.product(input_shape)).reshape(*input_shape)),
- **regular_op_with_empty_data('strided_slice', {'op': 'StridedSlice', 'type': 'StridedSlice',
- 'begin_mask': [1, 1, 1], 'end_mask': [1, 1, 1],
- 'shrink_axis_mask': [0, 0, 0],
- 'new_axis_mask': [0, 0, 0],
- 'ellipsis_mask': [0, 1, 0],
- 'infer': StridedSlice.infer}),
-
- **regular_op_with_empty_data('strided_slice_ref', {'op': 'StridedSlice', 'begin_mask': [1, 0, 0, 1],
- 'end_mask': [1, 0, 0, 1], 'ellipsis_mask': [0, 0, 0, 0],
- 'new_axis_mask': [0, 0, 0, 0],
- 'shrink_axis_mask': [0, 0, 0, 0],
- 'infer': StridedSlice.infer}),
-
- **valued_const_with_data('begin', int64_array([1, 0, 0])),
- **valued_const_with_data('split_axis_begin', int64_array(0)),
- **valued_const_with_data('splits_lengths_begin', int64_array([ellipsis_start, -1])),
- **regular_op_with_empty_data('split_for_begin', {'op': 'VariadicSplit', 'infer': VariadicSplit.infer}),
- **empty_data('split_for_begin_data_1'),
- **valued_const_with_data('begin_placeholder', int64_array([0])),
- **regular_op_with_empty_data('begin_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
-
- **valued_const_with_data('end', int64_array([4, 0, 5])),
- **valued_const_with_data('split_axis_end', int64_array(0)),
- **valued_const_with_data('splits_lengths_end', int64_array([ellipsis_start, -1])),
- **regular_op_with_empty_data('split_for_end', {'op': 'VariadicSplit', 'infer': VariadicSplit.infer}),
- **empty_data('split_for_end_data_1'),
- **valued_const_with_data('end_placeholder', int64_array([0])),
- **regular_op_with_empty_data('end_concat',
- {'op': 'Concat', 'infer': concat_infer, 'axis': 0, 'dim_attrs': {}}),
-
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- edges_ref_ellipsis_unrolled = (
- *connect('input', '0:strided_slice_ref'),
-
- *connect('begin', '0:split_for_begin'),
- *connect('split_axis_begin', '1:split_for_begin'),
- *connect('splits_lengths_begin', '2:split_for_begin'),
- *connect('split_for_begin:0', '0:begin_concat'),
- *connect('begin_placeholder', '1:begin_concat'),
- ('split_for_begin', 'split_for_begin_data_1', {'out': 1, 'in': 2}),
- ('split_for_begin_data_1', 'begin_concat', {'out': 1, 'in': 2}),
- *connect('begin_concat', '1:strided_slice_ref'),
-
- *connect('end', '0:split_for_end'),
- *connect('split_axis_end', '1:split_for_end'),
- *connect('splits_lengths_end', '2:split_for_end'),
- *connect('split_for_end:0', '0:end_concat'),
- *connect('end_placeholder', '1:end_concat'),
- ('split_for_end', 'split_for_end_data_1', {'out': 1, 'in': 2}),
- ('split_for_end_data_1', 'end_concat', {'out': 1, 'in': 2}),
- *connect('end_concat', '2:strided_slice_ref'),
-
- *connect('strided_slice_ref', 'res')
- )
-
- graph = build_graph(nodes, edges_without_strides, nodes_with_edges_only=True)
- graph_ref = build_graph(nodes, edges_ref_ellipsis_unrolled, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph_ref.stage = 'middle'
- graph = partial_infer(graph)
- StridedSliceNormalizer().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
- graph_ref = partial_infer(graph_ref)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'res', check_op_attrs=False)
- self.assertTrue(flag, 'Graphs after StridedSliceNormalizer do not match to reference: {}'.format(resp))
-
-
-class TestStridedSliceShapeInferAfterNormalizer(unittest.TestCase):
- # check that after inserting Splits and Concats we still get the same shape
-
- def run_infer_test(self, inp, ref_res, begin, end, strides, begin_mask, end_mask,
- shrink_axis_mask, new_axis_mask, ellipsis_mask):
- nodes = {
- **valued_const_with_data('input', np.arange(np.product(inp)).reshape(*inp)),
- **valued_const_with_data('begin', int64_array(begin)),
- **valued_const_with_data('end', int64_array(end)),
- **valued_const_with_data('strides', int64_array(strides)),
- **regular_op_with_empty_data('strided_slice', {'op': 'StridedSlice', 'type': 'StridedSlice',
- 'begin_mask': begin_mask, 'end_mask': end_mask,
- 'shrink_axis_mask': shrink_axis_mask,
- 'new_axis_mask': new_axis_mask,
- 'ellipsis_mask': ellipsis_mask,
- 'infer': StridedSlice.infer}),
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph = partial_infer(graph)
- StridedSliceNormalizer().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
-
- node = Node(graph, 'strided_slice')
- res = node.out_port(0).data.get_shape()
- npt.assert_array_equal(res, ref_res)
-
- def test_strided_slice_infer_after_normalizer_1(
- self, # inp[0, :34, 20, :2]
- inp=(1, 35, 35, 3), ref_res=(34, 2),
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1),
- begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1, 0, 1, 0), new_axis_mask=(0,),
- ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_2(
- self, # inp[0:3, 0:1, 5:0:-1]
- inp=(10, 10, 10, 10), ref_res=(3, 1, 5, 10),
- begin=(0, 0, 5), end=(3, 1, 0), strides=(1, 1, -1), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_3(
- self, # inp[1:34, 0, :, :2]
- inp=(1, 35, 35, 3), ref_res=(1, 35, 2),
- begin=(0, 0, 0, 0), end=(1, 34, 0, 2), strides=(1, 1, 1, 1), begin_mask=(1, 1, 0, 0), end_mask=(1, 0, 0, 1),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 0)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_4(
- self, # inp[1:34, :, :, :2] begin mask is (1,) so only one value can be specified
- inp=(1, 35, 35, 3), ref_res=(1, 35, 2),
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(1, 0, 0,), end_mask=(1, 0, 0, 1),
- shrink_axis_mask=(0, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_5(
- self, # inp[:, :, :, :] since all begin and end masks are zero
- inp=(1, 35, 35, 3), ref_res=(1, 35, 35, 3),
- begin=(1, 10, 10, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0),
- end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_6(
- self, # inp[0]
- inp=(1, 35, 35, 3), ref_res=(35, 35, 3),
- begin=(0,), end=(1,), strides=(1,), begin_mask=(1,), end_mask=(0,),
- shrink_axis_mask=(1,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_7(
- self, # inp[0, 20], ends can be of any value
- inp=(1, 35, 35, 3), ref_res=(35, 3),
- begin=(0, 20), end=(1, 9999), strides=(1, 1), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_8(
- self, # inp[0, 0:34, 20:22, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(34, 2, 1, 3),
- begin=(0, 0, 20, 0), end=(1, 34, 22, 2), strides=(1, 1, 1, 1), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1,), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_9(
- self, # inp[:, 0:4, 20, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(1, 4, 1, 3),
- begin=(0, 0, 20, 0), end=(0, 4, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 1, 0, 0), end_mask=(0, 1, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_10(
- self, # inp[:, 0:4, new_axis, 20], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(1, 4, 1, 3),
- begin=(0, 0, 0, 20), end=(0, 4, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 1, 0, 0), end_mask=(0, 1, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_11(
- self, # inp[0, :, 0:34, 20:22, new_axis], both new_axis and shrink_axis are present
- inp=(1, 3, 35, 35), ref_res=(3, 34, 2, 1),
- begin=(0, 0, 0, 20, 0), end=(1, 0, 34, 22, 0), strides=(1, 1, 1, 1, 1),
- begin_mask=(1, 0, 1, 1, 1), end_mask=(1, 0, 1, 1, 1),
- shrink_axis_mask=(1,), new_axis_mask=(0, 0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_12(
- self, # inp[0, :34, 20, :2]
- inp=(1, 35, 35, 3), ref_res=(34, 2),
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(0, 1, 1, 1),
- end_mask=(0, 1, 1, 1),
- shrink_axis_mask=(1, 0, 1, 0), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_13(
- self, # inp[0, 0, 0], since it's shrink_axis ends can be of any value
- inp=(1, 35, 35, 3), ref_res=(3,),
- begin=(0, 0, 0), end=(1, 34444, 20), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 1, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_14(
- self, # inp[0, 0, 0], since begin_mask is [0], begin can be of any value
- inp=(1, 35, 35, 3), ref_res=(1, 18, 18, 3),
- begin=(0, 0, 0), end=(1, 35, 35), strides=(2, 2, 2), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0, 0, 0), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- # with ellipsis
- def test_strided_slice_infer_after_normalizer_15(
- self, # inp[..., np.newaxis]
- inp=(1, 35, 35), ref_res=(1, 35, 35, 1),
- begin=(101, 0), end=(0, 0), strides=(-1, -1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_16(
- self, # inp_shape = (1, 720, 1080), out = inp[..., :100, None] => out_shape = (1, 720, 100, 1)
- inp=(1, 720, 1080), ref_res=(1, 720, 100, 1),
- begin=(0, 0, 0), end=(0, 100, 0), strides=(1, 1, 1), begin_mask=(0, 1, 0), end_mask=(0, 1, 0),
- shrink_axis_mask=(0,), new_axis_mask=(0, 0, 1), ellipsis_mask=(1,)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_17(
- self, # inp_shape = (1, 720, 1080, 3), out = inp[..., :-1] => out_shape = (1, 720, 100, 2)
- inp=(1, 720, 1080, 3), ref_res=(1, 720, 1080, 2),
- begin=(0, 0), end=(0, -1), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 1),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_infer_after_normalizer_18(
- self, # inp_shape = (1, 720, 1080, 3), out = inp[..., 2] => out_shape = (1, 720, 1080)
- inp=(1, 720, 1080, 3), ref_res=(1, 720, 1080),
- begin=(0, 2), end=(0, 0), strides=(1, 1), begin_mask=(0, 1), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- ):
- self.run_infer_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- # automatically generated the whole range of 2d slices over 2d, 3d and 4d input tensors
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_0(self):
- """
- inp_shape = (1, 100), out = inp[:, :] => out_shape = (1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_1(self):
- """
- inp_shape = (1, 100), out = inp[:, None] => out_shape = (1, 1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_2(self):
- """
- inp_shape = (1, 100), out = inp[:, 0] => out_shape = (1,)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_3(self):
- """
- inp_shape = (1, 100), out = inp[..., :] => out_shape = (1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_4(self):
- """
- inp_shape = (1, 100), out = inp[..., None] => out_shape = (1, 100, 1)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 100, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_5(self):
- """
- inp_shape = (1, 100), out = inp[..., 0] => out_shape = (1,)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_6(self):
- """
- inp_shape = (1, 100), out = inp[None, :] => out_shape = (1, 1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_7(self):
- """
- inp_shape = (1, 100), out = inp[None, None] => out_shape = (1, 1, 1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 1, 1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_8(self):
- """
- inp_shape = (1, 100), out = inp[None, 0] => out_shape = (1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_9(self):
- """
- inp_shape = (1, 100), out = inp[0, :] => out_shape = (100,)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(100,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_10(self):
- """
- inp_shape = (1, 100), out = inp[0, None] => out_shape = (1, 100)
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_2d_11(self):
- """
- inp_shape = (1, 100), out = inp[0, 0] => out_shape = ()
- """
- self.run_infer_test(
- inp=(1, 100), ref_res=(),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_0(self):
- """
- inp_shape = (1, 100, 200), out = inp[:, :] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_1(self):
- """
- inp_shape = (1, 100, 200), out = inp[:, None] => out_shape = (1, 1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_2(self):
- """
- inp_shape = (1, 100, 200), out = inp[:, 0] => out_shape = (1, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_3(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., :] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_4(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., None] => out_shape = (1, 100, 200, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_5(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., 0] => out_shape = (1, 100)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_6(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, :] => out_shape = (1, 1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_7(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, None] => out_shape = (1, 1, 1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 1, 1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_8(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, 0] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_9(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, :] => out_shape = (100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_10(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, None] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_3d_11(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, 0] => out_shape = (200,)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(200,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, :] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, None] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, 0] => out_shape = (1, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None] => out_shape = (1, 100, 200, 3, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_6(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_7(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, None] => out_shape = (1, 1, 1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_8(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_9(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, :] => out_shape = (100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_10(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_2d_over_4d_11(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, 0] => out_shape = (200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- # automatically generated slices from 3d to 5d d input tensors
- # fixed number of ellipsis, newaxis and shrink_axis
- def test_normalizer_auto_infer_strided_slice_3d_over_3d_0(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, ..., 0] => out_shape = (1, 1, 100)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 1, 100),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 0, 1), new_axis_mask=(1, 0, 0), ellipsis_mask=(0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_3d_1(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., None, 0] => out_shape = (1, 100, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 1),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 0, 1), new_axis_mask=(0, 1, 0), ellipsis_mask=(1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_3d_2(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, None, ...] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 0, 0), new_axis_mask=(0, 1, 0), ellipsis_mask=(0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_3d_3(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, ..., None] => out_shape = (100, 200, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(100, 200, 1),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 0, 0), new_axis_mask=(0, 0, 1), ellipsis_mask=(0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_3d_4(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, 0, ...] => out_shape = (1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 200),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 1, 0), new_axis_mask=(1, 0, 0), ellipsis_mask=(0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_3d_5(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., 0, None] => out_shape = (1, 100, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200), ref_res=(1, 100, 1),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 1, 0), new_axis_mask=(0, 0, 1), ellipsis_mask=(1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, ..., 0, :] => out_shape = (1, 1, 100, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None, 0, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, ..., None, :] => out_shape = (100, 200, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(100, 200, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0, None, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_5d_0(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, ..., 0, :, :] => out_shape = (1, 1, 100, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 100, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_5d_1(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., None, 0, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_5d_2(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, None, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_5d_3(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, ..., None, :, :] => out_shape = (100, 200, 1, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(100, 200, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_5d_4(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, 0, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_3d_over_5d_5(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., 0, None, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, ..., 0, :] => out_shape = (1, 1, 100, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None, 0, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, ..., None, :] => out_shape = (100, 200, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(100, 200, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0, None, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_6(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, ..., :, 0] => out_shape = (1, 1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_7(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None, :, 0] => out_shape = (1, 100, 1, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_8(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None, :, ...] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_9(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, ..., :, None] => out_shape = (100, 200, 3, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(100, 200, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_10(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0, :, ...] => out_shape = (1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_11(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0, :, None] => out_shape = (1, 100, 3, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_12(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, :, ..., 0] => out_shape = (1, 1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_13(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., :, None, 0] => out_shape = (1, 100, 200, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_14(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, :, None, ...] => out_shape = (100, 1, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(100, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_15(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, :, ..., None] => out_shape = (100, 200, 3, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(100, 200, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_16(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, :, 0, ...] => out_shape = (1, 1, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_17(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., :, 0, None] => out_shape = (1, 100, 200, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_18(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, None, ..., 0] => out_shape = (1, 1, 100, 200)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_19(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, ..., None, 0] => out_shape = (1, 100, 200, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_20(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, 0, None, ...] => out_shape = (1, 1, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_21(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, 0, ..., None] => out_shape = (1, 200, 3, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 200, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_22(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, None, 0, ...] => out_shape = (1, 1, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_4d_23(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, ..., 0, None] => out_shape = (1, 100, 200, 1)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_0(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, ..., 0, :, :] => out_shape = (1, 1, 100, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 100, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_1(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., None, 0, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_2(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, None, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_3(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, ..., None, :, :] => out_shape = (100, 200, 1, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(100, 200, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_4(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, 0, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_5(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., 0, None, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_6(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, ..., :, 0, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_7(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., None, :, 0, :] => out_shape = (1, 100, 1, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 1, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_8(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, None, :, ..., :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_9(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, ..., :, None, :] => out_shape = (100, 200, 10, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(100, 200, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_10(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, 0, :, ..., :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_11(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., 0, :, None, :] => out_shape = (1, 100, 10, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_12(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, :, ..., 0, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_13(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., :, None, 0, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_14(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, :, None, ..., :] => out_shape = (100, 1, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(100, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_15(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, :, ..., None, :] => out_shape = (100, 200, 10, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(100, 200, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_16(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, :, 0, ..., :] => out_shape = (1, 1, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_17(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., :, 0, None, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_18(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, None, ..., 0, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_19(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, ..., None, 0, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_20(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, 0, None, ..., :] => out_shape = (1, 1, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_21(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, 0, ..., None, :] => out_shape = (1, 200, 10, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 200, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_22(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, None, 0, ..., :] => out_shape = (1, 1, 200, 10, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_normalizer_auto_infer_strided_slice_4d_over_5d_23(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, ..., 0, None, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_infer_test(
- inp=(1, 100, 200, 10, 3), ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0),
- end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
-
-class TestStridedSlicePermute(unittest.TestCase):
- def run_permute_test(self, inp, ref_res, begin, end, strides, begin_mask, end_mask,
- shrink_axis_mask, new_axis_mask, ellipsis_mask):
- from openvino.tools.mo.middle.ApplyPermutations import ApplyPermutation
- from openvino.tools.mo.middle.MergeNodesPermutations import MergeNodesPermutations
- from openvino.tools.mo.middle.ApplyNHWCtoNCHWpermutation import ApplyNHWCtoNCHWpermutation
- from openvino.tools.mo.middle.InsertLayoutPropagationTransposes import InsertLayoutPropagationTranspose
- from openvino.tools.mo.middle.MarkSubgraphsWithCorrectLayout import MarkSubGraphsWithCorrectLayout
- nodes = {
- **regular_op_with_shaped_data('input', int64_array(inp), {'op': 'Parameter', 'type': 'Parameter',
- # need to specify shape in 2 places
- 'shape': int64_array(inp),
- 'infer': Parameter.infer}),
- **valued_const_with_data('begin', int64_array(begin)),
- **valued_const_with_data('end', int64_array(end)),
- **valued_const_with_data('strides', int64_array(strides)),
- **regular_op_with_empty_data('strided_slice',
- {'op': 'StridedSlice', 'type': 'StridedSlice', # need for permute
- 'begin_mask': begin_mask, 'end_mask': end_mask,
- 'shrink_axis_mask': shrink_axis_mask,
- 'new_axis_mask': new_axis_mask,
- 'ellipsis_mask': ellipsis_mask,
- 'infer': StridedSlice.infer}),
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph.graph['layout'] = 'NHWC'
-
- graph = partial_infer(graph)
- StridedSliceNormalizer().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
- MarkSubGraphsWithCorrectLayout().find_and_replace_pattern(graph)
- InsertLayoutPropagationTranspose().find_and_replace_pattern(graph)
- ApplyNHWCtoNCHWpermutation().find_and_replace_pattern(graph)
- MergeNodesPermutations().find_and_replace_pattern(graph)
- ApplyPermutation().find_and_replace_pattern(graph)
- graph = partial_infer(graph)
-
- node = Node(graph, 'strided_slice')
- res = node.out_port(0).data.get_shape()
- npt.assert_array_equal(res, ref_res)
-
- def test_strided_slice_permute_1(
- self, # inp[0, :34, 20, :2]
- inp=(1, 35, 35, 3), ref_res=(34, 2),
- begin=(0, 0, 20, 0), end=(1, 34, 21, 2), strides=(1, 1, 1, 1),
- begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1, 0, 1, 0), new_axis_mask=(0,),
- ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_2(
- self, # inp[0:3, 0:1, 5:0:-1]
- inp=(10, 10, 10, 10), ref_res=(3, 10, 1, 5),
- begin=(0, 0, 5), end=(3, 1, 0), strides=(1, 1, -1), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_3(
- self, # inp[1:34, 0, :, :2]
- inp=(1, 35, 35, 3), ref_res=(1, 35, 2),
- begin=(0, 0, 0, 0), end=(1, 34, 0, 2), strides=(1, 1, 1, 1), begin_mask=(1, 1, 0, 0), end_mask=(1, 0, 0, 1),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 0)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_4(
- # no shrink/new axis therefore will be permuted
- # inp[0:1, :, :, :2] begin mask is (1,) so only one begin value need to be specified
- self,
- inp=(16, 35, 35, 3), ref_res=(1, 2, 35, 35),
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(1, 0, 0,), end_mask=(1, 0, 0, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_5(
- self, # inp[:, :, :, :] since all begin and end masks are zero
- inp=(1, 35, 35, 3), ref_res=(1, 3, 35, 35),
- begin=(1, 10, 10, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0),
- end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_6(
- self, # inp[0]
- inp=(1, 35, 35, 3), ref_res=(35, 35, 3),
- begin=(0,), end=(1,), strides=(1,), begin_mask=(1,), end_mask=(0,),
- shrink_axis_mask=(1,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_7(
- self, # inp[0, 20], ends can be of any value
- inp=(1, 35, 35, 3), ref_res=(35, 3),
- begin=(0, 20), end=(1, 9999), strides=(1, 1), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_8(
- self, # inp[0, 0:34, 20:22, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(34, 2, 1, 3),
- begin=(0, 0, 20, 0), end=(1, 34, 22, 2), strides=(1, 1, 1, 1), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1,), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_9(
- self, # inp[:, 0:4, 20, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(1, 4, 1, 3),
- begin=(0, 0, 20, 0), end=(0, 4, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 1, 0, 0), end_mask=(0, 1, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_10(
- self, # inp[:, 0:4, new_axis, 20], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(1, 4, 1, 3),
- begin=(0, 0, 0, 20), end=(0, 4, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 1, 0, 0), end_mask=(0, 1, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_11(
- self, # inp[0, :, 0:34, 1:3, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(35, 34, 2, 1),
- begin=(0, 0, 0, 1, 0), end=(1, 0, 34, 3, 0), strides=(1, 1, 1, 1, 1),
- begin_mask=(1, 0, 1, 1, 1), end_mask=(1, 0, 1, 1, 1),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_12(
- self, # inp[0, :34, 20, :2]
- inp=(1, 35, 35, 3), ref_res=(34, 2),
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(0, 1, 1, 1),
- end_mask=(0, 1, 1, 1),
- shrink_axis_mask=(1, 0, 1, 0), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_13(
- self, # inp[0, 0, 0], since it's shrink_axis ends can be of any value
- inp=(1, 35, 35, 3), ref_res=(3,),
- begin=(0, 0, 0), end=(1, 34444, 20), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 1, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_14(
- self, # inp[0, 0, 0], since begin_mask is [0], begin can be of any value
- inp=(1, 35, 35, 3), ref_res=(1, 3, 18, 18),
- begin=(0, 0, 0), end=(1, 35, 35), strides=(2, 2, 2), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0, 0, 0), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- # with ellipsis
-
- def test_strided_slice_permute_15(
- self, # inp[..., np.newaxis]
- inp=(1, 35, 35), ref_res=(1, 35, 35, 1),
- begin=(101, 0), end=(0, 0), strides=(-1, -1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_16(
- self, # inp_shape = (1, 720, 1080), out = inp[..., :100, None] => out_shape = (1, 720, 100, 1)
- inp=(1, 720, 1080), ref_res=(1, 720, 100, 1),
- begin=(0, 0, 0), end=(0, 100, 0), strides=(1, 1, 1), begin_mask=(0, 1, 0), end_mask=(0, 1, 0),
- shrink_axis_mask=(0,), new_axis_mask=(0, 0, 1), ellipsis_mask=(1,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_17(
- self, # inp_shape = (1, 720, 1080, 3), out = inp[..., :-1] => out_shape = (1, 720, 100, 2)
- inp=(1, 720, 1080, 3), ref_res=(1, 2, 720, 1080),
- begin=(0, 0), end=(0, -1), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 1),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_18(
- self, # inp_shape = (1, 720, 1080, 3), out = inp[..., 2] => out_shape = (1, 720, 1080)
- inp=(1, 720, 1080, 3), ref_res=(1, 720, 1080),
- begin=(0, 2), end=(0, 0), strides=(1, 1), begin_mask=(0, 1), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_permute_19(
- self, # inp_shape = (1, 720, 1080, 3), out = input[..., 0:10, 0:3] => out_shape = (1, 720, 10, 3)
- inp=(1, 720, 1080, 3), ref_res=(1, 3, 720, 10),
- begin=(0, 0, 0), end=(0, 10, 3), strides=(1, 1, 1), begin_mask=(0, 1, 1), end_mask=(0, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(1,)
- ):
- self.run_permute_test(inp, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- # automatically generated permutation tests
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[:, :],
- out_nchw = inp[:, :, :, :] => out_shape = (1, 3, 100, 200)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 3, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[:, None] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[:, 0] => out_shape = (1, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[..., :],
- out_nchw = inp[:, :, :, ...] => out_shape = (1, 3, 100, 200)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 3, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[..., None] => out_shape = (1, 100, 200, 3, 1)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[..., 0],
- out_nchw = inp[:, 0, :, ...] => out_shape = (1, 100, 200)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_6(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[None, :] => out_shape = (1, 1, 100, 200, 3)
- out_nchw = inp[None, :, :, :, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_7(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[None, None] => out_shape = (1, 1, 1, 100, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_8(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC, (1, 3, 100, 200) in NCHW,
- out_nhwc = inp[None, 0] => out_shape = (1, 100, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_9(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC
- out_nhwc = inp[0, :] => out_shape = (100, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_10(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC
- out_nhwc = inp[0, None] => out_shape = (1, 100, 200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_permute_auto_infer_strided_slice_2d_slice_over_4d_11(self):
- """
- inp_shape = (1, 100, 200, 3) in NHWC
- out_nhwc = inp[0, 0] => out_shape = (200, 3)
- """
- self.run_permute_test(
- inp=(1, 100, 200, 3), ref_res=(200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
-
-class TestStridedSliceMaskAlignment(unittest.TestCase):
- def run_align_test(self, inp, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask,
- begin_mask_ref, end_mask_ref, shrink_axis_mask_ref, new_axis_mask_ref, ellipsis_mask_ref):
- nodes = {
- **regular_op_with_shaped_data('input', int64_array(inp), {'op': 'Parameter', 'type': 'Parameter',
- # need to specify shape in 2 places
- 'shape': int64_array(inp),
- 'infer': Parameter.infer}),
- **valued_const_with_data('begin', int64_array(begin)),
- **valued_const_with_data('end', int64_array(end)),
- **valued_const_with_data('strides', int64_array(strides)),
- **regular_op_with_empty_data('strided_slice',
- {'op': 'StridedSlice', 'type': 'StridedSlice', # need for permute
- 'begin_mask': begin_mask, 'end_mask': end_mask,
- 'shrink_axis_mask': shrink_axis_mask,
- 'new_axis_mask': new_axis_mask,
- 'ellipsis_mask': ellipsis_mask}),
- **regular_op('res', {'kind': 'op', 'type': 'Result', 'op': 'Result', 'infer': lambda x: None})
- }
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'middle'
- graph.graph['layout'] = 'NHWC'
-
- nodes_ref = nodes.copy()
- nodes_ref.update({
- **regular_op_with_empty_data('strided_slice',
- {'op': 'StridedSlice', 'type': 'StridedSlice', # need for permute
- 'begin_mask': begin_mask_ref, 'end_mask': end_mask_ref,
- 'shrink_axis_mask': shrink_axis_mask_ref,
- 'new_axis_mask': new_axis_mask_ref,
- 'ellipsis_mask': ellipsis_mask_ref}),
- })
-
- graph_ref = build_graph(nodes_ref, edges, nodes_with_edges_only=True)
- res, msg = compare_graphs(graph, graph_ref, 'res', check_op_attrs=True)
- assert res, msg
-
- def test_mask_align_compare_graphs_1(self):
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref=(0, 0), end_mask_ref=(0, 0),
- shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
-
- )
-
- def test_mask_align_compare_graphs_2(self):
- # begin_masks have different values, but they alight to the same mask
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref=(0), end_mask_ref=(0, 0),
- shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
-
- )
-
- def test_mask_align_compare_graphs_3(self):
- # begin_masks have different values, but they alight to the same mask
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref=(0, 0), end_mask_ref=(0),
- shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0), ellipsis_mask_ref=(0),
- )
-
- def test_mask_align_compare_graphs_4(self):
- # begin_masks have different values, but they alight to the same mask
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref=(0, 0), end_mask_ref=(0),
- shrink_axis_mask_ref=(1), new_axis_mask_ref=(0), ellipsis_mask_ref=(0),
- )
-
- # corner case with and empty slice
- def test_mask_align_compare_graphs_5(self):
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=[], end=[], strides=[],
- begin_mask=[], end_mask=[],
- shrink_axis_mask=[], new_axis_mask=[], ellipsis_mask=[],
- begin_mask_ref=[], end_mask_ref=[],
- shrink_axis_mask_ref=[], new_axis_mask_ref=[], ellipsis_mask_ref=[]
- )
-
- # emppty mask [] should be aligned into the length of begin
- def test_mask_align_compare_graphs_6(self):
- # begin_masks have different values, but they alight to the same mask
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref=[], end_mask_ref=(0, 0),
- shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
-
- )
-
- # empty mask "" should be transformed into [] and then aligned into the length of begin
- def test_mask_align_compare_graphs_7(self):
- # begin_masks have different values, but they alight to the same mask
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref="", end_mask_ref=(0, 0),
- shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
-
- )
-
- # negative test
- def test_negative_mask_align_compare_graphs(self):
- with self.assertRaisesRegex(AssertionError, 'have different attr "begin_mask"'):
- self.run_align_test(
- inp=(1, 100, 200, 3), begin=(0, 0), end=(0, 0), strides=(1, 1),
- begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0),
- begin_mask_ref=(0, 1), end_mask_ref=(0, 0),
- shrink_axis_mask_ref=(1, 1), new_axis_mask_ref=(0, 0), ellipsis_mask_ref=(0, 0),
- )
diff --git a/tools/mo/unit_tests/mo/middle/TensorIteratorBackEdge_test.py b/tools/mo/unit_tests/mo/middle/TensorIteratorBackEdge_test.py
deleted file mode 100644
index 20051bb04be1ce..00000000000000
--- a/tools/mo/unit_tests/mo/middle/TensorIteratorBackEdge_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.TensorIteratorBackEdge import BackEdgesMatching
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class BackEdgesMatchingTests(unittest.TestCase):
- def test_no_exit(self):
- pattern_matcher = BackEdgesMatching()
- pattern = pattern_matcher.pattern()
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'], update_edge_attrs=None,
- new_nodes_with_attrs=[('from_body_data', {'kind':'data'})],
- new_edges_with_attrs=[('from_body_data', 'NextIteration')])
-
- pattern_matcher.find_and_replace_pattern(graph)
- graph_ref = build_graph_with_attrs(nodes_with_attrs=[('condition', {'kind': 'op', 'op':'TensorIteratorCondition'}),
- ('condition_data', {'kind': 'data'}),
- ('back_edge', {'kind': 'op', 'op': 'TensorIteratorBackEdge'}),
- ('enter_data', {'kind': 'data'}),
- ('from_body_data', {'kind': 'data'}),
- ('Identity_1_data', {'kind': 'data'}),],
- edges_with_attrs=[('condition', 'condition_data'),
- ('enter_data', 'back_edge', {'in': 0}),
- ('condition_data', 'back_edge', {'in': 2}), # {in:2}
- ('from_body_data', 'back_edge', {'in': 1}),
- ('back_edge', 'Identity_1_data')],
- update_edge_attrs=None,
- new_nodes_with_attrs=[],
- new_edges_with_attrs=[],
- )
- (flag, resp) = compare_graphs(graph, graph_ref, 'Identity_1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_with_exit(self):
- pattern_matcher = BackEdgesMatching()
- pattern = pattern_matcher.pattern()
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'], update_edge_attrs=None,
- new_nodes_with_attrs=[('from_body_data', {'kind': 'data'}),
- ('exit', {'kind': 'op', 'op': 'Exit', 'name': 'exit'}),
- ('exit_data', {'kind': 'data'}),
- ('Switch_1_data_exit', {'kind': 'data'})],
-
- new_edges_with_attrs=[('from_body_data', 'NextIteration'),
- ('Switch_1', 'Switch_1_data_exit', {'out': 0}),
- ('Switch_1_data_exit', 'exit', {'out': 0}),
- ('exit', 'exit_data')])
-
- pattern_matcher.find_and_replace_pattern(graph)
- graph_ref = build_graph_with_attrs(nodes_with_attrs=[('condition', {'kind': 'op', 'op':'TensorIteratorCondition'}),
- ('condition_data', {'kind': 'data'}),
- ('back_edge', {'kind': 'op', 'op': 'TensorIteratorBackEdge'}),
- ('enter_data', {'kind': 'data'}),
- ('from_body_data', {'kind': 'data'}),
- ('Identity_1_data', {'kind': 'data'}),
- ('output', {'kind':'op', 'op':'TensorIteratorOutput'}),
- ('exit_data', {'kind': 'data'})
- ],
- edges_with_attrs=[('condition', 'condition_data'),
- ('enter_data', 'back_edge', {'in': 0}),
- ('condition_data', 'back_edge', {'in': 2}),
- ('from_body_data', 'back_edge', {'in': 1}),
- ('back_edge', 'Identity_1_data'),
- ('condition_data', 'output'),
- ('output', 'exit_data'),
- ('from_body_data', 'output')],
- update_edge_attrs=None,
- new_nodes_with_attrs=[],
- new_edges_with_attrs=[],
- )
- (flag, resp) = compare_graphs(graph, graph_ref, 'Identity_1_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/TensorIteratorCondition_test.py b/tools/mo/unit_tests/mo/middle/TensorIteratorCondition_test.py
deleted file mode 100644
index d4d2c48d2a6ffa..00000000000000
--- a/tools/mo/unit_tests/mo/middle/TensorIteratorCondition_test.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.TensorIteratorCondition import LoopConditionMatcher
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs, regular_op_with_empty_data, connect, build_graph
-
-
-class TensorIteratorConditionTests(unittest.TestCase):
- def test_not_dynamic_1(self):
- pattern_matcher = LoopConditionMatcher()
- pattern = pattern_matcher.pattern(1)
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- new_nodes_with_attrs=[
- ('TensorIteratorInput', {'kind': 'op', 'op': 'TensorIteratorInput'})],
- new_edges_with_attrs=[
- ('Identity_1_data', 'TensorIteratorInput')],
- update_nodes_attributes=[
- ('init_1_data', {'value': np.array([0])}),
- ('init_2_data', {'value': np.array([0])}),
- ('add_1_y_data', {'value': np.array(1)}),
- ('add_2_y_data', {'value': np.array(1)}),
- ('loop_cond_data', {'value': None}),
- ('Identity_2_data', {'value': None},),
- ('Enter_1_less_data', {'value': None},),
- ])
-
- pattern_matcher.find_and_replace_pattern(graph)
- nodes_attributes = {
- **regular_op_with_empty_data('StridedSlice', {'op': 'StridedSlice', 'type': None}),
- 'TensorIteratorCondition': {'kind': 'op', 'op': 'TensorIteratorCondition'},
- 'loop_cond_data': {'kind': 'data'},
- 'identity_data': {'kind': 'data'},
- 'minimum_data': {'kind': 'data'},
- 'TensorIteratorInput': {'kind': 'op', 'op': 'TensorIteratorInput'}
- }
- edges = [
- *connect('StridedSlice', '0:TensorIteratorCondition'),
- ('minimum_data', 'TensorIteratorCondition', {'in':1}),
- ('TensorIteratorCondition', 'loop_cond_data'),
- ('TensorIteratorCondition', 'identity_data'),
- ('identity_data', 'TensorIteratorInput')
- ]
- graph_ref = build_graph(nodes_attributes, edges)
- (flag, resp) = compare_graphs(graph, graph_ref, 'loop_cond_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_not_dynamic_2(self):
- pattern_matcher = LoopConditionMatcher()
- pattern = pattern_matcher.pattern(2)
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- new_nodes_with_attrs=[
- ('TensorIteratorInput', {'kind': 'op', 'op': 'TensorIteratorInput'}),
- ('some_op', {'kind': 'op', 'op': 'Add'})],
- new_edges_with_attrs=[
- ('Identity_1_data', 'TensorIteratorInput'),
- ('loop_cond_data', 'some_op'),
- ],
- update_nodes_attributes=[
- ('init_1_data', {'value': np.array([0])}),
- ('init_2_data', {'value': np.array([0])}),
- ('add_1_y_data', {'value': np.array(1)}),
- ('add_2_y_data', {'value': np.array(1)}),
- ('loop_cond_data', {'value': None}),
- ('Identity_2_data', {'value': None},),
- ('Enter_1_less_data', {'value': None},),
- ])
-
- pattern_matcher.find_and_replace_pattern(graph)
- nodes_attributes = {
- **regular_op_with_empty_data('loop_cond', {'op': 'TensorIteratorCondition', 'type': None}),
- **regular_op_with_empty_data('StridedSlice', {'op': 'StridedSlice', 'type': None}),
- 'some_op': {'kind': 'op', 'op': 'Add'},
- 'identity_data': {'kind': 'data'},
- 'TensorIteratorInput': {'kind': 'op', 'op': 'TensorIteratorInput'}
- }
- edges = [
- *connect('StridedSlice', 'loop_cond'),
- *connect('loop_cond', 'some_op'),
- ('loop_cond', 'identity_data'),
- ('identity_data', 'TensorIteratorInput')
- ]
- graph_ref = build_graph(nodes_attributes, edges)
- (flag, resp) = compare_graphs(graph, graph_ref, 'some_op', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/TensorIteratorInput_test.py b/tools/mo/unit_tests/mo/middle/TensorIteratorInput_test.py
deleted file mode 100644
index f64ccb87c37d54..00000000000000
--- a/tools/mo/unit_tests/mo/middle/TensorIteratorInput_test.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.TensorIteratorInput import SmartInputMatcher, SimpleInputMatcher, BackEdgeSimpleInputMatcher
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class SmartInputMatcherTests(unittest.TestCase):
- def test(self):
- pattern_matcher = SmartInputMatcher()
- pattern = pattern_matcher.pattern()
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- update_edge_attrs={('range_data', 'TensorArrayScatter', 0): {'in': 1},
- ('TensorArray_handle', 'TensorArrayScatter', 0): {'in': 0},
- ('TensorArray_flow', 'TensorArrayScatter', 0): {'in': 3}},
- new_nodes_with_attrs=[('ta_size', {'kind': 'data'}),
- ('ta_size_op', {'kind': 'op'}),
- ('value', {'kind': 'data'}),
- ],
- new_edges_with_attrs=[
- ('ta_size_op', 'ta_size'),
- ('ta_size', 'TensorArray'),
- ('value', 'TensorArrayScatter', {'in':2}),
- ],
- update_nodes_attributes=[('Enter_data', {'value': np.array([1])}),
- ('stack_data', {'value': np.array([0])}),
- ('stack_1_data', {'value': np.array([1])}),
- ('stack_2_data', {'value': np.array([1])}),
- ('start_data', {'value': np.array([0])}),
- ('delta_data', {'value': np.array([1])})
- ])
-
- pattern_matcher.find_and_replace_pattern(graph)
- graph_ref = build_graph_with_attrs(
- nodes_with_attrs=[('condition_data', {'kind': 'data'}),
- ('TensorIteratorInput', {'kind': 'op', 'op': 'TensorIteratorInput'}),
- ('TensorArrayRead_data', {'kind': 'data'}),
- ('condition_data', {'kind': 'data'}),
- ('value', {'kind': 'data'}),
- ('ta_size', {'kind': 'data'}),
- ('ta_size_op', {'kind': 'op'})],
- edges_with_attrs=[('ta_size', 'TensorIteratorInput', {'in': 0}),
- ('condition_data', 'TensorIteratorInput', {'in': 2}),
- ('value', 'TensorIteratorInput', {'in': 1}),
- ('TensorIteratorInput', 'TensorArrayRead_data'),
- ('ta_size_op', 'ta_size')],
- update_edge_attrs=None,
- new_nodes_with_attrs=[],
- new_edges_with_attrs=[],
- )
- (flag, resp) = compare_graphs(graph, graph_ref, 'TensorArrayRead_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class SimpleInputMatcherTest(unittest.TestCase):
- def test(self):
- pattern_matcher = SimpleInputMatcher()
- pattern = pattern_matcher.pattern()
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- update_edge_attrs=None,
- new_nodes_with_attrs=[('in_node', {'kind': 'data'}),
- ('Enter_data', {'kind': 'data'})],
- new_edges_with_attrs=[('in_node', 'Enter'), ('Enter', 'Enter_data')],
- update_nodes_attributes=[])
-
- pattern_matcher.find_and_replace_pattern(graph)
-
- graph_ref = build_graph_with_attrs(
- nodes_with_attrs=[('TensorIteratorInput', {'kind': 'op', 'op': 'TensorIteratorInput'}),
- ('in_node', {'kind': 'data'}),
- ('Enter_data', {'kind': 'data'})
- ],
- edges_with_attrs=[('in_node', 'TensorIteratorInput'), ('TensorIteratorInput', 'Enter_data')],
- )
- (flag, resp) = compare_graphs(graph, graph_ref, 'Enter_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class BackEdgeInputMatcherTest(unittest.TestCase):
- def test1(self):
- """
- Case with constant input to init
- """
- pattern_matcher = BackEdgeSimpleInputMatcher()
- pattern = pattern_matcher.pattern()
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- new_nodes_with_attrs=[('cycle_data', {'kind': 'data'}),
- ('condition', {'kind': 'data'}),
- ('init', {'kind': 'data', 'shape': np.array([1,3])}),
- ],
- new_edges_with_attrs=[('condition', 'BackEdge', {'in': 2}),
- ('init', 'BackEdge', {'in': 0}),
- ('cycle_data', 'BackEdge', {'in': 1})],)
-
- pattern_matcher.find_and_replace_pattern(graph)
- graph_ref = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- new_nodes_with_attrs=[('cycle_data', {'kind': 'data'}),
- ('condition', {'kind': 'data'}),
- ('init', {'kind': 'data', 'shape': np.array([1,3])}),
- ('TensorIteratorInput', {'kind': 'op', 'op': 'TensorIteratorInput'}),
- ('TensorIteratorInput_data', {'kind': 'data', 'shape': np.array([1,3])}),
- ],
- new_edges_with_attrs=[('TensorIteratorInput_data', 'TensorIteratorInput'),
- ('TensorIteratorInput', 'init'),
- ('condition', 'BackEdge', {'in': 2}),
- ('init', 'BackEdge', {'in': 0}),
- ('cycle_data', 'BackEdge', {'in': 1})],)
- (flag, resp) = compare_graphs(graph, graph_ref, 'BackEdge', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test2(self):
- """
- Case with non-constant input to init.
- Nothing should happen with graph.
- """
- pattern_matcher = BackEdgeSimpleInputMatcher()
- pattern = pattern_matcher.pattern()
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- new_nodes_with_attrs=[('cycle_data', {'kind': 'data'}),
- ('condition', {'kind': 'data'}),
- ('init', {'kind': 'data', 'shape': np.array([1, 3])}),
- ('Enter', {'kind': 'op', 'op': 'Enter'}),
- ],
- new_edges_with_attrs=[('Enter', 'init'),
- ('condition', 'BackEdge', {'in': 2}),
- ('init', 'BackEdge', {'in': 0}),
- ('cycle_data', 'BackEdge', {'in': 1})])
-
- pattern_matcher.find_and_replace_pattern(graph)
-
- graph_ref = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- new_nodes_with_attrs=[('cycle_data', {'kind': 'data'}),
- ('condition', {'kind': 'data'}),
- ('init', {'kind': 'data', 'shape': np.array([1, 3])}),
- ('Enter', {'kind': 'op', 'op': 'Enter'}),
- ],
- new_edges_with_attrs=[('Enter', 'init'),
- ('condition', 'BackEdge', {'in': 2}),
- ('init', 'BackEdge', {'in': 0}),
- ('cycle_data', 'BackEdge', {'in': 1})], )
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'BackEdge', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/TensorIteratorOutput_test.py b/tools/mo/unit_tests/mo/middle/TensorIteratorOutput_test.py
deleted file mode 100644
index 33ba540f223ad7..00000000000000
--- a/tools/mo/unit_tests/mo/middle/TensorIteratorOutput_test.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.TensorIteratorOutput import SmartOutputMatcher
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class SmartOutputMatcherTests(unittest.TestCase):
- def test(self):
- pattern_matcher = SmartOutputMatcher()
- pattern = pattern_matcher.pattern()
-
- graph = build_graph_with_attrs(nodes_with_attrs=pattern['nodes'], edges_with_attrs=pattern['edges'],
- # update_edge_attrs=None,
- new_nodes_with_attrs=[('index', {'kind': 'data'}),
- ('value', {'kind': 'data'}),
- ('ta_size', {'kind': 'data'}),
- ],
- new_edges_with_attrs=[('index', 'TensorArrayWrite', {'in':1}),
- ('value', 'TensorArrayWrite', {'in': 2}),
- ('ta_size', 'TensorArray')
- ],
- update_nodes_attributes=[('WriteEnter_data', {'value': np.array([1, 1])}),
-
- ('start_data', {'value': np.array([0])}),
- ('delta_data', {'value': np.array([1])}),
- ])
-
- pattern_matcher.find_and_replace_pattern(graph)
-
- graph_ref = build_graph_with_attrs(
- nodes_with_attrs=[
- ('TensorIteratorOutput', {'kind': 'op', 'op': 'TensorIteratorOutput'}),
- ('TensorArrayGather_data', {'kind': 'data'}),
- ('index', {'kind': 'data'}),
- ('value', {'kind': 'data'}),
- ('ta_size', {'kind': 'data'}), ],
- edges_with_attrs=[('ta_size', 'TensorIteratorOutput', {'in': 0}),
- ('index', 'TensorIteratorOutput', {'in': 2}),
- ('value', 'TensorIteratorOutput', {'in': 1}),
- ('TensorIteratorOutput', 'TensorArrayGather_data')],
- update_edge_attrs=None,
- new_nodes_with_attrs=[],
- new_edges_with_attrs=[],
- )
- (flag, resp) = compare_graphs(graph, graph_ref, 'TensorArrayGather_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/UnsqueezeTileReshapeBlockToInterpolate_test.py b/tools/mo/unit_tests/mo/middle/UnsqueezeTileReshapeBlockToInterpolate_test.py
deleted file mode 100644
index 72755b9d4aa853..00000000000000
--- a/tools/mo/unit_tests/mo/middle/UnsqueezeTileReshapeBlockToInterpolate_test.py
+++ /dev/null
@@ -1,399 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-import numpy as np
-
-from openvino.tools.mo.middle.UnsqueezeTileReshapeBlockToInterpolate import UnsqueezeTileReshapeBlockToInterpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-graph_node_attrs = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 8, 32, 32, 64]),
- 'kind': 'data',
- 'data_type': None
- },
- 'unsqueeze': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- 'dim': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([2]),
- 'shape': int64_array([1]),
- },
- 'dim_data': {
- 'kind': 'data',
- 'value': int64_array([2]),
- 'shape': int64_array([1]),
- },
- 'unsqueeze_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 8, 1, 32, 32, 64]),
- 'value': None,
- },
- 'tile': {'type': 'Tile', 'kind': 'op', 'op': 'Tile'},
- 'multipliers': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1, 1, 2, 1, 1, 1]),
- 'shape': int64_array([6]),
- },
- 'multipliers_data': {
- 'kind': 'data',
- 'value': int64_array([1, 1, 2, 1, 1, 1]),
- 'shape': int64_array([6]),
- },
- 'tile_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 8, 2, 32, 32, 64]),
- 'value': None,
- },
- 'reshape': {'type': 'Reshape', 'kind': 'op', 'op': 'Reshape'},
- 'reshape_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 16, 32, 32, 64]),
- 'value': None,
- },
- 'shape': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1, 16, 32, 32, 64]),
- 'shape': int64_array([5]),
- },
- 'shape_data': {
- 'kind': 'data',
- 'value': int64_array([1, 16, 32, 32, 64]),
- 'shape': int64_array([5]),
- },
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 16, 32, 32, 64]),
- 'value': None,
- },
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'unsqueeze', {'in': 0}),
- ('dim', 'dim_data'),
- ('dim_data', 'unsqueeze', {'in': 1}),
- ('unsqueeze', 'unsqueeze_data'),
- ('unsqueeze_data', 'tile', {'in': 0}),
- ('multipliers', 'multipliers_data'),
- ('multipliers_data', 'tile', {'in': 1}),
- ('tile', 'tile_data'),
- ('tile_data', 'reshape', {'in': 0}),
- ('reshape', 'reshape_data'),
- ('shape', 'shape_data'),
- ('shape_data', 'reshape', {'in': 1}),
- ('reshape_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-ref_graph_node_attrs_with_4_inputs_interpolate = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 8, 32, 32, 64]),
- 'kind': 'data',
- 'data_type': None
- },
- 'shapeof': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shapeof_data': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- },
- 'gather': {
- 'type': 'Gather',
- 'kind': 'op',
- 'op': 'Gather'
- },
- 'gather_data': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- },
- 'indices': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'indices_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': None,
- },
- 'gather_axis': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': np.array(0, dtype=np.int64),
- 'shape': np.array(0, dtype=np.int64).shape,
- },
- 'gather_axis_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': None,
- },
- 'scales_m': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': np.array([2], dtype=np.int64),
- 'shape': int64_array([1]),
- },
- 'scales_m_data': {
- 'kind': 'data',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1]),
- },
- 'mul': {'type': 'Mul', 'kind': 'op', 'op': 'Mul'},
- 'mul_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': None,
- },
- 'scales': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1]),
- },
- 'scales_data': {
- 'kind': 'data',
- 'value': np.array([2], dtype=np.float32),
- 'shape': int64_array([1]),
- },
- 'axes': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'axes_data': {
- 'kind': 'data',
- 'value': int64_array([1]),
- 'shape': int64_array([1]),
- },
- 'interpolate': {'type': 'Interpolate', 'kind': 'op', 'op': 'Interpolate'},
- 'interpolate_data': {
- 'kind': 'data',
- 'value': None,
- 'shape': int64_array([1, 16, 32, 32, 64]),
- },
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 16, 32, 32, 64]),
- 'value': None,
- },
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-
-ref_graph_edges_attrs_with_4_inputs_interpolate = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'shapeof'),
- ('shapeof', 'shapeof_data'),
- ('shapeof_data', 'gather', {'in': 0}),
- ('gather', 'gather_data'),
- ('indices', 'indices_data'),
- ('indices_data', 'gather', {'in': 1}),
- ('gather_axis', 'gather_axis_data'),
- ('gather_axis_data', 'gather', {'in': 2}),
- ('scales_m', 'scales_m_data'),
- ('gather_data', 'mul', {'in': 0}),
- ('scales_m_data', 'mul', {'in': 1}),
- ('mul', 'mul_data'),
- ('scales', 'scales_data'),
- ('axes', 'axes_data'),
- ('scales_data', 'interpolate', {'out': 0, 'in': 2}),
- ('mul_data', 'interpolate', {'in': 1}),
- ('placeholder_data', 'interpolate', {'in': 0}),
- ('axes_data', 'interpolate', {'in': 3}),
- ('interpolate', 'interpolate_data'),
- ('interpolate_data', 'abs'),
- ('abs', 'abs_data'),
- ('abs_data', 'output'),
-]
-
-
-graph_node_attrs_when_transformation_is_not_applicable = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {
- 'value': None,
- 'shape': int64_array([1, 8, 32]),
- 'kind': 'data',
- 'data_type': None
- },
- 'unsqueeze': {'type': 'Unsqueeze', 'kind': 'op', 'op': 'Unsqueeze'},
- 'dim': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([2]),
- 'shape': int64_array([1]),
- },
- 'dim_data': {
- 'kind': 'data',
- 'value': int64_array([2]),
- 'shape': int64_array([1]),
- },
- 'unsqueeze_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 8, 1, 32]),
- 'value': None,
- },
- 'tile': {'type': 'Tile', 'kind': 'op', 'op': 'Tile'},
- 'multipliers': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1, 1, 2, 1]),
- 'shape': int64_array([4]),
- },
- 'multipliers_data': {
- 'kind': 'data',
- 'value': int64_array([1, 1, 2, 1]),
- 'shape': int64_array([4]),
- },
- 'tile_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 8, 2, 32]),
- 'value': None,
- },
- 'reshape': {'type': 'Reshape', 'kind': 'op', 'op': 'Reshape'},
- 'reshape_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 16, 32]),
- 'value': None,
- },
- 'shape': {
- 'kind': 'op',
- 'op': 'Const',
- 'type': 'Const',
- 'value': int64_array([1, 16, 32]),
- 'shape': int64_array([3]),
- },
- 'shape_data': {
- 'kind': 'data',
- 'value': int64_array([1, 16, 32]),
- 'shape': int64_array([3]),
- },
- 'abs': {'type': 'Abs', 'kind': 'op', 'op': 'Abs'},
- 'abs_data': {
- 'kind': 'data',
- 'shape': int64_array([1, 16, 32]),
- 'value': None,
- },
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-graph_edges_when_transformation_is_not_applicable = graph_edges
-
-
-class UnsqueezeTileReshapeBlockToInterpolateTest(unittest.TestCase):
- def test_5d(self):
- graph = build_graph(nodes_attrs=graph_node_attrs, edges=graph_edges)
- ref_graph = build_graph(nodes_attrs=ref_graph_node_attrs_with_4_inputs_interpolate,
- edges=ref_graph_edges_attrs_with_4_inputs_interpolate)
- UnsqueezeTileReshapeBlockToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_4d(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs,
- edges=graph_edges,
- update_attributes={
- 'placeholder_data': {'shape': int64_array([1, 8, 32, 32])},
- 'unsqueeze_data': {'shape': int64_array([1, 8, 1, 32, 32])},
- 'multipliers': {'value': int64_array([1, 1, 2, 1, 1]), 'shape': int64_array([5])},
- 'multipliers_data': {'value': int64_array([1, 1, 2, 1, 1]), 'shape': int64_array([5])},
- 'tile_data': {'shape': int64_array([1, 8, 2, 32, 32])},
- 'reshape_data': {'shape': int64_array([1, 16, 32, 32]), 'value': None},
- 'shape': {'value': int64_array([1, 16, 32, 32]), 'shape': int64_array([4])},
- 'shape_data': {'value': int64_array([1, 16, 32, 32]), 'shape': int64_array([4])},
- 'abs_data': {'shape': int64_array([1, 16, 32, 32])},
- }
- )
- ref_graph = build_graph(
- nodes_attrs=ref_graph_node_attrs_with_4_inputs_interpolate,
- edges=ref_graph_edges_attrs_with_4_inputs_interpolate,
- update_attributes={
- 'placeholder_data': {'shape': int64_array([1, 8, 32, 32])},
- 'interpolate_data': {'shape': int64_array([1, 16, 32, 32])},
- 'abs_data': {'shape': int64_array([1, 16, 32, 32])},
- 'axes': {'shape': int64_array([1]), 'value': int64_array([1])},
- }
- )
- UnsqueezeTileReshapeBlockToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_3d(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_when_transformation_is_not_applicable,
- edges=graph_edges_when_transformation_is_not_applicable
- )
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_when_transformation_is_not_applicable,
- edges=graph_edges_when_transformation_is_not_applicable
- )
- UnsqueezeTileReshapeBlockToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
-
- def test_2d(self):
- graph = build_graph(
- nodes_attrs=graph_node_attrs_when_transformation_is_not_applicable,
- edges=graph_edges_when_transformation_is_not_applicable,
- update_attributes={
- 'placeholder_data': {'shape': int64_array([5, 8])},
- 'dim': {'value': int64_array([1])},
- 'dim_data': {'value': int64_array([1])},
- 'unsqueeze_data': {'shape': int64_array([5, 1, 8])},
- 'multipliers': {'value': int64_array([1, 10, 1])},
- 'multipliers_data': {'value': int64_array([1, 10, 1]), 'shape': int64_array([3])},
- 'tile_data': {'shape': int64_array([5, 10, 8])},
- 'reshape_data': {'shape': int64_array([50, 8])},
- 'shape': {'value': int64_array([50, 8]), 'shape': int64_array([2])},
- 'shape_data': {'value': int64_array([50, 8]), 'shape': int64_array([2])},
- 'abs_data': {'shape': int64_array([50, 8])},
- }
- )
- ref_graph = build_graph(
- nodes_attrs=graph_node_attrs_when_transformation_is_not_applicable,
- edges=graph_edges_when_transformation_is_not_applicable,
- update_attributes={
- 'placeholder_data': {'shape': int64_array([5, 8])},
- 'dim': {'value': int64_array([1])},
- 'dim_data': {'value': int64_array([1])},
- 'unsqueeze_data': {'shape': int64_array([5, 1, 8])},
- 'multipliers': {'value': int64_array([1, 10, 1])},
- 'multipliers_data': {'value': int64_array([1, 10, 1]), 'shape': int64_array([3])},
- 'tile_data': {'shape': int64_array([5, 10, 8])},
- 'reshape_data': {'shape': int64_array([50, 8])},
- 'shape': {'value': int64_array([50, 8]), 'shape': int64_array([2])},
- 'shape_data': {'value': int64_array([50, 8]), 'shape': int64_array([2])},
- 'abs_data': {'shape': int64_array([50, 8])},
- }
- )
- UnsqueezeTileReshapeBlockToInterpolate().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/UpsampleToResample_test.py b/tools/mo/unit_tests/mo/middle/UpsampleToResample_test.py
deleted file mode 100644
index 2129781e771fcf..00000000000000
--- a/tools/mo/unit_tests/mo/middle/UpsampleToResample_test.py
+++ /dev/null
@@ -1,215 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.middle.UpsampleToResample import UpsampleToResample
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-graph_node_attrs = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'scales': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': None, 'shape': None},
- 'scales_data': {'kind': 'data', 'value': None, 'shape': None},
- 'upsample': {'type': None, 'kind': 'op', 'op': 'Upsample', 'mode': 'linear'},
- 'upsample_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'upsample', {'in': 0}),
- ('scales', 'scales_data'),
- ('scales_data', 'upsample', {'in': 1}),
- ('upsample', 'upsample_data'),
- ('upsample_data', 'output'),
-]
-
-new_ref_graph_node_attr = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'ss_begin': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2]), 'shape': int64_array([1])},
- 'ss_begin_data': {'kind': 'data', 'value': int64_array([2]), 'shape': int64_array([1])},
- 'ss_end': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4]), 'shape': int64_array([1])},
- 'ss_end_data': {'kind': 'data', 'value': int64_array([4]), 'shape': int64_array([1])},
- 'ss_stride': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1]), 'shape': int64_array([1])},
- 'ss_stride_data': {'kind': 'data', 'value': int64_array([1]), 'shape': int64_array([1])},
- 'strided_slice': {'type': 'StridedSlice', 'kind': 'op', 'op': 'StridedSlice'},
- 'strided_slice_data': {'kind': 'data', 'shape': None, 'value': None},
- 'cast_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32},
- 'cast_to_float_d': {'kind': 'data', 'value': None, 'shape': None},
- 'factor': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([5, 5]), 'shape': int64_array([2])},
- 'factor_data': {'kind': 'data', 'value': int64_array([5, 5]), 'shape': int64_array([2])},
- 'shapeof': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shapeof_data': {'kind': 'data', 'shape': None, 'value': None},
- 'mul': {'type': 'Multiply', 'kind': 'op', 'op': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None, 'value': None},
- 'cast_to_int': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.int32},
- 'cast_to_int_d': {'kind': 'data', 'shape': None, 'value': None},
- 'axes_const': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': None, 'shape': None},
- 'axes_const_data': {'kind': 'data', 'value': None, 'shape': None},
- 'scales': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([5, 5]), 'shape': int64_array([2])},
- 'scales_data': {'kind': 'data', 'value': None, 'shape': None},
- 'interpolate': {'type': 'Interpolate', 'kind': 'op', 'op': 'Interpolate', 'axes': None},
- 'interpolate_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-new_ref_graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'shapeof', {'in': 0, 'out': 0}),
- ('placeholder_data', 'interpolate', {'in': 0, 'out': 0}),
- ('ss_begin', 'ss_begin_data'),
- ('ss_begin_data', 'strided_slice', {'in': 1, 'out': 0}),
- ('ss_end', 'ss_end_data'),
- ('ss_end_data', 'strided_slice', {'in': 2, 'out': 0}),
- ('ss_stride', 'ss_stride_data'),
- ('ss_stride_data', 'strided_slice', {'in': 3, 'out': 0}),
- ('strided_slice', 'strided_slice_data'),
- ('strided_slice_data', 'cast_to_float'),
- ('cast_to_float', 'cast_to_float_d'),
- ('shapeof', 'shapeof_data'),
- ('shapeof_data', 'strided_slice', {'in': 0, 'out': 0}),
- ('factor', 'factor_data'),
- ('cast_to_float_d', 'mul', {'in': 0, 'out': 0}),
- ('factor_data', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'mul_data'),
- ('mul_data', 'cast_to_int'),
- ('cast_to_int', 'cast_to_int_d'),
- ('cast_to_int_d', 'interpolate', {'in': 1, 'out': 0}),
- ('axes_const', 'axes_const_data'),
- ('axes_const_data', 'interpolate', {'in': 3, 'out': 0}),
- ('scales', 'scales_data'),
- ('scales_data', 'interpolate', {'in': 2, 'out': 0}),
- ('interpolate', 'interpolate_data'),
- ('interpolate_data', 'output')
-]
-
-ref_graph_node_attrs = {
- 'placeholder': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': np.float32},
- 'factor': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([5, 5]), 'shape': int64_array([2])},
- 'factor_data': {'kind': 'data', 'value': None, 'shape': None},
- 'shapeof': {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'},
- 'shapeof_data': {'kind': 'data', 'shape': None, 'value': None},
- 'strided_slice': {'type': 'StridedSlice', 'kind': 'op', 'op': 'StridedSlice'},
- 'strided_slice_data': {'kind': 'data', 'shape': None, 'value': None},
- 'ss_begin': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([2]), 'shape': int64_array([1])},
- 'ss_begin_data': {'kind': 'data', 'value': None, 'shape': None},
- 'ss_end': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([4]), 'shape': int64_array([1])},
- 'ss_end_data': {'kind': 'data', 'value': None, 'shape': None},
- 'ss_stride': {'kind': 'op', 'op': 'Const', 'type': 'Const', 'value': int64_array([1]), 'shape': int64_array([1])},
- 'ss_stride_data': {'kind': 'data', 'value': None, 'shape': None},
- 'cast_to_float': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.float32},
- 'cast_to_float_d': {'kind': 'data', 'value': None, 'shape': None},
- 'mul': {'type': 'Multiply', 'kind': 'op', 'op': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None, 'value': None},
- 'cast_to_int': {'kind': 'op', 'op': 'Cast', 'type': 'Convert', 'dst_type': np.int32},
- 'cast_to_int_d': {'kind': 'data', 'shape': None, 'value': None},
- 'interpolate': {'type': 'Interpolate', 'kind': 'op', 'op': 'Interpolate', 'axes': None},
- 'interpolate_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output': {'kind': 'op', 'op': 'Result', 'type': 'Result'},
-}
-
-ref_graph_edges = [
- ('placeholder', 'placeholder_data'),
- ('placeholder_data', 'interpolate', {'in': 0, 'out': 0}),
- ('placeholder_data', 'shapeof', {'in': 0, 'out': 0}),
- ('shapeof', 'shapeof_data'),
- ('interpolate', 'interpolate_data'),
- ('factor', 'factor_data'),
- ('shapeof_data', 'strided_slice', {'in': 0, 'out': 0}),
- ('ss_begin', 'ss_begin_data'),
- ('ss_begin_data', 'strided_slice', {'in': 1, 'out': 0}),
- ('ss_end', 'ss_end_data'),
- ('ss_end_data', 'strided_slice', {'in': 2, 'out': 0}),
- ('ss_stride', 'ss_stride_data'),
- ('ss_stride_data', 'strided_slice', {'in': 3, 'out': 0}),
- ('strided_slice', 'strided_slice_data'),
- ('strided_slice_data', 'cast_to_float'),
- ('cast_to_float', 'cast_to_float_d'),
- ('cast_to_float_d', 'mul', {'in': 0, 'out': 0}),
- ('factor_data', 'mul', {'in': 1, 'out': 0}),
- ('mul', 'mul_data'),
- ('mul_data', 'cast_to_int'),
- ('cast_to_int', 'cast_to_int_d'),
- ('cast_to_int_d', 'interpolate', {'in': 1, 'out': 0}),
- ('interpolate_data', 'output'),
-]
-
-
-class TestUpsampleToResampleTest():
- @pytest.mark.parametrize("input_shape, scales, axes",[([2, 10, 20, 30], [1, 1, 5, 5], [2, 3]),
- ([2, 20, 30, 40], [1, 1, 3, 3], [2, 3]),
- ([2, 10, 20, 30], [1, 1, 6, 5], [2, 3]),
- ([2, 20, 30, 40], [1, 1, 3, 4], [2, 3]),
- ([2, 3, 20, 30, 40], [1, 1, 3, 3, 3], [2, 3, 4]),
- ([2, 3, 20, 30, 40], [1, 1, 3, 4, 3], [2, 3, 4]),
- ([2, 3, 20, 30, 40], [1, 1, 4, 3, 3], [2, 3, 4]),
- ([2, 3, 20, 30, 40], [1, 1, 3, 3, 4], [2, 3, 4]),
- ([2, 10, 20, 30], [1, 1, 5.5, 5.7], [2, 3]),
- ([2, 20, 30, 40], [1, 1, 3.3, 3.1], [2, 3]),
- ([2, 10, 20, 30], [1, 1, 6.18, 5.34], [2, 3]),
- ([2, 20, 30, 40], [1, 1, 3.79, 4.16], [2, 3]),
- ([2, 3, 20, 30, 40], [1, 1, 3.12, 3.87, 3.92], [2, 3, 4]),
- ([2, 3, 20, 30, 40], [1, 1, 3.74, 4.873, 3.287], [2, 3, 4]),
- ([2, 3, 20, 30, 40], [1, 1, 4.8, 3.6, 3.11], [2, 3, 4]),
- ([2, 3, 20, 30, 40], [1, 1, 3.33, 3.73, 4.765], [2, 3, 4]),
- ])
- def test_conversion(self, input_shape, scales, axes):
- input_shape_as_array = int64_array(input_shape)
- scales_as_array = float32_array(scales)
- graph = build_graph(graph_node_attrs,
- graph_edges,
- {
- 'placeholder_data': {'shape': input_shape_as_array},
- 'scales': {'value': scales_as_array, 'shape': scales_as_array.shape},
- 'scales_data': {'value': scales_as_array, 'shape': scales_as_array.shape},
- 'upsample_data':
- {'shape': ((input_shape_as_array + 1.e-5) * scales_as_array).astype(np.int64)}
- })
- graph.graph['layout'] = 'NCHW'
- ref_graph = build_graph(new_ref_graph_node_attr,
- new_ref_graph_edges,
- {
- 'placeholder_data': {'shape': int64_array(input_shape)},
- 'ss_begin': {'value': int64_array([axes[0]])},
- 'ss_end': {'value': int64_array([axes[-1] + 1])},
- 'ss_begin_data': {'value': int64_array([axes[0]])},
- 'ss_end_data': {'value': int64_array([axes[-1] + 1])},
- 'factor': {'value': scales_as_array[2:],
- 'shape': scales_as_array[2:].shape},
- 'factor_data': {'value': scales_as_array[2:],
- 'shape': scales_as_array[2:].shape},
- 'axes_const': {'value': int64_array(axes), 'shape': int64_array(axes).shape},
- 'interpolate_data': {
- 'shape': (input_shape_as_array * scales_as_array + 1e-5).astype(np.int64)},
- })
- UpsampleToResample().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- assert flag, resp
-
- @pytest.mark.parametrize("input_shape, scales",[([2, 10, 20, 30], [1, 2, 5, 5],),
- ([2, 3, 20, 30, 40], [1, 2, 3, 3, 3],),
- ])
- def test_pattern_does_not_satisfy(self, input_shape, scales):
- graph = build_graph(graph_node_attrs, graph_edges,
- {'placeholder_data': {'shape': int64_array(input_shape)},
- 'scales': {'value': int64_array(scales), 'shape': int64_array(scales).shape},
- 'scales_data': {'value': int64_array(scales), 'shape': int64_array(scales).shape},
- 'upsample_data': {'shape': int64_array(input_shape) * int64_array(scales)}})
- graph.graph['layout'] = 'NCHW'
-
- ref_graph = build_graph(graph_node_attrs, graph_edges,
- {'placeholder_data': {'shape': int64_array(input_shape)},
- 'scales': {'value': int64_array(scales), 'shape': int64_array(scales).shape},
- 'scales_data': {'value': int64_array(scales), 'shape': int64_array(scales).shape},
- 'upsample_data': {'shape': int64_array(input_shape) * int64_array(scales)}})
-
- UpsampleToResample().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'output')
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/middle/__init__.py b/tools/mo/unit_tests/mo/middle/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/middle/dequantize_linear_resolver_test.py b/tools/mo/unit_tests/mo/middle/dequantize_linear_resolver_test.py
deleted file mode 100644
index 0c64f153ed3cd0..00000000000000
--- a/tools/mo/unit_tests/mo/middle/dequantize_linear_resolver_test.py
+++ /dev/null
@@ -1,237 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.dequantize_linear_resolver import DequantizeLinearResolver
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-import pytest
-
-nodes1_attributes = {
- 'input': {'kind': 'op', 'op': 'AnyOp'},
- 'input_data': {'kind': 'data', 'shape': None},
- 'dequantize': {'kind': 'op', 'op': 'DequantizeLinear', 'axis': 1},
- 'dequantize_data': {'kind': 'data', 'shape': None},
- 'scale_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'scale_param_dq_data': {'kind': 'data', 'shape': None},
- 'zerop_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'zerop_param_dq_data': {'kind': 'data', 'shape': None},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
- 'out_data': {'kind': 'data', 'shape': None},
- 'result': {'kind': 'op', 'op': 'Result'},
-}
-
-nodes_ref_attributes = {
- 'input': {'kind': 'op', 'op': 'AnyOp'},
- 'input_data': {'kind': 'data', 'shape': None},
- 'cast': {'kind': 'op', 'op': 'Cast', 'type': 'Convert'},
- 'cast_data': {'kind': 'data', 'shape': None},
- 'sub': {'kind': 'op', 'op': 'Sub', 'type': 'Subtract'},
- 'sub_data': {'kind': 'data', 'shape': None},
- 'mul': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul_data': {'kind': 'data', 'shape': None},
- 'scale_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'scale_param_dq_data': {'kind': 'data', 'shape': None},
- 'zerop_param_dq': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'zerop_param_dq_data': {'kind': 'data', 'shape': None},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
- 'out_data': {'kind': 'data', 'shape': None},
- 'result': {'kind': 'op', 'op': 'Result'},
-
- 'sub_reshape_const': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'sub_reshape_const_data': {'kind': 'data', 'shape': None},
- 'sub_reshape': {'kind': 'op', 'type': 'Reshape', 'op': 'Reshape'},
- 'sub_reshape_data': {'kind': 'data', 'shape': None},
-
- 'mul_reshape_const': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'mul_reshape_const_data': {'kind': 'data', 'shape': None},
- 'mul_reshape': {'kind': 'op', 'type': 'Reshape', 'op': 'Reshape'},
- 'mul_reshape_data': {'kind': 'data', 'shape': None},
-}
-
-
-class TestDequantizeLinearResolver(unittest.TestCase):
-
- def test_dequantize(self):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'dequantize'),
- ('dequantize', 'dequantize_data'),
- ('scale_param_dq', 'scale_param_dq_data'),
- ('zerop_param_dq', 'zerop_param_dq_data'),
- ('scale_param_dq_data', 'dequantize'),
- ('zerop_param_dq_data', 'dequantize'),
- ('dequantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'input_data': {'shape': int64_array([1, 3, 224, 224])},
- 'scale_param_dq': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_dq_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'zerop_param_dq': {'shape': np.array([]), 'value': np.uint8(0)},
- 'zerop_param_dq_data': {'shape': np.array([]), 'value': np.uint8(0)},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'sub'),
- ('zerop_param_dq', 'zerop_param_dq_data'),
- ('zerop_param_dq_data', 'sub'),
- ('sub', 'sub_data'),
- ('sub_data', 'mul'),
- ('scale_param_dq', 'scale_param_dq_data'),
- ('scale_param_dq_data', 'mul'),
- ('mul', 'mul_data'),
- ('mul_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'input_data': {'shape': int64_array([1, 3, 224, 224])},
- 'scale_param_dq': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_dq_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'zerop_param_dq': {'shape': np.array([]), 'value': np.uint8(0)},
- 'zerop_param_dq_data': {'shape': np.array([]), 'value': np.uint8(0)},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- DequantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_dequantize_no_zerop(self):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'dequantize'),
- ('dequantize', 'dequantize_data'),
- ('scale_param_dq', 'scale_param_dq_data'),
- ('scale_param_dq_data', 'dequantize'),
- ('dequantize', 'dequantize_data'),
- ('dequantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'input_data': {'shape': int64_array([1, 3, 224, 224])},
- 'scale_param_dq': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_dq_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'mul'),
- ('scale_param_dq', 'scale_param_dq_data'),
- ('scale_param_dq_data', 'mul'),
- ('mul', 'mul_data'),
- ('mul_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'input_data': {'shape': int64_array([1, 3, 224, 224])},
- 'scale_param_dq': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_dq_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- DequantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-class TestDequantizeWithAxis():
- @pytest.mark.parametrize("input_shape, scale_param_value, zero_param_value, target_shape, axis",
- [(int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 1, 4, 1]), 2),
- (int64_array([1, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 3, 1, 1]), 1),
- (int64_array([2, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([2, 1, 1, 1]), 0),
- (int64_array([1, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 1, 4, 1]), -2),
- (int64_array([1, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 1, 1, 4]), -1),
- (int64_array([1, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.int32), int64_array([1, 1, 4, 1]), 2),
- (int64_array([1, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.int32), int64_array([1, 3, 1, 1]), 1),
- (int64_array([2, 3, 4, 4]), int64_array([2, 3, 4, 5]),
- np.array([2, 3, 4, 5], dtype=np.int32), int64_array([2, 1, 1, 1]), 0),
- ])
- def test_dequantize_with_axis(self, input_shape, scale_param_value, zero_param_value, target_shape, axis):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'dequantize'),
- ('dequantize', 'dequantize_data'),
- ('scale_param_dq', 'scale_param_dq_data'),
- ('zerop_param_dq', 'zerop_param_dq_data'),
- ('scale_param_dq_data', 'dequantize'),
- ('zerop_param_dq_data', 'dequantize'),
- ('dequantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'input_data': {'shape': input_shape},
- 'dequantize': {'axis': axis},
- 'scale_param_dq': {'shape': scale_param_value.shape,
- 'value': scale_param_value},
- 'scale_param_dq_data': {'shape': scale_param_value.shape,
- 'value': scale_param_value},
- 'zerop_param_dq': {'shape': zero_param_value.shape,
- 'value': zero_param_value},
- 'zerop_param_dq_data': {'shape': zero_param_value.shape,
- 'value': zero_param_value},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'sub'),
- ('zerop_param_dq', 'zerop_param_dq_data'),
-
- ('zerop_param_dq_data', 'sub_reshape'),
- ('sub_reshape_const', 'sub_reshape_const_data'),
- ('sub_reshape_const_data', 'sub_reshape'),
- ('sub_reshape', 'sub_reshape_data'),
- ('sub_reshape_data', 'sub'),
-
- ('sub', 'sub_data'),
- ('sub_data', 'mul'),
- ('scale_param_dq', 'scale_param_dq_data'),
-
- ('scale_param_dq_data', 'mul_reshape'),
- ('mul_reshape_const', 'mul_reshape_const_data'),
- ('mul_reshape_const_data', 'mul_reshape'),
- ('mul_reshape', 'mul_reshape_data'),
- ('mul_reshape_data', 'mul'),
-
- ('mul', 'mul_data'),
- ('mul_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'input_data': {'shape': input_shape},
- 'scale_param_dq': {'shape': scale_param_value.shape,
- 'value': scale_param_value},
- 'scale_param_dq_data': {'shape': scale_param_value.shape,
- 'value': scale_param_value},
- 'zerop_param_dq': {'shape': zero_param_value.shape,
- 'value': zero_param_value},
- 'zerop_param_dq_data': {'shape': zero_param_value.shape,
- 'value': zero_param_value},
- 'sub_reshape_const_data': {'shape': target_shape.shape, 'value': target_shape},
- 'mul_reshape_const_data': {'shape': target_shape.shape, 'value': target_shape},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- DequantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'out', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/middle/layer_normalization_test.py b/tools/mo/unit_tests/mo/middle/layer_normalization_test.py
deleted file mode 100644
index 92b7d7e746d203..00000000000000
--- a/tools/mo/unit_tests/mo/middle/layer_normalization_test.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.layer_normalization import LayerNormalization
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, shaped_parameter, regular_op_with_empty_data, shaped_const_with_data, \
- result, connect
-
-
-class LayerNormalizationTest(unittest.TestCase):
-
- def test_1(self):
- graph = build_graph(
- nodes_attrs={
- **shaped_parameter('input', int64_array([1, 3, 15, 15])),
- **regular_op_with_empty_data('layer_norm', {'op': 'LayerNorm', 'epsilon': 0.001, 'axis': -1,
- 'output_mean_var': False}),
- **shaped_const_with_data('gamma', None),
- **shaped_const_with_data('beta', None),
- **result('result')
- },
- edges=[
- *connect('input', '0:layer_norm'),
- *connect('gamma', '1:layer_norm'),
- *connect('beta', '2:layer_norm'),
- *connect('layer_norm', 'result')
- ]
- )
-
- ref_graph = build_graph(
- nodes_attrs={
- **shaped_parameter('input', int64_array([1, 3, 15, 15])),
- **shaped_const_with_data('mvn_const', None),
- **regular_op_with_empty_data('mvn', {'eps': 0.001, 'across_channels': 1, 'normalize_variance': 1,
- 'eps_mode': 'inside_sqrt', 'op': 'MVN', 'type': 'MVN'}),
- **shaped_const_with_data('gamma', None),
- **regular_op_with_empty_data('gamma_unsqueeze', {'op': 'Unsqueeze', 'type': 'Unsqueeze'}),
- **shaped_const_with_data('gamma_unsqueeze_const', None),
- **regular_op_with_empty_data('beta_unsqueeze', {'op': 'Unsqueeze', 'type': 'Unsqueeze'}),
- **shaped_const_with_data('beta_unsqueeze_const', None),
- **regular_op_with_empty_data('mul', {'op': 'Mul', 'type': 'Multiply'}),
- **shaped_const_with_data('beta', None),
- **regular_op_with_empty_data('add', {'op': 'Add', 'type': 'Add'}),
- **result('result')
- },
- edges=[
- *connect('input', '0:mvn'),
- *connect('mvn_const', '1:mvn'),
- *connect('mvn', '0:mul'),
- *connect('gamma', 'gamma_unsqueeze'),
- *connect('gamma_unsqueeze_const', '1:gamma_unsqueeze'),
- *connect('gamma_unsqueeze', '1:mul'),
- *connect('mul', '0:add'),
- *connect('beta', 'beta_unsqueeze'),
- *connect('beta_unsqueeze_const', '1:beta_unsqueeze'),
- *connect('beta_unsqueeze', '1:add'),
- *connect('add', 'result')
- ],
- update_attributes={
- 'mvn_const': {'value': int64_array([-1]), 'shape': int64_array([1])},
- 'gamma_unsqueeze_const': {'value': int64_array([0, 1, 2]), 'shape': int64_array([3])},
- 'beta_unsqueeze_const': {'value': int64_array([0, 1, 2]), 'shape': int64_array([3])}
- }
- )
- LayerNormalization().find_and_replace_pattern(graph)
- flag, resp = compare_graphs(graph, ref_graph, 'result', 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_2(self):
- graph = build_graph(
- nodes_attrs={
- **shaped_parameter('input', int64_array([1, 3, 15, 15])),
- **regular_op_with_empty_data('layer_norm', {'op': 'LayerNorm', 'epsilon': 0.001, 'axis': 1,
- 'output_mean_var': False}),
- **shaped_const_with_data('gamma', None),
- **shaped_const_with_data('beta', None),
- **result('result')
- },
- edges=[
- *connect('input', '0:layer_norm'),
- *connect('gamma', '1:layer_norm'),
- *connect('beta', '2:layer_norm'),
- *connect('layer_norm', 'result')
- ]
- )
-
- ref_graph = build_graph(
- nodes_attrs={
- **shaped_parameter('input', int64_array([1, 3, 15, 15])),
- **shaped_const_with_data('mvn_const', None),
- **regular_op_with_empty_data('mvn', {'eps': 0.001, 'across_channels': 1, 'normalize_variance': 1,
- 'eps_mode': 'inside_sqrt', 'op': 'MVN', 'type': 'MVN'}),
- **shaped_const_with_data('gamma', None),
- **regular_op_with_empty_data('gamma_unsqueeze', {'op': 'Unsqueeze', 'type': 'Unsqueeze'}),
- **shaped_const_with_data('gamma_unsqueeze_const', None),
- **regular_op_with_empty_data('beta_unsqueeze', {'op': 'Unsqueeze', 'type': 'Unsqueeze'}),
- **shaped_const_with_data('beta_unsqueeze_const', None),
- **regular_op_with_empty_data('mul', {'op': 'Mul', 'type': 'Multiply'}),
- **shaped_const_with_data('beta', None),
- **regular_op_with_empty_data('add', {'op': 'Add', 'type': 'Add'}),
- **result('result')
- },
- edges=[
- *connect('input', '0:mvn'),
- *connect('mvn_const', '1:mvn'),
- *connect('mvn', '0:mul'),
- *connect('gamma', 'gamma_unsqueeze'),
- *connect('gamma_unsqueeze_const', '1:gamma_unsqueeze'),
- *connect('gamma_unsqueeze', '1:mul'),
- *connect('mul', '0:add'),
- *connect('beta', 'beta_unsqueeze'),
- *connect('beta_unsqueeze_const', '1:beta_unsqueeze'),
- *connect('beta_unsqueeze', '1:add'),
- *connect('add', 'result')
- ],
- update_attributes={
- 'mvn_const': {'value': int64_array([1]), 'shape': int64_array([1])},
- 'gamma_unsqueeze_const': {'value': int64_array([0, 2, 3]), 'shape': int64_array([3])},
- 'beta_unsqueeze_const': {'value': int64_array([0, 2, 3]), 'shape': int64_array([3])}
- }
- )
- LayerNormalization().find_and_replace_pattern(graph)
- flag, resp = compare_graphs(graph, ref_graph, 'result', 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_negative(self):
- graph = build_graph(
- nodes_attrs={
- **shaped_parameter('input', int64_array([1, 3, 15, 15])),
- **regular_op_with_empty_data('layer_norm', {'op': 'LayerNorm', 'epsilon': 0.001, 'axis': -1,
- 'output_mean_var': True}),
- **shaped_const_with_data('gamma', None),
- **shaped_const_with_data('beta', None),
- **result('result'),
- **result('result_1'),
- **result('result_2')
- },
- edges=[
- *connect('input', '0:layer_norm'),
- *connect('gamma', '1:layer_norm'),
- *connect('beta', '2:layer_norm'),
- *connect('layer_norm:0', 'result'),
- *connect('layer_norm:1', 'result_1'),
- *connect('layer_norm:2', 'result_2')
- ]
- )
-
- with self.assertRaises(Error):
- LayerNormalization().find_and_replace_pattern(graph)
diff --git a/tools/mo/unit_tests/mo/middle/passes/__init__.py b/tools/mo/unit_tests/mo/middle/passes/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/middle/passes/convert_data_type_test.py b/tools/mo/unit_tests/mo/middle/passes/convert_data_type_test.py
deleted file mode 100644
index 500bd4b74edaca..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/convert_data_type_test.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.middle.passes.convert_data_type import convert_blobs, SUPPORTED_DATA_TYPES
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'data_node': {'kind': 'data', 'value': None, 'shape': int64_array([5])},
- 'op_node': { 'kind': 'op', 'op': 'Result'}}
-
-
-class TestConvertBlob(UnitTestWithMockedTelemetry):
- def test_convert_blob_to_fp32_from_fp64(self):
- graph = build_graph(nodes_attributes,
- [('data_node', 'op_node', {'bin': 1})],
- {'data_node': {'value': np.array([4.0, 3.0, 2.0, 1.0], dtype=np.float64)}})
-
- convert_blobs(graph, "FP32")
- result_value = graph.node['data_node']['value']
- self.assertTrue(result_value.dtype == np.float32)
- self.assertListEqual(list(result_value), [4, 3, 2, 1])
-
- def test_convert_blob_to_fp16_from_fp64(self):
- graph = build_graph(nodes_attributes,
- [('data_node', 'op_node', {'bin': 1})],
- {'data_node': {'value': np.array([4.0, 3.0, 2.0, 1.0], dtype=np.float64)}})
-
- convert_blobs(graph, "FP16")
- result_value = graph.node['data_node']['value']
- self.assertTrue(result_value.dtype == np.float16)
- self.assertListEqual(list(result_value), [4, 3, 2, 1])
-
- def test_convert_blob_to_fp16_from_fp64_overflow(self):
- graph = build_graph(nodes_attributes,
- [('data_node', 'op_node', {'bin': 1})],
- {'data_node': {'value': np.array([4.0, 3.0, 2.0, 1e10], dtype=np.float64)}})
-
- convert_blobs(graph, "FP16")
- result_value = graph.node['data_node']['value']
- self.assertTrue(result_value.dtype == np.float16)
- self.assertListEqual(list(result_value), [4, 3, 2, np.inf])
-
- def test_convert_blob_to_int32_with_force_precision(self):
- graph = build_graph(nodes_attributes,
- [('data_node', 'op_node', {'bin': 1})],
- {'data_node': {'value': np.array([4.0, 3.0, 2.0, 1.0], dtype=np.float64)}})
-
- convert_blobs(graph, "I32")
- result_value = graph.node['data_node']['value']
- self.assertTrue(result_value.dtype == np.int32)
- self.assertListEqual(list(result_value), [4, 3, 2, 1])
-
- def test_convert_blob_to_int32_with_force_precision_error(self):
- graph = build_graph(nodes_attributes,
- [('data_node', 'op_node', {'bin': 1})],
- {'data_node': {'value': np.array([4.0, 3.0, 2.0, 1.1], dtype=np.float64)}})
-
- with self.assertRaisesRegex(Error, '.*results in rounding.*'):
- convert_blobs(graph, "I32")
-
-
-class TestUI8(unittest.TestCase):
- def test_supported_data_types_uint8_once(self):
- i = 0
- for data_type_str, values in SUPPORTED_DATA_TYPES.items():
- np_dt, precision, element_type = values
- if np_dt == np.uint8:
- i += 1
-
- self.assertEqual(i, 1, 'uint8 data type should be mentioned in SUPPORTED_DATA_TYPES only once, {} entries '
- 'found'.format(i))
diff --git a/tools/mo/unit_tests/mo/middle/passes/eliminate_test.py b/tools/mo/unit_tests/mo/middle/passes/eliminate_test.py
deleted file mode 100644
index 90f5bb4f6ae47a..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/eliminate_test.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.eliminate import mark_output_reachable_nodes, mark_const_producer_nodes
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'placeholder_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'node_1': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'node_4': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'node_5': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'node_6': {'type': 'Identity', 'value': None, 'kind': 'op', 'op': 'Identity'},
- 'placeholder_1_data_node': {'value': None, 'kind': 'data'},
- 'placeholder_2_data_node': {'value': None, 'kind': 'data'},
- 'data_node_1': {'value': None, 'kind': 'data'},
- 'data_node_2': {'value': None, 'kind': 'data'},
- 'data_node_3': {'value': None, 'kind': 'data'},
- 'data_node_3_2': {'value': None, 'kind': 'data'},
- 'data_node_4': {'value': None, 'kind': 'data'},
- 'data_node_5': {'value': None, 'shape': None, 'kind': 'data'},
- 'data_node_6': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- 'op_output_1': {'kind': 'op', 'op': 'Result'},
- 'op_output_2': {'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestEliminatePass(unittest.TestCase):
- def test_mark_output_unreachable_nodes(self):
- """
- Checks that all nodes that are unreachable from output nodes are marked correspondingly.
- The graph doesn't contain data nodes yet.
- "node_4" is output.
-
- placeholder_1->node_1->node_2
- \
- -> node_3->node_4
-
- :return: None
- """
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'node_1'),
- ('node_1', 'node_2'),
- ('placeholder_1', 'node_3'),
- ('node_3', 'node_4'),
- ('node_4', 'op_output')
- ],
- {'node_4': {}},
- nodes_with_edges_only=True)
- mark_output_reachable_nodes(graph)
-
- self.assertListEqual(sorted(['placeholder_1', 'node_3', 'op_output', 'node_4']),
- sorted(graph.get_nodes_with_attributes(is_output_reachable=True)))
- self.assertListEqual(sorted(['node_1', 'node_2']),
- sorted(graph.get_nodes_with_attributes(is_output_reachable=False)))
-
- def test_mark_output_unreachable_nodes_behind_output(self):
- """
- Checks case when unreachable node is 'behind' (i.e. is the child) of the output node.
- The graph doesn't contain data nodes yet.
- "node_2" is output.
-
- placeholder_1->node_1->node_2->node_3
-
- :return: None
- """
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'node_1'),
- ('node_1', 'node_2'),
- ('node_2', 'node_3'),
- ('node_2', 'op_output')
- ],
- {'node_2': {}},
- nodes_with_edges_only=True)
- mark_output_reachable_nodes(graph)
-
- self.assertListEqual(sorted(['node_1', 'node_2', 'op_output', 'placeholder_1']),
- sorted(graph.get_nodes_with_attributes(is_output_reachable=True)))
- self.assertFalse(graph.node['node_3']['is_output_reachable'])
-
- def test_mark_ops_producing_constant_values(self):
- """
- Checks case when operation produces only constant tensors so it could be removed. If the node produces several
- tensors and at least one of them is not constant then we should not mark this node.
- The graph contains data nodes.
- "data_node_2" and "data_node_5" are output.
- "node_3" produces constant tensor "data_node_3" and non-constant tensor "data_node_3_2".
- "node_6" produces constant tensor "data_node_6".
- "node_4" could be eliminated since it gets constant input.
-
- node_6->data_node_6->
- \
- placeholder_1->placeholder_1_data_node->node_1->data_node_1->node_2->data_node_2
- /
- node_3->data_node_3->node_4->data_node_4->
- \
- ->data_node_3_2->node_5->data_node_5
-
- :return: None
- """
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data_node'),
- ('placeholder_1_data_node', 'node_1'),
- ('node_1', 'data_node_1'),
- ('data_node_1', 'node_2'),
- ('node_2', 'data_node_2'),
- ('node_3', 'data_node_3'),
- ('node_3', 'data_node_3_2'),
- ('node_6', 'data_node_6'),
- ('data_node_6', 'node_1'),
- ('data_node_3_2', 'node_5'),
- ('node_5', 'data_node_5'),
- ('data_node_3', 'node_4'),
- ('data_node_4', 'node_1'),
- ('data_node_2', 'op_output'),
- ('data_node_5', 'op_output_1')
- ],
- {'data_node_2': {},
- 'data_node_5': {},
- 'data_node_3': {'value': np.array(1)},
- 'data_node_6': {'value': np.array(1)}},
- nodes_with_edges_only=True)
- mark_const_producer_nodes(graph)
- self.assertTrue((graph.node['node_6']['is_const_producer']))
- self.assertListEqual(sorted(['node_1', 'node_2', 'node_3', 'node_5', 'placeholder_1']),
- sorted(graph.get_nodes_with_attributes(is_const_producer=False, kind='op')))
-
- graph.clean_up()
- self.assertTrue('node_3' in graph.nodes())
- self.assertTrue('node_4' not in graph.nodes())
- self.assertTrue('node_6' not in graph.nodes())
-
- def test_undead_nodes_with_constant_inputs(self):
- """
- Checks that if node of 'undead' type has constant inputs it is not removed from the graph.
- :return: None
- """
- pass
-
- def test_remove_node_from_graph(self):
- """
- Checks case when remove node from graph.
- The graph doesn't contain removed node yet.
- "node_2" should be removed.
-
- placeholder_1->node_1->node_2->node_3
-
- :return: None
- """
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'node_1'),
- ('node_1', 'node_2'),
- ('node_2', 'node_3')],
- nodes_with_edges_only=True)
- graph.erase_node(Node(graph, 'node_2'))
-
- self.assertListEqual(sorted(['placeholder_1', 'node_1', 'node_3']), sorted(graph.nodes()))
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/__init__.py b/tools/mo/unit_tests/mo/middle/passes/fusing/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/decomposition_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/decomposition_test.py
deleted file mode 100644
index 8cb464727469f9..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/decomposition_test.py
+++ /dev/null
@@ -1,661 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.passes.fusing.decomposition import convert_scale_shift_to_mul_add, convert_batch_norm
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.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},
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # ScaleShift layer
- 'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift', 'axis': 0},
- 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_1': {'type': None, 'value': None, 'kind': 'op', 'op': 'Mul'},
- 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'add_1': {'type': None, 'kind': 'op', 'op': 'Add'},
- 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'add_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'add_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_2': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'mul_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'add_2': {'type': None, 'kind': 'op', 'op': 'Add'},
- 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'add_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'add_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Reshape
- 'placeholder_2/Reshape_': {'type': 'Reshape', 'kind': 'op', 'op': 'Reshape'},
- 'placeholder_2/Reshape_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'placeholder_2/Reshape_const': {'type': 'Const', 'kind': 'op', 'op': 'Const', 'value': None},
- 'placeholder_2/Reshape_const_data': {'kind': 'data', 'value': None, 'shape': None},
- # BatchNorm operation
- 'bn_op': {'type': None, 'kind': 'op', 'op': 'BatchNorm', 'can_be_fused': True},
- 'const_bn_const': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'bn_const': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_bn_beta': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'bn_beta': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_bn_mean': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'bn_mean': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_bn_var': {'value': None, 'shape': None, 'kind': 'op', 'op': 'Const'},
- 'bn_var': {'value': None, 'shape': None, 'kind': 'data'},
- 'bn_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Concat1 operation
- 'concat': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'}
-}
-
-
-class ScaleShiftToMulAdd(unittest.TestCase):
- # ScaleShift -> Mul
- def test_scaleshift_to_mul_1(self):
- graph = 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'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'scaleshift_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'scaleshift_1_data': {}
- })
-
- graph_ref = 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', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1': {'can_be_fused': True},
- 'scaleshift_1_data': {}
- })
-
- graph.graph['layout'] = 'NHWC'
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # ScaleShift 2 inputs-> Mul
- def test_scaleshift2_to_mul(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('placeholder_2_data', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([1, 227])},
- 'scaleshift_1_data': {}
- })
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'placeholder_2/Reshape_'),
- ('placeholder_2/Reshape_const', 'placeholder_2/Reshape_const_data'),
- ('placeholder_2/Reshape_const_data', 'placeholder_2/Reshape_'),
- ('placeholder_2/Reshape_', 'placeholder_2/Reshape_data'),
- ('placeholder_1_data', 'mul_1'),
- ('placeholder_2/Reshape_data', 'mul_1'),
- ('mul_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([1, 227])},
- 'placeholder_2/Reshape_const': {'value': np.array([1, 227, 1, 1]), 'shape': [4]},
- 'placeholder_2/Reshape_const_data': {'value': np.array([1, 227, 1, 1]), 'shape': [4]},
- 'placeholder_2/Reshape_data': {'shape': np.array([1, 227, 1, 1])},
- 'mul_1': {'can_be_fused': True},
- 'scaleshift_1_data': {}
- })
-
- graph.graph['layout'] = 'NHWC'
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # ScaleShift 2 inputs-> Mul (axis = 1)
- def test_scaleshift2_axis1_to_mul(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('placeholder_2_data', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([227])},
- 'scaleshift_1': {'axis': 1},
- 'scaleshift_1_data': {}
- })
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'placeholder_2/Reshape_'),
- ('placeholder_2/Reshape_const', 'placeholder_2/Reshape_const_data'),
- ('placeholder_2/Reshape_const_data', 'placeholder_2/Reshape_'),
- ('placeholder_2/Reshape_', 'placeholder_2/Reshape_data'),
- ('placeholder_1_data', 'mul_1'),
- ('placeholder_2/Reshape_data', 'mul_1'),
- ('mul_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([227])},
- 'placeholder_2/Reshape_const': {'value': np.array([1, 227, 1, 1]), 'shape': [4]},
- 'placeholder_2/Reshape_const_data': {'value': np.array([1, 227, 1, 1]), 'shape': [4]},
- 'placeholder_2/Reshape_data': {'shape': np.array([1, 227, 1, 1])},
- 'mul_1': {'can_be_fused': True},
- 'scaleshift_1_data': {}
- })
-
- graph.graph['layout'] = 'NHWC'
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # ScaleShift -> Mul (Zero biases)
- def test_scaleshift_to_mul_2(self):
- graph = 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_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([0, 0, 0])},
- 'scaleshift_1_data': {}
- })
-
- graph_ref = 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', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1': {'can_be_fused': True},
- 'scaleshift_1_data': {}
- })
-
- graph.graph['layout'] = 'NHWC'
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # ScaleShift -> Mul->Add
- def test_scaleshift_to_mul_add(self):
- graph = 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_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([3, 2, 1])},
- 'scaleshift_1_data': {}
- })
-
- graph_ref = 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', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_add_1_w': {'shape': np.array([3]), 'value': np.array([3, 2, 1])},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([3, 2, 1])},
- 'mul_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'add_1': {'can_be_fused': True},
- 'mul_1': {'can_be_fused': True},
- 'scaleshift_1_data': {}
- })
-
- graph.graph['layout'] = 'NHWC'
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # ScaleShift -> None (Zero weights and biases)
- def test_scaleshift_to_nothing(self):
- graph = 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_w': {'shape': np.array([3]), 'value': np.array([1, 1, 1])},
- 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([0, 0, 0])},
- 'scaleshift_1_data': {'shape': np.array([1, 227, 227, 3])}
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}}
- ,nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # ScaleShift -> ScaleShift (can_be_fused=False)
- def test_scaleshift_can_be_fused(self):
- graph = 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_w': {'shape': np.array([3]), 'value': np.array([1, 1, 1])},
- 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([0, 0, 0])},
- 'scaleshift_1': {'can_be_fused': False},
- 'scaleshift_1_data': {'shape': np.array([1, 227, 227, 3])}
- })
-
- 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])},
- '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([0, 0, 0])},
- 'scaleshift_1_b': {'shape': np.array([3]), 'value': np.array([0, 0, 0])},
- 'scaleshift_1': {'can_be_fused': False},
- 'scaleshift_1_data': {'shape': np.array([1, 227, 227, 3])}
- })
-
- convert_scale_shift_to_mul_add(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'scaleshift_1_data')
- self.assertTrue(flag, resp)
-
-
-class BatchNormDecomposition(unittest.TestCase):
- def test_bn_decomposition_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'bn_op'),
- ('const_bn_const', 'bn_const'),
- ('const_bn_beta', 'bn_beta'),
- ('const_bn_mean', 'bn_mean'),
- ('const_bn_var', 'bn_var'),
- ('bn_const', 'bn_op'),
- ('bn_beta', 'bn_op'),
- ('bn_mean', 'bn_op'),
- ('bn_var', 'bn_op'),
- ('bn_op', 'bn_data'),
- ('concat', 'concat_data'),
- ('bn_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'bn_op': {'eps': 1.2},
- 'bn_const': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_beta': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_mean': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_var': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_data': {'shape': np.array([1, 227, 227, 3])},
- 'concat_data': {}
- }, nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'add_2'),
- ('const_add_2_w', 'add_2_w'),
- ('add_2_w', 'add_2'),
- ('add_2', 'add_2_data'),
- ('concat', 'concat_data'),
- ('add_2_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]),
- 'value': np.array([0.67419986, 0.55901699, 0.48795004])},
- 'mul_1_w': {'shape': np.array([3]),
- 'value': np.array([0.67419986, 0.55901699, 0.48795004])},
- 'const_mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_add_1_w': {'shape': np.array([3]),
- 'value': np.array([-0.67419986, -1.11803399, -1.46385011])},
- 'add_1_w': {'shape': np.array([3]),
- 'value': np.array([-0.67419986, -1.11803399, -1.46385011])},
- 'const_add_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1': {'can_be_fused': True},
- 'mul_2': {'can_be_fused': True},
- 'add_1': {'can_be_fused': True},
- 'add_2': {'can_be_fused': True},
- 'concat_data': {}
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- convert_batch_norm(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_data')
- self.assertTrue(flag, resp)
-
- # 'can_be_fused': False for BatchNorm
- def test_bn_decomposition_2(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'bn_op'),
- ('const_bn_const', 'bn_const'),
- ('const_bn_beta', 'bn_beta'),
- ('const_bn_mean', 'bn_mean'),
- ('const_bn_var', 'bn_var'),
- ('bn_const', 'bn_op'),
- ('bn_beta', 'bn_op'),
- ('bn_mean', 'bn_op'),
- ('bn_var', 'bn_op'),
- ('bn_op', 'bn_data'),
- ('concat', 'concat_data'),
- ('bn_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'bn_op': {'eps': 1.2, 'can_be_fused': False},
- 'bn_const': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_beta': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_mean': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_var': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_data': {'shape': np.array([1, 227, 227, 3])},
- 'concat_data': {}
- })
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'add_2'),
- ('const_add_2_w', 'add_2_w'),
- ('add_2_w', 'add_2'),
- ('add_2', 'add_2_data'),
- ('concat', 'concat_data'),
- ('add_2_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]),
- 'value': np.array([0.67419986, 0.55901699, 0.48795004])},
- 'mul_1_w': {'shape': np.array([3]),
- 'value': np.array([0.67419986, 0.55901699, 0.48795004])},
- 'const_mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_add_1_w': {'shape': np.array([3]),
- 'value': np.array([-0.67419986, -1.11803399, -1.46385011])},
- 'add_1_w': {'shape': np.array([3]),
- 'value': np.array([-0.67419986, -1.11803399, -1.46385011])},
- 'const_add_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1': {'can_be_fused': False},
- 'mul_2': {'can_be_fused': False},
- 'add_1': {'can_be_fused': False},
- 'add_2': {'can_be_fused': False},
- 'concat_data': {}
- })
-
- graph.graph['layout'] = 'NHWC'
- convert_batch_norm(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_data')
- self.assertTrue(flag, resp)
-
- # graph - NCHW
- # BatchNorm - NHWC
- def test_bn_decomposition_different_layouts_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'bn_op'),
- ('const_bn_const', 'bn_const'),
- ('const_bn_beta', 'bn_beta'),
- ('const_bn_mean', 'bn_mean'),
- ('const_bn_var', 'bn_var'),
- ('bn_const', 'bn_op'),
- ('bn_beta', 'bn_op'),
- ('bn_mean', 'bn_op'),
- ('bn_var', 'bn_op'),
- ('bn_op', 'bn_data'),
- ('concat', 'concat_data'),
- ('bn_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'bn_op': {'eps': 1.2, 'data_format': 'NHWC'},
- 'bn_const': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_beta': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_mean': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_var': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_data': {'shape': np.array([1, 227, 227, 3])},
- 'concat_data': {}
- }, nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'add_2'),
- ('const_add_2_w', 'add_2_w'),
- ('add_2_w', 'add_2'),
- ('add_2', 'add_2_data'),
- ('concat', 'concat_data'),
- ('add_2_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]),
- 'value': np.array([0.67419986, 0.55901699, 0.48795004])},
- 'mul_1_w': {'shape': np.array([3]),
- 'value': np.array([0.67419986, 0.55901699, 0.48795004])},
- 'const_mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_add_1_w': {'shape': np.array([3]),
- 'value': np.array([-0.67419986, -1.11803399, -1.46385011])},
- 'add_1_w': {'shape': np.array([3]),
- 'value': np.array([-0.67419986, -1.11803399, -1.46385011])},
- 'const_add_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1': {'can_be_fused': True},
- 'mul_2': {'can_be_fused': True},
- 'add_1': {'can_be_fused': True},
- 'add_2': {'can_be_fused': True},
- 'concat_data': {}
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- convert_batch_norm(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_data')
- self.assertTrue(flag, resp)
-
- # graph - NHWC
- # BatchNorm - NCHW
- def test_bn_decomposition_different_layouts_2(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'bn_op'),
- ('const_bn_const', 'bn_const'),
- ('const_bn_beta', 'bn_beta'),
- ('const_bn_mean', 'bn_mean'),
- ('const_bn_var', 'bn_var'),
- ('bn_const', 'bn_op'),
- ('bn_beta', 'bn_op'),
- ('bn_mean', 'bn_op'),
- ('bn_var', 'bn_op'),
- ('bn_op', 'bn_data'),
- ('concat', 'concat_data'),
- ('bn_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 227, 227])},
- 'bn_op': {'eps': 1.2, 'data_format': 'NCHW'},
- 'bn_const': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_beta': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_mean': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_var': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'bn_data': {'shape': np.array([1, 3, 227, 227])},
- 'concat_data': {}
- }, nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'add_2'),
- ('const_add_2_w', 'add_2_w'),
- ('add_2_w', 'add_2'),
- ('add_2', 'add_2_data'),
- ('concat', 'concat_data'),
- ('add_2_data', 'concat'),
- ('concat_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 227, 227])},
- 'const_mul_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.array([[[0.67419986]], [[0.55901699]], [[0.48795004]]])},
- 'mul_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.array([[[0.67419986]], [[0.55901699]], [[0.48795004]]])},
- 'const_mul_2_w': {'shape': np.array([3, 1, 1]), 'value': np.array([[[1]], [[2]], [[3]]])},
- 'mul_2_w': {'shape': np.array([3, 1, 1]), 'value': np.array([[[1]], [[2]], [[3]]])},
- 'const_add_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.array([[[-0.67419986]], [[-1.11803399]], [[-1.46385011]]])},
- 'add_1_w': {'shape': np.array([3, 1, 1]),
- 'value': np.array([[[-0.67419986]], [[-1.11803399]], [[-1.46385011]]])},
- 'const_add_2_w': {'shape': np.array([3, 1, 1]), 'value': np.array([[[1]], [[2]], [[3]]])},
- 'add_2_w': {'shape': np.array([3, 1, 1]), 'value': np.array([[[1]], [[2]], [[3]]])},
- 'add_2_data': {'shape': np.array([1, 3, 227, 227])},
- 'mul_1': {'can_be_fused': True},
- 'mul_2': {'can_be_fused': True},
- 'add_1': {'can_be_fused': True},
- 'add_2': {'can_be_fused': True},
- 'concat_data': {}
- }, nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- convert_batch_norm(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_data')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_grouped_conv_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_grouped_conv_test.py
deleted file mode 100644
index 0030a716e35a37..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_grouped_conv_test.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.fusing.fuse_grouped_conv import grouped_convolutions_fusing
-from openvino.tools.mo.ops.op import PermuteAttrs
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, result, connect, regular_op_with_shaped_data, regular_op, shaped_data, \
- valued_const_with_data, shaped_const_with_data, valued_data
-
-nodes = {
- **regular_op_with_shaped_data('placeholder1', [1, 16, 10, 10], {'type': 'Parameter'}),
-
- **valued_const_with_data('split_1_axis', int64_array(1), {'type': 'Const'}),
- **regular_op('split_1', {'type': 'Split', 'can_be_fused': True}),
- **shaped_data('split_1_data1', [1, 4, 10, 10]),
- **shaped_data('split_1_data2', [1, 4, 10, 10]),
- **shaped_data('split_1_data3', [1, 4, 10, 10]),
- **shaped_data('split_1_data4', [1, 4, 10, 10]),
-
- **shaped_const_with_data('split_2_in_const_weights', int64_array([3, 3, 4, 16]), {'type': 'Const'}),
- **regular_op('split_2', {'type': 'Split'}),
- **valued_data('split_2_data1', np.zeros([3, 3, 4, 4])),
- **valued_data('split_2_data2', np.zeros([3, 3, 4, 4])),
- **valued_data('split_2_data3', np.zeros([3, 3, 4, 4])),
- **valued_data('split_2_data4', np.zeros([3, 3, 4, 4])),
-
- **regular_op_with_shaped_data('conv2d_1', [1, 4, 8, 8],
- {'type': 'Convolution', 'channel_dims': np.array([1]), 'pad': np.array([2, 2]),
- 'stride': np.array([2, 2]),
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([3, 2, 0, 1]),
- inv=int64_array([2, 3, 1, 0])),
- 'group': 1, 'output': 4, 'output_shape': [1, 4, 8, 8], 'can_be_fused': True}),
- **regular_op_with_shaped_data('conv2d_2', [1, 4, 8, 8],
- {'type': 'Convolution', 'pad': np.array([2, 2]), 'stride': np.array([2, 2]),
- 'can_be_fused': True}),
- **regular_op_with_shaped_data('conv2d_3', [1, 4, 8, 8],
- {'type': 'Convolution', 'pad': np.array([2, 2]), 'stride': np.array([2, 2]),
- 'can_be_fused': True}),
- **regular_op_with_shaped_data('conv2d_4', [1, 4, 8, 8],
- {'type': 'Convolution', 'pad': np.array([2, 2]), 'stride': np.array([2, 2]),
- 'can_be_fused': True}),
-
- **regular_op_with_shaped_data('concat', [1, 16, 8, 8], {'type': 'Concat', 'axis': np.array(1)}),
-
- **regular_op_with_shaped_data('fused_group_conv', [1, 16, 8, 8],
- {'type': 'Convolution', 'channel_dims': np.array([1]), 'pad': np.array([2, 2]),
- 'stride': np.array([2, 2]),
- 'get_weights_permute': PermuteAttrs.Permutation(perm=int64_array([3, 2, 0, 1]),
- inv=int64_array([2, 3, 1, 0])),
- 'group': 1, 'output': 4, 'output_shape': [1, 4, 8, 8], 'can_be_fused': True}),
- **shaped_const_with_data('new_weights_const', int64_array([3, 3, 4, 16]), {'type': 'Const'}),
-
- **result('result')
-}
-
-
-class FuseGroupedConvTest(unittest.TestCase):
- def test_fuse_grouped_conv(self):
- graph = build_graph(nodes, [*connect('placeholder1', '0:split_1'), *connect('split_1_axis', '1:split_1'),
- ('split_1', 'split_1_data1', {'out': 0}),
- ('split_1', 'split_1_data2', {'out': 1}),
- ('split_1', 'split_1_data3', {'out': 2}),
- ('split_1', 'split_1_data4', {'out': 3}),
-
- *connect('split_2_in_const_weights', 'split_2'),
- ('split_2', 'split_2_data1', {'out': 0}),
- ('split_2', 'split_2_data2', {'out': 1}),
- ('split_2', 'split_2_data3', {'out': 2}),
- ('split_2', 'split_2_data4', {'out': 3}),
-
- ('split_1_data1', 'conv2d_1', {'in': 0}),
- ('split_1_data2', 'conv2d_2', {'in': 0}),
- ('split_1_data3', 'conv2d_3', {'in': 0}),
- ('split_1_data4', 'conv2d_4', {'in': 0}),
-
- ('split_2_data1', 'conv2d_1', {'in': 1}),
- ('split_2_data2', 'conv2d_2', {'in': 1}),
- ('split_2_data3', 'conv2d_3', {'in': 1}),
- ('split_2_data4', 'conv2d_4', {'in': 1}),
-
- *connect('conv2d_1', '0:concat'),
- *connect('conv2d_2', '1:concat'),
- *connect('conv2d_3', '2:concat'),
- *connect('conv2d_4', '3:concat'),
-
- *connect('concat', 'result')])
-
- graph_ref = build_graph(nodes, [*connect('placeholder1', '0:fused_group_conv'),
- *connect('new_weights_const', '1:fused_group_conv'),
- *connect('fused_group_conv', 'result')])
-
- graph.graph['layout'] = 'NCHW'
- grouped_convolutions_fusing(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result')
- self.assertTrue(flag, resp)
-
- group_conv_node = Node(graph, 'conv2d_1')
- group_conv_weights_shape = group_conv_node.in_node(1).shape
- self.assertTrue((group_conv_weights_shape == int64_array([3, 3, 4, 16])).all())
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_linear_ops_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_linear_ops_test.py
deleted file mode 100644
index a16962091b00d8..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_linear_ops_test.py
+++ /dev/null
@@ -1,1301 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.fusing.fuse_linear_ops import _fuse_mul, fuse_linear_ops
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.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', 'kind': 'op', 'op': 'ScaleShift'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_1': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True,
- 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'add_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'add_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Mul2 and Add2 operations
- 'mul_2': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'mul_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'mul_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'add_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'add_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Concat1 operation
- 'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Convolutions
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'conv_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'const_conv_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'conv_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'const_conv_2_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'deconv': {'type': 'Deconvolution', 'kind': 'op', 'op': 'Deconv2D', 'layout': 'NHWC'},
- 'deconv_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'deconv_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_deconv_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'const_deconv_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'deconv_data': {'value': None, 'shape': None, 'kind': 'data'},
- # MatMul
- 'fc_1': {'type': 'MatMul', 'kind': 'op', 'layout': 'NHWC', 'op': 'MatMul'},
- 'fc_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'fc_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_fc_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'const_fc_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'fc_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Placeholders
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- 'op_output_1': {'kind': 'op', 'op': 'Result'},
- 'op_output_2': {'kind': 'op', 'op': 'Result'}
-}
-
-
-# Unit tests for fuse_mul
-class FuseMulTests(unittest.TestCase):
- # Mul(array)->Conv(w+b)
- def test_fuse_mul_to_conv_1(self):
- # Placeholder->Mul->Conv
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([1, 2, 3]), (3, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Mul(scalar)->Conv(w+b)
- def test_fuse_mul_to_conv_2(self):
- # Placeholder->Mul->Conv
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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([1]), 'value': 6},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([6, 6, 6]), (3, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Conv(w+b)->Mul(array)
- def test_fuse_mul_to_conv_3(self):
- # Placeholder->Conv->Mul
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.ones(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.ones(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'mul_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_mul_1_w': {'shape': np.array([96]), 'value': np.array([x for x in range(96)])},
- 'mul_1_w': {'shape': np.array([96]), 'value': np.array([x for x in range(96)])},
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([x for x in range(96)]), 96)
- ref_biases = np.ones(96) * np.array([x for x in range(96)])
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': ref_biases.shape, 'value': ref_biases},
- 'conv_1_b': {'shape': ref_biases.shape, 'value': ref_biases},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=True)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Conv(w)->Mul(scalar)
- def test_fuse_mul_to_conv_4(self):
- # Placeholder->Conv->Mul
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.ones(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.ones(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'mul_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.array([6])
- ref_biases = np.ones(96) * np.array([6])
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': ref_biases.shape, 'value': ref_biases},
- 'conv_1_b': {'shape': ref_biases.shape, 'value': ref_biases},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=True)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Op0-+->Op1--+----+-->Concat Op0-+->Op1--+--+-->Concat
- # | | | | | | | |
- # | +->Op2--+ | => | +->Op2--+ |
- # +---->Mul->Conv-+ +---->Conv----+
- def test_fuse_mul_to_conv_5(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('placeholder_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'placeholder_3'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_2_data', 'concat_1'),
- ('placeholder_3_data', 'concat_1'),
- ('conv_1_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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([1]), 'value': 6},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'concat_1_data': {}
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([6, 6, 6]), (3, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('placeholder_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'placeholder_3'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_2_data', 'concat_1'),
- ('placeholder_3_data', 'concat_1'),
- ('conv_1_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3,
- 'input_channel_dim': 2, 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {},
- 'placeholder_2_data': {},
- 'placeholder_3_data': {},
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- def test_fuse_mul_to_conv_5_nparray(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('placeholder_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'placeholder_3'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_2_data', 'concat_1'),
- ('placeholder_3_data', 'concat_1'),
- ('conv_1_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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([1]), 'value': np.array([6])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([6])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'concat_1_data': {}
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([6, 6, 6]), (3, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('placeholder_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_1_data', 'placeholder_3'),
- ('placeholder_3', 'placeholder_3_data'),
- ('placeholder_2_data', 'concat_1'),
- ('placeholder_3_data', 'concat_1'),
- ('conv_1_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3,
- 'input_channel_dim': 2, 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {},
- 'placeholder_2_data': {},
- 'placeholder_3_data': {},
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Op->Mul(array)-+->Conv(w+b)--+->Concat Op-+->Conv1-+-->Concat
- # | | => | |
- # +-->Conv(w+b)-+ +->Conv2-+
- def test_fuse_mul_to_convolutions_1(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('mul_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- 'concat_1_data': {}
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([1, 2, 3]), (3, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('placeholder_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_conv_2_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_2_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1'), Node(graph, 'conv_2')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Mul(array)->FC(w+b)
- def test_fuse_mul_to_fc_1(self):
- # Placeholder->Mul->FC
- 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', '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])},
- 'mul_1_data': {'shape': np.array([1, 2048])},
- 'const_mul_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])},
- 'mul_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)) * 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': 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_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'fc_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Mul(scalar)->Conv(w+b) can_be_fused = False
- def test_fuse_mul_to_conv_6(self):
- # Placeholder->Mul->Conv
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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([]), 'value': np.array(6)},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'conv_1': {'can_be_fused': False},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
-
- graph_ref = 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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([]), 'value': np.array(6)},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'conv_1': {'can_be_fused': False},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]),
- 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Mul(array)->DWConv(w+b)
- def test_fuse_mul_to_dwconv_1(self):
- # Placeholder->Mul->Conv
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('conv_1_w', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 112, 112, 6])},
- 'mul_1_data': {'shape': np.array([1, 112, 112, 6])},
- 'const_mul_1_w': {'shape': np.array([6]), 'value': np.array([1, 2, 3, 4, 5, 6])},
- 'mul_1_w': {'shape': np.array([6]), 'value': np.array([1, 2, 3, 4, 5, 6])},
- 'const_conv_1_w': {'shape': np.array([3, 3, 6, 1]), 'value': np.ones((3, 3, 6, 1))},
- 'conv_1_w': {'shape': np.array([3, 3, 6, 1]), 'value': np.ones((3, 3, 6, 1)),
- 'output_channel_dim': 2, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'conv_1_data': {}
- })
- ref_weights = np.ones((3, 3, 6, 1)) * np.reshape(np.array([1, 2, 3, 4, 5, 6]), (6, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('conv_1_w', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 112, 112, 6])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 2, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'conv_1_data': {}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # DWConv(w)->Mul(scalar)
- def test_fuse_mul_to_dwconv_2(self):
- # Placeholder->Conv->Mul
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('conv_1_w', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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, 112, 112, 6])},
- 'mul_1_data': {'shape': np.array([1, 112, 112, 6])},
- 'const_mul_1_w': {'shape': np.array([6]), 'value': np.array([1, 2, 3, 4, 5, 6])},
- 'mul_1_w': {'shape': np.array([6]), 'value': np.array([1, 2, 3, 4, 5, 6])},
- 'const_conv_1_w': {'shape': np.array([3, 3, 6, 1]), 'value': np.ones((3, 3, 6, 1))},
- 'conv_1_w': {'shape': np.array([3, 3, 6, 1]), 'value': np.ones((3, 3, 6, 1)),
- 'output_channel_dim': 2, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'conv_1_data': {}
- })
-
- ref_weights = np.ones((3, 3, 6, 1)) * np.reshape(np.array([1, 2, 3, 4, 5, 6]), (6, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('conv_1_w', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 112, 112, 6])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 2, 'input_channel_dim': 2,
- 'dims_number': 4},
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=True)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # Deconv(w)->Mul(array)
- def test_fuse_mul_to_deconv_1(self):
- # Placeholder->Deonv->Mul
- in_shape = np.array([1, 20, 10, 10])
- w_shape = np.array([20, 2, 3, 3])
- out_shape = np.array([1, 10, 21, 21])
- mul_const = np.array(range(10))
-
- edges = [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'deconv'),
- ('const_deconv_w', 'deconv_w'),
- ('deconv_w', 'deconv'),
- ('deconv', 'deconv_data'),
- ('deconv_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')
- ]
- attr_updates = {'placeholder_1_data': {'shape': in_shape},
- 'const_conv_1_w': {'shape': w_shape, 'value': np.ones(w_shape)},
- 'deconv': {'group': 5},
- 'deconv_w': {'shape': w_shape, 'value': np.ones(w_shape),
- 'output_channel_dim': 1, 'input_channel_dim': 0,
- 'dims_number': 4},
- 'deconv_data': {'shape': out_shape},
- 'mul_1_data': {'shape': mul_const.shape},
- 'const_mul_1_w': {'shape': mul_const.shape, 'value': mul_const},
- 'mul_1_w': {'shape': mul_const.shape, 'value': mul_const},
- }
- graph = build_graph(nodes_attributes, edges, attr_updates)
- # same graph, nothing fused
- graph_ref = build_graph(nodes_attributes, edges, attr_updates)
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'deconv')], backward=True)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1', 'placeholder_1')
- self.assertTrue(flag, resp)
-
- def test_fuse_mul_data_nodes_names(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_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([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]),
- 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {}
- })
-
- _fuse_mul(graph, Node(graph, 'mul_1'), [Node(graph, 'conv_1')], backward=False)
-
- conv_node = Node(graph, 'conv_1')
- conv_in_data_name = conv_node.in_node(1)['name']
- const_node = Node(graph, 'const_conv_1_w')
- const_out_data_name = const_node.out_node(0)['name']
- mul_node = Node(graph, 'mul_1')
- conv_in_data = conv_node.in_node(1)
-
- # Check that transformation doesn't produce identical data node names,
- # as this may lead to appearing of Const ops with identical names.
- self.assertFalse(conv_in_data_name == const_out_data_name)
-
- # Attributes that are required for fusing are kept on data nodes.
- # These checks are needed to ensure that _fuse_mul doesn't remove any of these attributes.
- self.assertTrue(conv_in_data['output_channel_dim'] == 3)
- self.assertTrue(conv_in_data['input_channel_dim'] == 2)
- self.assertTrue(conv_in_data['dims_number'] == 4)
- self.assertTrue(mul_node['can_be_fused'] is True)
-
-
-# Unit tests for fuse_linear_ops
-class FuseLinOpsTests(unittest.TestCase):
- # Op->Mul(array)-+->Conv(w+b)->Add-+->Concat Op-+->Conv1-+-->Concat
- # | | => | |
- # +-->Conv(w+b)-----+ +->Conv2-+
- def test_fuse_lin_ops_1(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('mul_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- 'concat_1_data': {}
- })
- ref_weights = np.ones((11, 11, 3, 96)) * np.reshape(np.array([1, 2, 3]), (3, 1))
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('placeholder_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_1_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_conv_2_w': {'shape': ref_weights.shape, 'value': ref_weights},
- 'conv_2_w': {'shape': ref_weights.shape, 'value': ref_weights,
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- })
-
- fuse_linear_ops(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Mul(array)->FC(w+b)
- def test_fuse_mul_to_fc_1(self):
- # Placeholder->Mul->FC
- 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', '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])},
- 'mul_1_data': {'shape': np.array([1, 2048])},
- 'const_mul_1_w': {'shape': np.array([2048]), 'value': np.array([x for x in range(2048)])},
- 'mul_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)) * 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': 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_linear_ops(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'fc_1_data')
- self.assertTrue(flag, resp)
-
- # +-----------+
- # | | => Same
- # Placeholder--->Add->Mul-----+->Concat
- def test_fuse_lin_op_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1_data', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1_data', 'add_1'),
- ('const_add_1_w', 'add_1_w'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('concat_1', 'concat_1_data'),
- ('const_mul_1_w', 'mul_1_w'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('add_1_data', 'concat_1'),
- ('mul_1_data', 'concat_1'),
- ('add_1_data', 'mul_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': np.array([1, 1, 3, 3]), 'value': np.zeros((1, 1, 3, 3))},
- 'conv_1_w': {'shape': np.array([1, 1, 3, 3]), 'value': np.zeros((1, 1, 3, 3)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([3]), 'value': np.zeros(3)},
- 'conv_1_b': {'shape': np.array([3]), 'value': np.zeros(3)},
- 'conv_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([1]), 'value': np.array([6])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([6])},
- 'const_add_1_w': {'shape': np.array([1]), 'value': np.array([1])},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([1])},
- 'concat_1_data': {}
- })
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1_data', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1_data', 'concat_1'),
- ('const_mul_1_w', 'mul_1_w'),
- ('mul_1_w', 'mul_1'),
- ('conv_1_data', 'mul_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_conv_1_w': {'shape': np.array([1, 1, 3, 3]), 'value': np.zeros((1, 1, 3, 3))},
- 'conv_1_w': {'shape': np.array([1, 1, 3, 3]), 'value': np.zeros((1, 1, 3, 3)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([3]), 'value': np.ones(3)},
- 'conv_1_b': {'shape': np.array([3]), 'value': np.ones(3)},
- 'conv_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([1]), 'value': np.array([6])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([6])},
- 'concat_1_data': {}
- })
-
- fuse_linear_ops(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- # TODO: refactor this test
- # self.assertTrue(flag, resp)
-
- # Op->Mul(array)-+->Conv(w+b)------+->Concat
- # | | => Same('can_be_fused': False)
- # +-->Conv(w+b)-----+
- def test_fuse_lin_ops_2(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('mul_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'conv_2': {'can_be_fused': False},
- 'const_conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- 'concat_1_data': {}
- })
-
- graph_ref = 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('mul_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]),
- 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'conv_2': {'can_be_fused': False},
- 'const_conv_2_w': {'shape': np.array([11, 11, 3, 96]),
- 'value': np.ones((11, 11, 3, 96))},
- 'conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- 'concat_1_data': {}
- })
-
- fuse_linear_ops(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Op->Mul(array)-+->Conv(w+b)------+->Concat
- # | | => Same('can_be_fused': False)
- # +-->Conv(w+b)-----+
- def test_fuse_lin_ops_3(self):
- 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('mul_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1': {'can_be_fused': False},
- 'mul_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96))},
- 'conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- 'concat_1_data': {}
- })
-
- graph_ref = 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', 'conv_1'),
- ('const_conv_1_w', 'conv_1_w'),
- ('const_conv_1_b', 'conv_1_b'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('mul_1_data', 'conv_2'),
- ('const_conv_2_w', 'conv_2_w'),
- ('const_conv_2_b', 'conv_2_b'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_1_data', 'concat_1'),
- ('conv_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1': {'can_be_fused': False},
- 'mul_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'const_mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'const_conv_1_w': {'shape': np.array([11, 11, 3, 96]),
- 'value': np.ones((11, 11, 3, 96))},
- 'conv_1_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_1_data': {'shape': np.array([1, 55, 55, 96])},
- 'const_conv_2_w': {'shape': np.array([11, 11, 3, 96]),
- 'value': np.ones((11, 11, 3, 96))},
- 'conv_2_w': {'shape': np.array([11, 11, 3, 96]), 'value': np.ones((11, 11, 3, 96)),
- 'output_channel_dim': 3, 'input_channel_dim': 2,
- 'dims_number': 4},
- 'const_conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_b': {'shape': np.array([96]), 'value': np.zeros(96)},
- 'conv_2_data': {'shape': np.array([1, 55, 55, 96])},
- 'concat_1_data': {}
- })
-
- fuse_linear_ops(graph)
- graph.clean_up()
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_linear_seq_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_linear_seq_test.py
deleted file mode 100644
index c458b79538d99e..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/fuse_linear_seq_test.py
+++ /dev/null
@@ -1,993 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.passes.fusing.fuse_linear_seq import fuse_mul_add_sequence
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.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', 'kind': 'op', 'op': 'ScaleShift'},
- 'const_scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_1': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'add_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Mul2 and Add2 operations
- 'mul_2': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'mul_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'add_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Mul3 and Add3 operations
- 'mul_3': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_3_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'mul_3_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_3': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_3_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'add_3_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Mul4 and Add4 operations
- 'mul_4': {'type': 'Mul', 'kind': 'op', 'op': 'Mul', 'can_be_fused': True},
- 'const_mul_4_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'mul_4_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_4_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_4': {'type': 'Add', 'kind': 'op', 'op': 'Add', 'can_be_fused': True},
- 'const_add_4_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'add_4_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_4_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Concat1 operation
- 'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Convolutions
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'const_conv_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'conv_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'const_conv_2_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'conv_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_conv_2_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- # FullyConnected
- 'fc_1': {'type': 'MatMul', 'kind': 'op', 'op': 'FullyConnected', 'layout': 'NHWC'},
- 'const_fc_1_w': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'fc_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'const_fc_1_b': {'value': None, 'shape': None, 'kind': 'op', 'data_type': None, 'op': 'Const'},
- 'fc_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'fc_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Placeholders
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'op_output': {'kind': 'op', 'op': 'Result'}
-}
-
-
-# Unit tests for fuse_mul_add_sequence
-class LinSeqFusingTests(unittest.TestCase):
- # Placeholder-+->Mul->Add->Mul-+->Concat
- # | |
- # +----------------+
- def test_fuse_lin_seq_1(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'add_1_w': {'shape': np.array([1]), 'value': 6},
- 'mul_2_w': {'shape': np.array([1]), 'value': 6},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'mul_1': {'can_be_fused': True},
- 'add_1': {'can_be_fused': True},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # +----------------+
- # | |
- # Placeholder-+->Mul->Add->Mul-+---------------+->Concat
- # | |
- # +-->Placeholder----+
- def test_fuse_lin_seq_2(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('mul_2_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'add_1_w': {'shape': np.array([1]), 'value': 6},
- 'mul_2_w': {'shape': np.array([1]), 'value': 6},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('add_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'mul_1': {'can_be_fused': True},
- 'add_1': {'can_be_fused': True},
- },
- nodes_with_edges_only=True)
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # +----->Placeholder
- # | | => The same graph
- # Placeholder--->Mul->Add->Mul--+->Concat
- def test_fuse_lin_seq_3(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('add_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('add_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'placeholder_1')
- self.assertTrue(flag, resp)
-
- # +-------->Placeholder +-------->Placeholder
- # | | => | |
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder-+->Mul->Mul->Add-+->Concat
- def test_fuse_lin_seq_4(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'add_1'),
- ('const_add_1_w', 'add_1_w'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array([6])},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'mul_2_w': {'shape': np.array([1]), 'value': np.array([6])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'op_output')
- self.assertTrue(flag, resp)
-
- # +-------->Placeholder +->Placeholder
- # | | => | |
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder--->Mul-----------+->Concat
- def test_fuse_lin_seq_5(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(0)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(1)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array([6])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
-
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # +-------->Placeholder +->Placeholder
- # | | => | |
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder--->Mul-->Add-----+->Concat
- def test_fuse_lin_seq_6(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(1)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([6])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
-
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # +-------->Placeholder +->Placeholder
- # | | => | |
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder--->Mul-->Mul-----+->Concat
- def test_fuse_lin_seq_7(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(0)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('mul_1_data', 'placeholder_2'),
- ('placeholder_2', 'placeholder_2_data'),
- ('placeholder_2_data', 'concat_1'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'placeholder_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([1]), 'value': np.array([6])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder->Concat
- def test_fuse_lin_seq_8(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(1)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(0)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(1)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ],
- {'placeholder_1_data': {'shape': np.array([1, 227, 227, 3])}},
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder->Mul->Add->Concat
- def test_fuse_lin_seq_9(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([1]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Placeholder--->Mul->Add->Mul-+->Concat Placeholder->Mul->Add->Concat
- def test_fuse_lin_seq_10(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([6, 6, 6])},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_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])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([36, 36, 36])},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([36, 36, 36])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Placeholder-+->Mul->Add->Mul-+->Concat
- # | | With 'can_be_fused' = False
- # +----------------+
- def test_fuse_lin_seq_11(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_1': {'can_be_fused': False},
- 'add_1': {'can_be_fused': False},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_1': {'can_be_fused': False},
- 'add_1': {'can_be_fused': False},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Placeholder-+->Mul->Add->Mul-+->Concat
- # | | With 'can_be_fused' = False
- # +----------------+
- def test_fuse_lin_seq_12(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1': {'can_be_fused': False},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1': {'can_be_fused': False},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node), len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
-
- # Placeholder-+->Mul->Add->Mul-+->Concat
- # | |
- # +->Mul->Mul->----+ (This Mul ops has shared weights with upper Mul ops)
- def test_fuse_lin_seq_shared_weights_1(self):
- 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', 'mul_2'),
- ('const_mul_2_w', 'mul_2_w'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'mul_3'),
- ('mul_3', 'mul_3_data'),
- ('mul_1_w', 'mul_3'),
- ('mul_3_data', 'mul_4'),
- ('mul_2_w', 'mul_4'),
- ('mul_4', 'mul_4_data'),
- ('mul_4_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_3_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_4_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'add_1_w': {'shape': np.array([]), 'value': np.array(6)},
- 'mul_2_w': {'shape': np.array([]), 'value': np.array(6)},
- },
- nodes_with_edges_only=True)
-
- graph_ref = 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', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'mul_3'),
- ('mul_3', 'mul_3_data'),
- ('const_mul_3_w', 'mul_3_w'),
- ('mul_3_w', 'mul_3'),
- ('mul_3_data', 'concat_1'),
- ('concat_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])},
- 'mul_3_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'mul_3_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'add_1_w': {'shape': np.array([1]), 'value': np.array([36])},
- 'mul_1': {'can_be_fused': True},
- 'add_1': {'can_be_fused': True},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NHWC'
- fuse_mul_add_sequence(graph)
- graph.clean_up()
- self.assertTrue(len(graph.node) == len(graph_ref.node),
- "Graphs has different number of nodes: {} and {}".format(len(graph.node),
- len(graph_ref.node)))
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'concat_1_data')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/helpers_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/helpers_test.py
deleted file mode 100644
index ee5fee48ff0c2d..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/helpers_test.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.fusing.helpers import forward_bfs, backward_bfs, get_next_operation, common_bfs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, connect, result, \
- valued_const_with_data, connect_data
-
-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', 'kind': 'op', 'op': 'ScaleShift'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_1': {'type': 'Mul', 'kind': 'op', 'op': 'Mul'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'add_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Mul2 and Add2 operations
- 'mul_2': {'type': 'Mul', 'kind': 'op', 'op': 'Mul'},
- 'mul_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'add_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Concat1 operation
- 'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Convolutions
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'conv_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'conv_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- # FullyConnected
- 'fc_1': {'type': 'MatMul', 'kind': 'op', 'op': 'FullyConnected', 'layout': 'NHWC'},
- 'fc_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'fc_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'fc_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Placeholders
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
-}
-
-
-# Unit tests for forward and backward bfs (forward_bfs, backward_bfs)
-class BFSTests(unittest.TestCase):
- def test_forward_bfs_simple(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'op_output')
- ])
-
- res = forward_bfs(Node(graph, 'placeholder_1'), ['ScaleShift', 'Mul'], ['Add'])
- self.assertTrue(len(res) == 1 and res[0].id == 'add_1', 'Add operation was not found by bfs')
-
- res = forward_bfs(Node(graph, 'placeholder_1'), [], ['Add'], allowed_all=True)
- self.assertTrue(len(res) == 1 and res[0].id == 'add_1', 'Add operation was not found by bfs')
-
- res = forward_bfs(Node(graph, 'placeholder_1_data'), ['ScaleShift'], ['Add'])
- self.assertTrue(len(res) == 0, 'No one node should be found! But bfs found {} nodes'.format(len(res)))
-
- res = forward_bfs(Node(graph, 'placeholder_1_data'), ['ScaleShift'], ['Mul', 'Add'])
- self.assertTrue(len(res) == 1 and res[0].id == 'mul_1', 'BFS should find only one Mul operation')
-
- def test_backward_bfs_simple(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'op_output')
- ])
-
- res = backward_bfs(Node(graph, 'add_1_data'), ['Add', 'ScaleShift', 'Mul'], ['Parameter'])
- self.assertTrue(len(res) == 1 and res[0].id == 'placeholder_1', 'Placeholder operation was not found by bfs')
-
- res = backward_bfs(Node(graph, 'add_1'), [], ['Parameter'], allowed_all=True)
- self.assertTrue(len(res) == 1 and res[0].id == 'placeholder_1', 'Placeholder operation was not found by bfs')
-
- res = backward_bfs(Node(graph, 'add_1_data'), ['Add'], ['ScaleShift'])
- self.assertTrue(len(res) == 0, 'No one node should be found! But bfs found {} nodes'.format(len(res)))
-
- res = backward_bfs(Node(graph, 'add_1_data'), ['Add', 'Mul'], ['Parameter', 'ScaleShift'])
- self.assertTrue(len(res) == 1 and res[0].id == 'scaleshift_1', 'BFS should find only one ScaleShift operation')
-
- def test_forward_bfs_hard(self):
- # Placeholder->ScaleShift->Mul1->Add1---->Concat
- # `----------->Add2->Mul2--'
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('placeholder_1_data', 'add_2'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_2', 'add_2_data'),
- ('add_2_data', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('add_1_data', 'concat_1'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ])
-
- res = forward_bfs(Node(graph, 'placeholder_1'), ['ScaleShift', 'Mul', 'Add'], ['Concat'])
- self.assertTrue(len(res) == 1 and res[0].id == 'concat_1', 'Probably Concat operation was not found by bfs')
-
- res = forward_bfs(Node(graph, 'placeholder_1'), ['ScaleShift', 'Mul'], ['Add'])
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = forward_bfs(Node(graph, 'placeholder_1'), ['ScaleShift'], ['Add'])
- self.assertTrue(len(res) == 0, 'BFS shouldn\'t find any operations')
-
- res = forward_bfs(Node(graph, 'placeholder_1'), [], ['Add'], allowed_all=True)
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = forward_bfs(Node(graph, 'placeholder_1_data'), ['ScaleShift'], ['Concat'])
- self.assertTrue(len(res) == 0, 'No one node should be found! But bfs found {} nodes'.format(len(res)))
-
- def test_backward_bfs_hard(self):
- # Placeholder->ScaleShift->Mul1->Add1---->Concat
- # `----------->Add2->Mul2--'
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('placeholder_1_data', 'add_2'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_2', 'add_2_data'),
- ('add_2_data', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('add_1_data', 'concat_1'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ])
-
- res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift', 'Mul', 'Add'], ['Parameter'])
- self.assertTrue(len(res) == 0, 'Smth went wrong with bfs')
-
- res = backward_bfs(Node(graph, 'concat_1'), ['Mul'], ['Add'])
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['Add'])
- self.assertTrue(len(res) == 0, 'BFS shouldn\'t find any operations')
-
- res = backward_bfs(Node(graph, 'concat_1'), [], ['Add'], allowed_all=True)
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['ScaleShift'])
- self.assertTrue(len(res) == 0, 'No one node should be found! But bfs found {} nodes'.format(len(res)))
-
- def test_backward_bfs_hard2(self):
- # Placeholder->ScaleShift->Mul1->Add1---->Concat
- # `----------->Add2->Mul2--'
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'add_2'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_2', 'add_2_data'),
- ('add_2_data', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('add_1_data', 'concat_1'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ])
-
- res = backward_bfs(Node(graph, 'concat_1'), ['Mul', 'Add'], ['Parameter'])
- self.assertTrue(len(res) == 0, 'Smth went wrong with bfs')
-
- res = backward_bfs(Node(graph, 'concat_1'), ['Mul'], ['Add'])
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['Add'])
- self.assertTrue(len(res) == 0, 'BFS shouldn\'t find any operations')
-
- res = backward_bfs(Node(graph, 'concat_1'), [], ['Add'], allowed_all=True)
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = backward_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['ScaleShift'])
- self.assertTrue(len(res) == 0, 'No one node should be found! But bfs found {} nodes'.format(len(res)))
-
- def test_backward_bfs_cycle(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'placeholder_1'),
- ('add_1_data', 'op_output')
- ])
-
- res = backward_bfs(Node(graph, 'add_1_data'), ['Add', 'ScaleShift', 'Mul', 'Parameter'], ['Conv2D'])
- self.assertTrue(len(res) == 0, 'Sholdn\'t find any nodes due to cycle in graph')
-
- def test_backward_bfs_check_op_instead_of_type(self):
- # Placeholder->ScaleShift->Mul1->Add1---->Concat
- # `----------->Add2->Mul2--'
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'add_2'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_2', 'add_2_data'),
- ('add_2_data', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('add_1_data', 'concat_1'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('concat_1_data', 'op_output')
- ])
-
- res = common_bfs(Node(graph, 'concat_1'), ['Mul', 'Add'], ['Parameter'], is_backward=True, attr_to_check='op')
- self.assertTrue(len(res) == 0, 'Smth went wrong with bfs')
-
- res = common_bfs(Node(graph, 'concat_1'), ['Mul'], ['Add'], is_backward=True, attr_to_check='op')
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = common_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['Add'], is_backward=True, attr_to_check='op')
- self.assertTrue(len(res) == 0, 'BFS shouldn\'t find any operations')
-
- res = common_bfs(Node(graph, 'concat_1'), [], ['Add'], allowed_all=True, is_backward=True, attr_to_check='op')
- self.assertTrue(len(res) == 2 and all([res[x].id in ['add_1', 'add_2'] for x in range(len(res))]),
- 'Add operations was not found by bfs')
-
- res = common_bfs(Node(graph, 'concat_1'), ['ScaleShift'], ['ScaleShift'], is_backward=True, attr_to_check='op')
- self.assertTrue(len(res) == 0, 'No one node should be found! But bfs found {} nodes'.format(len(res)))
-
- def test_backward_bfs_multi_consumer_data_nodes(self):
- # Placeholder-> Mul -> Result
- # Const -/ \- Result2
-
- graph = build_graph({**regular_op_with_shaped_data('parameter', [1], {'op': 'Parameter'}),
- **valued_const_with_data('const', int64_array([5])),
- **regular_op_with_shaped_data('mul', [1], {'op': 'Mul'}),
- **result('result'),
- **result('result2'),
- },
- [*connect('parameter', '0:mul'),
- *connect('const', '1:mul'),
- *connect('mul:0', 'result'),
- *connect_data('mul', 'result2'),
- ])
-
- res = common_bfs(Node(graph, 'result'), ['Mul'], ['Parameter'], is_backward=True, attr_to_check='op',
- follow_multi_consumer_data_nodes=True)
- self.assertTrue(len(res) == 1, 'The multi-consumer data node "mul_d" was not followed')
-
- res = common_bfs(Node(graph, 'result'), ['Mul'], ['Parameter'], is_backward=True, attr_to_check='op')
- self.assertTrue(len(res) == 0, 'The multi-consumer data node "mul_d" was followed')
-
-
-# Unit tests for get_next_operation
-class GetNextOperationTests(unittest.TestCase):
- def test_get_next_operation_1(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'scaleshift_1'),
- ('scaleshift_1_w', 'scaleshift_1'),
- ('scaleshift_1', 'scaleshift_1_data'),
- ('scaleshift_1_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'op_output')
- ])
-
- res = get_next_operation(Node(graph, 'mul_1'))
- self.assertTrue(len(res) == 1 and res[0].id == 'add_1', 'get_nex_operation returned wrong op')
-
- def test_get_next_operation_2(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('placeholder_1_data', 'add_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'op_output')
- ])
-
- res = get_next_operation(Node(graph, 'placeholder_1'))
- self.assertTrue(len(res) == 2 and all([x.id in ['add_1', 'mul_1'] for x in res]),
- 'get_nex_operation returned wrong op')
-
- def test_get_next_operation_3(self):
- # Placeholder-+--->ScaleShift
- # +-----^
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1', 'placeholder_2_data'),
- ('placeholder_1_data', 'mul_1'),
- ('placeholder_2_data', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'op_output')
- ])
-
- res = get_next_operation(Node(graph, 'placeholder_1'))
- self.assertTrue(len(res) == 1 and res[0].id == 'mul_1', 'get_nex_operation returned wrong op')
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/mark_unfused_nodes_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/mark_unfused_nodes_test.py
deleted file mode 100644
index 67823244f2144a..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/mark_unfused_nodes_test.py
+++ /dev/null
@@ -1,301 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.passes.fusing.mark_unfused_nodes import mark_unfused_nodes
-from unit_tests.utils.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', 'kind': 'op', 'op': 'ScaleShift'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul and Add operations
- 'mul_1': {'type': 'Mul', 'kind': 'op', 'op': 'Mul'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'add_1_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Mul2 and Add2 operations
- 'mul_2': {'type': 'Mul', 'kind': 'op', 'op': 'Mul'},
- 'mul_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'mul_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2': {'type': 'Add', 'kind': 'op', 'op': 'Add'},
- 'add_2_w': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'add_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Concat1 operation
- 'concat_1': {'type': 'Concat', 'kind': 'op', 'op': 'Concat'},
- 'concat_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Convolutions
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'conv_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NHWC'},
- 'conv_2_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
- # FullyConnected
- 'fc_1': {'type': 'MatMul', 'kind': 'op', 'layout': 'NHWC'},
- 'fc_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'fc_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'fc_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Placeholders
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_3': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
-}
-
-
-# Unit tests for forward and backward bfs (forward_bfs, backward_bfs)
-class MarkFusedNodes(unittest.TestCase):
- def test_mark_unfused_nodes_1(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'add_1_w': {'shape': np.array([1]), 'value': 6},
- 'mul_2_w': {'shape': np.array([1]), 'value': 6},
- })
-
- graph.graph['layout'] = 'NHWC'
-
- mark_unfused_nodes(graph, '.*mul.*')
-
- self.assertFalse(graph.node['mul_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['mul_2']['can_be_fused'], "can_be_fused should be False")
- self.assertTrue(graph.node['add_1']['can_be_fused'], "can_be_fused should be True")
-
- def test_mark_unfused_nodes_2(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'add_1_w': {'shape': np.array([1]), 'value': 6},
- 'mul_2_w': {'shape': np.array([1]), 'value': 6},
- })
- graph.graph['layout'] = 'NHWC'
-
- mark_unfused_nodes(graph, '.*')
-
- self.assertFalse(graph.node['mul_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['mul_2']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['add_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['placeholder_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['concat_1']['can_be_fused'], "can_be_fused should be False")
-
- def test_mark_unfused_nodes_3(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([1]), 'value': 6},
- 'add_1_w': {'shape': np.array([1]), 'value': 6},
- 'mul_2_w': {'shape': np.array([1]), 'value': 6},
- })
- graph.graph['layout'] = 'NHWC'
-
- mark_unfused_nodes(graph, 'mul_1,add_1')
-
- self.assertFalse(graph.node['mul_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['add_1']['can_be_fused'], "can_be_fused should be False")
- self.assertTrue(graph.node['mul_2']['can_be_fused'], "can_be_fused should be True")
-
- def test_mark_unfused_nodes_4(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- })
- graph.graph['layout'] = 'NHWC'
-
- mark_unfused_nodes(graph, '')
-
- self.assertTrue(graph.node['mul_1']['can_be_fused'], "can_be_fused should be True")
- self.assertTrue(graph.node['add_1']['can_be_fused'], "can_be_fused should be True")
- self.assertTrue(graph.node['mul_2']['can_be_fused'], "can_be_fused should be True")
-
- def test_mark_unfused_nodes_5(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- })
- graph.graph['layout'] = 'NCHW'
-
- mark_unfused_nodes(graph, '')
-
- self.assertTrue(graph.node['mul_1']['can_be_fused'], "can_be_fused should be True")
- self.assertTrue(graph.node['add_1']['can_be_fused'], "can_be_fused should be True")
- self.assertTrue(graph.node['mul_2']['can_be_fused'], "can_be_fused should be True")
-
- def test_mark_unfused_nodes_5(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- })
- graph.graph['layout'] = 'NCHW'
-
- mark_unfused_nodes(graph, '')
-
- self.assertFalse(graph.node['mul_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['add_1']['can_be_fused'], "can_be_fused should be False")
- self.assertFalse(graph.node['mul_2']['can_be_fused'], "can_be_fused should be False")
-
- def test_mark_unfused_nodes_6(self):
- # Placeholder->ScaleShift->Mul->Add
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'mul_1'),
- ('mul_1_w', 'mul_1'),
- ('mul_1', 'mul_1_data'),
- ('mul_1_data', 'add_1'),
- ('add_1_w', 'add_1'),
- ('add_1', 'add_1_data'),
- ('add_1_data', 'mul_2'),
- ('mul_2_w', 'mul_2'),
- ('mul_2', 'mul_2_data'),
- ('mul_2_data', 'concat_1'),
- ('concat_1', 'concat_1_data'),
- ('placeholder_1_data', 'concat_1'),
- ('concat_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])},
- 'mul_2_data': {'shape': np.array([1, 227, 227, 3])},
- 'mul_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'add_1_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- 'mul_2_w': {'shape': np.array([3]), 'value': np.array([1, 2, 3])},
- })
- graph.graph['layout'] = 'NHWC'
-
- mark_unfused_nodes(graph, '')
-
- self.assertTrue(graph.node['mul_1']['can_be_fused'], "can_be_fused should be True")
- self.assertTrue(graph.node['add_1']['can_be_fused'], "can_be_fused should be True")
- self.assertTrue(graph.node['mul_2']['can_be_fused'], "can_be_fused should be True")
diff --git a/tools/mo/unit_tests/mo/middle/passes/fusing/resnet_optimization_test.py b/tools/mo/unit_tests/mo/middle/passes/fusing/resnet_optimization_test.py
deleted file mode 100644
index d30f4fd96a8a73..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/fusing/resnet_optimization_test.py
+++ /dev/null
@@ -1,628 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.middle.passes.fusing.resnet_optimization import stride_optimization
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.ops.pooling import Pooling
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-max_elt_lambda = lambda node: eltwise_infer(node, lambda a, b: np.maximum(a, b))
-
-nodes_attributes = {
- # Placeholders
- 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Concat1 operation
- 'eltwise_1': {'type': 'Maximum', 'kind': 'op', 'op': 'Maximum', 'infer': max_elt_lambda},
- 'eltwise_1_data': {'name': 'eltwise_1_data', 'value': None, 'shape': None, 'kind': 'data'},
- # Convolutions
- 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
- 'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'batch_dims': np.array([0]), 'infer': Convolution.infer,
- 'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
- 'output_feature_channel': 0, },
- 'conv_1_w': {'value': None, 'shape': None, 'kind': 'data',
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
- 'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'batch_dims': np.array([0]), 'infer': Convolution.infer,
- 'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
- 'output_feature_channel': 0, },
- 'conv_2_w': {'value': None, 'shape': None, 'kind': 'data',
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_2_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_2_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'conv_3': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
- 'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'batch_dims': np.array([0]), 'infer': Convolution.infer,
- 'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
- 'output_feature_channel': 0, },
- 'conv_3_w': {'value': None, 'shape': None, 'kind': 'data',
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_3_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_3_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'conv_4': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
- 'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'batch_dims': np.array([0]), 'infer': Convolution.infer,
- 'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
- 'output_feature_channel': 0, },
- 'conv_4_w': {'value': None, 'shape': None, 'kind': 'data',
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_4_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_4_data': {'value': None, 'shape': None, 'kind': 'data'},
-
- 'conv_5': {'type': 'Convolution', 'kind': 'op', 'op': 'Conv2D', 'layout': 'NCHW',
- 'output_spatial_shape': None, 'output_shape': None, 'bias_term': True, 'group': 1,
- 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]),
- 'batch_dims': np.array([0]), 'infer': Convolution.infer,
- 'kernel_spatial_idx': np.array([2, 3], dtype=np.int64), 'input_feature_channel': 1,
- 'output_feature_channel': 0, },
- 'conv_5_w': {'value': None, 'shape': None, 'kind': 'data',
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_5_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'conv_5_data': {'value': None, 'shape': None, 'kind': 'data'},
- # ReLU
- 'relu_1': {'shape': None, 'type': 'ReLU', 'kind': 'op', 'op': 'ReLU', 'infer': copy_shape_infer},
- 'relu_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'relu_2': {'shape': None, 'type': 'ReLU', 'kind': 'op', 'op': 'ReLU', 'infer': copy_shape_infer},
- 'relu_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'relu_3': {'shape': None, 'type': 'ReLU', 'kind': 'op', 'op': 'ReLU', 'infer': copy_shape_infer},
- 'relu_3_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # Pooling
- 'pool_1': {'type': 'Pooling', 'kind': 'op', 'op': 'Pooling',
- 'spatial_dims': np.array([2, 3]),
- 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'infer': Pooling.infer},
- 'pool_1_data': {'value': None, 'shape': None, 'kind': 'data'},
-}
-
-
-# In description of unit tests below will be used next syntax: Operation(NxM,XxY), where NxM - kernel size, XxY - stride
-class ResnetOptimizationTests(unittest.TestCase):
- # Pl->Conv(1x1,1x1)->Conv(1x1,2x2) => Pl->Conv(1x1,2x2)->Conv(1x1,1x1)
- def test_resnet_optimization_1(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_2': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_2': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- stride_optimization(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'conv_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Pl->Conv(3x3,2x2)->Conv(1x1,2x2) => Pl->Conv(3x3,4x4)->Conv(1x1,1x1)
- def test_resnet_optimization_2(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_2': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 4, 4]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 56, 56])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_2': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- stride_optimization(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'conv_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Pl->Conv(3x3,2x2)->Conv(3x3,2x2) => Same
- def test_resnet_optimization_3(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_1': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_2': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_1': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_2': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- stride_optimization(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'conv_2_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Pl--->Conv(3x3,2x2)->ReLU--->Eltwise-->Conv(1x1,2x2) => Pl--->Conv(3x3,4x4)->ReLU--->Eltwise-->Conv(1x1,1x1)
- # `-->Conv(3x3,2x2)->ReLU---` `-->Conv(3x3,4x4)->ReLU---`
- def test_resnet_optimization_4(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'relu_1'),
- ('relu_1', 'relu_1_data'),
-
- ('placeholder_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_2_data', 'relu_2'),
- ('relu_2', 'relu_2_data'),
-
- ('relu_1_data', 'eltwise_1'),
- ('relu_2_data', 'eltwise_1'),
-
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_1_data', 'conv_3'),
- ('conv_3_w', 'conv_3'),
- ('conv_3_b', 'conv_3'),
- ('conv_3', 'conv_3_data'),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_1': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
- 'relu_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_2': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
- 'relu_2_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'eltwise_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_3': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_3_data': {'shape': np.array([1, 3, 56, 56])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'relu_1'),
- ('relu_1', 'relu_1_data'),
-
- ('placeholder_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
- ('conv_2_data', 'relu_2'),
- ('relu_2', 'relu_2_data'),
-
- ('relu_1_data', 'eltwise_1'),
- ('relu_2_data', 'eltwise_1'),
-
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_1_data', 'conv_3'),
- ('conv_3_w', 'conv_3'),
- ('conv_3_b', 'conv_3'),
- ('conv_3', 'conv_3_data'),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_1': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 4, 4]),
- 'output': np.array([3])},
- 'conv_1_data': {'shape': np.array([1, 3, 56, 56])},
- 'relu_1_data': {'shape': np.array([1, 3, 56, 56])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_2': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 4, 4]),
- 'output': np.array([3])},
- 'conv_2_data': {'shape': np.array([1, 3, 56, 56])},
- 'relu_2_data': {'shape': np.array([1, 3, 56, 56])},
-
- 'eltwise_1_data': {'shape': np.array([1, 3, 56, 56])},
-
- 'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_3': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3])},
- 'conv_3_data': {'shape': np.array([1, 3, 56, 56])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- stride_optimization(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'conv_3_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Pl--->Conv(1x1,1x1)->ReLU--->Eltwise-->Conv(1x1,2x2) => Pl--->Conv(1x1,2x2)->ReLU--->Eltwise-->Conv(1x1,1x1)
- # `----------------->ReLU---` `-->Pool(1x1,2x2)->ReLU---`
- def test_resnet_optimization_5(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'relu_1'),
- ('relu_1', 'relu_1_data'),
-
- ('placeholder_1_data', 'relu_2'),
- ('relu_2', 'relu_2_data'),
-
- ('relu_1_data', 'eltwise_1'),
- ('relu_2_data', 'eltwise_1'),
-
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_1_data', 'conv_3'),
- ('conv_3_w', 'conv_3'),
- ('conv_3_b', 'conv_3'),
- ('conv_3', 'conv_3_data'),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 224, 224])},
- 'relu_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'relu_2_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'eltwise_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_3': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_3_data': {'shape': np.array([1, 3, 112, 112])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
- ('conv_1_data', 'relu_1'),
- ('relu_1', 'relu_1_data'),
-
- ('placeholder_1_data', 'pool_1'),
- ('pool_1', 'pool_1_data'),
- ('pool_1_data', 'relu_2'),
- ('relu_2', 'relu_2_data'),
-
- ('relu_1_data', 'eltwise_1'),
- ('relu_2_data', 'eltwise_1'),
-
- ('eltwise_1', 'eltwise_1_data'),
- ('eltwise_1_data', 'conv_3'),
- ('conv_3_w', 'conv_3'),
- ('conv_3_b', 'conv_3'),
- ('conv_3', 'conv_3_data'),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3])},
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
- 'relu_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'pool_1': {'stride': np.array([1, 1, 2, 2])},
- 'pool_1_data': {'shape': np.array([1, 3, 112, 112])},
- 'relu_2_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'eltwise_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_3_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_3': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3])},
- 'conv_3_data': {'shape': np.array([1, 3, 112, 112])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- stride_optimization(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'conv_3_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Pl->Conv(1x1,1x1)->Conv(1x1,2x2)->Conv(3x3,1x1)->Conv(1x1,2x2)
- # =>
- # Pl->Conv(1x1,2x2)->Conv(1x1,1x1)->Conv(3x3,2x2)->Conv(1x1,1x1)
- def test_resnet_optimization_6(self):
- graph = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
-
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
-
- ('conv_2_data', 'conv_3'),
- ('conv_3_w', 'conv_3'),
- ('conv_3_b', 'conv_3'),
- ('conv_3', 'conv_3_data'),
-
- ('conv_3_data', 'conv_4'),
- ('conv_4_w', 'conv_4'),
- ('conv_4_b', 'conv_4'),
- ('conv_4', 'conv_4_data'),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3]), },
- 'conv_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_2': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_3_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_3': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3]), },
- 'conv_3_data': {'shape': np.array([1, 3, 110, 110])},
-
- 'conv_4_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_4': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3]), },
- 'conv_4_data': {'shape': np.array([1, 3, 55, 55])},
- },
- nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_attributes,
- [('placeholder_1', 'placeholder_1_data'),
- ('placeholder_1_data', 'conv_1'),
- ('conv_1_w', 'conv_1'),
- ('conv_1_b', 'conv_1'),
- ('conv_1', 'conv_1_data'),
-
- ('conv_1_data', 'conv_2'),
- ('conv_2_w', 'conv_2'),
- ('conv_2_b', 'conv_2'),
- ('conv_2', 'conv_2_data'),
-
- ('conv_2_data', 'conv_3'),
- ('conv_3_w', 'conv_3'),
- ('conv_3_b', 'conv_3'),
- ('conv_3', 'conv_3_data'),
-
- ('conv_3_data', 'conv_4'),
- ('conv_4_w', 'conv_4'),
- ('conv_4_b', 'conv_4'),
- ('conv_4', 'conv_4_data'),
-
- ],
- {'placeholder_1_data': {'shape': np.array([1, 3, 224, 224])},
-
- 'conv_1_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_1': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3])},
- 'conv_1_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_2_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_2': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3])},
- 'conv_2_data': {'shape': np.array([1, 3, 112, 112])},
-
- 'conv_3_w': {'value': np.zeros([3, 3, 3, 3]), 'shape': np.array([3, 3, 3, 3])},
- 'conv_3': {'kernel_spatial': np.array([3, 3]),
- 'stride': np.array([1, 1, 2, 2]),
- 'output': np.array([3])},
- 'conv_3_data': {'shape': np.array([1, 3, 55, 55])},
-
- 'conv_4_w': {'value': np.zeros([3, 3, 1, 1]), 'shape': np.array([3, 3, 1, 1])},
- 'conv_4': {'kernel_spatial': np.array([1, 1]),
- 'stride': np.array([1, 1, 1, 1]),
- 'output': np.array([3])},
- 'conv_4_data': {'shape': np.array([1, 3, 55, 55])},
- },
- nodes_with_edges_only=True)
-
- graph.graph['layout'] = 'NCHW'
- graph_ref.graph['layout'] = 'NCHW'
-
- stride_optimization(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'conv_4_data', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/passes/infer_test.py b/tools/mo/unit_tests/mo/middle/passes/infer_test.py
deleted file mode 100644
index 5d3920ee5a74d4..00000000000000
--- a/tools/mo/unit_tests/mo/middle/passes/infer_test.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import override_placeholder_shapes, partial_infer
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_1_data': {'value': None, 'kind': 'data', 'data_type': None},
- 'node_2': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'concat': {'type': 'Concat', 'value': None, 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'op'},
- 'node_3_data': {'value': None, 'kind': 'data', 'data_type': None},
- # Placeholders
- 'placeholder_1': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_1_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- 'placeholder_2': {'shape': None, 'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pl_1': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pl_1_data': {'value': None, 'kind': 'data', 'data_type': None},
- 'pl_2': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'},
- 'pl_2_data': {'value': None, 'kind': 'data', 'data_type': None},
- 'placeholder_2_data': {'value': None, 'shape': None, 'kind': 'data', 'data_type': None},
- # ScaleShift layer
- 'scaleshift_1': {'type': 'ScaleShift', 'kind': 'op', 'op': 'ScaleShift'},
- 'scaleshift_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_b': {'value': None, 'shape': None, 'kind': 'data'},
- 'scaleshift_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- # Mul op
- 'mul_1': {'type': None, 'kind': 'op', 'op': 'Mul'},
- 'mul_1_w': {'value': None, 'shape': None, 'kind': 'data'},
- 'mul_1_data': {'value': None, 'shape': None, 'kind': 'data'},
- 'op_output': { 'kind': 'op', 'op': 'Result', 'infer': lambda x: None}
- }
-
-
-class TestInferPass(UnitTestWithMockedTelemetry):
- def test_override_placeholder_shapes(self):
- """
- Test for overriding shape in placeholder by shape from user_shapes.
- """
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227]), 'op': 'Parameter'}
- },
- nodes_with_edges_only=True)
-
- ph_shape = np.array([1, 3, 224, 224])
- user_dict = {'node_1': [{'shape': ph_shape}]}
- override_placeholder_shapes(graph, user_dict)
- res_shape = graph.node['node_1']['shape']
- self.assertTrue(np.array_equal(ph_shape, res_shape))
-
- def test_override_placeholder_no_shape(self):
- """
- Test for case when user_shapes is not defined.
- """
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None, 'op': 'Parameter'},
- 'node_1': {'shape': np.array([1, 3, 227, 227]), 'op': 'Parameter'}
- },
- nodes_with_edges_only=True)
- out = override_placeholder_shapes(graph, None)
- res_shape = graph.node['node_1']['shape']
- placeholder_shape = np.array([1, 3, 227, 227])
- self.assertIsNone(out)
- self.assertTrue(np.array_equal(placeholder_shape, res_shape))
-
- def test_override_placeholder_shapes(self):
- """
- Test for case when user_shapes is not None, but it shouldn't rewrite shapes.
- """
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227]), 'op': 'Parameter'}
- },
- nodes_with_edges_only=True)
-
- node_1_shape = np.array([1, 3, 227, 227])
- user_dict = {'some_node': [{'shape': np.zeros((3))}]}
- override_placeholder_shapes(graph, user_dict)
- res_shape = graph.node['node_1']['shape']
- self.assertTrue(np.array_equal(node_1_shape, res_shape))
-
- def test_override_placeholder_shapes_dict(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None, 'op': 'Parameter'},
- 'node_1': {'shape': np.array([1, 3, 227, 227]), 'op': 'Parameter'}
- },
- nodes_with_edges_only=True)
-
- placeholder_shape = np.array([1, 3, 224, 224])
- user_shapes = {
- 'node_1': [{'shape': placeholder_shape}],
- 'node_2': [{'shape': placeholder_shape}],
- }
- override_placeholder_shapes(graph, user_shapes)
- res_shape = graph.node['node_1']['shape']
- res_shape2 = graph.node['node_2']['shape']
- self.assertTrue(np.array_equal(placeholder_shape, res_shape))
- self.assertTrue(np.array_equal(placeholder_shape, res_shape2))
-
- nodes = {
- 'placeholder_1': {'name': 'placeholder_1', 'shape': [1, 2, 3, 4], 'type': 'Parameter', 'value': None,
- 'kind': 'op', 'op': 'Parameter'},
- 'placeholder_2': {'name': 'placeholder_2', 'shape': [5, 6, 7, 8], 'type': 'Parameter', 'value': None,
- 'kind': 'op', 'op': 'Parameter'},
- '1': {'name': 'node_1', 'type': 'Identity', 'value': None, 'kind': 'op'},
- '2': {'name': 'node_2', 'type': 'Identity', 'value': None, 'kind': 'op'},
- '3': {'name': 'concat', 'type': 'Identity', 'value': None, 'kind': 'op'},
- '4': {'name': 'output', 'type': 'SoftMax', 'value': None, 'kind': 'op'}
- }
- edges = [
- ('placeholder_1', '1'),
- ('1', '3'),
- ('placeholder_2', '2'),
- ('2', '3'),
- ('3', '4')
- ]
-
- def test_override_placeholder_shapes_batch_is_not_set(self):
- """
- Test case when batch is not set. (shapes shouldn't change)
- """
- graph = build_graph(self.nodes, self.edges)
- shapes = {}
- batch = None
- override_placeholder_shapes(graph, shapes, batch)
- res_shape_1 = graph.node['placeholder_1']['shape']
- res_shape_2 = graph.node['placeholder_2']['shape']
- self.assertTrue(np.array_equal(self.nodes['placeholder_1']['shape'], res_shape_1))
- self.assertTrue(np.array_equal(self.nodes['placeholder_2']['shape'], res_shape_2))
-
- def test_override_placeholder_shapes_real_inputs_and_batch(self):
- """
- Test case when batch is set and shapes should overwrite by user shapes.
- """
- graph = build_graph(self.nodes, self.edges)
- shapes = {'placeholder_1': [{'shape': np.array([1, 2, 3, 4])}],
- 'placeholder_2': [{'shape': np.array([1, 5, 6, 7])}]}
- batch = 4
- override_placeholder_shapes(graph, shapes, batch)
- res_shape_1 = graph.node['placeholder_1']['shape']
- res_shape_2 = graph.node['placeholder_2']['shape']
- self.assertTrue(np.array_equal(res_shape_1, np.array([4, 2, 3, 4])))
- self.assertTrue(np.array_equal(res_shape_2, np.array([4, 5, 6, 7])))
-
- def test_override_placeholder_shapes_real_inputs_and_batch_2(self):
- """
- Test case when batch is set, but shapes in user_shapes is None.
- """
- graph = build_graph(self.nodes, self.edges)
- shapes = {'placeholder_1': [{'shape': None}], 'placeholder_2': [{'shape': None}]}
- batch = 4
- graph.node['placeholder_2']['shape'] = np.array([1, 2, 3, 4])
- graph.node['placeholder_2']['shape'] = np.array([1, 5, 6, 7])
- override_placeholder_shapes(graph, shapes, batch)
- np.testing.assert_array_equal(graph.node['placeholder_1']['shape'], np.array([4, 2, 3, 4]))
- np.testing.assert_array_equal(graph.node['placeholder_2']['shape'], np.array([4, 5, 6, 7]))
-
- def test_partial_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'kind': 'data', 'shape': None, 'infer': None},
- 'node_1': {'kind': 'data', 'shape': np.array([1, 3, 227, 227]), 'infer': None},
- 'node_2': {'kind': 'data', 'shape': np.array([1, 3, 227, 227]), 'infer': None},
- 'concat': {'kind': 'op', 'axis': 2, 'infer': concat_infer}
- },
- nodes_with_edges_only=True)
-
- start_node = 'concat'
- partial_infer(graph, start_node)
- node = Node(graph, start_node)
- self.assertTrue(node.is_partial_inferred)
- self.assertTrue(node.out_node().is_partial_inferred)
-
- # check if previous nodes are not inferred
- node = Node(graph, start_node)
- while True:
- # collect nodes in a list
- if isinstance(node.in_nodes(), list):
- in_nodes = node.in_nodes()
- else:
- in_nodes = [y for x, y in node.in_nodes().items()]
-
- # check parents and find next parent
- for n in in_nodes:
- if 'embedded_input_' not in n.id:
- node = n
- self.assertFalse(n.has('is_partial_inferred'))
-
- if not len(in_nodes):
- break
-
- def test_partial_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None, 'infer': None},
- 'node_1': {'shape': None, 'infer': None}
- },
- nodes_with_edges_only=True)
- self.assertRaises(Error, partial_infer, graph, 'node_1')
-
- def test_partial_infer_cycle(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'concat'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'kind': 'data', 'shape': None, 'infer': None},
- 'node_1': {'kind': 'data', 'shape': np.array([1, 3, 227, 227]), 'infer': None},
- 'node_2': {'kind': 'data', 'shape': np.array([1, 3, 227, 227]), 'infer': None},
- 'concat': {'kind': 'op', 'axis': 2, 'infer': concat_infer}
- },
- nodes_with_edges_only=True)
-
- start_node = 'concat'
- self.assertRaises(Error, partial_infer, graph, start_node)
-
-
-class CycleTest(UnitTestWithMockedTelemetry):
- def test_is_not_fully_inferred_param(self):
- # Node that have is_not_fully_inferred=True
- graph = build_graph(nodes_attributes,
- [('node_1', 'concat'),
- ('node_2', 'concat'),
- ('concat', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'kind': 'data', 'shape': None, 'infer': None},
- 'node_1': {'kind': 'data', 'shape': np.array([1, 3, 227, 227]), 'infer': None},
- 'node_2': {'kind': 'data', 'shape': np.array([1, 3, 227, 227]), 'infer': None},
- 'concat': {'kind': 'op', 'axis': 2, 'infer': concat_infer, 'is_not_fully_inferred': True}
- },
- nodes_with_edges_only=True)
-
- start_node = 'concat'
- try:
- partial_infer(graph, start_node)
- except Error:
- self.fail("Unexpected Error raised")
- node = Node(graph, start_node)
- self.assertTrue(node.is_partial_inferred)
- self.assertTrue(node.out_node().is_partial_inferred)
-
- def test_for_is_cyclic1(self):
- # Test for case of cyclic graph without is_cyclic attrs
- graph = build_graph(nodes_attributes,
- [('node_1', 'node_1_data'),
- ('node_1_data', 'node_3'),
- ('node_3', 'node_3_data'),
- ('node_3_data', 'node_1')],
- nodes_with_edges_only=True)
- with self.assertRaisesRegex(Error, 'Graph contains a cycle. Can not proceed.*'):
- partial_infer(graph)
diff --git a/tools/mo/unit_tests/mo/middle/quantize_dequantize_linear_resolver_test.py b/tools/mo/unit_tests/mo/middle/quantize_dequantize_linear_resolver_test.py
deleted file mode 100644
index 55ffb57c43af17..00000000000000
--- a/tools/mo/unit_tests/mo/middle/quantize_dequantize_linear_resolver_test.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright (C) 2018-2021 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array, int8_array
-from openvino.tools.mo.middle.quantize_dequantize_linear_resolver import QuantizeDequantizeLinearResolver
-from openvino.tools.mo.middle.quantize_linear_resolver import QuantizeLinearResolver
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, result, connect, connect_data, \
- valued_const_with_data, regular_op_with_empty_data
-
-nodes_attributes = {
- **valued_const_with_data('y_scale_1', float32_array(1.0 / 255.0)),
- **valued_const_with_data('y_scale_2', float32_array(1.0 / 255.0)),
- **valued_const_with_data('y_zeropoint_1', int8_array(0)),
- **valued_const_with_data('y_zeropoint_2', int8_array(0)),
- **valued_const_with_data('x_scale_1', float32_array(1.0 / 255.0)),
- **valued_const_with_data('x_scale_2', float32_array(1.0 / 255.0)),
- **valued_const_with_data('x_zeropoint_1', int8_array(0)),
- **valued_const_with_data('x_zeropoint_2', int8_array(0)),
- **valued_const_with_data('const_input', float32_array([[0.3, 0.6], [-0.7, -0.9]])),
- **valued_const_with_data('in_low', float32_array(-128.0)),
- **valued_const_with_data('in_high', float32_array(127.0)),
- **valued_const_with_data('out_low', float32_array(-128.0)),
- **valued_const_with_data('out_high', float32_array(127.0)),
- **valued_const_with_data('non_const_in_low', float32_array(-128.0)),
- **valued_const_with_data('non_const_in_high', float32_array(127.0)),
- **valued_const_with_data('non_const_out_low', float32_array(-128.0)),
- **valued_const_with_data('non_const_out_high', float32_array(127.0)),
- **regular_op_with_shaped_data('input', [1, 2, 2], {'op': 'Parameter', 'type': 'Parameter'}),
- **regular_op_with_empty_data('const_quantize', {'op': 'QuantizeLinear'}),
- **regular_op_with_empty_data('non_const_quantize', {'op': 'QuantizeLinear'}),
- **regular_op_with_empty_data('const_dequantize', {'op': 'DequantizeLinear'}),
- **regular_op_with_empty_data('non_const_dequantize', {'op': 'DequantizeLinear'}),
- **regular_op_with_empty_data('add', {'op': 'Add'}),
- **regular_op_with_empty_data('mul_low', {'op': 'Mul'}),
- **regular_op_with_empty_data('mul_high', {'op': 'Mul'}),
- **regular_op_with_empty_data('const_fq', {'op': 'FakeQuantize'}),
- **regular_op_with_empty_data('const_cast', {'op': 'Cast', 'type': 'Convert', 'dst_type': np.uint8}),
- **regular_op_with_empty_data('non_const_mul_low', {'op': 'Mul'}),
- **regular_op_with_empty_data('non_const_mul_high', {'op': 'Mul'}),
- **regular_op_with_empty_data('non_const_fq', {'op': 'FakeQuantize'}),
- **regular_op_with_empty_data('non_const_cast', {'op': 'Cast', 'type': 'Convert', 'dst_type': np.uint8}),
- **result('result'),
-
-}
-
-
-class QuantizeDequantizeLinearResolverTest(unittest.TestCase):
- def test_quantize_dequantize_linear_resolver(self):
- graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:non_const_quantize'),
- *connect('y_scale_2', '1:non_const_quantize'),
- *connect('y_zeropoint_2', '2:non_const_quantize'),
- *connect('non_const_quantize', '0:non_const_dequantize'),
- *connect('x_scale_2', '1:non_const_dequantize'),
- *connect('x_zeropoint_2', '2:non_const_dequantize'),
-
- *connect('const_input', '0:const_quantize'),
- *connect('y_scale_1', '1:const_quantize'),
- *connect('y_zeropoint_1', '2:const_quantize'),
- *connect('const_quantize', '0:const_dequantize'),
- *connect('x_scale_1', '1:const_dequantize'),
- *connect('x_zeropoint_1', '2:const_dequantize'),
- *connect('const_dequantize', '0:add'),
- *connect('non_const_dequantize', '1:add'),
- *connect('add', 'result')
- ], nodes_with_edges_only=True)
-
- const_ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:non_const_quantize'),
- *connect('y_scale_2', '1:non_const_quantize'),
- *connect('y_zeropoint_2', '2:non_const_quantize'),
- *connect('non_const_quantize', '0:non_const_dequantize'),
- *connect('x_scale_2', '1:non_const_dequantize'),
- *connect('x_zeropoint_2', '2:non_const_dequantize'),
-
- *connect('const_input', '0:const_fq'),
- *connect('y_scale_1:0', '0:mul_low'),
- *connect('in_low', '1:mul_low'),
- ('y_scale_1_d', 'mul_high', {'out': 1, 'in': 0}),
- *connect('in_high', '1:mul_high'),
- *connect('mul_low', '1:const_fq'),
- *connect('mul_high', '2:const_fq'),
- *connect('out_low', '3:const_fq'),
- *connect('out_high', '4:const_fq'),
- *connect('const_fq', 'const_cast'),
- *connect('const_cast', '0:const_dequantize'),
- *connect('x_scale_1', '1:const_dequantize'),
- *connect('x_zeropoint_1', '2:const_dequantize'),
- *connect('const_dequantize', '0:add'),
- *connect('non_const_dequantize', '1:add'),
- *connect('add', 'result')
- ],nodes_with_edges_only=True)
- QuantizeDequantizeLinearResolver().find_and_replace_pattern(graph)
- graph.graph['layout'] = 'NCHW'
- (flag, resp) = compare_graphs(graph, const_ref_graph, 'result')
- self.assertTrue(flag, resp)
-
- ref_graph = build_graph(nodes_attrs=nodes_attributes,
- edges=[
- *connect('input', '0:non_const_fq'),
- *connect('y_scale_2:0', '0:non_const_mul_low'),
- *connect('non_const_in_low', '1:non_const_mul_low'),
- ('y_scale_2_d', 'non_const_mul_high', {'out': 1, 'in': 0}),
- *connect('non_const_in_high', '1:non_const_mul_high'),
- *connect('non_const_mul_low', '1:non_const_fq'),
- *connect('non_const_mul_high', '2:non_const_fq'),
- *connect('non_const_out_low', '3:non_const_fq'),
- *connect('non_const_out_high', '4:non_const_fq'),
- *connect('non_const_fq', 'non_const_cast'),
- *connect('non_const_cast', '0:non_const_dequantize'),
- *connect('x_scale_2', '1:non_const_dequantize'),
- *connect('x_zeropoint_2', '2:non_const_dequantize'),
-
- *connect('const_input', '0:const_fq'),
- *connect('y_scale_1:0', '0:mul_low'),
- *connect('in_low', '1:mul_low'),
- ('y_scale_1_d', 'mul_high', {'out': 1, 'in': 0}),
- *connect('in_high', '1:mul_high'),
- *connect('mul_low', '1:const_fq'),
- *connect('mul_high', '2:const_fq'),
- *connect('out_low', '3:const_fq'),
- *connect('out_high', '4:const_fq'),
- *connect('const_fq', 'const_cast'),
- *connect('const_cast', '0:const_dequantize'),
- *connect('x_scale_1', '1:const_dequantize'),
- *connect('x_zeropoint_1', '2:const_dequantize'),
- *connect('const_dequantize', '0:add'),
- *connect('non_const_dequantize', '1:add'),
- *connect('add', 'result')
- ], nodes_with_edges_only=True)
- QuantizeLinearResolver().find_and_replace_pattern(graph)
- (flag, resp) = compare_graphs(graph, ref_graph, 'result')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/quantize_fuses_test.py b/tools/mo/unit_tests/mo/middle/quantize_fuses_test.py
deleted file mode 100644
index c715bc2dd1466c..00000000000000
--- a/tools/mo/unit_tests/mo/middle/quantize_fuses_test.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.quantize_fuses import FakeQuantizeFuse
-from openvino.tools.mo.front.common.partial_infer.eltwise import eltwise_infer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-nodes = {
- 'placeholder': {'kind': 'op', 'op': 'Placeholder'},
- 'placeholder_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
-
- 'mi_i': {'kind': 'op', 'op': 'Const'},
- 'mi_i_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- 'ma_i': {'kind': 'op', 'op': 'Const'},
- 'ma_i_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- 'mi_o': {'kind': 'op', 'op': 'Const'},
- 'mi_o_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- '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'},
- 'quantize_d': {'kind': 'data', 'shape': None},
-
- 'mul_val': {'kind': 'op', 'op': 'Const'},
- 'mul_val_d': {'kind': 'data', 'shape': np.array([1]), 'value': np.array([5])},
-
- 'mul': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- 'mul_1': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_1_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- 'mul_2': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_2_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- 'mul_3': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_3_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
- 'mul_4': {'kind': 'op', 'op': 'Mul', 'infer': lambda node: eltwise_infer(node, lambda a, b: a * b)},
- 'mul_4_d': {'kind': 'data', 'shape': np.array([1, 3, 224, 224]), 'value': None},
-
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-edges = [
- ('placeholder', 'placeholder_d'),
- ('mi_i', 'mi_i_d'),
- ('ma_i', 'ma_i_d'),
- ('mi_o', 'mi_o_d'),
- ('ma_o', 'ma_o_d'),
- ('quantize', 'quantize_d'),
- ('mul', 'mul_d'),
- ('mul_val', 'mul_val_d'),
-
- ('placeholder_d', 'quantize', {'in': 0}),
- ('mi_i_d', 'quantize', {'in': 1}),
- ('ma_i_d', 'quantize', {'in': 2}),
- ('mi_o_d', 'quantize', {'in': 3}),
- ('ma_o_d', 'quantize', {'in': 4}),
-
- ('quantize_d', 'mul', {'in': 0}),
- ('mul_val_d', 'mul', {'in': 1}),
-
- ('mul_d', 'output'),
-]
-
-edges_ref_1 = [
- ('placeholder', 'placeholder_d'),
- ('mi_i', 'mi_i_d'),
- ('ma_i', 'ma_i_d'),
- ('mi_o', 'mi_o_d'),
- ('ma_o', 'ma_o_d'),
- ('quantize', 'quantize_d'),
- ('mul', 'mul_d'),
- ('mul_val', 'mul_val_d'),
-
- ('placeholder_d', 'mul', {'in': 0}),
- ('mul_val_d', 'mul', {'in': 1}),
-
- ('mul_d', 'quantize', {'in': 0}),
- ('mi_i_d', 'quantize', {'in': 1}),
- ('ma_i_d', 'quantize', {'in': 2}),
- ('mi_o_d', 'quantize', {'in': 3}),
- ('ma_o_d', 'quantize', {'in': 4}),
-
- ('quantize_d', 'output'),
-]
-
-edges_ref_5 = [
- ('placeholder', 'placeholder_d'),
- ('mi_i', 'mi_i_d'),
- ('ma_i', 'ma_i_d'),
- ('mi_o', 'mi_o_d'),
- ('ma_o', 'ma_o_d'),
- ('quantize', 'quantize_d'),
- ('mul', 'mul_d'),
- ('mul_1', 'mul_1_d'),
- ('mul_2', 'mul_2_d'),
- ('mul_3', 'mul_3_d'),
- ('mul_4', 'mul_4_d'),
- ('mul_val', 'mul_val_d'),
-
-
- ('placeholder_d', 'mul', {'in': 0}),
- ('mi_i_d', 'mul_1'),
- ('ma_i_d', 'mul_2'),
- ('mi_o_d', 'mul_3'),
- ('ma_o_d', 'mul_4'),
-
- ('mul_val_d', 'mul', {'in': 1, 'out': 0}),
- ('mul_d', 'quantize', {'in': 0}),
-
- ('mul_val_d', 'mul_1', {'in': 1, 'out': 0}),
- ('mul_1_d', 'quantize', {'in': 1}),
-
- ('mul_val_d', 'mul_2', {'in': 1, 'out': 0}),
- ('mul_2_d', 'quantize', {'in': 2}),
-
- ('mul_val_d', 'mul_3', {'in': 1, 'out': 0}),
- ('mul_3_d', 'quantize', {'in': 3}),
-
- ('mul_val_d', 'mul_4', {'in': 1, 'out': 0}),
- ('mul_4_d', 'quantize', {'in': 4}),
-
- ('quantize_d', 'output'),
-]
-
-
-class TestQuantizeFuses(unittest.TestCase):
- def test_pool_1_port_through_quantize(self):
- graph = build_graph(nodes, edges, {'mul': {'fuse_up_to_quantize_ports': [0]}}, nodes_with_edges_only=True)
- graph.stage = 'middle'
- FakeQuantizeFuse().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, edges_ref_1, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_pool_5_ports_through_quantize(self):
- graph = build_graph(nodes, edges, {'mul': {'fuse_up_to_quantize_ports': [0, 1, 2, 3, 4]}},
- nodes_with_edges_only=True)
- graph.stage = 'middle'
- FakeQuantizeFuse().find_and_replace_pattern(graph)
-
- graph_ref = build_graph(nodes, edges_ref_5, nodes_with_edges_only=True)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/quantize_linear_resolver_test.py b/tools/mo/unit_tests/mo/middle/quantize_linear_resolver_test.py
deleted file mode 100644
index 3e18f1f5319ac6..00000000000000
--- a/tools/mo/unit_tests/mo/middle/quantize_linear_resolver_test.py
+++ /dev/null
@@ -1,369 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.quantize_linear_resolver import QuantizeLinearResolver
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-import pytest
-
-nodes1_attributes = {
- 'input': {'kind': 'op', 'op': 'AnyOp'},
- 'input_data': {'kind': 'data', 'shape': None},
- 'quantize': {'kind': 'op', 'op': 'QuantizeLinear', 'axis': 1},
- 'quantize_data': {'kind': 'data', 'shape': None},
- 'scale_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'scale_param_q_data': {'kind': 'data', 'shape': None},
- 'zerop_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'zerop_param_q_data': {'kind': 'data', 'shape': None},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
- 'out_data': {'kind': 'data', 'shape': None},
- 'result': {'kind': 'op', 'op': 'Result'},
-}
-
-nodes_ref_attributes = {
- 'input': {'kind': 'op', 'op': 'AnyOp'},
- 'input_data': {'kind': 'data', 'shape': None},
- 'cast': {'kind': 'op', 'op': 'Cast', 'type': 'Convert'},
- 'cast_data': {'kind': 'data', 'shape': None},
- 'f_quantize': {'kind': 'op', 'op': 'FakeQuantize', 'type': 'FakeQuantize'},
- 'f_quantize_data': {'kind': 'data', 'shape': None},
- 'mul1': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul1_data': {'kind': 'data', 'shape': None},
- 'mul2': {'kind': 'op', 'op': 'Mul', 'type': 'Multiply'},
- 'mul2_data': {'kind': 'data', 'shape': None},
- 'scale_param_q': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'scale_param_q_data': {'kind': 'data', 'shape': None},
- 'in_low': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'in_low_data': {'kind': 'data', 'shape': None},
- 'in_high': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'in_high_data': {'kind': 'data', 'shape': None},
- 'out_low': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'out_low_data': {'kind': 'data', 'shape': None},
- 'out_high': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'out_high_data': {'kind': 'data', 'shape': None},
- 'out': {'kind': 'op', 'op': 'AnyOp'},
- 'out_data': {'kind': 'data', 'shape': None},
- 'result': {'kind': 'op', 'op': 'Result'},
-
- 'high_reshape_const': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'high_reshape_const_data': {'kind': 'data', 'shape': None},
- 'high_reshape': {'kind': 'op', 'type': 'Reshape', 'op': 'Reshape'},
- 'high_reshape_data': {'kind': 'data', 'shape': None},
-
- 'low_reshape_const': {'kind': 'op', 'type': 'Const', 'op': 'Const'},
- 'low_reshape_const_data': {'kind': 'data', 'shape': None},
- 'low_reshape': {'kind': 'op', 'type': 'Reshape', 'op': 'Reshape'},
- 'low_reshape_data': {'kind': 'data', 'shape': None},
-}
-
-
-class TestQuantizeLinearResolver(unittest.TestCase):
-
- def test_quantize_uint8(self):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'quantize'),
- ('zerop_param_q', 'zerop_param_q_data'),
- ('zerop_param_q_data', 'quantize'),
- ('quantize', 'quantize_data'),
- ('quantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {
- 'quantize': {'axis': 2},
- 'scale_param_q': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_q_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'zerop_param_q': {'shape': np.array([]), 'value': np.uint8(128)},
- 'zerop_param_q_data': {'shape': np.array([]), 'value': np.uint8(128)},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'f_quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'mul1', {'out': 0}),
- ('in_low', 'in_low_data'),
- ('in_low_data', 'mul1'),
- ('mul1', 'mul1_data'),
- ('mul1_data', 'f_quantize'),
- ('f_quantize', 'f_quantize_data'),
- ('scale_param_q_data', 'mul2', {'out': 0}),
- ('in_high', 'in_high_data'),
- ('in_high_data', 'mul2'),
- ('mul2', 'mul2_data'),
- ('mul2_data', 'f_quantize'),
- ('out_low', 'out_low_data'),
- ('out_low_data', 'f_quantize'),
- ('out_high', 'out_high_data'),
- ('out_high_data', 'f_quantize'),
- ('f_quantize_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'in_low': {'shape': np.array([]), 'value': -128},
- 'in_low_data': {'shape': np.array([]), 'value': -128},
- 'in_high': {'shape': np.array([]), 'value': 127},
- 'in_high_data': {'shape': np.array([]), 'value': 127},
- 'out_low': {'shape': np.array([]), 'value': 0},
- 'out_low_data': {'shape': np.array([]), 'value': 0},
- 'out_high': {'shape': np.array([]), 'value': 255},
- 'out_high_data': {'shape': np.array([]), 'value': 255},
- 'cast': {'dst_type': np.uint8}
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- QuantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_quantize_int8(self):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'quantize'),
- ('zerop_param_q', 'zerop_param_q_data'),
- ('zerop_param_q_data', 'quantize'),
- ('quantize', 'quantize_data'),
- ('quantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'scale_param_q': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_q_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'zerop_param_q': {'shape': np.array([]), 'value': np.int8(0)},
- 'zerop_param_q_data': {'shape': np.array([]), 'value': np.int8(0)},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'f_quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'mul1', {'out': 0}),
- ('in_low', 'in_low_data'),
- ('in_low_data', 'mul1'),
- ('mul1', 'mul1_data'),
- ('mul1_data', 'f_quantize'),
- ('f_quantize', 'f_quantize_data'),
- ('scale_param_q_data', 'mul2', {'out': 0}),
- ('in_high', 'in_high_data'),
- ('in_high_data', 'mul2'),
- ('mul2', 'mul2_data'),
- ('mul2_data', 'f_quantize'),
- ('out_low', 'out_low_data'),
- ('out_low_data', 'f_quantize'),
- ('out_high', 'out_high_data'),
- ('out_high_data', 'f_quantize'),
- ('f_quantize_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'in_low': {'shape': np.array([]), 'value': -128},
- 'in_low_data': {'shape': np.array([]), 'value': -128},
- 'in_high': {'shape': np.array([]), 'value': 127},
- 'in_high_data': {'shape': np.array([]), 'value': 127},
- 'out_low': {'shape': np.array([]), 'value': -128},
- 'out_low_data': {'shape': np.array([]), 'value': -128},
- 'out_high': {'shape': np.array([]), 'value': 127},
- 'out_high_data': {'shape': np.array([]), 'value': 127},
- 'cast': {'dst_type': np.int8}
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- QuantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_quantize_no_zerop(self):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'quantize'),
- ('quantize', 'quantize_data'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'quantize'),
- ('quantize', 'quantize_data'),
- ('quantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'scale_param_q': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- 'scale_param_q_data': {'shape': np.array([]), 'value': np.float32(1.0 / 255)},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'f_quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'mul1', {'out': 0}),
- ('in_low', 'in_low_data'),
- ('in_low_data', 'mul1'),
- ('mul1', 'mul1_data'),
- ('mul1_data', 'f_quantize'),
- ('f_quantize', 'f_quantize_data'),
- ('scale_param_q_data', 'mul2', {'out': 0}),
- ('in_high', 'in_high_data'),
- ('in_high_data', 'mul2'),
- ('mul2', 'mul2_data'),
- ('mul2_data', 'f_quantize'),
- ('out_low', 'out_low_data'),
- ('out_low_data', 'f_quantize'),
- ('out_high', 'out_high_data'),
- ('out_high_data', 'f_quantize'),
- ('f_quantize_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'in_low': {'shape': np.array([]), 'value': 0},
- 'in_low_data': {'shape': np.array([]), 'value': 0},
- 'in_high': {'shape': np.array([]), 'value': 255},
- 'in_high_data': {'shape': np.array([]), 'value': 255},
- 'out_low': {'shape': np.array([]), 'value': 0},
- 'out_low_data': {'shape': np.array([]), 'value': 0},
- 'out_high': {'shape': np.array([]), 'value': 255},
- 'out_high_data': {'shape': np.array([]), 'value': 255},
- 'cast': {'dst_type': np.uint8}
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- QuantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
-
-class TestQuantizeWithAxis():
- @pytest.mark.parametrize("input_shape, scale_param_value, zero_param_value,target_shape, in_low, in_high, out_low, out_high, axis",
- [(int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 1, 4, 1]),
- np.array([-2., -3., -4., -5.]), np.array([253., 252., 251., 250.]),
- 0, 255, 2),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 3, 1, 1]),
- np.array([-2., -3., -4., -5.]), np.array([253., 252., 251., 250.]),
- 0, 255, 1),
- (int64_array([2, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([2, 1, 1, 1]),
- np.array([-2., -3., -4., -5.]), np.array([253., 252., 251., 250.]),
- 0, 255, 0),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 1, 1, 4]),
- np.array([-2., -3., -4., -5.]), np.array([253., 252., 251., 250.]),
- 0, 255, -1),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.uint8), int64_array([1, 1, 4, 1]),
- np.array([-2., -3., -4., -5.]), np.array([253., 252., 251., 250.]),
- 0, 255, -2),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.int8), int64_array([1, 1, 4, 1]),
- np.array([-130., -131., -132., -133.]), np.array([125., 124., 123., 122.]),
- -128.0, 127.0, 2),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.int8), int64_array([1, 3, 1, 1]),
- np.array([-130., -131., -132., -133.]), np.array([125., 124., 123., 122.]),
- -128.0, 127.0, 1),
- (int64_array([2, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.int8), int64_array([2, 1, 1, 1]),
- np.array([-130., -131., -132., -133.]), np.array([125., 124., 123., 122.]),
- -128.0, 127.0, 0),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.int8), int64_array([1, 1, 1, 4]),
- np.array([-130., -131., -132., -133.]), np.array([125., 124., 123., 122.]),
- -128.0, 127.0, -1),
- (int64_array([1, 3, 4, 4]), np.array([2, 3, 4, 5], dtype=np.float32),
- np.array([2, 3, 4, 5], dtype=np.int8), int64_array([1, 1, 4, 1]),
- np.array([-130., -131., -132., -133.]), np.array([125., 124., 123., 122.]),
- -128.0, 127.0, -2),
- ])
- def test_quantize_with_axis(self, input_shape, scale_param_value, zero_param_value,
- target_shape, in_low, in_high, out_low, out_high, axis):
- graph = build_graph(nodes1_attributes,
- [('input', 'input_data'),
- ('input_data', 'quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'quantize'),
- ('zerop_param_q', 'zerop_param_q_data'),
- ('zerop_param_q_data', 'quantize'),
- ('quantize', 'quantize_data'),
- ('quantize_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {
- 'quantize': {'axis': axis},
- 'input': {'shape': input_shape},
- 'input_data': {'shape': input_shape},
- 'scale_param_q': {'shape': scale_param_value.shape, 'value': scale_param_value},
- 'scale_param_q_data': {'shape': scale_param_value.shape, 'value': scale_param_value},
- 'zerop_param_q': {'shape': zero_param_value.shape, 'value': zero_param_value},
- 'zerop_param_q_data': {'shape': zero_param_value.shape, 'value': zero_param_value},
- }, nodes_with_edges_only=True)
-
- graph_ref = build_graph(nodes_ref_attributes,
- [('input', 'input_data'),
- ('input_data', 'f_quantize'),
- ('scale_param_q', 'scale_param_q_data'),
- ('scale_param_q_data', 'mul1', {'out': 0}),
- ('in_low', 'in_low_data'),
- ('in_low_data', 'mul1'),
- ('mul1', 'mul1_data'),
- ('mul1_data', 'high_reshape'),
- ('high_reshape_const', 'high_reshape_const_data'),
- ('high_reshape_const_data', 'high_reshape'),
- ('high_reshape', 'high_reshape_data'),
- ('high_reshape_data', 'f_quantize'),
-
- ('f_quantize', 'f_quantize_data'),
- ('scale_param_q_data', 'mul2', {'out': 0}),
- ('in_high', 'in_high_data'),
- ('in_high_data', 'mul2'),
- ('mul2', 'mul2_data'),
- ('mul2_data', 'low_reshape'),
- ('low_reshape', 'low_reshape_data'),
- ('low_reshape_data', 'f_quantize'),
- ('low_reshape_const', 'low_reshape_const_data'),
- ('low_reshape_const_data', 'low_reshape'),
- ('out_low', 'out_low_data'),
- ('out_low_data', 'f_quantize'),
-
- ('out_high', 'out_high_data'),
- ('out_high_data', 'f_quantize'),
- ('f_quantize_data', 'cast'),
- ('cast', 'cast_data'),
- ('cast_data', 'out'),
- ('out', 'out_data'),
- ('out_data', 'result'),
- ],
- {'in_low': {'shape': in_low.shape, 'value': in_low},
- 'in_low_data': {'shape': in_low.shape, 'value': in_low},
- 'in_high': {'shape': in_high.shape, 'value': in_high},
- 'in_high_data': {'shape': in_high.shape, 'value': in_high},
- 'out_low': {'shape': np.array([]), 'value': out_low},
- 'out_low_data': {'shape': np.array([]), 'value': out_low},
- 'out_high': {'shape': np.array([]), 'value': out_high},
- 'out_high_data': {'shape': np.array([]), 'value': out_high},
- 'cast': {'dst_type': zero_param_value.dtype},
- 'low_reshape_const_data': {'shape': target_shape.shape, 'value': target_shape},
- 'high_reshape_const_data': {'shape': target_shape.shape, 'value': target_shape},
- }, nodes_with_edges_only=True)
-
- graph.stage = 'middle'
- QuantizeLinearResolver().find_and_replace_pattern(graph)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/middle/reverse_tensor_iterator_test.py b/tools/mo/unit_tests/mo/middle/reverse_tensor_iterator_test.py
deleted file mode 100644
index c462d0e9a6dd36..00000000000000
--- a/tools/mo/unit_tests/mo/middle/reverse_tensor_iterator_test.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.middle.reverse_tensor_iterator import ReverseTensorIteratorLSTM
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, connect, \
- valued_const_with_data, regular_op_with_empty_data, result
-
-nodes = {
- **regular_op_with_shaped_data('parameter', [1, 3, 227, 227],
- {'type': 'Parameter', 'op': 'Parameter', 'shape': [1, 3, 227, 227]}),
- **valued_const_with_data('seq_len', np.array([227])),
- **regular_op_with_empty_data('shapeof', {'type': 'ShapeOf', 'op': 'ShapeOf'}),
- **valued_const_with_data('gather_axis', np.array([0])),
- **valued_const_with_data('gather_batch_ind', np.array([0])),
- **valued_const_with_data('gather_seq_ind', np.array([2])),
- **regular_op_with_empty_data('gather_batch', {'type': 'Gather', 'op': 'Gather'}),
- **regular_op_with_empty_data('gather_seq', {'type': 'Gather', 'op': 'Gather'}),
- **regular_op_with_empty_data('broadcast', {'type': 'Broadcast', 'op': 'Broadcast'}),
- **regular_op_with_shaped_data('direct_reverse', [1, 3, 227, 227], {'type': 'ReverseSequence',
- 'op': 'ReverseSequence',
- 'seq_axis': 2, 'batch_axis': 0}),
- **regular_op_with_empty_data('init_hidden', {'type': 'Init', 'op': 'Init'}),
-
- **regular_op_with_shaped_data('ti', [1, 2, 34, 56], {'type': 'TensorIterator', 'op': 'TensorIterator',
- 'output_port_map': [{'axis': 2, 'start': 0, 'end': -1,
- 'stride': 1, 'external_port_id': 0}],
- 'input_port_map': [{'axis': 2, 'start': -1, 'end': 0,
- 'stride': -1, 'external_port_id': 0}]}),
- **valued_const_with_data('inverse_seq_len', np.array([34])),
- **regular_op_with_empty_data('inverse_shapeof', {'type': 'ShapeOf', 'op': 'ShapeOf'}),
- **regular_op_with_empty_data('inverse_gather_batch', {'type': 'Gather', 'op': 'Gather'}),
- **regular_op_with_empty_data('inverse_gather_seq', {'type': 'Gather', 'op': 'Gather'}),
- **regular_op_with_empty_data('inverse_broadcast', {'type': 'Broadcast', 'op': 'Broadcast'}),
- **regular_op_with_shaped_data('inverse_reverse', [1, 2, 34, 56], {'type': 'ReverseSequence',
- 'op': 'ReverseSequence',
- 'seq_axis': 2, 'batch_axis': 0}),
- **regular_op_with_empty_data('some_op', {'op': 'SomeOp'}),
- **result()
-}
-
-ref_nodes = {
- **regular_op_with_shaped_data('parameter', [1, 3, 227, 227],
- {'type': 'Parameter', 'op': 'Parameter', 'shape': [1, 3, 227, 227]}),
- **regular_op_with_empty_data('init_hidden', {'type': 'Init', 'op': 'Init'}),
- **regular_op_with_empty_data('ti', {'type': 'TensorIterator', 'op': 'TensorIterator',
- 'output_port_map': [{'axis': 2, 'start': -1, 'end': 0, 'stride': -1,
- 'external_port_id': 0}],
- 'input_port_map': [{'axis': 2, 'start': 0, 'end': -1, 'stride': 1,
- 'external_port_id': 0}]}),
- **regular_op_with_empty_data('some_op', {'op': 'SomeOp'}),
- **result()
-}
-
-
-class ReverseTensorIteratorTest(unittest.TestCase):
- def test_ti_reverse(self):
- graph = build_graph(nodes, [*connect('parameter:0', '0:direct_reverse'),
- *connect('parameter:0', 'shapeof', skip_data=True),
- *connect('shapeof:0', '0:gather_batch'),
- *connect('gather_batch_ind', '1:gather_batch'),
- *connect('gather_axis', '2:gather_batch'),
- *connect('shapeof:0', '0:gather_seq', skip_data=True),
- *connect('gather_seq_ind', '1:gather_seq'),
- *connect('gather_axis', '2:gather_seq'),
- *connect('gather_seq', '0:broadcast'),
- *connect('gather_batch', '1:broadcast'),
- *connect('broadcast', '1:direct_reverse'),
- *connect('direct_reverse', '0:ti'),
- *connect('init_hidden', '1:ti'),
- *connect('ti', 'inverse_shapeof'),
- *connect('inverse_shapeof:0', '0:inverse_gather_batch'),
- *connect('gather_batch_ind', '1:inverse_gather_batch'),
- *connect('gather_axis', '2:inverse_gather_batch'),
- *connect('inverse_shapeof:0', '0:inverse_gather_seq', skip_data=True),
- *connect('gather_seq_ind', '1:inverse_gather_seq'),
- *connect('gather_axis', '2:inverse_gather_seq'),
- *connect('inverse_gather_seq', '0:inverse_broadcast'),
- *connect('inverse_gather_batch', '1:inverse_broadcast'),
- *connect('ti', '0:inverse_reverse', skip_data=True),
- *connect('inverse_broadcast', '1:inverse_reverse'),
- *connect('inverse_reverse', 'some_op'),
- *connect('some_op', 'output')], nodes_with_edges_only=True)
-
- ReverseTensorIteratorLSTM().find_and_replace_pattern(graph)
- graph.clean_up()
-
- ref_graph = build_graph(ref_nodes, [*connect('parameter', '0:ti'),
- *connect('init_hidden', '1:ti'),
- *connect('ti', 'some_op'),
- *connect('some_op', 'output')])
- flag, resp = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_ti_reverse_const(self):
- graph = build_graph(nodes, [*connect('parameter:0', '0:direct_reverse'),
- *connect('seq_len', '1:direct_reverse'),
- *connect('direct_reverse', '0:ti'),
- *connect('init_hidden', '1:ti'),
- *connect('ti', '0:inverse_reverse'),
- *connect('inverse_seq_len', '1:inverse_reverse'),
- *connect('inverse_reverse', 'some_op'),
- *connect('some_op', 'output')], nodes_with_edges_only=True)
-
- ReverseTensorIteratorLSTM().find_and_replace_pattern(graph)
- graph.clean_up()
-
- ref_graph = build_graph(ref_nodes, [*connect('parameter', '0:ti'),
- *connect('init_hidden', '1:ti'),
- *connect('ti', 'some_op'),
- *connect('some_op', 'output')])
- flag, resp = compare_graphs(graph, ref_graph, 'output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/middle/sparse_reshape_test.py b/tools/mo/unit_tests/mo/middle/sparse_reshape_test.py
deleted file mode 100644
index 6269e0e430c0e4..00000000000000
--- a/tools/mo/unit_tests/mo/middle/sparse_reshape_test.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.middle.sparse_reshape import SparseReshapeMiddleReplacer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class SparseReshapeMiddleReplacerTests(unittest.TestCase):
- def test1(self):
- graph = build_graph({
- 'const_dense_shape': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': int64_array([4, 5]), 'shape': int64_array([2])},
- 'const_dense_shape_data': {'kind': 'data',
- 'value': int64_array([4, 5]), 'shape': int64_array([2])},
- 'const_new_dense_shape': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': int64_array([4, -1]), 'shape': int64_array([2])},
- 'const_new_dense_shape_data': {'kind': 'data',
- 'value': int64_array([4, -1]), 'shape': int64_array([2])},
- 'const_default_value': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': 2, 'shape': int64_array([])},
- 'const_default_value_data': {'kind': 'data','value': 2, 'shape': int64_array([])},
-
- 'input_indices': {'value': None, 'shape': int64_array([10, 2]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_indices_data': {'shape': int64_array([10, 2]), 'value': None, 'kind': 'data'},
- 'input_values': {'value': None, 'shape': int64_array([10]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_values_data': {'shape': int64_array([10]), 'value': None, 'kind': 'data'},
- 'input_params_table': {'value': None, 'shape': int64_array([100, 4, 3]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_params_table_data': {'shape': int64_array([10, 4, 3]), 'value': None, 'kind': 'data'},
-
- 'sparse_reshape': {'kind': 'op', 'op': 'SparseReshape'},
-
- 'output_indices_data': {'shape': int64_array([10, 2]), 'value': None, 'kind': 'data'},
- 'output_new_dense_shape_data': {'kind': 'data', 'value': int64_array([4, 5]), 'shape': int64_array([2])},
-
- 'sparse_weighted_sum': {'kind': 'op', 'op': 'SparseWeightedSum'},
- },
- [
- ('input_indices', 'input_indices_data'),
- ('input_indices_data', 'sparse_reshape', {'in': 0}),
- ('const_dense_shape', 'const_dense_shape_data'),
- ('const_dense_shape_data', 'sparse_reshape', {'in': 1}),
- ('const_new_dense_shape', 'const_new_dense_shape_data'),
- ('const_new_dense_shape_data', 'sparse_reshape', {'in': 2}),
- ('sparse_reshape', 'output_indices_data', {'out': 0, 'in': 0}),
- ('sparse_reshape', 'output_new_dense_shape_data', {'out': 1, 'in': 0}),
- ('output_indices_data', 'sparse_weighted_sum', {'in': 0}),
- ('input_values', 'input_values_data'),
- ('input_values_data', 'sparse_weighted_sum', {'in': 1}),
- ('output_new_dense_shape_data', 'sparse_weighted_sum', {'in': 2}),
- ('input_params_table', 'input_params_table_data'),
- ('input_params_table_data', 'sparse_weighted_sum', {'in': 3}),
- ('const_default_value', 'const_default_value_data'),
- ('const_default_value_data', 'sparse_weighted_sum', {'in': 4})
- ])
- SparseReshapeMiddleReplacer().find_and_replace_pattern(graph)
- #graph_clean_up(graph)
- ref_graph = build_graph({
- 'const_dense_shape': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': int64_array([4, 5]), 'shape': int64_array([2])},
- 'output_new_dense_shape_data': {'kind': 'data',
- 'value': int64_array([4, 5]), 'shape': int64_array([2])},
- 'const_default_value': {'type': 'Const', 'kind': 'op', 'op': 'Const',
- 'value': 2, 'shape': int64_array([])},
- 'const_default_value_data': {'kind': 'data','value': 2, 'shape': int64_array([])},
- 'input_indices': {'value': None, 'shape': int64_array([10, 2]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'output_indices_data': {'shape': int64_array([10, 2]), 'value': None, 'kind': 'data'},
- 'input_values': {'value': None, 'shape': int64_array([10]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_values_data': {'shape': int64_array([10]), 'value': None, 'kind': 'data'},
- 'input_params_table': {'value': None, 'shape': int64_array([100, 4, 3]), 'type': 'Parameter', 'kind': 'op',
- 'op': 'Parameter'},
- 'input_params_table_data': {'shape': int64_array([10, 4, 3]), 'value': None, 'kind': 'data'},
- 'sparse_weighted_sum': {'kind': 'op', 'op': 'SparseWeightedSum'},
- },
- [
- ('input_indices', 'output_indices_data'),
- ('output_indices_data', 'sparse_weighted_sum', {'in': 0}),
- ('input_values', 'input_values_data'),
- ('input_values_data', 'sparse_weighted_sum', {'in': 1}),
- ('const_dense_shape', 'output_new_dense_shape_data'),
- ('output_new_dense_shape_data', 'sparse_weighted_sum', {'in': 2}),
- ('input_params_table', 'input_params_table_data'),
- ('input_params_table_data', 'sparse_weighted_sum', {'in': 3}),
- ('const_default_value', 'const_default_value_data'),
- ('const_default_value_data', 'sparse_weighted_sum', {'in': 4})
- ])
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'sparse_weighted_sum')
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/moc_frontend/moc_extractor_test_actual.py b/tools/mo/unit_tests/mo/moc_frontend/moc_extractor_test_actual.py
deleted file mode 100644
index cac56f82bf897b..00000000000000
--- a/tools/mo/unit_tests/mo/moc_frontend/moc_extractor_test_actual.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.moc_frontend.extractor import decode_name_with_port
-from openvino.tools.mo.utils.error import Error
-
-import pytest
-
-
-mock_available = True
-
-try:
- # pylint: disable=no-name-in-module,import-error
- from mock_mo_python_api import get_model_statistic, get_place_statistic, \
- clear_frontend_statistic, clear_model_statistic, clear_place_statistic, \
- clear_setup, set_equal_data, set_max_port_counts
-
- # pylint: disable=no-name-in-module,import-error
- from openvino.frontend import FrontEndManager
-
-except Exception:
- print("No mock frontend API available, "
- "ensure to use -DENABLE_TESTS=ON option when running these tests")
- mock_available = False
-
-# FrontEndManager shall be initialized and destroyed after all tests finished
-# This is because destroy of FrontEndManager will unload all plugins,
-# no objects shall exist after this
-if mock_available:
- fem = FrontEndManager()
-
-mock_needed = pytest.mark.skipif(not mock_available,
- reason="mock MO fe is not available")
-
-
-class TestMainFrontend(unittest.TestCase):
- def setUp(self):
- clear_frontend_statistic()
- clear_model_statistic()
- clear_place_statistic()
- clear_setup()
- set_max_port_counts(10, 10)
- self.fe = fem.load_by_framework('openvino_mock_mo_frontend')
- self.model = self.fe.load('abc.bin')
-
- # Mock model has 'tensor' tensor place
- @mock_needed
- def test_decode_name_with_port_tensor(self):
- node = decode_name_with_port(self.model, "tensor")
- model_stat = get_model_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert node
-
- # pylint: disable=wrong-spelling-in-comment
- # Mock model doesn't have 'mocknoname' place
- @mock_needed
- def test_decode_name_with_port_noname(self):
- with self.assertRaisesRegex(Error, 'No\\ node\\ with\\ name.*mocknoname*'):
- decode_name_with_port(self.model, 'mocknoname')
- model_stat = get_model_statistic()
- assert model_stat.get_place_by_tensor_name == 1
-
- # Mock model has both tensor and tensor:0 places with non equal data
- # Collision is expected
- @mock_needed
- def test_decode_name_with_port_collision(self):
- with self.assertRaisesRegex(Error, 'Name\\ collision.*tensorAndOp*'):
- decode_name_with_port(self.model, 'tensorAndOp:0')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.is_equal_data > 0
-
-
- # Mock model has 'operation' and output port up to 10
- @mock_needed
- def test_decode_name_with_port_delim_op_out(self):
- node = decode_name_with_port(self.model, 'operation:7')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_output_port == 1
- assert place_stat.lastArgInt == 7
- assert node
-
- # Mock model has 'operation' and input port up to 10
- @mock_needed
- def test_decode_name_with_port_delim_op_in(self):
- node = decode_name_with_port(self.model, '7:operation')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_input_port == 1
- assert place_stat.lastArgInt == 7
- assert node
-
- # Mock model has 'tensor' and 'tensor:0' tensor places, no collision is expected
- @mock_needed
- def test_decode_name_with_port_delim_tensor_no_collision_out(self):
- node = decode_name_with_port(self.model, 'tensor:0')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_output_port == 0
- assert node
-
- # Mock model has 'tensor' and '0:tensor' tensor places, no collision is expected
- @mock_needed
- def test_decode_name_with_port_delim_tensor_no_collision_in(self):
- node = decode_name_with_port(self.model, '0:tensor')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_input_port == 0
- assert node
-
- # Mock model doesn't have such '1234:operation' or output port=1234 for 'operation'
- @mock_needed
- def test_decode_name_with_port_delim_no_port_out(self):
- with self.assertRaisesRegex(Error, 'No\\ node\\ with\\ name.*operation\\:1234*'):
- decode_name_with_port(self.model, 'operation:1234')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_output_port == 1
- assert place_stat.lastArgInt == 1234
-
- # Mock model doesn't have such '1234:operation' or input port=1234 for 'operation'
- @mock_needed
- def test_decode_name_with_port_delim_no_port_in(self):
- with self.assertRaisesRegex(Error, 'No\\ node\\ with\\ name.*1234\\:operation*'):
- decode_name_with_port(self.model, '1234:operation')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_input_port == 1
- assert place_stat.lastArgInt == 1234
-
- # Mock model has tensor with name 'conv2d:0' and operation 'conv2d' with output port = 1
- # It is setup to return 'is_equal_data=True' for these tensor and port
- # So no collision is expected
- @mock_needed
- def test_decode_name_with_port_delim_equal_data_out(self):
- set_equal_data('conv2d', 'conv2d')
- node = decode_name_with_port(self.model, 'conv2d:0')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_output_port == 1
- assert place_stat.is_equal_data > 0
- assert node
-
- # Mock model has tensor with name '0:conv2d' and operation 'conv2d' with input port = 1
- # It is setup to return 'is_equal_data=True' for these tensor and port
- # So no collision is expected
- @mock_needed
- def test_decode_name_with_port_delim_equal_data_in(self):
- set_equal_data('conv2d', 'conv2d')
- node = decode_name_with_port(self.model, '0:conv2d')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 1
- assert place_stat.get_input_port == 1
- assert place_stat.is_equal_data > 0
- assert node
-
- # Stress case: Mock model has:
- # Tensor '8:9'
- # Operation '8:9'
- # Operation '8' with output port = 9
- # Operation '9' with input port = 8
- # All places point to same data - no collision is expected
- @mock_needed
- def test_decode_name_with_port_delim_all_same_data(self):
- set_equal_data('8', '9')
- node = decode_name_with_port(self.model, '8:9')
- model_stat = get_model_statistic()
- place_stat = get_place_statistic()
-
- assert model_stat.get_place_by_tensor_name == 1
- assert model_stat.get_place_by_operation_name == 2
- assert place_stat.get_input_port == 1
- assert place_stat.get_output_port == 1
- # At least 3 comparisons of places are expected
- assert place_stat.is_equal_data > 2
- assert node
diff --git a/tools/mo/unit_tests/mo/ops/Complex_test.py b/tools/mo/unit_tests/mo/ops/Complex_test.py
deleted file mode 100644
index b14bc67c193c10..00000000000000
--- a/tools/mo/unit_tests/mo/ops/Complex_test.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.Complex import Complex
-from unit_tests.utils.graph import build_graph
-
-graph_node_attrs_sizes = {
- 'input_real': {'type': 'Parameter', 'kind': 'op'},
- 'input_imag': {'type': 'Parameter', 'kind': 'op'},
- 'input_real_data': {'kind': 'data', 'shape': None, 'value': None},
- 'input_imag_data': {'kind': 'data', 'shape': None, 'value': None},
- 'complex': {'op': 'Complex', 'kind': 'op'},
- 'complex_data': {'kind': 'data', 'shape': None, 'value': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges_sizes = [
- ('input_real', 'input_real_data'),
- ('input_imag', 'input_imag_data'),
- ('input_real_data', 'complex', {'in': 0}),
- ('input_imag_data', 'complex', {'in': 1}),
- ('complex', 'complex_data'),
- ('complex_data', 'op_output'),
-]
-
-
-class TestComplexOp():
- @pytest.mark.parametrize("input_shape, output_shape",[
- ([1, 260, 100, 150], [1, 260, 100, 150, 2]),
- ([1, 260, 100], [1, 260, 100, 2]),
- ([5, 14, 300, 40], [5, 14, 300, 40, 2]),
- ([1, 3, 260, 100, 150], [1, 3, 260, 100, 150, 2]),
- ([5, 14, 1000, 300, 40], [5, 14, 1000, 300, 40, 2])
- ])
- def test_complex_op_shape_inference(self, input_shape, output_shape):
- graph = build_graph(nodes_attrs=graph_node_attrs_sizes,
- edges=graph_edges_sizes,
- update_attributes={
- 'input_real_data': {'shape': int64_array(input_shape)},
- 'input_imag_data': {'shape': int64_array(input_shape)},
- })
- node = Node(graph, 'complex')
- Complex.infer(node)
-
- msg = "Complex operation infer failed for case: expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['complex_data']['shape'], int64_array(output_shape)),\
- msg.format(output_shape, graph.node['complex_data']['shape'])
diff --git a/tools/mo/unit_tests/mo/ops/ExtractImagePatches_test.py b/tools/mo/unit_tests/mo/ops/ExtractImagePatches_test.py
deleted file mode 100644
index 7a51f02203b9e1..00000000000000
--- a/tools/mo/unit_tests/mo/ops/ExtractImagePatches_test.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.ExtractImagePatches import ExtractImagePatches
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes = {
- 'input': {'op': 'Parameter', 'kind': 'op', 'shape': None},
- 'input_data': {'value': None, 'kind': 'data', 'shape': None},
- 'EIP': {'op': 'ExtractImagePatches', 'kind': 'op', 'sizes': None, 'strides': None, 'rates': None, 'auto_pad': None},
- 'EIP_data': {'value': None, 'kind': 'data', 'shape': None},
- 'output': {'op': 'Result', 'kind': 'op', 'shape': None},
-}
-
-edges = [
- ('input', 'input_data'),
- ('input_data', 'EIP'),
- ('EIP', 'EIP_data'),
- ('EIP_data', 'output'),
-]
-
-class TestExtractImagePatchesPartialInfer():
- @pytest.mark.parametrize("input_shape, sizes, strides, rates, auto_pad, layout, output_shape",[
- ([1, 10, 10, 3], [1, 3, 3, 1], [1, 5, 5, 1], [1, 1, 1, 1], 'valid', 'NHWC', [1, 2, 2, 27]),
- ([1, 10, 10, 3], [1, 3, 3, 1], [1, 5, 5, 1], [1, 2, 2, 1], 'valid', 'NHWC', [1, 2, 2, 27]),
- ([1, 10, 10, 3], [1, 4, 4, 1], [1, 8, 8, 1], [1, 1, 1, 1], 'valid', 'NHWC', [1, 1, 1, 48]),
- ([1, 10, 10, 3], [1, 4, 4, 1], [1, 8, 8, 1], [1, 1, 1, 1], 'same_upper', 'NHWC', [1, 2, 2, 48]),
- ([1, 10, 10, 3], [1, 4, 4, 1], [1, 9, 9, 1], [1, 1, 1, 1], 'same_upper', 'NHWC', [1, 2, 2, 48]),
- ([1, 10, 10, 3], [1, 4, 4, 1], [1, 9, 9, 1], [1, 1, 1, 1], 'same_lower', 'NHWC', [1, 2, 2, 48]),
- ([1, 64, 64, 3], [1, 3, 3, 1], [1, 1, 1, 1], [1, 1, 1, 1], 'valid', 'NHWC', [1, 62, 62, 27]),
- ([1, 64, 64, 3], [1, 3, 3, 1], [1, 1, 1, 1], [1, 1, 1, 1], 'same_upper', 'NHWC', [1, 64, 64, 27]),
-
- ([1, 3, 10, 10], [1, 1, 3, 3], [1, 1, 5, 5], [1, 1, 1, 1], 'valid', 'NCHW', [1, 27, 2, 2]),
- ([1, 3, 10, 10], [1, 1, 4, 4], [1, 1, 8, 8], [1, 1, 1, 1], 'valid', 'NCHW', [1, 48, 1, 1]),
-
- ([1, 3, 10, 10], [1, 1, 4, 4], [1, 1, 9, 9], [1, 1, 1, 1], 'same_upper', 'NCHW', [1, 48, 2, 2]),
- ([1, 3, 10, 10], [1, 1, 4, 4], [1, 1, 9, 9], [1, 1, 1, 1], 'same_lower', 'NCHW', [1, 48, 2, 2]),
-
- ])
-
-
- def test_eip_infer(self, input_shape, sizes, strides, rates, auto_pad, layout, output_shape):
- graph = build_graph(
- nodes_attrs=nodes,
- edges=edges,
- update_attributes={
- 'input': {'shape': int64_array(input_shape)},
- 'input_data': {'shape': int64_array(input_shape)},
- 'EIP': {'spatial_dims': int64_array([1, 2]) if layout == 'NHWC' else int64_array([2, 3]),
- 'sizes': int64_array(sizes), 'strides': int64_array(strides), 'rates': int64_array(rates),
- 'auto_pad': auto_pad},
- }
- )
-
- graph.graph['layout'] = layout
-
- eip_node = Node(graph, 'EIP')
- ExtractImagePatches.infer(eip_node)
-
- assert np.array_equal(eip_node.out_port(0).data.get_shape(), output_shape)
diff --git a/tools/mo/unit_tests/mo/ops/If_test.py b/tools/mo/unit_tests/mo/ops/If_test.py
deleted file mode 100644
index 73828ac6d8ad41..00000000000000
--- a/tools/mo/unit_tests/mo/ops/If_test.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-import numpy.testing as npt
-
-from openvino.tools.mo.ops.If import If
-from openvino.tools.mo.ops.elementwise import Add, Mul
-from openvino.tools.mo.ops.identity import Identity
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, strict_compare_tensors, \
- dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.eltwise import eltwise_infer
-from openvino.tools.mo.ops.shape import Shape
-from unit_tests.utils.graph import build_graph_with_edge_attrs, build_graph
-from unit_tests.utils.graph import regular_op_with_empty_data, connect, result, valued_const_with_data, regular_op, \
- empty_data
-
-
-class TestIf():
- @pytest.mark.parametrize("cond, output_port_0_shape, output_port_1_shape",[
- (np.array([True], dtype=bool), shape_array([3]), shape_array([3])),
- (np.array([False], dtype=bool), shape_array([3]), shape_array([2])),
- (shape_array(dynamic_dimension_value), shape_array([3]), shape_array([dynamic_dimension_value])),
- ])
- def test_simple_shape_inf(self, cond, output_port_0_shape, output_port_1_shape):
- then_graph_nodes = {**regular_op_with_empty_data('param_1', {'type': 'Parameter', 'kind': 'op', 'input_id': 1,
- 'shape': None, 'infer': Parameter.infer}),
- **regular_op_with_empty_data('param_2', {'type': 'Parameter', 'kind': 'op', 'input_id': 2,
- 'shape': None, 'infer': Parameter.infer}),
- **regular_op_with_empty_data('add', {'type': 'Add', 'kind': 'op', 'op': 'Add',
- 'infer': lambda node: eltwise_infer(node,
- Add.operation)}),
- **regular_op_with_empty_data('mul', {'type': 'Mul', 'kind': 'op', 'op': 'Mul',
- 'infer': lambda node: eltwise_infer(node,
- Mul.operation)}),
- **regular_op_with_empty_data('res1', {'kind': 'op', 'type': 'Result', 'op': 'Result',
- 'infer': lambda x: 0, 'output_id': 0}),
- **regular_op_with_empty_data('res2', {'kind': 'op', 'type': 'Result', 'op': 'Result',
- 'infer': lambda x: 0, 'output_id': 1})}
- then_graph_edges = [*connect('param_1', '0:add'),
- *connect('param_2', '1:add'),
- *connect('param_1', '1:mul'),
- *connect('param_2', '0:mul'),
- *connect('add', 'res1'),
- *connect('mul', 'res2'),
- ]
-
- else_graph_nodes = {**regular_op_with_empty_data('param_1', {'type': 'Parameter', 'kind': 'op', 'input_id': 1,
- 'shape': None, 'infer': Parameter.infer}),
- **regular_op_with_empty_data('param_2', {'type': 'Parameter', 'kind': 'op', 'input_id': 3,
- 'shape': None, 'infer': Parameter.infer}),
- **regular_op_with_empty_data('identity',
- {'kind': 'op', 'op': 'Identity', 'infer': Identity.infer}),
- **regular_op_with_empty_data('identity_1',
- {'kind': 'op', 'op': 'Identity', 'infer': Identity.infer}),
- **regular_op_with_empty_data('res1', {'kind': 'op', 'type': 'Result', 'op': 'Result',
- 'infer': lambda x: 0, 'output_id': 0}),
- **regular_op_with_empty_data('res2', {'kind': 'op', 'type': 'Result', 'op': 'Result',
- 'infer': lambda x: 0, 'output_id': 1})}
- else_graph_edges = [*connect('param_1', 'identity'),
- *connect('param_2', 'identity_1'),
- *connect('identity_1', 'res2'),
- *connect('identity', 'res1'), ]
- then_graph = build_graph_with_edge_attrs(then_graph_nodes, then_graph_edges)
- else_graph = build_graph_with_edge_attrs(else_graph_nodes, else_graph_edges)
- external_graph_nodes = {
- **valued_const_with_data('cond', cond),
- **valued_const_with_data('input_2', int64_array([3, 2, 1])),
- **valued_const_with_data('input_1', int64_array([1, 2, 3])),
- **valued_const_with_data('input_3', int64_array([8, 4])),
- **regular_op('if', {'kind': 'op', 'op': 'If', 'then_graph': then_graph,
- 'else_graph': else_graph, 'infer': If.infer}),
- **empty_data('if_d_1'),
- **empty_data('if_d_2'),
- **result('res_1'),
- **result('res_2')}
- external_graph_edges = [*connect('cond', '0:if'),
- *connect('input_1', '1:if'),
- *connect('input_2', '2:if'),
- *connect('input_3', '3:if'),
- ('if', 'if_d_1', {'out': 0}),
- ('if', 'if_d_2', {'out': 1}),
- ('if_d_1', 'res_1'),
- ('if_d_2', 'res_2')]
-
- graph = build_graph(external_graph_nodes, external_graph_edges)
- graph.stage = 'middle'
- partial_infer(graph)
- if_node = Node(graph, 'if')
- assert strict_compare_tensors(if_node.out_port(0).data.get_shape(), output_port_0_shape)
- # shape of the "then" branch is [3] and shape of the "else" branch is [2], so the output shape is "[dynamic]"
- assert strict_compare_tensors(if_node.out_port(1).data.get_shape(), output_port_1_shape)
-
- def test_fake_results(self):
- then_graph_nodes = {**valued_const_with_data('fake_const', int64_array(0)),
- **regular_op_with_empty_data('shapeof',
- {'kind': 'op', 'type': 'ShapeOf', 'op': 'ShapeOf', 'infer': Shape.infer,
- 'output_type': np.int64}),
- **regular_op_with_empty_data('res_1', {'kind': 'op', 'type': 'Result', 'op': 'Result',
- 'infer': lambda x: 0, 'output_id': 0})}
- then_graph_edges = [*connect('fake_const', 'shapeof'),
- *connect('shapeof', 'res_1'),
- ]
-
- else_graph_nodes = {**regular_op_with_empty_data('param_1', {'type': 'Parameter', 'kind': 'op', 'input_id': 1,
- 'shape': None, 'infer': Parameter.infer}),
- **regular_op_with_empty_data('res_1', {'kind': 'op', 'type': 'Result', 'op': 'Result',
- 'infer': lambda x: 0, 'output_id': 0})}
- else_graph_edges = [*connect('param_1', 'res_1')]
- then_graph = build_graph_with_edge_attrs(then_graph_nodes, then_graph_edges)
- else_graph = build_graph_with_edge_attrs(else_graph_nodes, else_graph_edges)
- external_graph_nodes = {
- **valued_const_with_data('cond', shape_array([dynamic_dimension_value])),
- **valued_const_with_data('input_1', int64_array([1, 2, 3, 3, 2, 3]).reshape((2, 3))),
- **regular_op_with_empty_data('if', {'kind': 'op', 'op': 'If', 'then_graph': then_graph,
- 'else_graph': else_graph, 'infer': If.infer}),
- **result('res_1')}
- external_graph_edges = [*connect('cond', '0:if'),
- *connect('input_1', '1:if'),
- *connect('if', 'res_1')]
-
- graph = build_graph(external_graph_nodes, external_graph_edges)
- graph.stage = 'middle'
- partial_infer(graph)
- npt.assert_array_equal(Node(graph, 'if').out_port(0).data.get_shape(), int64_array([2, 3]))
diff --git a/tools/mo/unit_tests/mo/ops/LookupTableInsert_test.py b/tools/mo/unit_tests/mo/ops/LookupTableInsert_test.py
deleted file mode 100644
index 2d8682d4ce8dc2..00000000000000
--- a/tools/mo/unit_tests/mo/ops/LookupTableInsert_test.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.LookupTableInsert import LookupTableInsert
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'table': {'kind': 'op'},
- 'table_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'keys': {'kind': 'op'},
- 'keys_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'values': {'kind': 'op'},
- 'values_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'lookuptableinsert_node': {'op': 'LookupTableInsert', 'kind': 'op'},
- 'output': {'shape': None, 'value': None, 'kind': 'data'}}
-
-# graph 1
-edges1 = [('table', 'table_data'),
- ('keys', 'keys_data'),
- ('values', 'values_data'),
- ('table_data', 'lookuptableinsert_node', {'in': 0}),
- ('keys_data', 'lookuptableinsert_node', {'in': 1}),
- ('values_data', 'lookuptableinsert_node', {'in': 2}),
- ('lookuptableinsert_node', 'output')]
-
-# valid test case
-inputs1 = {'table_data': {},
- 'keys_data': {'shape': int64_array([4])},
- 'values_data': {'shape': int64_array([4])}}
-
-# invalid test case
-inputs2 = {'table_data': {},
- 'keys_data': {'shape': int64_array([5, 2])},
- 'values_data': {'shape': int64_array([4])}}
-
-class TestLookupTableInsert(unittest.TestCase):
- def test_infer1(self):
- graph = build_graph(nodes_attributes, edges1, inputs1)
- lookuptableinsert_node = Node(graph, 'lookuptableinsert_node')
- LookupTableInsert.infer(lookuptableinsert_node)
-
- # prepare reference results
- ref_output_shape = int64_array([])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_infer_invalid1(self):
- graph = build_graph(nodes_attributes, edges1, inputs2)
- lookuptableinsert_node = Node(graph, 'lookuptableinsert_node')
- self.assertRaises(AssertionError, LookupTableInsert.infer, lookuptableinsert_node)
diff --git a/tools/mo/unit_tests/mo/ops/MatMul_test.py b/tools/mo/unit_tests/mo/ops/MatMul_test.py
deleted file mode 100644
index 46e3bc91f20f16..00000000000000
--- a/tools/mo/unit_tests/mo/ops/MatMul_test.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.MatMul import MatMul
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class TestMatMul():
- nodes = [
- ('A', {'type': 'Parameter', 'kind': 'op'}),
- ('A_d', {'kind': 'data'}),
- ('B', {'type': 'Parameter', 'kind': 'op'}),
- ('B_d', {'kind': 'data', 'dim_attrs': []}),
- ('mat_mul', {'type': 'MatMul', 'kind': 'op'}),
- ('mat_mul_d', {'kind': 'data', 'value': None, 'shape': None}),
- ('op_output', {'kind': 'op', 'op': 'Result'}),
- ]
- edges = [
- ('A', 'A_d'),
- ('B', 'B_d'),
- ('A_d', 'mat_mul', {'in': 0}),
- ('B_d', 'mat_mul', {'in': 1}),
- ('mat_mul', 'mat_mul_d'),
- ('mat_mul_d', 'op_output'),
- ]
-
- @pytest.mark.parametrize("A_shape, B_shape, C_shape, transpose_a, transpose_b",[
- ([1024], [1024, 1000], [1000], False, False),
- ([dynamic_dimension_value], [1024, 1000], [1000], False, False),
- ([1024], [dynamic_dimension_value, 1000], [1000], False, False),
- ([1024], [1024, 1000], [1000], True, False),
- ([1024], [1000, 1024], [1000], True, True),
- ([dynamic_dimension_value], [dynamic_dimension_value, dynamic_dimension_value], [dynamic_dimension_value], True,
- True),
- ([1, 1024], [1024, 1000], [1, 1000], False, False),
- ([1, 1024], [1000, 1024], [1, 1000], False, True),
- ([1024, 1000], [1000], [1024], False, False),
- ([1024, 1000], [1000], [1024], False, True),
- ([1000, 1024], [1000], [1024], True, True),
- ([1000, dynamic_dimension_value], [1000], [dynamic_dimension_value], True, True),
- ([10, 1024], [1024, 1000], [10, 1000], False, False),
- ([5, 10, 1024], [1024, 1000], [5, 10, 1000], False, False),
- ([5, 10, 1024], [5, 1024, 1000], [5, 10, 1000], False, False),
- ([5, 10, 1024], [1, 1024, 1000], [5, 10, 1000], False, False),
- ([5, 10, 1024], [1, 1000, 1024], [5, 10, 1000], False, True),
- ])
- def test_positive_matmul_infer(self, A_shape, B_shape, C_shape, transpose_a, transpose_b):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
- update_nodes_attributes=[
- ('A_d', {'shape': shape_array(A_shape)}),
- ('B_d', {'shape': shape_array(B_shape)}),
- ('mat_mul', {'transpose_a': transpose_a, 'transpose_b': transpose_b}),
- ])
- node = Node(graph, 'mat_mul')
- MatMul.infer(node)
-
- msg = "MatMul infer failed for case: A_shape={}, B_shape={}, transpose_a={}, transpose_b={} " \
- "expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['mat_mul_d']['shape'], shape_array(C_shape)),\
- msg.format(A_shape, B_shape, transpose_a, transpose_b, C_shape,
- graph.node['mat_mul_d']['shape'])
-
- @pytest.mark.parametrize("A_shape, B_shape",[
- (None, [1024, 1000]),
- (1, [1024, 1000]),
- ([], [1024, 1000]),
- ([1024, 1000], [1024, 1000]),
- ([5, 10, 1024], [3, 1024, 1000]),
- ])
- def test_negative_matmul_infer(self, A_shape, B_shape):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
- update_nodes_attributes=[
- ('A_d', {'shape': np.array(A_shape)}),
- ('B_d', {'shape': int64_array(B_shape)}),
- ])
-
- node = Node(graph, 'mat_mul')
- with pytest.raises(AssertionError):
- MatMul.infer(node)
diff --git a/tools/mo/unit_tests/mo/ops/MatMul_value_propagation_test.py b/tools/mo/unit_tests/mo/ops/MatMul_value_propagation_test.py
deleted file mode 100644
index bc3fd1813a91ed..00000000000000
--- a/tools/mo/unit_tests/mo/ops/MatMul_value_propagation_test.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.MatMul import MatMul, transpose
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-graph_nodes_attrs = {
- 'A': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'A_data': {'kind': 'data', 'shape': None, 'value': None},
- 'B': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'B_data': {'kind': 'data', 'shape': None, 'value': None, 'dim_attrs': []},
- 'matmul': {'type': 'MatMul', 'op': 'MatMul', 'kind': 'op', 'transpose_a': False, 'transpose_b': False},
- 'matmul_data': {'kind': 'data', 'value': None, 'shape': None},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-graph_edges=[
- ('A', 'A_data'),
- ('B', 'B_data'),
- ('A_data', 'matmul', {'in': 0}),
- ('B_data', 'matmul', {'in': 1}),
- ('matmul', 'matmul_data'),
- ('matmul_data', 'output'),
-]
-
-
-class TestMatMulValuePropagation():
- @pytest.mark.parametrize("a_shape, a_value, b_shape, b_value, transpose_a, transpose_b",[
- ([16, 3], np.arange(-5, -5 + 16 * 3).reshape((16, 3)),
- [3, 5], np.arange(0, 3 * 5).reshape((3, 5)),
- False, False),
- ([3, 16], np.arange(-5, -5 + 16 * 3).reshape((3, 16)),
- [3, 5], np.arange(0, 3 * 5).reshape((3, 5)),
- True, False),
- ([5, 8], np.arange(-1, -1 + 5 * 8).reshape((5, 8)),
- [4, 8], np.arange(-2, -2 + 4 * 8).reshape((4, 8)),
- False, True),
- ([8, 8], np.arange(1, 1 + 8 * 8).reshape((8, 8)),
- [4, 8], np.arange(-2, -2 + 4 * 8).reshape((4, 8)),
- True, True),
-
- ([7, 16, 3], np.arange(0, 0 + 16 * 3 * 7).reshape((7, 16, 3)),
- [3, 5], np.arange(0, 3 * 5).reshape((3, 5)),
- False, False),
- ([1, 3, 16], np.arange(-5, -5 + 16 * 3).reshape((1, 3, 16)),
- [3, 5], np.arange(0, 3 * 5).reshape((3, 5)),
- True, False),
- ([11, 5, 8], np.arange(-1, -1 + 5 * 8 * 11).reshape((11, 5, 8)),
- [11, 4, 8], np.arange(-2, -2 + 4 * 8 * 11).reshape((11, 4, 8)),
- False, True),
- ([1, 3, 5, 8, 8], np.arange(1, 1 + 8 * 8 * 3 * 5).reshape((1, 3, 5, 8, 8)),
- [4, 8], np.arange(-2, -2 + 4 * 8).reshape((4, 8)),
- True, True),
-
- ([2], np.zeros((2)), [2], np.zeros((2)), False, False),
- ([2], np.zeros((2)), [1, 2, 3], np.zeros((1, 2, 3)), False, False),
- ([1, 2, 3], np.zeros((1, 2, 3)), [3], np.zeros((3)), False, False),
- ])
- def test_value_propagation(self, a_shape, a_value, b_shape, b_value, transpose_a, transpose_b):
- graph = build_graph(
- nodes_attrs=graph_nodes_attrs,
- edges=graph_edges,
- update_attributes={
- 'A': {'shape': int64_array(a_shape), 'value': a_value},
- 'A_data': {'shape': int64_array(a_shape), 'value': a_value},
- 'B': {'shape': int64_array(b_shape), 'value': b_value},
- 'B_data': {'shape': int64_array(b_shape), 'value': b_value},
- 'matmul': {'transpose_a': transpose_a, 'transpose_b': transpose_b},
- 'matmul_data': {'value': None, 'shape': None},
- }
- )
- node = Node(graph, 'matmul')
- MatMul.infer(node)
- node_data = node.out_port(0).get_destination().data.get_value()
- a = a_value
- b = b_value
- if transpose_a:
- a = transpose(a)
- if transpose_b:
- b = transpose(b)
- ref_data = np.matmul(a, b)
- node_data_shape = node_data.shape
- ref_data_shape = ref_data.shape
- msg = "Value propagation for 'matmul' node is not correct."
- assert node_data_shape == ref_data_shape and np.all(node_data == ref_data), msg
diff --git a/tools/mo/unit_tests/mo/ops/ONNXResize11_test.py b/tools/mo/unit_tests/mo/ops/ONNXResize11_test.py
deleted file mode 100644
index ed17446c02af12..00000000000000
--- a/tools/mo/unit_tests/mo/ops/ONNXResize11_test.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.ONNXResize11 import ONNXResize11Op
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-graph_node_attrs_sizes = {
- 'input': {'type': 'Parameter', 'kind': 'op'},
- 'input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'roi': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'roi_data': {'kind': 'data', 'shape': None, 'value': None},
- 'scales': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'scales_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sizes': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'sizes_data': {'kind': 'data', 'shape': None, 'value': None},
- 'onnx_resize11': {
- 'op': 'ONNXResize11', 'kind': 'op', 'mode': 'nearest', 'nearest_mode': 'round_prefer_floor',
- 'coordinate_transformation_mode': 'half_pixel', 'cube_coeff': -0.75
- },
- 'onnx_resize11_data': {'kind': 'data', 'value': None, 'shape': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges_sizes = [
- ('input', 'input_data'),
- ('roi', 'roi_data'),
- ('sizes', 'sizes_data'),
- ('input_data', 'onnx_resize11', {'in': 0}),
- ('roi_data', 'onnx_resize11', {'in': 1}),
- ('sizes_data', 'onnx_resize11', {'in': 3}),
- ('onnx_resize11', 'onnx_resize11_data'),
- ('onnx_resize11_data', 'op_output'),
-]
-
-
-graph_node_attrs_scales = {
- 'input': {'type': 'Parameter', 'kind': 'op'},
- 'input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'roi': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'roi_data': {'kind': 'data', 'shape': None, 'value': None},
- 'scales': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'scales_data': {'kind': 'data', 'shape': None, 'value': None},
- 'onnx_resize11': {
- 'op': 'ONNXResize11', 'kind': 'op', 'mode': 'nearest', 'nearest_mode': 'round_prefer_floor',
- 'coordinate_transformation_mode': 'half_pixel', 'cube_coeff': -0.75
- },
- 'onnx_resize11_data': {'kind': 'data', 'value': None, 'shape': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges_scales = [
- ('input', 'input_data'),
- ('roi', 'roi_data'),
- ('scales', 'scales_data'),
- ('input_data', 'onnx_resize11', {'in': 0}),
- ('roi_data', 'onnx_resize11', {'in': 1}),
- ('scales_data', 'onnx_resize11', {'in': 2}),
- ('onnx_resize11', 'onnx_resize11_data'),
- ('onnx_resize11_data', 'op_output'),
-]
-
-
-class TestONNXResize11Op():
- @pytest.mark.parametrize("input_shape, output_shape, sizes, scales",[([1, 260, 100, 150], [1, 260, 200, 350], [1, 260, 200, 350], [1.0, 1.0, 1.0, 1.0]),
- ([1, 260, 100, 150], [1, 260, 200, 350], [1, 1, 200, 350], [1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 300, 40], [5, 14, 140, 280], [1, 1, 140, 280], [1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 300, 40], [5, 14, 140, 280], [5, 14, 140, 280], [1.0, 1.0, 1.0, 1.0]),
- ([1, 3, 260, 100, 150], [1, 3, 780, 200, 350], [1, 3, 780, 200, 350], [1.0, 1.0, 1.0, 1.0, 1.0]),
- ([1, 3, 450, 100, 150], [1, 3, 260, 200, 350], [1, 3, 260, 200, 350], [1.0, 1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 1000, 300, 40], [5, 14, 500, 140, 280], [1, 1, 500, 140, 280], [1.0, 1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 1000, 300, 40], [5, 14, 500, 140, 280], [5, 14, 500, 140, 280], [1.0, 1.0, 1.0, 1.0, 1.0])])
- def test_onnx_resize11_using_sizes(self, input_shape, output_shape, sizes, scales):
- np_scales = np.array(scales)
- np_sizes = int64_array(sizes)
- graph = build_graph(nodes_attrs=graph_node_attrs_sizes,
- edges=graph_edges_sizes,
- update_attributes={
- 'input_data': {'shape': int64_array(input_shape)},
- 'scales': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- 'scales_data': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- 'sizes': {'shape': int64_array(np_sizes.shape), 'value': np_sizes},
- 'sizes_data': {'shape': int64_array(np_sizes.shape), 'value': np_sizes},
- })
- node = Node(graph, 'onnx_resize11')
- ONNXResize11Op.onnx_resize_infer(node)
-
- msg = "ONNXResize11 infer failed for case: sizes={}, scales={}, expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['onnx_resize11_data']['shape'], int64_array(output_shape)),\
- msg.format(sizes, scales, output_shape, graph.node['onnx_resize11_data']['shape'])
-
- @pytest.mark.parametrize("input_shape, output_shape, scales",
- [([1, 260, 100, 150], [1, 260, 200, 350], [1.0, 1.0, 2.0, 350 / 150]),
- ([1, 3, 100, 200], [1, 3, 350, 150], [1.0, 1.0, 3.5, 150 / 200]),
- ([5, 14, 300, 40], [5, 14, 140, 280], [1.0, 1.0, 140 / 300, 7.0]),
- ([5, 14, 300, 40], [5, 14, 140, 560], [1.0, 1.0, 140 / 300, 14.0]),
- ([1, 3, 260, 100, 150], [1, 3, 780, 200, 350], [1.0, 1.0, 3.0, 2.0, 350 / 150]),
- ([1, 3, 450, 100, 150], [1, 3, 260, 200, 350], [1.0, 1.0, 260 / 450, 2.0, 350 / 150]),
- ([5, 14, 1000, 300, 40], [5, 14, 500, 140, 280], [1.0, 1.0, 0.5, 140 / 300, 7.0]),
- ([4, 3, 180, 1340], [4, 3, 60, 804], [1.0, 1.0, 0.33333334, 0.6]),
- ([4, 3, 500, 180, 1340], [4, 3, 750, 60, 804], [1.0, 1.0, 1.5, 0.33333334, 0.6])])
- def test_onnx_resize_using_scales(self, input_shape, output_shape, scales):
- np_scales = np.array(scales)
- graph = build_graph(nodes_attrs=graph_node_attrs_scales,
- edges=graph_edges_scales,
- update_attributes={
- 'input_data': {'shape': int64_array(input_shape)},
- 'scales': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- 'scales_data': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- })
- node = Node(graph, 'onnx_resize11')
- ONNXResize11Op.onnx_resize_infer(node)
-
- msg = "ONNXResize11 infer failed for case: scales={}, expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['onnx_resize11_data']['shape'], int64_array(output_shape)),\
- msg.format(scales, output_shape, graph.node['onnx_resize11_data']['shape'])
-
- @pytest.mark.parametrize("input_shape, output_shape, sizes, scales",
- [([1, 260, 100, 150], [1, 260, 200, 350], [1, 260, 200, 350], [1.0, 1.0, 1.0, 1.0]),
- ([1, 260, 100, 150], [1, 260, 200, 350], [1, 1, 200, 350], [1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 300, 40], [5, 14, 140, 280], [1, 1, 140, 280], [1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 300, 40], [5, 14, 140, 280], [5, 14, 140, 280], [1.0, 1.0, 1.0, 1.0]),
- ([1, 3, 260, 100, 150], [1, 3, 780, 200, 350], [1, 3, 780, 200, 350], [1.0, 1.0, 1.0, 1.0, 1.0]),
- ([1, 3, 450, 100, 150], [1, 3, 260, 200, 350], [1, 3, 260, 200, 350], [1.0, 1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 1000, 300, 40], [5, 14, 500, 140, 280], [1, 1, 500, 140, 280], [1.0, 1.0, 1.0, 1.0, 1.0]),
- ([5, 14, 1000, 300, 40], [5, 14, 500, 140, 280], [5, 14, 500, 140, 280], [1.0, 1.0, 1.0, 1.0, 1.0])])
- def test_onnx_resize11_using_sizes_without_roi_input(self, input_shape, output_shape, sizes, scales):
- np_scales = np.array(scales)
- np_sizes = int64_array(sizes)
- graph = build_graph(nodes_attrs=graph_node_attrs_sizes,
- edges=[('input', 'input_data'),
- ('sizes', 'sizes_data'),
- ('input_data', 'onnx_resize11', {'in': 0}),
- ('sizes_data', 'onnx_resize11', {'in': 3}),
- ('onnx_resize11', 'onnx_resize11_data'),
- ('onnx_resize11_data', 'op_output'),
- ],
- update_attributes={
- 'input_data': {'shape': int64_array(input_shape)},
- 'scales': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- 'scales_data': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- 'sizes': {'shape': int64_array(np_sizes.shape), 'value': np_sizes},
- 'sizes_data': {'shape': int64_array(np_sizes.shape), 'value': np_sizes},
- })
- node = Node(graph, 'onnx_resize11')
- ONNXResize11Op.onnx_resize_infer(node)
-
- msg = "ONNXResize11 infer failed for case: sizes={}, scales={}, expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['onnx_resize11_data']['shape'], int64_array(output_shape)),\
- msg.format(sizes, scales, output_shape, graph.node['onnx_resize11_data']['shape'])
-
- @pytest.mark.parametrize("input_shape, output_shape, scales",
- [([1, 260, 100, 150], [1, 260, 200, 350], [1.0, 1.0, 2.0, 350 / 150]),
- ([1, 3, 100, 200], [1, 3, 350, 150], [1.0, 1.0, 3.5, 150 / 200]),
- ([5, 14, 300, 40], [5, 14, 140, 280], [1.0, 1.0, 140 / 300, 7.0]),
- ([5, 14, 300, 40], [5, 14, 140, 560], [1.0, 1.0, 140 / 300, 14.0]),
- ([1, 3, 260, 100, 150], [1, 3, 780, 200, 350], [1.0, 1.0, 3.0, 2.0, 350 / 150]),
- ([1, 3, 450, 100, 150], [1, 3, 260, 200, 350], [1.0, 1.0, 260 / 450, 2.0, 350 / 150]),
- ([5, 14, 1000, 300, 40], [5, 14, 500, 140, 280], [1.0, 1.0, 0.5, 140 / 300, 7.0]),
- ([4, 3, 180, 1340], [4, 3, 60, 804], [1.0, 1.0, 0.33333334, 0.6]),
- ([4, 3, 500, 180, 1340], [4, 3, 750, 60, 804], [1.0, 1.0, 1.5, 0.33333334, 0.6])])
- def test_onnx_resize_using_scales_without_roi(self, input_shape, output_shape, scales):
- np_scales = np.array(scales)
- graph = build_graph(nodes_attrs=graph_node_attrs_scales,
- edges=[('input', 'input_data'),
- ('scales', 'scales_data'),
- ('input_data', 'onnx_resize11', {'in': 0}),
- ('scales_data', 'onnx_resize11', {'in': 2}),
- ('onnx_resize11', 'onnx_resize11_data'),
- ('onnx_resize11_data', 'op_output'),
- ],
- update_attributes={
- 'input_data': {'shape': int64_array(input_shape)},
- 'scales': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- 'scales_data': {'shape': int64_array(np_scales.shape), 'value': np_scales},
- })
- node = Node(graph, 'onnx_resize11')
- ONNXResize11Op.onnx_resize_infer(node)
-
- msg = "ONNXResize11 infer failed for case: scales={}, expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['onnx_resize11_data']['shape'], int64_array(output_shape)),\
- msg.format(scales, output_shape, graph.node['onnx_resize11_data']['shape'])
diff --git a/tools/mo/unit_tests/mo/ops/ReduceOps_test.py b/tools/mo/unit_tests/mo/ops/ReduceOps_test.py
deleted file mode 100644
index 947fc95c38ab9f..00000000000000
--- a/tools/mo/unit_tests/mo/ops/ReduceOps_test.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.ReduceOps import reduce_infer
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, strict_compare_tensors, is_fully_defined
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, result, connect, valued_const_with_data
-
-nodes_attributes = {
- **regular_op_with_shaped_data('data', [1, 3, 224, 224], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.float32}}),
- **valued_const_with_data('axis', int64_array(0)),
- **regular_op_with_shaped_data('reduce_lp', None, {'op': 'ReduceLp', 'type': None, 'name': 'my_reduce_lp'}),
- **regular_op_with_shaped_data('identity', None, {'op': 'Identity', 'name': 'identity'}),
- **result('output'),
-}
-
-
-class TestReduceLpTest():
- @unittest.skip("Skipped due to function array_equal failure")
- @pytest.mark.parametrize("shape, axes, keepdims, p",[
- ([3, 2, 2], [0], True, 1),
- ([3, 2, 2], [0], True, 2),
- ([3, 2, 2], [1], True, 2),
- ([3, 2, 2], [2], True, 2),
- ([3, 2, 2], [0], False, 1),
- ([3, 2, 2], [0], False, 2),
- ([3, 2, 2], [1], False, 2),
- ([3, 2, 2], [2], False, 2),
- ])
- def test_reduce_lp(self, shape, axes, keepdims, p):
- data = np.reshape(np.arange(1, np.prod(shape) + 1, dtype=np.float32), shape)
- reduced = np.power(np.sum(a=np.abs(np.power(data, p)), axis=tuple(axes), keepdims=keepdims), 1 / p)
- axis = int64_array(axes)
- p = int64_array(p)
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:reduce_lp'),
- *connect('axis', '1:reduce_lp'),
- *connect('reduce_lp', '0:identity'),
- ('identity', 'identity_d', {'out': 0}),
- ('identity_d', 'output')
- ],
- {'data_d': {'value': data, 'shape': data.shape},
- 'axis_d': {'value': axis, 'shape': axis.shape},
- 'reduce_lp': {'keep_dims': keepdims}},
- nodes_with_edges_only=True)
-
- reduce_node = Node(graph, 'reduce_lp')
- reduce_node.op = reduce_node.type = 'ReduceL' + str(p)
- reduce_infer(reduce_node)
- assert np.array_equal(reduce_node.out_port(0).data.get_value(), reduced)
-
- @pytest.mark.parametrize("shape, axes, keepdims, p",[
- ([3, 2, 2], [0], True, 1),
- ([3, 2, 2], [2], False, 2),
- ([3, 2, 2], [0, 2], False, 2),
- ])
- def test_reduce_dynamic(self, shape, axes, keepdims, p):
- false_mask = np.zeros(shape)
- false_mask[0][1][1] = True
- data = np.ma.masked_array(np.ones(shape), mask=false_mask)
- assert not is_fully_defined(data)
- reduced_tensor = np.sum(data, axis=tuple(axes), keepdims=keepdims)
- # create an array of all masked elements which is the expected result of the reduce of the tensor with dynamic
- # values
- fully_undefined = np.ma.masked_array(reduced_tensor, mask=np.ones(reduced_tensor.shape))
- axis = int64_array(axes)
- p = int64_array(p)
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:reduce_lp'),
- *connect('axis', '1:reduce_lp'),
- *connect('reduce_lp', '0:identity'),
- ('identity', 'identity_d', {'out': 0}),
- ('identity_d', 'output')
- ],
- {'data_d': {'value': data, 'shape': data.shape},
- 'axis_d': {'value': axis, 'shape': axis.shape},
- 'reduce_lp': {'keep_dims': keepdims}},
- nodes_with_edges_only=True)
-
- reduce_node = Node(graph, 'reduce_lp')
- reduce_node.op = reduce_node.type = 'ReduceL' + str(p)
- reduce_infer(reduce_node)
- assert strict_compare_tensors(reduce_node.out_port(0).data.get_value(), fully_undefined)
diff --git a/tools/mo/unit_tests/mo/ops/Reverse_test.py b/tools/mo/unit_tests/mo/ops/Reverse_test.py
deleted file mode 100644
index fe16c245bf995a..00000000000000
--- a/tools/mo/unit_tests/mo/ops/Reverse_test.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.Reverse import Reverse
-from openvino.tools.mo.front.common.extractors.utils import layout_attrs
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'node_1_data': {'type': 'Identity', 'kind': 'data', 'value': np.array([[1, 3, 227, 227]])},
- 'node_2': {'type': 'Identity', 'kind': 'op'},
- 'node_2_data': {'kind': 'data', 'value': np.array([1])},
- 'reverse': {'type': 'Reverse', 'kind': 'op', },
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-class TestReverse(unittest.TestCase):
- def test_reverse_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'node_1_data'),
- ('node_1_data', 'reverse'),
- ('node_2', 'node_2_data'),
- ('node_2_data', 'reverse'),
- ('reverse', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1_data': {'shape': np.array([1, 4])},
- 'reverse': {'stride': 2,
- **layout_attrs()}
- })
-
- reverse_node = Node(graph, 'reverse')
- Reverse.infer(reverse_node)
- exp_shape = np.array([1, 4])
- exp_value = np.array([[227, 227, 3, 1]])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
- for i in range(0, len(exp_value[0])):
- self.assertEqual(exp_value[0][i], res_value[0][i])
diff --git a/tools/mo/unit_tests/mo/ops/__init__.py b/tools/mo/unit_tests/mo/ops/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/ops/activation_test.py b/tools/mo/unit_tests/mo/ops/activation_test.py
deleted file mode 100644
index 9e0441431b362b..00000000000000
--- a/tools/mo/unit_tests/mo/ops/activation_test.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.activation_ops import Elu, SoftPlus, Mish, Swish, SoftSign
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-class TestActivationOp(unittest.TestCase):
- nodes_attributes = {
- 'node_1': {
- 'shape': np.array([4]),
- 'value': None
- },
- 'activation_node': {
- 'op': 'Activation',
- 'kind': 'op',
- 'operation': None
- },
- 'node_3': {
- 'shape': None
- }
- }
-
- def test_activation_elu_infer(self):
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'activation_node'),
- ('activation_node', 'node_3')
- ],
- {
- 'node_1': {
- 'value': np.array([6, -4, -2, -1])
- },
- 'activation_node': {
- 'operation': 'elu',
- 'alpha': 1.0,
- },
- 'node_3': {
- 'value': None
- }
- })
- graph.graph['layout'] = 'NCHW'
- activation_node = Node(graph, 'activation_node')
- Elu.infer(activation_node)
- exp_shape = np.array([4])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- exp_value = np.array([6., -0.98168436, -0.86466472, -0.63212056])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
-
- def test_activation_softplus_infer(self):
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'activation_node'),
- ('activation_node', 'node_3')
- ],
- {
- 'node_1': {
- 'value': np.array([-1.0, 0.0, 1.0, 20.0])
- },
- 'activation_node': {
- 'op': 'SoftPlus',
- 'operation': SoftPlus.operation,
- },
- 'node_3': {
- 'value': None
- }
- })
- graph.graph['layout'] = 'NCHW'
- activation_node = Node(graph, 'activation_node')
- SoftPlus.infer(activation_node)
- exp_shape = np.array([4])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- exp_value = np.array([0.3132617, 0.6931472, 1.3132617, 20.0])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
-
- def test_activation_mish_infer(self):
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'activation_node'),
- ('activation_node', 'node_3')
- ],
- {
- 'node_1': {
- 'value': np.array([-1.0, 0.0, 1.0, 20.0])
- },
- 'activation_node': {
- 'op': 'Mish',
- 'operation': Mish.operation,
- },
- 'node_3': {
- 'value': None
- }
- })
- graph.graph['layout'] = 'NCHW'
- activation_node = Node(graph, 'activation_node')
- Mish.infer(activation_node)
- exp_shape = np.array([4])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- exp_value = np.array([-0.30340146, 0.0, 0.8650984, 20.0])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
-
- def test_activation_swish_infer(self):
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'activation_node'),
- ('activation_node', 'node_3')
- ],
- {
- 'node_1': {
- 'value': np.array([-1.0, 0.0, 1.0, 20.0])
- },
- 'activation_node': {
- 'op': 'Swish',
- },
- 'node_3': {
- 'value': None
- }
- })
- graph.graph['layout'] = 'NCHW'
- activation_node = Node(graph, 'activation_node')
- Swish.infer(activation_node)
- exp_shape = np.array([4])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- exp_value = np.array([-0.26894142, 0.0, 0.73105858, 19.99999996])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
-
- def test_activation_softsign_infer(self):
- graph = build_graph(self.nodes_attributes,
- edges=[
- ('node_1', 'activation_node'),
- ('activation_node', 'node_3')
- ],
- update_attributes={
- 'node_1': {
- 'value': np.array([1.0, -1.0, 3.5, -5.8])
- },
- 'activation_node': {
- 'op': 'SoftSign',
- 'operation': SoftSign.operation
- },
- 'node_3': {
- 'value': None
- }
- })
- graph.graph['layout'] = 'NCHW'
- activation_node = Node(graph, 'activation_node')
- SoftSign.infer(activation_node)
- exp_shape = np.array([4])
- res_shape = graph.nodes['node_3']['shape']
- res_value = graph.nodes['node_3']['value']
- exp_value = np.array([0.5, -0.5, 0.7777777777777, -0.85294117647])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
diff --git a/tools/mo/unit_tests/mo/ops/argmax_test.py b/tools/mo/unit_tests/mo/ops/argmax_test.py
deleted file mode 100644
index 5a55528495f7f4..00000000000000
--- a/tools/mo/unit_tests/mo/ops/argmax_test.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.argmax import arg_ops_infer
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'op_input': {'kind': 'op', 'op': 'Parameter'},
- 'node_1': {'kind': 'data'},
- 'argmax': {'op': 'ArgMax', 'kind': 'op'},
- 'node_3': {'kind': 'data', 'value': None},
- 'op_output': {'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestArgMaxOp(unittest.TestCase):
- def test_caffe_argmax_axis(self):
- graph = build_graph(nodes_attributes,
- [
- ('op_input', 'node_1'),
- ('node_1', 'argmax'),
- ('argmax', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 1025, 2049])},
- 'argmax': {
- 'out_max_val': True,
- 'top_k': 100,
- 'axis': 2
- }
- })
-
- argmax_node = Node(graph, 'argmax')
- arg_ops_infer(argmax_node)
- exp_shape = np.array([1, 3, 100, 2049])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_argmax_axis_negative(self):
- graph = build_graph(nodes_attributes,
- [
- ('op_input', 'node_1'),
- ('node_1', 'argmax'),
- ('argmax', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 1025, 2049])},
- 'argmax': {
- 'out_max_val': True,
- 'top_k': 100,
- 'axis': -1
- }
- })
-
- argmax_node = Node(graph, 'argmax')
- arg_ops_infer(argmax_node)
- exp_shape = np.array([1, 3, 1025, 100])
- res_shape = graph.node['node_3']['shape']
- self.assertEqual(argmax_node.axis, 3)
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_argmax_no_axis(self):
- graph = build_graph(nodes_attributes,
- [
- ('op_input', 'node_1'),
- ('node_1', 'argmax'),
- ('argmax', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 1025, 2049])},
- 'argmax': {
- 'out_max_val': True,
- 'top_k': 100
- }
- })
-
- argmax_node = Node(graph, 'argmax')
- arg_ops_infer(argmax_node)
- exp_shape = np.array([1, 2, 100, 1])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_argmax_extend_shape(self):
- graph = build_graph(nodes_attributes,
- [
- ('op_input', 'node_1'),
- ('node_1', 'argmax'),
- ('argmax', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3])},
- 'argmax': {
- 'out_max_val': True,
- 'top_k': 100
- }
- })
-
- argmax_node = Node(graph, 'argmax')
- arg_ops_infer(argmax_node)
- exp_shape = np.array([1, 2, 100])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_argmax_out_max_val_false(self):
- graph = build_graph(nodes_attributes,
- [
- ('op_input', 'node_1'),
- ('node_1', 'argmax'),
- ('argmax', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3])},
- 'argmax': {
- 'out_max_val': False,
- 'top_k': 100
- }
- })
-
- argmax_node = Node(graph, 'argmax')
- arg_ops_infer(argmax_node)
- exp_shape = np.array([1, 1, 100])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/assert_test.py b/tools/mo/unit_tests/mo/ops/assert_test.py
deleted file mode 100644
index 96a12be4d88c35..00000000000000
--- a/tools/mo/unit_tests/mo/ops/assert_test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import Mock
-
-from openvino.tools.mo.ops.assert_op import Assert
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-class TestAssert(unittest.TestCase):
- def test_assert_cf_true(self):
- me_mock = Mock()
- nodes = {
- 'input_data': {'kind': 'data', 'executable': True},
- 'assert': {'type': 'Assert', 'value': None, 'kind': 'op', 'op': 'Assert'},
- 'assert_data': {'value': True, 'kind': 'data', 'executable': True}}
- edges = [
- ('input_data', 'assert', {'in': 0}),
- ('assert', 'assert_data', {'out': 0, 'control_flow_edge': False})]
- graph = build_graph_with_edge_attrs(nodes, edges)
- tested_class = Assert(graph=graph, attrs={})
- node = Node(graph, 'assert')
- tested_class.assert_control_flow_infer(node=node, is_executable=True, mark_executability=me_mock)
- me_mock.assert_called_once_with('assert_data', True)
-
- def test_assert_cf_false(self):
- me_mock = Mock()
- nodes = {
- 'input_data': {'name': 'input', 'kind': 'data', 'executable': True},
- 'assert': {'name': 'assert', 'type': 'Assert', 'value': None, 'kind': 'op', 'op': 'Assert'},
- 'assert_data': {'name': 'output', 'value': False, 'kind': 'data', 'executable': True}}
- edges = [
- ('input_data', 'assert', {'in': 0}),
- ('assert', 'assert_data', {'out': 0, 'control_flow_edge': False})]
- graph = build_graph_with_edge_attrs(nodes, edges)
- tested_class = Assert(graph=graph, attrs={})
- node = Node(graph, 'assert')
- tested_class.assert_control_flow_infer(node=node, is_executable=True, mark_executability=me_mock)
- me_mock.assert_called_once_with('assert_data', False)
diff --git a/tools/mo/unit_tests/mo/ops/block_lstm_test.py b/tools/mo/unit_tests/mo/ops/block_lstm_test.py
deleted file mode 100644
index 2b5271d3a668e8..00000000000000
--- a/tools/mo/unit_tests/mo/ops/block_lstm_test.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import strict_compare_tensors, shape_array, dynamic_dimension
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.BlockLSTM import BlockLSTM
-from unit_tests.utils.graph import build_graph, result, connect, regular_op_with_shaped_data, regular_op_with_empty_data
-
-
-class TestBlockLSTM(unittest.TestCase):
-
- def run_test(self, time_len, batch_size, num_inputs, hidden_size, ref_hidden_states_shape, ref_cell_states_shape):
- nodes = {
- **regular_op_with_shaped_data('x', [time_len, batch_size, num_inputs], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('weights', [num_inputs, hidden_size * 4], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('bias', [hidden_size * 4], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('init_hidden_state', [hidden_size * 4], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('init_cell_state', [hidden_size * 4], {'type': 'Parameter'}),
- **regular_op_with_empty_data('block_lstm', {'op': 'BlockLSTM'}),
- **result('hidden_states'),
- **result('cell_states'),
- }
-
- edges = [
- *connect('x', '0:block_lstm'),
- *connect('weights', '1:block_lstm'),
- *connect('bias', '2:block_lstm'),
- *connect('init_hidden_state', '3:block_lstm'),
- *connect('init_cell_state', '4:block_lstm'),
- *connect('block_lstm:0', 'hidden_states'),
- *connect('block_lstm:1', 'cell_states')
- ]
-
- graph = build_graph(nodes, edges)
- node = Node(graph, 'block_lstm')
- BlockLSTM.infer(node)
- hidden_states_shape = node.out_port(0).data.get_shape()
- cell_states_shape = node.out_port(1).data.get_shape()
- self.assertTrue(strict_compare_tensors(hidden_states_shape, ref_hidden_states_shape))
- self.assertTrue(strict_compare_tensors(cell_states_shape, ref_cell_states_shape))
-
- def test_block_lstm_basic_infer(self):
- self.run_test(time_len=4, batch_size=2, num_inputs=40, hidden_size=60,
- ref_hidden_states_shape=shape_array([4, 2, 60]), ref_cell_states_shape=shape_array([4, 2, 60]))
-
- def test_block_lstm_dynamic_infer(self):
- self.run_test(time_len=dynamic_dimension, batch_size=dynamic_dimension, num_inputs=40, hidden_size=60,
- ref_hidden_states_shape=shape_array([dynamic_dimension, dynamic_dimension, 60]),
- ref_cell_states_shape=shape_array([dynamic_dimension, dynamic_dimension, 60]))
-
- def test_failed_three_outputs(self):
- nodes = {
- **regular_op_with_shaped_data('x', [30, 3, 70], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('weights', [70, 120], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('bias', [120], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('init_hidden_state', [120], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('init_cell_state', [120], {'type': 'Parameter'}),
- **regular_op_with_empty_data('block_lstm', {'op': 'BlockLSTM'}),
- **result('hidden_states'),
- **result('cell_states'),
- **result('f'),
- }
-
- edges = [
- *connect('x', '0:block_lstm'),
- *connect('weights', '1:block_lstm'),
- *connect('bias', '2:block_lstm'),
- *connect('init_hidden_state', '3:block_lstm'),
- *connect('init_cell_state', '4:block_lstm'),
- *connect('block_lstm:0', 'hidden_states'),
- *connect('block_lstm:1', 'cell_states'),
- *connect('block_lstm:2', 'f')
- ]
-
- graph = build_graph(nodes, edges)
- node = Node(graph, 'block_lstm')
- with self.assertRaisesRegex(AssertionError, 'Internal Model Optimizer Error or unsupported BlockLSTM*'):
- BlockLSTM.infer(node)
diff --git a/tools/mo/unit_tests/mo/ops/broadcast_test.py b/tools/mo/unit_tests/mo/ops/broadcast_test.py
deleted file mode 100644
index bded97d9cb9ff9..00000000000000
--- a/tools/mo/unit_tests/mo/ops/broadcast_test.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, undefined_shape_of_rank
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.broadcast import Broadcast
-from unit_tests.utils.graph import build_graph, valued_const_with_data, regular_op_with_empty_data, \
- shaped_data
-
-
-class TestBroadcastTest():
- @pytest.mark.parametrize("data, target_shape, axes_mapping, mode, ref_out, test_raising",[
- ([1], [3, 3], None, 'numpy', [[1, 1, 1], [1, 1, 1], [1, 1, 1]], False),
- ([1], [3, 3], None, 'numpy', None, False),
-
- # shape broadcasting
- ([1], [1, 2], [0], 'explicit', None, False),
- ([1], [1, 2], [-2], 'explicit', None, False),
- ([1, 7], [5, 1, 7, 3], [1, 2], 'explicit', None, False),
- ([2, 1, 3], [2, 1, 3, 3], [0, 1, 2], 'explicit', None, False),
- ([2, 1, 3], [5, 2, 1, 3], [1, 2, 3], 'explicit', None, False),
-
- # value broadcasting
- ([1], [1, 2], [0], 'explicit', [[1, 1]], False),
-
- ([[3, 1]], [2, 1, 2], [1, 2], 'explicit', [[[3, 1]], [[3, 1]]], False), # ref_shape (2, 1, 2)
-
- ([[3, 1]], [2, 1, 2], [-2, -1], 'explicit', [[[3, 1]], [[3, 1]]], False), # ref_shape (2, 1, 2)
-
- ([[[9, 5, 7]], [[9, 5, 7]]], [2, 2, 1, 3], [1, 2, 3], 'explicit', # in_shape (2, 1, 3)
- [[[[9, 5, 7]], [[9, 5, 7]]], [[[9, 5, 7]], [[9, 5, 7]]]], False), # ref_out_shape (2, 2, 1, 3)
-
- ([[[9, 5, 7]], [[3, 4, 8]]], [2, 1, 3, 3], [0, 1, 2], 'explicit', # in_shape (2, 1, 3)
- [[[[9, 9, 9], [5, 5, 5], [7, 7, 7]]], [[[3, 3, 3], [4, 4, 4], [8, 8, 8]]]], False), # ref_out_shape (2, 1, 3, 3)
-
- # negative tests
- ([1], [2, 2], [0], 'explicit', None, True),
- ([1, 7], [5, 2, 7, 3], [1, 2], 'explicit', None, True),
- ([1, 7], [5, 2, 7, 3], [2, 1], 'explicit', None, True),
- ([1, 7], [5, 2, 7, 3], [-3, -2], 'explicit', None, True),
- ])
- def test_broadcast(self, data, target_shape, axes_mapping, mode, ref_out, test_raising):
- if ref_out is not None:
- input = valued_const_with_data('data', int64_array(data))
- else:
- input = shaped_data('data', int64_array(data))
-
- nodes = {
- **input,
- **valued_const_with_data('target_shape', int64_array(target_shape)),
- **regular_op_with_empty_data('broadcast', {'op': 'Broadcast', 'mode': mode}),
- }
-
- edges = [('data', 'broadcast'),
- ('target_shape', 'broadcast'),
- ('broadcast', 'broadcast_d')]
-
- if axes_mapping is not None:
- nodes.update(**valued_const_with_data('axes_mapping', int64_array(axes_mapping)))
- edges.append(('axes_mapping', 'broadcast'))
- graph = build_graph(nodes, edges)
-
- broadcast_node = Node(graph, 'broadcast')
- if test_raising:
- with pytest.raises(AssertionError):
- Broadcast.infer(broadcast_node)
- return
-
- Broadcast.infer(broadcast_node)
- if ref_out is not None:
- assert np.array_equal(broadcast_node.out_node().value, np.array(ref_out))
- else:
- assert np.array_equal(broadcast_node.out_node().shape, np.array(target_shape))
-
- @pytest.mark.parametrize("data, target_shape_shape, axes_mapping, mode, ref_out_shape, test_raising",[
- ([1], [3], [0], 'explicit', undefined_shape_of_rank(3), False),
- ([1], [3], None, 'numpy', undefined_shape_of_rank(3), False),
- ([1], [3], None, 'bidirectional', undefined_shape_of_rank(3),False),
- ([1, 7], [4], [1, 2], 'explicit', undefined_shape_of_rank(4), False),
- ([1, 2], [3], None, 'numpy', undefined_shape_of_rank(3),False),
- ([1, 1], [2], None, 'bidirectional', undefined_shape_of_rank(2), False),
- ([1, 1], [2, 1], None, 'numpy', None, True),
- ])
- def test_broadcast_dynamic(self, data, target_shape_shape, axes_mapping, mode, ref_out_shape, test_raising):
- nodes = {
- **shaped_data('data', int64_array(data)),
- **shaped_data('target_shape', int64_array(target_shape_shape)),
- **regular_op_with_empty_data('broadcast', {'op': 'Broadcast', 'mode': mode}),
- }
-
- edges = [('data', 'broadcast'),
- ('target_shape', 'broadcast'),
- ('broadcast', 'broadcast_d')]
-
- if axes_mapping is not None:
- nodes.update(**valued_const_with_data('axes_mapping', int64_array(axes_mapping)))
- edges.append(('axes_mapping', 'axes_mapping_d'))
- edges.append(('axes_mapping_d', 'broadcast'))
- graph = build_graph(nodes, edges)
-
- broadcast_node = Node(graph, 'broadcast')
- if test_raising:
- with pytest.raises(AssertionError):
- Broadcast.infer(broadcast_node)
- return
-
- Broadcast.infer(broadcast_node)
- assert np.array_equal(broadcast_node.out_node().shape, ref_out_shape)
diff --git a/tools/mo/unit_tests/mo/ops/bucketize_test.py b/tools/mo/unit_tests/mo/ops/bucketize_test.py
deleted file mode 100644
index b9b3589bef47df..00000000000000
--- a/tools/mo/unit_tests/mo/ops/bucketize_test.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.bucketize import Bucketize
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'input_tensor': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_buckets': {'shape': None, 'value': None, 'kind': 'data'},
- 'bucketize_node': {'op': 'Bucketize', 'kind': 'op', 'with_right_bound': False, 'output_type': np.int32},
- 'output': {'shape': None, 'value': None, 'kind': 'data'}}
-
-# graph 1
-edges1 = [('input_tensor', 'bucketize_node', {'in': 0}),
- ('input_buckets', 'bucketize_node', {'in': 1}),
- ('bucketize_node', 'output', {'out': 0})]
-
-inputs1 = {'input_tensor': {'shape': int64_array([4]), 'value': np.array([0.2, 6.4, 3.0, 1.6])},
- 'input_buckets': {'shape': int64_array([5]), 'value': np.array([0.0, 1.0, 2.5, 4.0, 10.0])}}
-
-inputs2 = {'input_tensor': {'shape': int64_array([4]), 'value': np.array([0.2, 6.4, 3.0, 1.6])},
- 'input_buckets': {'shape': int64_array([5]), 'value': np.array([])}}
-
-inputs3 = {'input_tensor': {'shape': int64_array([10, 40]), 'value': None},
- 'input_buckets': {'shape': int64_array([5]), 'value': None}}
-
-class TestBucketize(unittest.TestCase):
- def test_infer1(self):
- graph = build_graph(nodes_attributes, edges1, inputs1)
- bucketize_node = Node(graph, 'bucketize_node')
- Bucketize.infer(bucketize_node)
-
- # prepare reference results
- ref_output_value = np.array([1, 4, 3, 2], dtype=np.int32)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(ref_output_value, res_output_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_value, res_output_value))
-
- def test_infer2(self):
- graph = build_graph(nodes_attributes, edges1, inputs2)
- bucketize_node = Node(graph, 'bucketize_node')
- Bucketize.infer(bucketize_node)
-
- # prepare reference results
- ref_output_value = np.array([0, 0, 0, 0], dtype=np.int32)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(ref_output_value, res_output_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_value, res_output_value))
-
- def test_partial_infer1(self):
- graph = build_graph(nodes_attributes, edges1, inputs3)
- bucketize_node = Node(graph, 'bucketize_node')
- Bucketize.infer(bucketize_node)
-
- # prepare reference results
- ref_output_shape = np.array([10, 40], dtype=np.int32)
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
diff --git a/tools/mo/unit_tests/mo/ops/cast_test.py b/tools/mo/unit_tests/mo/ops/cast_test.py
deleted file mode 100644
index db48340190c96e..00000000000000
--- a/tools/mo/unit_tests/mo/ops/cast_test.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.Cast import Cast
-from openvino.tools.mo.middle.passes.convert_data_type import packed_U4, packed_I4
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import valued_const_with_data, regular_op_with_empty_data, result, build_graph, connect
-
-nodes = lambda value, dst_type: {
- **valued_const_with_data('value', np.array(value)),
- **regular_op_with_empty_data('convert', {'dst_type': dst_type, 'infer': Cast.infer}),
- **result(),
-}
-
-
-class TestCastTest():
- """
- Example of checking:
- 7 == 0111, padded to 00000111, results in 7
- 7 == 0111, 8 == 1000 packed to 10000111, results in 7+16
-
- -8 == 1000, padded to 00001000, results in 8
- """
-
- @pytest.mark.parametrize("value, expected, custom_dtype",
- [([i], [i], packed_U4) for i in range(16)] +
- [([i, 15-i], [i + (15-i)*16], packed_U4) for i in range(16)] +
- [([-i], [16-i], packed_I4) for i in range(1, 8+1)] +
- [([i], [i], packed_I4) for i in range(8)] +
- [([-i-1, i], [16-i-1 + 16*i], packed_I4) for i in range(8)] +
- [([i, -i-1], [i + 16*(16-i-1)], packed_I4) for i in range(8)]
- )
- def test_custom_value_propagation(self, value, expected, custom_dtype):
- graph = build_graph(nodes(value, custom_dtype), [
- *connect('value', 'convert'), *connect('convert', 'output'),
- ])
- partial_infer(graph)
-
- graph_ref = build_graph(nodes(value, custom_dtype), [
- *connect('value', 'convert'), *connect('convert', 'output')],
- {'convert_d': {'force_type': custom_dtype, 'force_shape': np.array(value).shape,
- 'value': expected}})
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True)
- assert flag, resp
diff --git a/tools/mo/unit_tests/mo/ops/concat_test.py b/tools/mo/unit_tests/mo/ops/concat_test.py
deleted file mode 100644
index 29cea71208e6d0..00000000000000
--- a/tools/mo/unit_tests/mo/ops/concat_test.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.concat import concat_infer
-from openvino.tools.mo.ops.concat import Concat
-from unit_tests.utils.graph import build_graph
-
-
-class TestConcatOp(unittest.TestCase):
- nodes_attributes = {
- 'node_1': {
- 'shape': np.array([227, 227, 227, 227])
- },
- 'concat_node': {
- },
- 'node_3': {
- 'kind': 'data'
- }
- }
-
- def test_concat_op(self):
- graph = build_graph(self.nodes_attributes,
- [
- ('node_1', 'concat_node'),
- ('concat_node', 'node_3')
- ])
- concat_node = Concat(graph, self.nodes_attributes['concat_node']).add_node()
- self.assertEqual(concat_node.type, 'Concat')
- self.assertEqual(concat_node.op, 'Concat')
- self.assertEqual(concat_node.infer, concat_infer)
diff --git a/tools/mo/unit_tests/mo/ops/convolution_test.py b/tools/mo/unit_tests/mo/ops/convolution_test.py
deleted file mode 100644
index f5e9a547e2702e..00000000000000
--- a/tools/mo/unit_tests/mo/ops/convolution_test.py
+++ /dev/null
@@ -1,460 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.convolution import Convolution
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.extractors import FakeValue
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'conv_input': {'value': None, 'kind': 'data'},
- 'conv_node': {'type': 'Convolution', 'kind': 'op'},
- 'conv_weights': {'value': FakeValue(None), 'kind': 'data'},
- 'conv_output': {'value': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestConvolutionPartialInfer(unittest.TestCase):
- def test_caffe_conv2d_infer(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': np.array([1, 3, 227, 227])},
- 'conv_weights': {'shape': np.array([64, 3, 3, 3]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'stride': np.array([1, 1, 1, 1]), 'group': 1,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'output': 64, 'kernel_spatial': np.array([3, 3]),
- 'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0])}
- })
-
- conv_node = Node(graph, 'conv_node')
- Convolution.infer(conv_node)
- exp_shape = np.array([1, 64, 225, 225])
- res_shape = graph.node['conv_output']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_conv2d_dynamic_input_infer(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': shape_array([1, 3, dynamic_dimension_value, 227])},
- 'conv_weights': {'shape': np.array([64, 3, 3, 3]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'stride': np.array([1, 1, 1, 1]), 'group': 1,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'output': 64, 'kernel_spatial': np.array([3, 3]),
- 'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0])}
- })
-
- conv_node = Node(graph, 'conv_node')
- Convolution.infer(conv_node)
- exp_shape = shape_array([1, 64, dynamic_dimension_value, 225])
- res_shape = graph.node['conv_output']['shape']
- self.assertTrue(strict_compare_tensors(exp_shape, res_shape))
-
- def test_caffe_conv2d_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': None},
- 'conv_weights': {'shape': None,
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'stride': np.array([1, 1, 1, 1]), 'group': 1,
- 'output': 64, 'kernel_spatial': np.array([3, 3]),
- 'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0])}
- })
-
- conv_node = Node(graph, 'conv_node')
- with self.assertRaisesRegex(Error, "Input data shape is None for node.*"):
- Convolution.infer(conv_node)
-
- def test_deconv_infer_ideal(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': np.array([1, 21, 16, 16])},
- 'conv_weights': {'shape': np.array([1, 21, 4, 4]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {#'spatial_dims': np.array([2, 3]), 'batch_dims': np.array([0]),
- 'channel_dims': np.array([1]), 'bias_addable': True, 'bias_term': False,
- 'batch_dims': np.array([0]),
- 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'kernel_spatial': np.array([4, 4]), 'output_spatial_shape': None,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'output_padding': np.array([0, 0, 1, 1]),
- 'type': 'Deconvolution', 'output': 21, 'dilation': np.array([1, 1, 1, 1]),
- 'group': 1, 'stride': np.array([1, 1, 2, 2]), 'output_shape': None}
- })
-
- deconv_node = Node(graph, 'conv_node')
-
- Convolution.infer(deconv_node)
- res_shape = deconv_node['output_shape']
- exp_shape = np.array([1, 21, 35, 35])
-
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- # Check that after double infer shape and pad attrs do not changes
- Convolution.infer(deconv_node)
-
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_deconv_dynamic_infer_ideal(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': shape_array([1, 21, dynamic_dimension_value, 16])},
- 'conv_weights': {'shape': np.array([1, 21, 4, 4]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {#'spatial_dims': np.array([2, 3]), 'batch_dims': np.array([0]),
- 'channel_dims': np.array([1]), 'bias_addable': True, 'bias_term': False,
- 'batch_dims': np.array([0]),
- 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'kernel_spatial': np.array([4, 4]), 'output_spatial_shape': None,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'output_padding': np.array([0, 0, 1, 1]),
- 'type': 'Deconvolution', 'output': 21, 'dilation': np.array([1, 1, 1, 1]),
- 'group': 1, 'stride': np.array([1, 1, 2, 2]), 'output_shape': None}
- })
-
- deconv_node = Node(graph, 'conv_node')
-
- Convolution.infer(deconv_node)
- res_shape = deconv_node['output_shape']
- exp_shape = shape_array([1, 21, dynamic_dimension_value, 35])
-
- self.assertTrue(strict_compare_tensors(exp_shape, res_shape))
-
- # Check that after double infer shape and pad attrs do not changes
- Convolution.infer(deconv_node)
-
- self.assertTrue(strict_compare_tensors(exp_shape, res_shape))
-
- def test_deconv_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': None},
- 'conv_weights': {'shape': np.array([1, 21, 16, 16]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {'spatial_dims': np.array([2, 3]), 'batch_dims': np.array([0]),
- 'channel_dims': np.array([1]),
- 'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'kernel_spatial': np.array([4, 4]), 'output_spatial_shape': None,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'type': 'Deconvolution', 'output': 21, 'dilation': np.array([1, 1, 1, 1]),
- 'group': 1, 'stride': np.array([1, 1, 2, 2]), 'output_shape': None}
- })
-
- deconv_node = Node(graph, 'conv_node')
- with self.assertRaisesRegex(Error, "Input data shape is None for node.*"):
- Convolution.infer(deconv_node)
-
- def test_conv_infer_set_default_attrs_nchw(self):
- graph = build_graph(nodes_attributes,
- [
- ('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {
- 'conv_output': {
- 'shape': None
- },
- 'conv_input': {
- 'shape': int64_array([1, 3, 224, 224])
- },
- 'conv_weights': {
- 'shape': int64_array([3, 64, 7, 7]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']
- },
- 'conv_node': {
- 'type': 'Convolution',
- 'bias_term': None,
- 'stride': None,
- 'dilation': None,
-
- 'batch_dims': int64_array([0]),
- 'channel_dims': int64_array([1]),
-
- 'output_spatial_shape': None,
-
- 'input_feature_channel': 0,
- 'output_feature_channel': 1,
-
- 'group': 1,
- 'output_shape': None,
- 'layout': 'NCHW'
- }
- })
-
- conv_node = Node(graph, 'conv_node')
- conv_output = Node(graph, 'conv_output')
-
- Convolution.infer(conv_node)
-
- # Check bias_term attribute
- self.assertTrue(conv_node.has_valid('bias_term'))
- self.assertTrue(not conv_node.bias_term)
- # Check kernel_spatial_idx attr detection
- self.assertTrue(conv_node.has_valid('kernel_spatial_idx'))
- self.assertTrue(np.array_equal(int64_array([2, 3]), conv_node.kernel_spatial_idx))
- # Check spatial_dims attr detection
- self.assertTrue(conv_node.has_valid('spatial_dims'))
- self.assertTrue(np.array_equal(int64_array([2, 3]), conv_node.spatial_dims))
- # Check kernel_spatial attr detection
- self.assertTrue(conv_node.has_valid('kernel_spatial'))
- self.assertTrue(np.array_equal(int64_array([7, 7]), conv_node.kernel_spatial))
- # Check output attribute
- self.assertTrue(conv_node.has_valid('output'))
- self.assertEqual(64, conv_node.output)
- # Check dilation value. Should be set to default
- self.assertTrue(conv_node.has_valid('dilation'))
- self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.dilation))
- # Check stride value. Should be set to default
- self.assertTrue(conv_node.has_valid('stride'))
- self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.stride))
- # Check pad value. Should be set to default
- self.assertTrue(conv_node.has_valid('pad'))
- self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0], [0, 0]]), conv_node.pad))
- # Check pad_spatial_shape
- self.assertTrue(conv_node.has_valid('pad_spatial_shape'))
- self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0]]), conv_node.pad_spatial_shape))
- # Check resulting output shape
- self.assertTrue(np.array_equal(int64_array([1, 64, 218, 218]), conv_output.shape))
-
- def test_conv_infer_set_default_attrs_nhwc(self):
- graph = build_graph(nodes_attributes,
- [
- ('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {
- 'conv_output': {
- 'shape': None
- },
- 'conv_input': {
- 'shape': int64_array([1, 224, 224, 3])
- },
- 'conv_weights': {
- 'shape': int64_array([3, 64, 7, 7]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']
- },
- 'conv_node': {
- 'type': 'Convolution',
- 'bias_term': None,
- 'stride': None,
- 'dilation': None,
-
- 'batch_dims': int64_array([0]),
- 'channel_dims': int64_array([3]),
-
- 'output_spatial_shape': None,
-
- 'input_feature_channel': 0,
- 'output_feature_channel': 1,
-
- 'group': 1,
- 'output_shape': None,
- 'layout': 'NHWC'
- }
- })
-
- conv_node = Node(graph, 'conv_node')
- conv_output = Node(graph, 'conv_output')
-
- Convolution.infer(conv_node)
-
- # Check bias_term attribute
- self.assertTrue(conv_node.has_valid('bias_term'))
- self.assertTrue(not conv_node.bias_term)
- # Check kernel_spatial_idx attr detection
- self.assertTrue(conv_node.has_valid('kernel_spatial_idx'))
- self.assertTrue(np.array_equal(int64_array([2, 3]), conv_node.kernel_spatial_idx))
- # Check spatial_dims attr detection
- self.assertTrue(conv_node.has_valid('spatial_dims'))
- self.assertTrue(np.array_equal(int64_array([1, 2]), conv_node.spatial_dims))
- # Check kernel_spatial attr detection
- self.assertTrue(conv_node.has_valid('kernel_spatial'))
- self.assertTrue(np.array_equal(int64_array([7, 7]), conv_node.kernel_spatial))
- # Check output attribute
- self.assertTrue(conv_node.has_valid('output'))
- self.assertEqual(64, conv_node.output)
- # Check dilation value. Should be set to default
- self.assertTrue(conv_node.has_valid('dilation'))
- self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.dilation))
- # Check stride value. Should be set to default
- self.assertTrue(conv_node.has_valid('stride'))
- self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1]), conv_node.stride))
- # Check pad value. Should be set to default
- self.assertTrue(conv_node.has_valid('pad'))
- self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0], [0, 0]]), conv_node.pad))
- # Check pad_spatial_shape
- self.assertTrue(conv_node.has_valid('pad_spatial_shape'))
- self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0]]), conv_node.pad_spatial_shape))
- # Check resulting output shape
- self.assertTrue(np.array_equal(int64_array([1, 218, 218, 64]), conv_output.shape))
-
- def test_conv_infer_3D_convolution(self):
- graph = build_graph(nodes_attributes,
- [
- ('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {
- 'conv_output': {
- 'shape': None
- },
- 'conv_input': {
- 'shape': int64_array([1, 3, 16, 224, 224])
- },
- 'conv_weights': {
- 'shape': int64_array([3, 64, 1, 7, 7]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']
- },
- 'conv_node': {
- 'type': 'Convolution',
- 'bias_term': None,
- 'stride': None,
- 'dilation': None,
-
- 'batch_dims': int64_array([0]),
- 'channel_dims': int64_array([1]),
-
- 'output_spatial_shape': None,
-
- 'input_feature_channel': 0,
- 'output_feature_channel': 1,
-
- 'group': 1,
- 'output_shape': None,
- 'layout': 'NCHW'
- }
- })
-
- conv_node = Node(graph, 'conv_node')
- conv_output = Node(graph, 'conv_output')
-
- Convolution.infer(conv_node)
-
- # Check bias_term attribute
- self.assertTrue(conv_node.has_valid('bias_term'))
- self.assertTrue(not conv_node.bias_term)
- # Check kernel_spatial_idx attr detection
- self.assertTrue(conv_node.has_valid('kernel_spatial_idx'))
- self.assertTrue(np.array_equal(int64_array([2, 3, 4]), conv_node.kernel_spatial_idx))
- # Check spatial_dims attr detection
- self.assertTrue(conv_node.has_valid('spatial_dims'))
- self.assertTrue(np.array_equal(int64_array([2, 3, 4]), conv_node.spatial_dims))
- # Check kernel_spatial attr detection
- self.assertTrue(conv_node.has_valid('kernel_spatial'))
- self.assertTrue(np.array_equal(int64_array([1, 7, 7]), conv_node.kernel_spatial))
- # Check output attribute
- self.assertTrue(conv_node.has_valid('output'))
- self.assertEqual(64, conv_node.output)
- # Check dilation value. Should be set to default
- self.assertTrue(conv_node.has_valid('dilation'))
- self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1, 1]), conv_node.dilation))
- # Check stride value. Should be set to default
- self.assertTrue(conv_node.has_valid('stride'))
- self.assertTrue(np.array_equal(int64_array([1, 1, 1, 1, 1]), conv_node.stride))
- # Check pad value. Should be set to default
- self.assertTrue(conv_node.has_valid('pad'))
- self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]), conv_node.pad))
- # Check pad_spatial_shape
- self.assertTrue(conv_node.has_valid('pad_spatial_shape'))
- self.assertTrue(np.array_equal(int64_array([[0, 0], [0, 0], [0, 0]]), conv_node.pad_spatial_shape))
- # Check resulting output shape
- self.assertTrue(np.array_equal(int64_array([1, 64, 16, 218, 218]), conv_output.shape))
-
- def test_caffe_conv2d_infer_wrong_input_shape(self):
- graph = build_graph(nodes_attributes,
- [('conv_input', 'conv_node'),
- ('conv_weights', 'conv_node'),
- ('conv_node', 'conv_output'),
- ('conv_output', 'op_output')
- ],
- {'conv_output': {'shape': None},
- 'conv_input': {'shape': np.array([1, 3, 1, 1])},
- 'conv_weights': {'shape': np.array([64, 3, 3, 3]),
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'conv_node': {'pad_spatial_shape': np.array([[0, 0], [0, 0]]),
- 'conv_pad': np.array([[0, 0], [0, 0], [0, 0], [0, 0]]),
- 'dilation': np.array([1, 1, 1, 1]), 'bias_addable': True, 'bias_term': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'stride': np.array([1, 1, 1, 1]), 'group': 1,
- 'kernel_spatial_idx': np.array([2, 3]),
- 'input_feature_channel': 1,
- 'output_feature_channel': 0,
- 'output': 64, 'kernel_spatial': np.array([3, 3]),
- 'spatial_dims': np.array([2, 3]), 'channel_dims': np.array([1]),
- 'batch_dims': np.array([0])}
- })
-
- conv_node = Node(graph, 'conv_node')
- with self.assertRaises(Error):
- Convolution.infer(conv_node)
diff --git a/tools/mo/unit_tests/mo/ops/crop_test.py b/tools/mo/unit_tests/mo/ops/crop_test.py
deleted file mode 100644
index 71bc61e9e27e08..00000000000000
--- a/tools/mo/unit_tests/mo/ops/crop_test.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.crop import Crop
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-
-class TestCropPartialInfer(unittest.TestCase):
- @staticmethod
- def _create_graph_type1():
- nodes_attributes = {'crop_input': {'shape': None, 'value': None, 'kind': 'data'},
- 'crop_node': {'op': 'Crop', 'kind': 'op'},
- 'crop_output': {'shape': None, 'value': None, 'kind': 'data'}
- }
- return build_graph(nodes_attributes,
- [
- ('crop_input', 'crop_node'), ('crop_node', 'crop_output')
- ],
- {
- 'crop_input': {'shape': int64_array([1, 3, 224, 224])},
- 'crop_node': {'axis': int64_array([2, 3]),
- 'crop_begin': int64_array([10, 15]),
- 'crop_end': int64_array([10, 15])
- },
- })
-
- @staticmethod
- def _create_graph_type2():
- nodes_attributes = {'crop_input': {'shape': None, 'value': None, 'kind': 'data'},
- 'crop_node': {'op': 'Crop', 'kind': 'op'},
- 'crop_output': {'shape': None, 'value': None, 'kind': 'data'}
- }
- return build_graph(nodes_attributes,
- [
- ('crop_input', 'crop_node'), ('crop_node', 'crop_output')
- ],
- {
- 'crop_input': {'shape': int64_array([1, 3, 224, 224])},
- 'crop_node': {'axis': int64_array([2, 3]), 'dim': int64_array([100, 150])},
- })
-
- @staticmethod
- def _create_graph_type3():
- nodes_attributes = {'crop_input': {'shape': None, 'value': None, 'kind': 'data'},
- 'crop_input2': {'shape': None, 'value': None, 'kind': 'data'},
- 'crop_node': {'op': 'Crop', 'kind': 'op'},
- 'crop_output': {'shape': None, 'value': None, 'kind': 'data'}
- }
- return build_graph(nodes_attributes,
- [
- ('crop_input', 'crop_node'), ('crop_input2', 'crop_node'), ('crop_node', 'crop_output')
- ],
- {
- 'crop_input': {'shape': int64_array([1, 3, 224, 224])},
- 'crop_input2': {'shape': int64_array([1, 3, 100, 150])},
- 'crop_node': {'axis': 2, 'offset': int64_array([10, 15])},
- })
-
- def test_crop_type1_infer(self):
- graph = self._create_graph_type1()
-
- crop_node = Node(graph, 'crop_node')
- Crop.infer(crop_node)
-
- exp_shape = int64_array([1, 3, 204, 194])
- res_shape = graph.node['crop_output']['shape']
-
- self.assertTrue(np.array_equal(exp_shape, res_shape),
- 'shapes do not match expected: {} and given: {}'.format(exp_shape, res_shape))
-
- def test_crop_type1_infer_neg1(self):
- graph = self._create_graph_type1()
-
- crop_node = Node(graph, 'crop_node')
- crop_node['axis'] = None
-
- with self.assertRaisesRegex(Error, "axis attribute is missing .*"):
- Crop.infer(crop_node)
-
- def test_crop_type1_infer_neg2(self):
- graph = self._create_graph_type1()
-
- crop_node = Node(graph, 'crop_node')
- crop_node['crop_begin'] = int64_array([1, 2, 3])
-
- with self.assertRaisesRegex(Error, "number of crop_begin.*"):
- Crop.infer(crop_node)
-
- def test_crop_type2_infer(self):
- graph = self._create_graph_type2()
-
- crop_node = Node(graph, 'crop_node')
- Crop.infer(crop_node)
-
- exp_shape = int64_array([1, 3, 100, 150])
- res_shape = graph.node['crop_output']['shape']
-
- self.assertTrue(np.array_equal(exp_shape, res_shape),
- 'shapes do not match expected: {} and given: {}'.format(exp_shape, res_shape))
-
- def test_crop_type2_infer_neg1(self):
- graph = self._create_graph_type2()
-
- crop_node = Node(graph, 'crop_node')
- crop_node['dim'] = int64_array([1, 2, 3])
-
- with self.assertRaisesRegex(Error, "Number of axis.*"):
- Crop.infer(crop_node)
-
- def test_crop_type2_infer_neg2(self):
- graph = self._create_graph_type2()
-
- crop_node = Node(graph, 'crop_node')
- crop_node['dim'] = None
- crop_node['crop_begin'] = None
-
- with self.assertRaisesRegex(Error, "Crop node crop_node should have either.*"):
- Crop.infer(crop_node)
-
- def test_crop_type3_infer(self):
- graph = self._create_graph_type3()
-
- crop_node = Node(graph, 'crop_node')
- Crop.infer(crop_node)
-
- exp_shape = int64_array([1, 3, 100, 150])
- res_shape = graph.node['crop_output']['shape']
-
- self.assertTrue(np.array_equal(exp_shape, res_shape),
- 'shapes do not match expected: {} and given: {}'.format(exp_shape, res_shape))
-
- def test_crop_type3_infer_neg1(self):
- graph = self._create_graph_type3()
-
- crop_node = Node(graph, 'crop_node')
- crop_input2 = Node(graph, 'crop_input2')
- crop_input2.shape = None
-
- with self.assertRaisesRegex(Error, "Not all input shapes were defined.*"):
- Crop.infer(crop_node)
-
- def test_crop_type3_infer_neg2(self):
- graph = self._create_graph_type3()
-
- crop_node = Node(graph, 'crop_node')
- crop_node['axis'] = None
-
- with self.assertRaisesRegex(Error, "axis attribute is missing for .*"):
- Crop.infer(crop_node)
-
- def test_crop_type3_infer_neg3(self):
- graph = self._create_graph_type3()
-
- crop_node = Node(graph, 'crop_node')
- crop_node['offset'] = None
-
- with self.assertRaisesRegex(Error, "offset attribute is missing.*"):
- Crop.infer(crop_node)
-
- def test_crop_type3_infer_neg4(self):
- graph = self._create_graph_type3()
-
- crop_node = Node(graph, 'crop_node')
- crop_input2 = Node(graph, 'crop_input2')
- crop_input2.shape = int64_array([1, 4, 423, 563])
-
- with self.assertRaisesRegex(Error, "The crop for dimension is out of bounds.*"):
- Crop.infer(crop_node)
diff --git a/tools/mo/unit_tests/mo/ops/ctc_greedy_decoder_test.py b/tools/mo/unit_tests/mo/ops/ctc_greedy_decoder_test.py
deleted file mode 100644
index 5e1ab46dc3d419..00000000000000
--- a/tools/mo/unit_tests/mo/ops/ctc_greedy_decoder_test.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.ctc_greedy_decoder_seq_len import CTCGreedyDecoderSeqLenOp
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-nodes_attributes = {'logits': {'kind': 'op'},
- 'logits_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'seq_mask': {'kind': 'op'},
- 'seq_mask_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'ctcgreedydecoder_node': {'op': 'CTCGreedyDecoderSeqLen', 'kind': 'op',
- 'ctc_merge_repeated': True},
- 'output1': {'shape': None, 'value': None, 'kind': 'data'},
- 'last_output1': {'shape': None, 'value': None, 'kind': 'op'},
- 'output2': {'shape': None, 'value': None, 'kind': 'data'}
- }
-
-# graph 1
-edges1 = [('logits', 'logits_data'),
- ('seq_mask', 'seq_mask_data'),
- ('logits_data', 'ctcgreedydecoder_node', {'in': 0}),
- ('seq_mask_data', 'ctcgreedydecoder_node', {'in': 1}),
- ('ctcgreedydecoder_node', 'output1', {'out': 0}),
- ('ctcgreedydecoder_node', 'output2', {'out': 1}),
- ('output1', 'last_output1', {'out': 0}),]
-
-# valid test case
-inputs1 = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'seq_mask_data': {'shape': int64_array([4])}}
-
-# invalid test case with incorrect rank for the first input tensor
-inputs1_inv = {'logits_data': {'shape': int64_array([4, 100, 5, 6])},
- 'seq_mask_data': {'shape': int64_array([4])}}
-
-# invalid test case with incorrect rank for the second input tensor
-inputs2_inv = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'seq_mask_data': {'shape': int64_array([4, 100])}}
-
-# invalid test case with incorrect time dimension
-inputs3_inv = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'seq_mask_data': {'shape': int64_array([4, 101])}}
-
-# invalid test case with incorrect batch dimension
-inputs4_inv = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'seq_mask_data': {'shape': int64_array([14, 100])}}
-
-class TestCTCGreedyDecoder(unittest.TestCase):
- def test_infer1(self):
- graph = build_graph(nodes_attributes, edges1, inputs1)
- ctcgreedydecoder_node = Node(graph, 'ctcgreedydecoder_node')
- CTCGreedyDecoderSeqLenOp.infer(ctcgreedydecoder_node)
-
- # prepare reference results
- ref_output1_shape = int64_array([4, 100])
-
- # get the result
- res_output1_shape = graph.node['output1']['shape']
-
- self.assertTrue(np.array_equal(ref_output1_shape, res_output1_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output1_shape, res_output1_shape))
-
- def test_infer_invalid1(self):
- graph = build_graph(nodes_attributes, edges1, inputs1_inv)
- ctcgreedydecoder_node = Node(graph, 'ctcgreedydecoder_node')
- self.assertRaises(AssertionError, CTCGreedyDecoderSeqLenOp.infer, ctcgreedydecoder_node)
-
- def test_infer_invalid2(self):
- graph = build_graph(nodes_attributes, edges1, inputs2_inv)
- ctcgreedydecoder_node = Node(graph, 'ctcgreedydecoder_node')
- self.assertRaises(AssertionError, CTCGreedyDecoderSeqLenOp.infer, ctcgreedydecoder_node)
-
- def test_infer_invalid3(self):
- graph = build_graph(nodes_attributes, edges1, inputs3_inv)
- ctcgreedydecoder_node = Node(graph, 'ctcgreedydecoder_node')
- self.assertRaises(AssertionError, CTCGreedyDecoderSeqLenOp.infer, ctcgreedydecoder_node)
-
- def test_infer_invalid4(self):
- graph = build_graph(nodes_attributes, edges1, inputs4_inv)
- ctcgreedydecoder_node = Node(graph, 'ctcgreedydecoder_node')
- self.assertRaises(AssertionError, CTCGreedyDecoderSeqLenOp.infer, ctcgreedydecoder_node)
diff --git a/tools/mo/unit_tests/mo/ops/ctc_loss_test.py b/tools/mo/unit_tests/mo/ops/ctc_loss_test.py
deleted file mode 100644
index 9b7f8d782c1a29..00000000000000
--- a/tools/mo/unit_tests/mo/ops/ctc_loss_test.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.ctc_loss import CTCLoss
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'logits': {'kind': 'op'},
- 'logits_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'logit_length': {'kind': 'op'},
- 'logit_length_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'labels': {'kind': 'op'},
- 'labels_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'label_length': {'kind': 'op'},
- 'label_length_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'blank_index': {'kind': 'op'},
- 'blank_index_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'ctcloss_node': {'op': 'CTCLoss', 'kind': 'op', 'preprocess_collapse_repeated': False,
- 'ctc_merge_repeated': True, 'unique': False},
- 'output': {'shape': None, 'value': None, 'kind': 'data'}}
-
-# graph 1
-edges1 = [('logits', 'logits_data'),
- ('logit_length', 'logit_length_data'),
- ('labels', 'labels_data'),
- ('label_length', 'label_length_data'),
- ('blank_index', 'blank_index_data'),
- ('logits_data', 'ctcloss_node', {'in': 0}),
- ('logit_length_data', 'ctcloss_node', {'in': 1}),
- ('labels_data', 'ctcloss_node', {'in': 2}),
- ('label_length_data', 'ctcloss_node', {'in': 3}),
- ('blank_index_data', 'ctcloss_node', {'in': 4}),
- ('ctcloss_node', 'output', {'out': 0})]
-
-# valid test case
-inputs1 = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'logit_length_data': {'shape': int64_array([4])},
- 'labels_data': {'shape': int64_array([4, 100])},
- 'label_length_data': {'shape': int64_array([4])},
- 'blank_index_data': {'shape': int64_array([])}}
-
-# invalid test case with incorrect rank for the second input tensor
-inputs2 = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'logit_length_data': {'shape': int64_array([4, 3])},
- 'labels_data': {'shape': int64_array([4, 100])},
- 'label_length_data': {'shape': int64_array([4])},
- 'blank_index_data': {'shape': int64_array([])}}
-
-# invalid test case with incorrect time dimension
-inputs3 = {'logits_data': {'shape': int64_array([4, 100, 5])},
- 'logit_length_data': {'shape': int64_array([4])},
- 'labels_data': {'shape': int64_array([4, 300])},
- 'label_length_data': {'shape': int64_array([4])},
- 'blank_index_data': {'shape': int64_array([])}}
-
-class TestCTCLoss(unittest.TestCase):
- def test_infer1(self):
- graph = build_graph(nodes_attributes, edges1, inputs1)
- ctc_loss_node = Node(graph, 'ctcloss_node')
- CTCLoss.infer(ctc_loss_node)
-
- # prepare reference results
- ref_output_shape = int64_array([4])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_infer_invalid1(self):
- graph = build_graph(nodes_attributes, edges1, inputs2)
- ctc_loss_node = Node(graph, 'ctcloss_node')
- self.assertRaises(AssertionError, CTCLoss.infer, ctc_loss_node)
-
- def test_infer_invalid2(self):
- graph = build_graph(nodes_attributes, edges1, inputs3)
- ctc_loss_node = Node(graph, 'ctcloss_node')
- self.assertRaises(AssertionError, CTCLoss.infer, ctc_loss_node)
diff --git a/tools/mo/unit_tests/mo/ops/cumsum_test.py b/tools/mo/unit_tests/mo/ops/cumsum_test.py
deleted file mode 100644
index a87c6f5da48cb9..00000000000000
--- a/tools/mo/unit_tests/mo/ops/cumsum_test.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.cumsum import CumSum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, valued_const_with_data, regular_op_with_shaped_data, result, connect
-
-nodes_attributes = {
- **regular_op_with_shaped_data('data', [1, 3, 224, 224], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.float32}}),
- **valued_const_with_data('axis', int64_array(0)),
- **regular_op_with_shaped_data('cumsum', None, {'op': 'CumSum', 'type': 'CumSum', 'name': 'cumsum'}),
- **regular_op_with_shaped_data('identity', None, {'op': 'Identity', 'name': 'identity'}),
- **result('output'),
-}
-
-
-class TestCumSum(unittest.TestCase):
- def test_cumsum_axis(self):
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:cumsum'),
- *connect('axis', '1:cumsum'),
- *connect('cumsum', '0:identity'),
- ('identity', 'identity_d', {'out': 0}),
- ('identity_d', 'output'),
- ],
- {'cumsum': {'reverse': False, 'exclusive': False}
- }, nodes_with_edges_only=True)
-
- cumsum_node = Node(graph, 'cumsum')
- CumSum.infer(cumsum_node)
- self.assertTrue(np.array_equal(cumsum_node.out_port(0).data.get_shape(), int64_array([1, 3, 224, 224])))
-
- def test_cumsum_value_prop(self):
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:cumsum'),
- *connect('axis', '1:cumsum'),
- ('cumsum', 'cumsum_d', {'out': 0}),
- ('cumsum_d', 'output'),
- ],
- {'data_d': {'value': np.array([1., 2., 3., 4., 5.]).astype(np.float32), 'shape': [5]},
- 'cumsum': {'reverse': False, 'exclusive': False}
- }, nodes_with_edges_only=True)
-
- cumsum_node = Node(graph, 'cumsum')
- CumSum.infer(cumsum_node)
- self.assertTrue(np.array_equal(cumsum_node.out_port(0).data.get_value(),
- np.array([1., 3., 6., 10., 15.]).astype(np.float32)))
-
- def test_cumsum_value_prop_exclusive(self):
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:cumsum'),
- *connect('axis', '1:cumsum'),
- ('cumsum', 'cumsum_d', {'out': 0}),
- ('cumsum_d', 'output'),
- ],
- {'data_d': {'value': np.array([1., 2., 3., 4., 5.]).astype(np.float32), 'shape': [5]},
- 'cumsum': {'reverse': False, 'exclusive': True}
- }, nodes_with_edges_only=True)
-
- cumsum_node = Node(graph, 'cumsum')
- CumSum.infer(cumsum_node)
- self.assertTrue(np.array_equal(cumsum_node.out_port(0).data.get_value(),
- np.array([0., 1., 3., 6., 10.]).astype(np.float32)))
-
- def test_cumsum_value_prop_reverse(self):
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:cumsum'),
- *connect('axis', '1:cumsum'),
- ('cumsum', 'cumsum_d', {'out': 0}),
- ('cumsum_d', 'output'),
- ],
- {'data_d': {'value': np.array([1., 2., 3., 4., 5.]).astype(np.float32), 'shape': [5]},
- 'cumsum': {'reverse': True, 'exclusive': False}
- }, nodes_with_edges_only=True)
-
- cumsum_node = Node(graph, 'cumsum')
- CumSum.infer(cumsum_node)
- self.assertTrue(np.array_equal(cumsum_node.out_port(0).data.get_value(),
- np.array([15., 14., 12., 9., 5.]).astype(np.float32)))
-
- def test_cumsum_value_prop_exclusive_reverse(self):
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:cumsum'),
- *connect('axis', '1:cumsum'),
- ('cumsum', 'cumsum_d', {'out': 0}),
- ('cumsum_d', 'output'),
- ],
- {'data_d': {'value': np.array([1., 2., 3., 4., 5.]).astype(np.float32), 'shape': [5]},
- 'cumsum': {'reverse': True, 'exclusive': True}
- }, nodes_with_edges_only=True)
-
- cumsum_node = Node(graph, 'cumsum')
- CumSum.infer(cumsum_node)
- self.assertTrue(np.array_equal(cumsum_node.out_port(0).data.get_value(),
- np.array([14., 12., 9., 5., 0.]).astype(np.float32)))
-
- def test_cumsum_value_prop_axis_1(self):
- graph = build_graph(nodes_attributes,
- [*connect('data', '0:cumsum'),
- *connect('axis', '1:cumsum'),
- ('cumsum', 'cumsum_d', {'out': 0}),
- ('cumsum_d', 'output'),
- ],
- {'data_d': {'value': np.array([[1., 2., 3.], [4., 5., 6.]]).astype(np.float32),
- 'shape': [2, 3]},
- 'axis_d': {'value': int64_array(1),
- 'shape': []},
- 'cumsum': {'reverse': False, 'exclusive': False}
- }, nodes_with_edges_only=True)
-
- cumsum_node = Node(graph, 'cumsum')
- CumSum.infer(cumsum_node)
- self.assertTrue(np.array_equal(cumsum_node.out_port(0).data.get_value(),
- np.array([[1., 3., 6.], [4., 9., 15.]]).astype(np.float32)))
diff --git a/tools/mo/unit_tests/mo/ops/deconvolution_test.py b/tools/mo/unit_tests/mo/ops/deconvolution_test.py
deleted file mode 100644
index ed99f87f029b1c..00000000000000
--- a/tools/mo/unit_tests/mo/ops/deconvolution_test.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.front.tf.deconv_ext import get_conv_backprop_groups
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.deconvolution import Deconvolution
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'deconv_input': {'value': None, 'kind': 'data'},
- 'deconv_weights': {'value': None, 'kind': 'data'},
- 'deconv_output_shape': {'value': None, 'kind': 'data'},
- 'deconv_node': {'type': 'Deconvolution', 'op': 'Deconvolution', 'kind': 'op'},
- 'deconv_output': {'value': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'}
- }
-
-
-def create_deconv_graph(input_shape: int64_array, weights_shape: int64_array, output_shape: int64_array):
- graph = build_graph(nodes_attributes,
- [('deconv_input', 'deconv_node'),
- ('deconv_weights', 'deconv_node'),
- ('deconv_output_shape', 'deconv_node'),
- ('deconv_node', 'deconv_output'),
- ('deconv_output', 'op_output')
- ],
- {'deconv_input': {'shape': input_shape},
- 'deconv_weights': {'shape': weights_shape,
- 'dim_attrs': ['spatial_dims', 'channel_dims', 'batch_dims', 'axis']},
- 'deconv_output_shape': {'value': output_shape},
- 'deconv_node': {'channel_dims': int64_array([1]),
- 'batch_dims': int64_array([0]),
- 'spatial_dims': int64_array([2, 3]),
- 'pad_spatial_shape': int64_array([[0, 0], [0, 0]]),
- 'kernel_spatial': int64_array([4, 4]),
- 'kernel_spatial_idx': int64_array([2, 3]),
- 'input_feature_channel': 0,
- 'output_feature_channel': 1,
- 'auto_pad': 'same_lower',
- 'output_padding': int64_array([0, 0, 1, 1]),
- 'type': 'Deconvolution',
- 'dilation': int64_array([1, 1, 1, 1]),
- 'stride': int64_array([1, 1, 2, 2]),
- 'pad': None,
- 'output': None,
- 'output_shape': None,
- 'get_group': get_conv_backprop_groups},
- 'deconv_output': {'shape': None},
- })
- return graph
-
-
-class TestConvolutionPartialInfer(unittest.TestCase):
- def test_deconv_infer_one_group(self):
- graph = create_deconv_graph(int64_array([1, 21, 18, 18]), int64_array([21, 50, 4, 4]),
- int64_array([1, 50, 35, 35]))
-
- Deconvolution.infer(Node(graph, 'deconv_node'))
- res_shape = graph.node['deconv_output']['shape']
- exp_shape = np.array([1, 50, 35, 35])
-
- res_group = graph.node['deconv_node']['group']
- exp_group = int64_array([1])
-
- self.assertTrue(np.array_equal(exp_shape, res_shape),
- 'values do not match expected: {} and computed: {}'.format(exp_shape, res_shape))
-
- self.assertTrue(np.array_equal(exp_group, res_group),
- 'group number values do not match expected: {} and computed: {}'.format(exp_group, res_group))
-
- def test_deconv_infer_several_groups(self):
- graph = create_deconv_graph(int64_array([1, 21, 18, 18]), int64_array([21, 50, 4, 4]),
- int64_array([1, 350, 35, 35]))
-
- Deconvolution.infer(Node(graph, 'deconv_node'))
- res_shape = graph.node['deconv_output']['shape']
- exp_shape = np.array([1, 350, 35, 35])
-
- res_group = graph.node['deconv_node']['group']
- exp_group = int64_array([7])
-
- self.assertTrue(np.array_equal(exp_shape, res_shape),
- 'values do not match expected: {} and computed: {}'.format(exp_shape, res_shape))
-
- self.assertTrue(np.array_equal(exp_group, res_group),
- 'group number values do not match expected: {} and computed: {}'.format(exp_group, res_group))
diff --git a/tools/mo/unit_tests/mo/ops/depth_to_space_test.py b/tools/mo/unit_tests/mo/ops/depth_to_space_test.py
deleted file mode 100644
index 7e9379101f0ce2..00000000000000
--- a/tools/mo/unit_tests/mo/ops/depth_to_space_test.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-import numpy as np
-from openvino.tools.mo.ops.depth_to_space import DepthToSpaceOp
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-nodes = {
- 'in_data_node': {'value': None, 'kind': 'data', 'shape': np.array([1, 1024, 576, 256])},
- 'DtS': {'op': 'DepthToSpace', 'kind': 'op', 'block_size': 2},
- 'out_data_node': {'value': None, 'kind': 'data', 'shape': None}
-}
-
-edges = [
- ('in_data_node', 'DtS'),
- ('DtS', 'out_data_node')
-]
-
-
-class TestDepthToSpacePartialInfer(unittest.TestCase):
- def test_tf_depth_to_space_infer_nhwc(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NHWC'
- dts_node = Node(graph, 'DtS')
- DepthToSpaceOp.infer(dts_node)
- exp_shape = np.array([1, 2048, 1152, 64])
- res_shape = graph.node['out_data_node']['shape']
- self.assertTrue(np.array_equal(exp_shape, res_shape))
-
- def test_tf_depth_to_space_infer_nchw(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NCHW'
- graph.node['in_data_node']['shape'] = np.array([1, 256, 1024, 576])
- dts_node = Node(graph, 'DtS')
- DepthToSpaceOp.infer(dts_node)
- exp_shape = np.array([1, 64, 2048, 1152])
- res_shape = graph.node['out_data_node']['shape']
- self.assertTrue(np.array_equal(exp_shape, res_shape))
-
- def test_tf_depth_to_space_infer_error(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NHWC'
- graph.node['in_data_node']['shape'] = np.array([1024, 576, 256])
- dts_node = Node(graph, 'DtS')
- self.assertRaises(Error, DepthToSpaceOp.infer, dts_node)
-
- def test_tf_depth_to_space_infer_divisibility_error_1(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NHWC'
- graph.node['in_data_node']['shape'] = np.array([1, 1024, 576, 255])
- dts_node = Node(graph, 'DtS')
- self.assertRaises(Error, DepthToSpaceOp.infer, dts_node)
-
- def test_tf_depth_to_space_infer_divisibility_error_2(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NCHW'
- graph.node['in_data_node']['shape'] = np.array([1, 255, 1024, 576])
- dts_node = Node(graph, 'DtS')
- self.assertRaises(Error, DepthToSpaceOp.infer, dts_node)
-
diff --git a/tools/mo/unit_tests/mo/ops/dft_signal_size_canonicalization_test.py b/tools/mo/unit_tests/mo/ops/dft_signal_size_canonicalization_test.py
deleted file mode 100644
index c28adc5d0da168..00000000000000
--- a/tools/mo/unit_tests/mo/ops/dft_signal_size_canonicalization_test.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.dft import FFTBase
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-
-
-class TestDFTSignalSizeCanonicalizationTest():
- @pytest.mark.parametrize("signal_size, axes, input_shape, expected_result",[
- (int64_array([-1, 77]), int64_array([1, 2]), int64_array([2, 180, 180, 2]), int64_array([180, 77])),
- (int64_array([390, 87]), int64_array([2, 0]), int64_array([2, 180, 180, 2]), int64_array([390, 87])),
- (int64_array([600, -1, 40]),
- int64_array([3, 0, 1]),
- int64_array([7, 50, 130, 400, 2]),
- int64_array([600, 7, 40])),
- (int64_array([-1, 16, -1]),
- int64_array([3, 0, 2]),
- int64_array([7, 50, 130, 400, 2]),
- int64_array([400, 16, 130])),
- (int64_array([16, -1, -1]),
- int64_array([3, 0, 2]),
- int64_array([7, 50, 130, 400, 2]),
- int64_array([16, 7, 130])),
- (int64_array([-1, -1, 16]),
- int64_array([3, 0, 2]),
- int64_array([7, 50, 130, 400, 2]),
- int64_array([400, 7, 16])),
- (int64_array([-1, -1, -1]),
- int64_array([3, 0, 2]),
- int64_array([7, 50, 130, 400, 2]),
- int64_array([400, 7, 130])),
- ])
- def test_canonicalization(self, signal_size, axes, input_shape, expected_result):
- canonicalized_signal_size = FFTBase.canonicalize_signal_size(signal_size, axes, input_shape)
- assert np.array_equal(canonicalized_signal_size, expected_result)
diff --git a/tools/mo/unit_tests/mo/ops/div_value_propagation_test.py b/tools/mo/unit_tests/mo/ops/div_value_propagation_test.py
deleted file mode 100644
index 3fd2b200e714bb..00000000000000
--- a/tools/mo/unit_tests/mo/ops/div_value_propagation_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Div
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-graph_nodes_attrs = {
- 'A': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'A_data': {'kind': 'data', 'shape': None, 'value': None},
- 'B': {'type': 'Const', 'op': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'B_data': {'kind': 'data', 'shape': None, 'value': None, 'dim_attrs': []},
- 'div': {'type': 'Divide', 'op': 'Div', 'kind': 'op'},
- 'div_data': {'kind': 'data', 'value': None, 'shape': None},
- 'output': {'kind': 'op', 'op': 'Result'},
-}
-
-
-graph_edges = [
- ('A', 'A_data'),
- ('B', 'B_data'),
- ('A_data', 'div', {'in': 0}),
- ('B_data', 'div', {'in': 1}),
- ('div', 'div_data'),
- ('div_data', 'output'),
-]
-
-
-class TestDivValuePropagation():
- @pytest.mark.parametrize("a_shape, a_value, b_shape, b_value, elem_type",[
- ([2, 3], np.array([[1, 4, -6], [0, -16, 45]], dtype=np.int64),
- [2, 3], np.array([[1, 2, -4], [1, -8, -5]], dtype=np.int64),
- np.int64),
- ([2, 3], np.array([[1, 4, -6], [0, -16, 45]], dtype=np.int64),
- [2, 3], np.array([[1, 2, -4], [1, -8, -5]], dtype=np.int64),
- np.float64),
- ([2, 3], np.array([[1, 4, -6], [0, -16, 45]], dtype=np.int64),
- [2, 3], np.array([[1, 2, -4], [1, -8, -5]], dtype=np.int64),
- np.float32),
- ([3, 3], np.array([[15, 2, 11], [14, 7, 8], [24, 12, 0]], dtype=np.int64),
- [3, 3], np.array([[-5, 4, 2], [7, 2, 4], [6, 24, 1]], dtype=np.int64),
- np.int64),
- ([3, 3], np.array([[15, 2, 11], [14, 7, 8], [24, 12, 0]], dtype=np.int64),
- [3, 3], np.array([[-5, 4, 2], [7, 2, 4], [6, 24, 1]], dtype=np.int64),
- np.float64),
- ([3, 3], np.array([[15, 2, 11], [14, 7, 8], [24, 12, 0]], dtype=np.int64),
- [3, 3], np.array([[-5, 4, 2], [7, 2, 4], [6, 24, 1]], dtype=np.int64),
- np.float32),
- ])
- def test_value_propagation(self, a_shape, a_value, b_shape, b_value, elem_type):
- graph = build_graph(
- nodes_attrs=graph_nodes_attrs,
- edges=graph_edges,
- update_attributes={
- 'A': {'shape': int64_array(a_shape), 'value': a_value.astype(elem_type)},
- 'A_data': {'shape': int64_array(a_shape), 'value': a_value.astype(elem_type)},
- 'B': {'shape': int64_array(b_shape), 'value': b_value.astype(elem_type)},
- 'B_data': {'shape': int64_array(b_shape), 'value': b_value.astype(elem_type)},
- }
- )
- node = Node(graph, 'div')
- node['infer'] = Div(graph, node.attrs()).create_node().infer
- node.infer(node)
- node_data = node.out_port(0).get_destination().data.get_value()
-
- def func_for_ref():
- if np.issubdtype(elem_type, np.integer):
- return lambda a, b: a // b
- else:
- return lambda a, b: a / b
-
- ref_data = func_for_ref()(a_value, b_value)
- node_data_shape = node_data.shape
- ref_data_shape = ref_data.shape
- msg = "Value propagation for 'div' node is not correct."
- assert node_data_shape == ref_data_shape and np.all(node_data == ref_data), msg
diff --git a/tools/mo/unit_tests/mo/ops/einsum_test.py b/tools/mo/unit_tests/mo/ops/einsum_test.py
deleted file mode 100644
index eb896425da905c..00000000000000
--- a/tools/mo/unit_tests/mo/ops/einsum_test.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.einsum import Einsum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Graph
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, result, connect
-
-
-def create_einsum_graph(input_shapes: list, equation: str) -> Graph:
- num_inputs = len(input_shapes)
- assert num_inputs > 0, "Einsum node must have at least one input"
- nodes = {}
- edges = []
- for input_ind in range(num_inputs):
- input_name = 'input' + str(input_ind)
- parameter_op = regular_op_with_shaped_data(input_name, input_shapes[input_ind],
- {'op': 'Parameter', 'type': 'Parameter'})
- nodes.update(parameter_op)
- edges += connect(input_name, str(input_ind) + ":einsum_node")
- einsum_op = regular_op_with_shaped_data('einsum_node', None,
- {'op': 'Einsum', 'type': 'Einsum', 'equation': equation})
- nodes.update(einsum_op)
- result_op = result('output')
- nodes.update(result_op)
- edges += connect('einsum_node', 'output')
-
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- return graph
-
-
-class TestEinsum():
- @pytest.mark.parametrize("input_shapes, equation, ref_output_shape",[
- # dot product
- ([int64_array([10]), int64_array([10])], "i,i->", int64_array([])),
- # matrix multiplication
- ([int64_array([2, 3]), int64_array([3, 4])], "ab,bc->ac", int64_array([2, 4])),
- # trace per batch
- ([int64_array([2, 3, 3])], "kii->k", int64_array([2])),
- # diagonal extraction
- ([int64_array([6, 5, 5])], "kii->ki", int64_array([6, 5])),
- # transpose
- ([int64_array([1, 2, 3])], "ijk->kij", int64_array([3, 1, 2])),
- # multiple matrix multiplication
- ([int64_array([2, 5]), int64_array([5, 3, 6]), int64_array([5, 3])], "ab,bcd,bc->ca", int64_array([3, 2])),
- # ellipsis for one operand
- ([int64_array([5, 3, 4])], "a...->...", int64_array([3, 4])),
- # ellipsis for multiple operands
- ([int64_array([3, 5]), int64_array([1])], "a...,...->a...", int64_array([3, 5])),
- # ellipsis with broadcasting
- ([int64_array([9, 1, 4, 3]), int64_array([3, 11, 7, 1])], "a...b,b...->a...", int64_array([9, 11, 7, 4])),
- # mixed case letters in equation
- ([int64_array([1, 3, 5])], "AbC", int64_array([1, 5, 3])),
- # mixed case letters and equation in implicit mode
- ([int64_array([3, 11, 1, 5]), int64_array([1, 3, 1, 7])], "a...b,B...", int64_array([3, 11, 7, 1, 3, 5])),
- # inner product in implicit mode
- ([int64_array([3]), int64_array([3])], "i,i", int64_array([])),
- # equation with ellipsis and repeated labels in implicit mode
- # "a...b,b..." is equivalent to "a...b,b...->...a"
- ([int64_array([9, 1, 4, 3]), int64_array([3, 11, 7, 1])], "a...b,b...", int64_array([11, 7, 4, 9])),
- ])
- def test_einsum(self, input_shapes, equation, ref_output_shape):
- graph = create_einsum_graph(input_shapes, equation)
- einsum_node = Node(graph, 'einsum_node')
- Einsum.infer(einsum_node)
-
- # get the result
- res_output_shape = graph.node['einsum_node_d']['shape']
-
- assert np.array_equal(ref_output_shape, res_output_shape),\
- 'shape does not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape)
-
- @pytest.mark.parametrize("input_shapes, equation, ref_output_shape", [
- # incorrect subscript numbers or inputs
- ([int64_array([3, 11]), int64_array([11, 4])], "ab,bc,cd->ac", None),
- # invalid labels
- ([int64_array([3, 11]), int64_array([11, 4])], "a$,Bc->ac", None),
- # incompatible shapes
- ([int64_array([3, 11]), int64_array([12, 4])], "ab,bc->ac", None),
- # not broadcastable shapes
- ([int64_array([11, 1, 4, 3]), int64_array([3, 11, 7, 5])], "a...b,b...->a...", None),
- # missed ellipsis
- ([int64_array([11, 1, 4, 3]), int64_array([3, 11, 7, 4])], "a...b,b...->a", None),
-])
- def test_invalid_cases(self, input_shapes, equation, ref_output_shape):
- graph = create_einsum_graph(input_shapes, equation)
- einsum_node = Node(graph, 'einsum_node')
- with pytest.raises(AssertionError):
- Einsum.infer(einsum_node)
diff --git a/tools/mo/unit_tests/mo/ops/elementwise_test.py b/tools/mo/unit_tests/mo/ops/elementwise_test.py
deleted file mode 100644
index cd47b78c6b824b..00000000000000
--- a/tools/mo/unit_tests/mo/ops/elementwise_test.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.elementwise import Round, Elementwise
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import type_infer
-from unit_tests.utils.graph import valued_const_with_data, result, regular_op_with_empty_data, connect, \
- shaped_parameter, build_graph
-
-
-def round_test_graph(nodes_attributes, value, mode: str):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'elementwise_node'),
- ('elementwise_node', 'node_3')
- ],
- {
- 'node_1': {
- 'value': value
- },
- 'elementwise_node': {
- 'op': 'Round',
- 'mode': mode,
- },
- 'node_3': {
- 'value': None
- }
- })
- return graph
-
-
-class TestElementwiseOp(unittest.TestCase):
- nodes_attributes = {
- 'node_1': {
- 'shape': np.array([13]),
- 'value': None
- },
- 'elementwise_node': {
- 'op': None,
- 'kind': 'op',
- 'operation': None
- },
- 'node_3': {
- 'shape': None
- }
- }
-
- value = np.array([-23.5, -22.5, -2.5, -1.5, -0.5, 0.5, 0.9, 1.5, 2.3, 2.5, 3.5, 22.5, 23.5])
-
- def test_elementwise_round_even_infer(self):
- graph = round_test_graph(self.nodes_attributes, self.value, 'half_to_even')
-
- graph.graph['layout'] = 'NCHW'
- elementwise_node = Node(graph, 'elementwise_node')
- Round.infer(elementwise_node)
- exp_shape = np.array([13])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- exp_value = np.array([-24., -22., -2., -2., -0., 0., 1., 2., 2., 2., 4., 22., 24., ])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
-
- def test_elementwise_round_away_infer(self):
- graph = round_test_graph(self.nodes_attributes, self.value, 'half_away_from_zero')
-
- graph.graph['layout'] = 'NCHW'
- elementwise_node = Node(graph, 'elementwise_node')
- Round.infer(elementwise_node)
- exp_shape = np.array([13])
- res_shape = graph.node['node_3']['shape']
- res_value = graph.node['node_3']['value']
- exp_value = np.array([-24., -23., -3., -2., -1., 1., 1., 2., 2., 3., 4., 23., 24.])
- for i, value in enumerate(exp_shape):
- self.assertEqual(res_shape[i], value)
- for i, value in enumerate(exp_value):
- self.assertAlmostEqual(res_value[i], value)
-
-
-class TestElementwiseTypeAlignment(unittest.TestCase):
-
- @staticmethod
- def build_graph_to_test_type_alignment(edges,
- input_1_type=np.float32,
- input_2_type=np.float32,
- const_type=np.float32):
- input_shape = int64_array([1, 3, 255, 255])
- const_value = np.array([1], dtype=const_type)
-
- nodes = {
- **shaped_parameter('input_1', input_shape, {'data_type': input_1_type}),
- **shaped_parameter('input_2', input_shape, {'data_type': input_2_type}),
- **regular_op_with_empty_data('add', {'op': 'Add', 'type': 'Add', 'type_infer': Elementwise.type_infer}),
- **valued_const_with_data('const', const_value, kwargs={'data_type': const_type}),
- **result('result'),
- }
- graph = build_graph(nodes, edges, nodes_with_edges_only=True)
- graph.stage = 'back'
- return graph
-
- def test_first_input_const(self):
- edges = [
- *connect('const', '0:add'),
- *connect('input_1', '1:add'),
- *connect('add', 'result')
- ]
- graph = self.build_graph_to_test_type_alignment(edges, const_type=np.float16, input_1_type=np.float32)
-
- type_infer(graph)
- const_node = Node(graph, 'const')
- self.assertEqual(const_node.out_port(0).get_data_type(), np.float32)
-
- def test_second_input_const(self):
- edges = [
- *connect('input_1', '0:add'),
- *connect('const', '1:add'),
- *connect('add', 'result')
- ]
- graph = self.build_graph_to_test_type_alignment(edges, input_1_type=np.float32, const_type=np.float16)
-
- type_infer(graph)
- const_node = Node(graph, 'const')
- self.assertEqual(const_node.out_port(0).get_data_type(), np.float32)
-
- def test_raises(self):
- edges = [
- *connect('input_1', '0:add'),
- *connect('input_2', '1:add'),
- *connect('add', 'result')
- ]
- graph = self.build_graph_to_test_type_alignment(edges, input_1_type=np.float32, input_2_type=np.float16)
-
- self.assertRaises(Exception, type_infer, graph)
-
- def test_not_raises(self):
- edges = [
- *connect('input_1', '0:add'),
- *connect('input_2', '1:add'),
- *connect('add', 'result')
- ]
- graph = self.build_graph_to_test_type_alignment(edges, input_1_type=np.float32, input_2_type=np.float32)
-
- type_infer(graph)
- add_node = Node(graph, 'add')
- self.assertEqual(add_node.out_port(0).get_data_type(), np.float32)
diff --git a/tools/mo/unit_tests/mo/ops/embedding_bag_test.py b/tools/mo/unit_tests/mo/ops/embedding_bag_test.py
deleted file mode 100644
index 9e9e4a62515ea9..00000000000000
--- a/tools/mo/unit_tests/mo/ops/embedding_bag_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.embedding_bag import EmbeddingBagOffsetsSum, EmbeddingBagPackedSum, EmbeddingSegmentsSum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect
-
-nodes = {
- **valued_const_with_data('data', np.random.randn(3000, 8)),
- **regular_op_with_shaped_data('indices1d', [100], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.int32}}),
- **regular_op_with_shaped_data('indices2d', [30, 3], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.int32}}),
- **regular_op_with_shaped_data('offsets', [30], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.int32}}),
- **regular_op_with_shaped_data('segment_ids', [100], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.int32}}),
- **valued_const_with_data('num_segments', np.array(30, dtype=np.int32)),
- **regular_op_with_shaped_data('embedding_bag_offsets', None,
- {'op': 'EmbeddingBagOffsetsSum', 'type': 'EmbeddingBagOffsetsSum',
- 'name': 'embedding_bag_offsets'}),
- **regular_op_with_shaped_data('embedding_bag_packed', None,
- {'op': 'EmbeddingBagPackedSum', 'type': 'EmbeddingBagPackedSum',
- 'name': 'embedding_bag_packed'}),
- **regular_op_with_shaped_data('embedding_segments', None,
- {'op': 'EmbeddingSegmentsSum', 'type': 'EmbeddingSegmentsSum',
- 'name': 'embedding_bag_packed'}),
- **result('output'),
-}
-
-
-class TestEmbeddingInfer(unittest.TestCase):
- def test_embedding_bag_offsets_sum(self):
- graph = build_graph(nodes, [
- *connect('data', '0:embedding_bag_offsets'),
- *connect('indices1d', '1:embedding_bag_offsets'),
- *connect('offsets', '2:embedding_bag_offsets'),
- ('embedding_bag_offsets', 'embedding_bag_offsets_d', {'out': 0}),
- ('embedding_bag_offsets_d', 'output'),
- ], nodes_with_edges_only=True)
- eb_node = Node(graph, 'embedding_bag_offsets')
- EmbeddingBagOffsetsSum.infer(eb_node)
-
- self.assertTrue(np.array_equal(eb_node.out_port(0).data.get_shape(), int64_array([30, 8])))
-
- def test_embedding_bag_packed_sum(self):
- graph = build_graph(nodes, [
- *connect('data', '0:embedding_bag_packed'),
- *connect('indices2d', '1:embedding_bag_packed'),
- ('embedding_bag_packed', 'embedding_bag_packed_d', {'out': 0}),
- ('embedding_bag_packed_d', 'output'),
- ], nodes_with_edges_only=True)
- eb_node = Node(graph, 'embedding_bag_packed')
- EmbeddingBagPackedSum.infer(eb_node)
-
- self.assertTrue(np.array_equal(eb_node.out_port(0).data.get_shape(), int64_array([30, 8])))
-
- def test_embedding_segments_sum(self):
- graph = build_graph(nodes, [
- *connect('data', '0:embedding_segments'),
- *connect('indices1d', '1:embedding_segments'),
- *connect('segment_ids', '2:embedding_segments'),
- *connect('num_segments', '3:embedding_segments'),
- ('embedding_segments', 'embedding_segments_d', {'out': 0}),
- ('embedding_segments_d', 'output'),
- ], nodes_with_edges_only=True)
- eb_node = Node(graph, 'embedding_segments')
- EmbeddingSegmentsSum.infer(eb_node)
-
- self.assertTrue(np.array_equal(eb_node.out_port(0).data.get_shape(), int64_array([30, 8])))
diff --git a/tools/mo/unit_tests/mo/ops/exit_test.py b/tools/mo/unit_tests/mo/ops/exit_test.py
deleted file mode 100644
index e38c05b12e543b..00000000000000
--- a/tools/mo/unit_tests/mo/ops/exit_test.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2021 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-import numpy as np
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.Exit import Exit
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, shaped_parameter
-
-
-# test for TensorIterator
-graph_nodes = {
- **shaped_parameter("input", int64_array([1, 4, 64, 54])),
- **regular_op_with_empty_data("exit", {'op': "Exit"}),
- **result("output")
-}
-
-
-class ExitTest(unittest.TestCase):
- def test_exit_static(self):
- graph = build_graph(nodes_attrs=graph_nodes,
- edges=[*connect('input', 'exit'),
- *connect('exit', 'output')],
- nodes_with_edges_only=True)
- exit_node = Node(graph, 'exit')
- in_node = Node(graph, 'input')
-
- Exit.exit_infer(exit_node)
-
- self.assertTrue(np.ma.allequal(exit_node.out_port(0).data.get_shape(), in_node.shape))
-
- def test_exit_dynamic(self):
- graph = build_graph(nodes_attrs=graph_nodes,
- edges=[*connect('input', 'exit'),
- *connect('exit', 'output')],
- nodes_with_edges_only=True)
- exit_node = Node(graph, 'exit')
- in_node = Node(graph, 'input')
- shape = int64_array([-1, 36])
- in_node.shape = np.ma.masked_array(shape, mask=shape == -1, fill_value=dynamic_dimension_value)
- in_node.out_port(0).data.set_shape(in_node.shape)
-
- Exit.exit_infer(exit_node)
-
- self.assertTrue(np.ma.allequal(exit_node.out_port(0).data.get_shape(), in_node.shape))
diff --git a/tools/mo/unit_tests/mo/ops/expand_dims_test.py b/tools/mo/unit_tests/mo/ops/expand_dims_test.py
deleted file mode 100644
index f73ece25c39237..00000000000000
--- a/tools/mo/unit_tests/mo/ops/expand_dims_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.expand_dims import ExpandDims
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'data_1': {
- 'kind': 'data',
- 'shape': np.array([2, 3, 224, 224]),
- 'value': None,
- },
- 'expand_dims': {
- 'type': 'None',
- 'kind': 'op',
- },
- 'data_2': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- }
-}
-
-class TestExpandDimsOp():
- @pytest.mark.parametrize("axis, ref_out_shape",[(0, [1, 2, 3, 224, 224]),
- (1, [2, 1, 3, 224, 224]),
- (2, [2, 3, 1, 224, 224]),
- (3, [2, 3, 224, 1, 224]),
- (4, [2, 3, 224, 224, 1]),
- ])
- def test_expand_dims_infer(self, axis, ref_out_shape):
- graph = build_graph(nodes_attributes,
- [('data_1', 'expand_dims'),
- ('expand_dims', 'data_2')],
- {'expand_dims': {'expand_axis': axis}})
- expand_dims_node = Node(graph, 'expand_dims')
-
- ExpandDims.infer(expand_dims_node)
-
- assert np.array_equal(expand_dims_node.out_node().shape, np.array(ref_out_shape))
-
-
-class TestExpandDimsOpDynamicDims():
- @pytest.mark.parametrize("axis, ref_out_shape",[(0, [1, 2, 3, dynamic_dimension_value, 224]),
- (1, [2, 1, 3, dynamic_dimension_value, 224]),
- (2, [2, 3, 1, dynamic_dimension_value, 224]),
- (3, [2, 3, dynamic_dimension_value, 1, 224]),
- (4, [2, 3, dynamic_dimension_value, 224, 1]),
- ])
- def test_expand_dims_infer(self, axis, ref_out_shape):
- graph = build_graph(nodes_attributes,
- [('data_1', 'expand_dims'),
- ('expand_dims', 'data_2')],
- {'expand_dims': {'expand_axis': axis}})
- Node(graph, 'data_1').shape = shape_array([2, 3, dynamic_dimension_value, 224])
- expand_dims_node = Node(graph, 'expand_dims')
-
- ExpandDims.infer(expand_dims_node)
-
- assert strict_compare_tensors(expand_dims_node.out_node().shape, shape_array(ref_out_shape))
-
-
-class TestExpandDimsOpValueInfer():
- @pytest.mark.parametrize("axis, in_shape, ref_out_shape",[(0, [2, 3, 224, 224], [1, 2, 3, 224, 224]),
- (1, [2, 3, 224, 224], [2, 1, 3, 224, 224]),
- (2, [2, 3, 224, 224], [2, 3, 1, 224, 224]),
- (3, [2, 3, 224, 224], [2, 3, 224, 1, 224]),
- (4, [2, 3, 224, 224], [2, 3, 224, 224, 1]),
- ])
- def test_expand_dims_infer_value(self, axis, in_shape, ref_out_shape):
- in_value = np.random.rand(*in_shape)
- graph = build_graph(nodes_attributes,
- [('data_1', 'expand_dims'),
- ('expand_dims', 'data_2')],
- {'data_1': {'value': in_value},
- 'expand_dims': {'expand_axis': axis}})
- expand_dims_node = Node(graph, 'expand_dims')
-
- ExpandDims.infer(expand_dims_node)
-
- assert np.array_equal(expand_dims_node.out_node().shape, np.array(ref_out_shape))
- assert np.array_equal(expand_dims_node.out_node().value, np.array(in_value.reshape(ref_out_shape)))
diff --git a/tools/mo/unit_tests/mo/ops/eye_test.py b/tools/mo/unit_tests/mo/ops/eye_test.py
deleted file mode 100644
index d3d83ca6a75970..00000000000000
--- a/tools/mo/unit_tests/mo/ops/eye_test.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-import numpy as np
-
-
-from openvino.tools.mo.ops.eye import Eye
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph_with_attrs, build_graph
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension_value
-from unit_tests.utils.graph import valued_const_with_data, result, regular_op_with_empty_data, connect
-
-
-graph_node_attrs_sizes = [
- ('num_rows', {'type': 'Parameter', 'kind': 'op'}),
- ('num_rows_data', {'kind': 'data'}),
-
- ('num_columns', {'type': 'Parameter', 'kind': 'op'}),
- ('num_columns_data', {'kind': 'data'}),
-
- ('diagonal_index', {'type': 'Parameter', 'kind': 'op'}),
- ('diagonal_index_data', {'kind': 'data'}),
-
- ('batch_shape', {'type': 'Parameter', 'kind': 'op'}),
- ('batch_shape_data', {'kind': 'data'}),
-
- ('eye_op', {'type': 'Eye', 'kind': 'op'}),
- ('eye_op_data', {'kind': 'data', 'shape': None, 'value': None}),
-
- ('op_output', {'kind': 'op', 'op': 'Result'}),
-]
-
-
-graph_edges_sizes = [
- ('num_rows', 'num_rows_data'),
- ('num_columns', 'num_columns_data'),
- ('diagonal_index', 'diagonal_index_data'),
- ('batch_shape', 'batch_shape_data'),
-
- ('num_rows_data', 'eye_op', {'in': 0}),
- ('num_columns_data', 'eye_op', {'in': 1}),
- ('diagonal_index_data', 'eye_op', {'in': 2}),
- ('batch_shape_data', 'eye_op', {'in': 3}),
-
- ('eye_op', 'eye_op_data'),
- ('eye_op_data', 'op_output'),
-]
-
-
-class TestComplexOp():
- @pytest.mark.parametrize("input_shape, output_shape, num_rows, num_cols, batch_shape",[
- ([], [dynamic_dimension_value, dynamic_dimension_value],None,None,[]),
- ([1], [dynamic_dimension_value, dynamic_dimension_value],None,None,[]),
- ([1], [2, dynamic_dimension_value, dynamic_dimension_value], None, None, [2]),
- ([1], [2, 3, dynamic_dimension_value], 3, None, [2]),
- ([1], [2, dynamic_dimension_value, 4], None, 4, [2]),
- ([1], [2, 3, 4], [3], [4], [2])
- ])
- def test_complex_op_shape_inference(self, input_shape, output_shape, num_rows, num_cols, batch_shape):
- graph = build_graph_with_attrs(nodes_with_attrs=graph_node_attrs_sizes,
- edges_with_attrs=graph_edges_sizes,
- update_nodes_attributes=[
- ('num_rows_data', {'shape': int64_array(input_shape), 'value': num_rows}),
- ('num_columns_data', {'shape': int64_array(input_shape), 'value': num_cols}),
- ('diagonal_index_data', {'shape': int64_array(input_shape)}),
- ('batch_shape_data', {'shape': int64_array([len(batch_shape)]), 'value': batch_shape}),
- ('eye_op', {'output_type': np.float32}),
- ])
- node = Node(graph, 'eye_op')
- Eye.infer(node)
-
- msg = "Eye operation infer failed for case: expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['eye_op_data']['shape'], output_shape),\
- msg.format(output_shape, graph.node['eye_op_data']['shape'])
-
- def test_value_inference(self):
- graph_node_attrs_sizes = {
- **valued_const_with_data('num_rows', int64_array([128])),
- **valued_const_with_data('num_columns', int64_array([128])),
- **valued_const_with_data('diagonal_index', int64_array([0])),
- **valued_const_with_data('batch_shape', int64_array([])),
- **regular_op_with_empty_data('eye_op', {'op': 'Eye', 'output_type': np.float32}),
- **result('res'),
- }
- graph_edges_sizes = [
- *connect('num_rows', '0:eye_op'),
- *connect('num_columns', '1:eye_op'),
- *connect('diagonal_index', '2:eye_op'),
- *connect('batch_shape', '3:eye_op'),
- *connect('eye_op', 'res'),
- ]
- graph = build_graph(
- graph_node_attrs_sizes, graph_edges_sizes)
- node = Node(graph, 'eye_op')
- Eye.infer(node)
- output_value = np.eye(int64_array(128), M=int64_array(
- 128), k=int64_array(0), dtype=np.float32)
-
- msg = "Eye operation infer failed for case: expected_value={}, actual_value={}"
-
- assert np.array_equal(graph.node['eye_op_d']['value'], output_value),\
- msg.format(output_value, graph.node['eye_op_d']['value'])
diff --git a/tools/mo/unit_tests/mo/ops/gather_test.py b/tools/mo/unit_tests/mo/ops/gather_test.py
deleted file mode 100644
index d5760f2d6fcdad..00000000000000
--- a/tools/mo/unit_tests/mo/ops/gather_test.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy.testing as npt
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, strict_compare_tensors, \
- dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.gather import Gather
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import valued_const_with_data, result, regular_op_with_empty_data, connect, \
- shaped_parameter, build_graph
-
-
-class TestGatherPartialInfer(UnitTestWithMockedTelemetry):
-
- @staticmethod
- def build_and_test_value_inference(data, indices, axis, batch_dims, ref_value, negative_test_string=None):
- nodes = {
- **valued_const_with_data('data', int64_array(data)),
- **valued_const_with_data('indices', int64_array(indices)),
- **valued_const_with_data('axis', int64_array(axis)),
- **regular_op_with_empty_data('gather', {'op': 'Gather', 'batch_dims': batch_dims, 'infer': Gather.infer}),
- **result('res'),
- }
-
- edges = [
- *connect('data', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', 'res')
- ]
-
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- partial_infer(graph)
-
- node = Node(graph, 'gather')
- res = node.out_port(0).data.get_value()
- npt.assert_array_equal(res, ref_value)
-
- @staticmethod
- def build_and_test_shape_inference(data_shape, indices_shape, axis, batch_dims, ref_shape):
- nodes = {
- **shaped_parameter('data', int64_array(data_shape)),
- **shaped_parameter('indices', int64_array(indices_shape)),
- **valued_const_with_data('axis', int64_array(axis)),
- **regular_op_with_empty_data('gather', {'op': 'Gather', 'batch_dims': batch_dims, 'infer': Gather.infer}),
- **result('res'),
- }
-
- edges = [
- *connect('data', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', 'res')
- ]
-
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- partial_infer(graph)
-
- node = Node(graph, 'gather')
- res = node.out_port(0).data.get_shape()
- npt.assert_array_equal(res, ref_shape)
-
- def test_shape_axis_1(self):
- self.build_and_test_shape_inference(axis=1, batch_dims=0,
- data_shape=[3, 3],
- indices_shape=[1, 2],
- ref_shape=[3, 1, 2])
-
- def test_shape_axis_1_1(self):
- self.build_and_test_shape_inference(axis=1, batch_dims=0,
- data_shape=[3, 3],
- indices_shape=[1, 2, 4],
- ref_shape=[3, 1, 2, 4])
-
- def test_shape_axis_1_2(self):
- self.build_and_test_shape_inference(axis=1, batch_dims=0,
- data_shape=[1, 2, 4],
- indices_shape=[3, 3],
- ref_shape=[1, 3, 3, 4])
-
- def test_shape_axis_1_3(self):
- self.build_and_test_shape_inference(axis=1, batch_dims=0,
- data_shape=[1, 2, 4],
- indices_shape=[5, 8, 16],
- ref_shape=[1, 5, 8, 16, 4])
-
- def test_shape_axis_0(self):
- self.build_and_test_shape_inference(axis=0, batch_dims=0,
- data_shape=[3, 3],
- indices_shape=[1, 2],
- ref_shape=[1, 2, 3])
-
- def test_shape_axis_0_1(self):
- self.build_and_test_shape_inference(axis=0, batch_dims=0,
- data_shape=[3, 3],
- indices_shape=[1, 2, 5],
- ref_shape=[1, 2, 5, 3])
-
- def test_shape_axis_0_2(self):
- self.build_and_test_shape_inference(axis=0, batch_dims=0,
- data_shape=[1, 2, 5],
- indices_shape=[3, 3],
- ref_shape=[3, 3, 2, 5])
-
- def test_shape_axis_0_3(self):
- self.build_and_test_shape_inference(axis=0, batch_dims=0,
- data_shape=[1, 2, 5],
- indices_shape=[6, 8, 15],
- ref_shape=[6, 8, 15, 2, 5])
-
- def test_shape_axis_minus_2(self):
- self.build_and_test_shape_inference(axis=-2, batch_dims=0,
- data_shape=[2, 3, 7],
- indices_shape=[1, 4],
- ref_shape=[2, 1, 4, 7])
-
- def test_shape_axis_1_batch_dims_1(self):
- self.build_and_test_shape_inference(axis=1, batch_dims=1,
- data_shape=[3, 4],
- indices_shape=[3, 1, 2],
- ref_shape=[3, 1, 2])
-
- def test_shape_axis_2_batch_dims_1(self):
- self.build_and_test_shape_inference(axis=2, batch_dims=1,
- data_shape=[3, 4, 7],
- indices_shape=[3, 1, 2],
- ref_shape=[3, 4, 1, 2])
-
- def test_shape_axis_2_batch_dims_minus_1(self):
- self.build_and_test_shape_inference(axis=2, batch_dims=-1,
- data_shape=[3, 1, 7],
- indices_shape=[3, 1, 2],
- ref_shape=[3, 1, 2])
-
- def test_shape_axis_2_batch_dims_minus_2(self):
- self.build_and_test_shape_inference(axis=2, batch_dims=-2,
- data_shape=[3, 4, 7],
- indices_shape=[3, 1, 2],
- ref_shape=[3, 4, 1, 2])
-
- def test_axis_0_batch_dims_0(self):
- self.build_and_test_value_inference(axis=0, batch_dims=0,
- data=[1, 2, 3, 4, 5],
- indices=[0, 0, 4],
- ref_value=[1, 1, 5])
-
- def test_axis_0_batch_dims_0_negative_indices(self):
- self.build_and_test_value_inference(axis=0, batch_dims=0,
- data=[1, 2, 3, 4, 5],
- indices=[-1, -2, -3],
- ref_value=[5, 4, 3])
-
- def test_axis_1_batch_dims_1(self):
- self.build_and_test_value_inference(axis=1, batch_dims=1,
- data=[[1, 2, 3, 4, 5],
- [6, 7, 8, 9, 10]],
- indices=[[0, 0, 4],
- [4, 0, 0]],
-
- ref_value=[[1, 1, 5],
- [10, 6, 6]])
-
- def test_axis_minus_1_batch_dims_1(self):
- self.build_and_test_value_inference(axis=-1, batch_dims=1,
- data=[[1, 2, 3, 4, 5],
- [6, 7, 8, 9, 10]],
- indices=[[0, 0, 4],
- [4, 0, 0]],
-
- ref_value=[[1, 1, 5],
- [10, 6, 6]])
-
- def test_axis_2_batch_dims_1(self):
- self.build_and_test_value_inference(axis=2, batch_dims=1,
- data=[[[[ 1, 2, 3, 4], # <-- first batch
- [ 5, 6, 7, 8],
- [ 9, 10, 11, 12],
- [13, 14, 15, 16],
- [17, 18, 19, 20]]],
- [[[21, 22, 23, 24], # < -- second batch
- [25, 26, 27, 28],
- [29, 30, 31, 32],
- [33, 34, 35, 36],
- [37, 38, 39, 40]]]], # data_shape = (2, 1, 5, 4)
- indices=[[1, 2, 4],
- [4, 3, 2]],
- ref_value=[[[[ 5, 6, 7, 8],
- [ 9, 10, 11, 12],
- [17, 18, 19, 20]]],
- [[[37, 38, 39, 40],
- [33, 34, 35, 36],
- [29, 30, 31, 32]]]])
-
- def test_axis_2_batch_dims_1_with_negative_indices(self):
- self.build_and_test_value_inference(axis=2, batch_dims=1,
- data=[[[[ 1, 2, 3, 4], # <-- first batch
- [ 5, 6, 7, 8],
- [ 9, 10, 11, 12],
- [13, 14, 15, 16],
- [17, 18, 19, 20]]],
- [[[21, 22, 23, 24], # < -- second batch
- [25, 26, 27, 28],
- [29, 30, 31, 32],
- [33, 34, 35, 36],
- [37, 38, 39, 40]]]], # data_shape = (2, 1, 5, 4)
- indices=[[-4, -3, -1],
- [-1, 3, 2]],
- ref_value=[[[[ 5, 6, 7, 8],
- [ 9, 10, 11, 12],
- [17, 18, 19, 20]]],
- [[[37, 38, 39, 40],
- [33, 34, 35, 36],
- [29, 30, 31, 32]]]])
-
- def test_axis_2_batch_dims_mimus_1(self):
- self.build_and_test_value_inference(axis=2, batch_dims=-1,
- data=[[[[ 1, 2, 3, 4], # <-- first batch
- [ 5, 6, 7, 8],
- [ 9, 10, 11, 12],
- [13, 14, 15, 16],
- [17, 18, 19, 20]]],
- [[[21, 22, 23, 24], # < -- second batch
- [25, 26, 27, 28],
- [29, 30, 31, 32],
- [33, 34, 35, 36],
- [37, 38, 39, 40]]]], # data_shape = (2, 1, 5, 4)
- indices=[[1, 2, 4],
- [4, 3, 2]],
- ref_value=[[[[ 5, 6, 7, 8],
- [ 9, 10, 11, 12],
- [17, 18, 19, 20]]],
- [[[37, 38, 39, 40],
- [33, 34, 35, 36],
- [29, 30, 31, 32]]]])
-
- # negative tests
- def test_shape_indices_data_shape_inconsistency(self):
- self.assertRaises(Error, self.build_and_test_shape_inference,
- axis=2, batch_dims=2,
- data_shape=[3, 4, 7],
- indices_shape=[3, 1, 2],
- ref_shape=[3, 4, 2])
-
- def test_shape_batch_dims_greater_than_axis(self):
- self.assertRaises(Error, self.build_and_test_shape_inference,
- axis=2, batch_dims=3,
- data_shape=[3, 4, 7],
- indices_shape=[3, 4, 2],
- ref_shape=[3, 4, 2])
-
- def test_shape_batch_dims_out_of_bound(self):
- self.assertRaises(Error, self.build_and_test_shape_inference,
- axis=2, batch_dims=4,
- data_shape=[3, 4, 7],
- indices_shape=[3, 4, 2],
- ref_shape=[3, 4, 2])
-
- def test_shape_axis_out_of_bound(self):
- self.assertRaises(Error, self.build_and_test_shape_inference,
- axis=3, batch_dims=2,
- data_shape=[3, 4, 7],
- indices_shape=[3, 4, 2],
- ref_shape=[3, 4, 2])
-
-
-dyn = dynamic_dimension_value
-
-
-class TestElementwiseReverseInfer(UnitTestWithMockedTelemetry):
- @staticmethod
- def build_and_test_reverse_inference(data_shape, indices_shape, axis, batch_dims, out_shape, ref_shape):
- in_port_with_defined_shape = 0 if data_shape is not None else 1
- defined_shape = shape_array(data_shape if data_shape is not None else indices_shape)
-
- nodes = {
- **shaped_parameter('data', data_shape, {'reverse_infer': Parameter.reverse_infer}),
- **shaped_parameter('indices', indices_shape, {'reverse_infer': Parameter.reverse_infer}),
- **valued_const_with_data('axis', int64_array(axis)),
- **regular_op_with_empty_data('gather', {'op': 'Gather', 'batch_dims': batch_dims,
- 'infer': Gather.infer,
- 'reverse_infer': Gather.reverse_infer}),
- **result('res'),
- }
-
- edges = [
- *connect('data', '0:gather'),
- *connect('indices', '1:gather'),
- *connect('axis', '2:gather'),
- *connect('gather', 'res')
- ]
-
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
-
- Node(graph, 'gather').out_port(0).data.set_shape(shape_array(out_shape))
- Node(graph, 'gather').in_port(in_port_with_defined_shape).data.set_shape(defined_shape)
-
- partial_infer(graph)
- actual_shape = Node(graph, 'gather').in_port(int(not in_port_with_defined_shape)).data.get_shape()
- assert strict_compare_tensors(actual_shape, shape_array(ref_shape))
-
- # undefined indices pshape
- def test_reverse_infer_1(self):
- self.build_and_test_reverse_inference(data_shape=[dyn, dyn],
- indices_shape=None,
- axis=0,
- batch_dims=0,
- out_shape=[dyn, dyn, dyn, dyn],
- ref_shape=[dyn, dyn, dyn])
-
- def test_reverse_infer_2(self):
- self.build_and_test_reverse_inference(data_shape=[3, 10],
- indices_shape=None,
- axis=1,
- batch_dims=0,
- out_shape=[3, 40, 50, 60],
- ref_shape=[40, 50, 60])
-
- # undefined data pshape
- def test_reverse_infer_3(self):
- self.build_and_test_reverse_inference(data_shape=None,
- indices_shape=[4, 5],
- axis=0,
- batch_dims=0,
- out_shape=[4, 5, 10],
- ref_shape=[dyn, 10])
-
- def test_reverse_infer_4(self):
- self.build_and_test_reverse_inference(data_shape=None,
- indices_shape=[4, 67],
- axis=1,
- batch_dims=0,
- out_shape=[3, 4, 67, 100],
- ref_shape=[3, dyn, 100])
diff --git a/tools/mo/unit_tests/mo/ops/gatherelements_test.py b/tools/mo/unit_tests/mo/ops/gatherelements_test.py
deleted file mode 100644
index 63f187ff14083e..00000000000000
--- a/tools/mo/unit_tests/mo/ops/gatherelements_test.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.gatherelements import GatherElements
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, strict_compare_tensors, dynamic_dimension
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, \
- valued_const_with_data, shaped_parameter
-
-dyn = dynamic_dimension
-
-class TestGatherElementsInferTest():
- @pytest.mark.parametrize("data, indices, axis, ref_res",[
- ([[1, 2],
- [3, 4]],
- [[0, 1],
- [0, 0]],
- 0, # axis
- [[1, 4], # ref_res
- [1, 2]]),
-
- ([[1, 2],
- [3, 4]],
- [[0, 1],
- [0, 0]],
- 1, # axis
- [[1, 2], # ref_res
- [3, 3]]),
-
- ([[1, 2, 3],
- [4, 5, 6],
- [7, 8, 9]],
- [[1, 2, 0],
- [2, 0, 0]],
- 0, # axis
- [[4, 8, 3], # ref_res
- [7, 2, 3]]),
-
- ([[1, 2],
- [3, 4]],
- [[0, 1],
- [0, 0]],
- -1, # axis
- [[1, 2], # ref_res
- [3, 3]]),
-
- ([ # 3D case
- [[1, 2],
- [3, 4]],
- [[5, 6],
- [7, 8]],
- [[9, 10],
- [11, 12]]
- ],
- [
- [[1, 0],
- [0, 1]],
- [[1, 1],
- [1, 0]],
- [[0, 0],
- [1, 1]]
- ],
- -1, # axis
- [
- [[2, 1],
- [3, 4]],
- [[6, 6],
- [8, 7]],
- [[9, 9],
- [12, 12]]
- ]),
- ])
- def test_gatherelements_value_infer(self, data, indices, axis, ref_res):
- nodes = {
- **valued_const_with_data('data', int64_array(data)),
- **valued_const_with_data('indices', int64_array(indices)),
- **regular_op_with_empty_data('gather_elements', {'op': 'GatherElements', 'axis': axis}),
- **result()
- }
-
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect('data', '0:gather_elements'),
- *connect('indices', '1:gather_elements'),
- *connect('gather_elements', 'output')
- ], nodes_with_edges_only=True)
- graph.stage = 'middle'
-
- gather_el_node = Node(graph, 'gather_elements')
- GatherElements.infer(gather_el_node)
-
- res_output_shape = gather_el_node.out_node().shape
- assert np.array_equal(int64_array(ref_res).shape, res_output_shape)
-
- res_output_value = gather_el_node.out_node().value
- if res_output_value is not None:
- assert np.array_equal(int64_array(ref_res), res_output_value)
-
- def check_shape_infer(self, data_shape, indices_shape, axis, ref):
- nodes = {
- **shaped_parameter('data', data_shape),
- **shaped_parameter('indices', indices_shape),
- **regular_op_with_empty_data('gather_elements', {'op': 'GatherElements', 'axis': axis}),
- **result()
- }
-
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect('data', '0:gather_elements'),
- *connect('indices', '1:gather_elements'),
- *connect('gather_elements', 'output')
- ], nodes_with_edges_only=True)
- graph.stage = 'middle'
-
- gather_el_node = Node(graph, 'gather_elements')
- GatherElements.infer(gather_el_node)
-
- res_output_shape = gather_el_node.out_node().shape
- assert strict_compare_tensors(res_output_shape, ref)
-
- def test_shape_infer_1(self):
- self.check_shape_infer(data_shape=[3], indices_shape=[100], ref=[100], axis=0)
-
- def test_shape_infer_2(self):
- self.check_shape_infer(data_shape=[100, 4], indices_shape=[4, 4], ref=[4, 4], axis=0)
-
- def test_shape_infer_3(self):
- self.check_shape_infer(data_shape=[3, 4], indices_shape=[3, 100], ref=[3, 100], axis=1)
-
- def test_shape_infer_4(self):
- self.check_shape_infer(data_shape=[1, 3, 256], indices_shape=[256, 3, 256], ref=[256, 3, 256], axis=0)
-
- def test_shape_infer_5(self):
- self.check_shape_infer(data_shape=[1, 3, 256], indices_shape=[1, 1024, 256], ref=[1, 1024, 256], axis=1)
-
- def test_shape_infer_6(self):
- self.check_shape_infer(data_shape=[1, 3, 256], indices_shape=[1, 3, 1024], ref=[1, 3, 1024], axis=2)
-
- def test_shape_infer_7(self):
- self.check_shape_infer(data_shape=[1, 25, 64, 256], indices_shape=[1, 25, 64, 2], ref=[1, 25, 64, 2], axis=-1)
-
- # dynamic dimensions
- def test_shape_infer_8(self):
- self.check_shape_infer(data_shape=[dyn, 4], indices_shape=[3, 100], ref=[3, 100], axis=1)
-
- def test_shape_infer_9(self):
- self.check_shape_infer(data_shape=[100, 4], indices_shape=[dyn, 100], ref=[100, 100], axis=1)
-
- def test_shape_infer_10(self):
- self.check_shape_infer(data_shape=[1, 3, 256], indices_shape=[dyn, 3, 256], ref=[dyn, 3, 256], axis=0)
-
- def test_shape_infer_11(self):
- self.check_shape_infer(data_shape=[dyn, dyn, dyn], indices_shape=[dyn, dyn, dyn], ref=[dyn, dyn, dyn], axis=0)
-
- def test_shape_infer_12(self):
- self.check_shape_infer(data_shape=[1, 3, 256], indices_shape=[dyn, 1024, dyn], ref=[1, 1024, 256], axis=1)
-
- def test_shape_infer_13(self):
- self.check_shape_infer(data_shape=[1, 3, 256], indices_shape=[dyn, dyn, 1024], ref=[1, 3, 1024], axis=2)
-
- # negative tests
- def test_negative_shape_infer_ranks_differ(self):
- with pytest.raises(AssertionError):
- self.check_shape_infer(data_shape=[1, 3, 64], indices_shape=[1, 3], ref=[1, 3, 1024], axis=2)
-
- def test_negative_shape_infer_axis_out_of_bound(self):
- with pytest.raises(AssertionError):
- self.check_shape_infer(data_shape=[1, 4, 64], indices_shape=[1, 3, 64], ref=[1, 3, 1024], axis=20)
-
- def test_negative_shape_infer_inconsistent_shapes(self):
- with pytest.raises(Error):
- self.check_shape_infer(data_shape=[1, 4, 64], indices_shape=[1, 3, 64], ref=[1, 3, 1024], axis=2)
diff --git a/tools/mo/unit_tests/mo/ops/gathernd_test.py b/tools/mo/unit_tests/mo/ops/gathernd_test.py
deleted file mode 100644
index ae1d28dd65ea68..00000000000000
--- a/tools/mo/unit_tests/mo/ops/gathernd_test.py
+++ /dev/null
@@ -1,456 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.gathernd import GatherND
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'data': {'kind': 'op'},
- 'data_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'indices': {'kind': 'op'},
- 'indices_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'gathernd_node': {'op': 'GatherNDUpdate', 'kind': 'op', 'batch_dims': 0, 'version': 'opset8'},
- 'output': {'shape': None, 'value': None, 'kind': 'data'}}
-
-# graph 1
-edges = [('data', 'data_data', {'in': 0}),
- ('indices', 'indices_data', {'in': 1}),
- ('data_data', 'gathernd_node', {'in': 0}),
- ('indices_data', 'gathernd_node', {'in': 1}),
- ('gathernd_node', 'output', {'out': 0})]
-
-# test data for partial infer: gather elements
-inputs = {'data_data': {'shape': int64_array([10, 40]), 'value': None},
- 'indices_data': {'shape': int64_array([3, 2]), 'value': None}}
-
-# test data for partial infer: gather slices
-inputs1 = {'data_data': {'shape': int64_array([10, 40, 30]), 'value': None},
- 'indices_data': {'shape': int64_array([3, 2]), 'value': None}}
-
-# test data for partial infer: gather slices and batch_dims=2
-inputs2 = {'data_data': {'shape': int64_array([10, 40, 4, 9]), 'value': None},
- 'indices_data': {'shape': int64_array([10, 40, 3, 5, 1]), 'value': None}}
-
-# test data for partial infer: gather slices and batch_dims=3 and indices.shape[-1]=len(data.shape)-batch_dims
-inputs3 = {'data_data': {'shape': int64_array([1, 64, 64, 320]), 'value': None},
- 'indices_data': {'shape': int64_array([1, 64, 64, 1, 1]), 'value': None}}
-
-# test data for constant folding: gather elements, batch_dims = 0
-inputs4 = {'data_data': {'shape': int64_array([2, 2]), 'value': int64_array([[1, 2],
- [3, 4]])},
- 'indices_data': {'shape': int64_array([2, 2]), 'value': int64_array([[0, 0],
- [1, 0]])}}
-output4 = int64_array([1, 3])
-
-# test data for constant folding: gather slices, batch_dims = 0
-inputs5 = {'data_data': {'shape': int64_array([2, 3, 4]), 'value': int64_array([[[1, 2, 3, 4],
- [5, 6, 7, 8],
- [9, 10, 11, 12]],
- [[13, 14, 15, 16],
- [17, 18, 19, 20],
- [21, 22, 23, 24]]])},
- 'indices_data': {'shape': int64_array([3, 2]), 'value': int64_array([[0, 1],
- [1, 0],
- [1, 2]])}}
-output5 = int64_array([[5, 6, 7, 8],
- [13, 14, 15, 16],
- [21, 22, 23, 24]])
-
-# test data for constant folding: gather slices, batch_dims = 1
-inputs6 = {'data_data': {'shape': int64_array([2, 3, 4]), 'value': int64_array([[[1, 2, 3, 4],
- [5, 6, 7, 8],
- [9, 10, 11, 12]],
- [[13, 14, 15, 16],
- [17, 18, 19, 20],
- [21, 22, 23, 24]]])},
- 'indices_data': {'shape': int64_array([2, 1]), 'value': int64_array([[1],
- [0]])}}
-output6 = int64_array([[5, 6, 7, 8],
- [13, 14, 15, 16]])
-
-# test data for constant folding: gather slices with leading dimensions, batch_dims = 2
-inputs7 = {'data_data': {'shape': int64_array([2, 3, 4]), 'value': int64_array([[[1, 2, 3, 4],
- [5, 6, 7, 8],
- [9, 10, 11, 12]],
- [[13, 14, 15, 16],
- [17, 18, 19, 20],
- [21, 22, 23, 24]]])},
- 'indices_data': {'shape': int64_array([2, 3, 1, 1]), 'value': int64_array([[[[1]],
- [[0]],
- [[2]]],
- [[[0]],
- [[2]],
- [[2]]]])}}
-output7 = int64_array([[2], [5], [11], [13], [19], [23]])
-
-# test data for constant folding: gather elements, batch_dims = 2
-inputs8 = {'data_data': {'shape': int64_array([2, 3, 4, 2]),
- 'value': int64_array([[[[1, 2], [3, 4], [5, 6], [7, 8]],
- [[9, 10], [11, 12], [13, 14], [15, 16]],
- [[17, 18], [19, 20], [21, 22], [23, 24]]],
- [[[25, 26], [27, 28], [29, 30], [31, 32]],
- [[33, 34], [35, 36], [37, 38], [39, 40]],
- [[41, 42], [43, 44], [45, 46], [47, 48]]]])},
- 'indices_data': {'shape': int64_array([2, 3, 3, 2]),
- 'value': int64_array([[[[1, 0], [3, 1], [2, 1]],
- [[0, 1], [1, 1], [2, 0]],
- [[3, 0], [3, 1], [2, 1]]],
- [[[2, 0], [1, 1], [3, 1]],
- [[1, 1], [2, 0], [2, 0]],
- [[0, 0], [3, 1], [3, 1]]]])}}
-output8 = int64_array([[3, 8, 6],
- [10, 12, 13],
- [23, 24, 22],
- [29, 28, 32],
- [36, 37, 37],
- [41, 48, 48]])
-
-# test data for partial infer: gather slices and batch_dims=2
-inputs9 = {'data_data': {'shape': shape_array([dynamic_dimension_value, 40, 4, 9]), 'value': None},
- 'indices_data': {'shape': shape_array([dynamic_dimension_value, 40, 3, 5, 1]), 'value': None}}
-
-# test data for partial infer: gather slices and batch_dims=2
-inputs10 = {'data_data': {'shape': shape_array([40, dynamic_dimension_value, 4, 9]), 'value': None},
- 'indices_data': {'shape': shape_array([40, dynamic_dimension_value, 3, 5, 1]), 'value': None}}
-
-# test data for partial infer: gather slices and batch_dims=2
-inputs11 = {'data_data': {'shape': shape_array([dynamic_dimension_value, 40, 4, 9]), 'value': None},
- 'indices_data': {'shape': shape_array([40, dynamic_dimension_value, 3, 5, 1]), 'value': None}}
-
-# invalid test case with incorrect rank for indices
-inputs_inv1 = {'data_data': {'shape': int64_array([10, 40]), 'value': None},
- 'indices_data': {'shape': int64_array([5, 3, 4]), 'value': None}}
-
-# invalid test case with unequal batch dimensions, batch_dims = 2
-inputs_inv2 = {'data_data': {'shape': int64_array([10, 40, 20]), 'value': None},
- 'indices_data': {'shape': int64_array([5, 3, 4]), 'value': None}}
-
-# invalid test case with indices rank greater than a rank of data excluding batch dimensions, batch_dims = 2
-inputs_inv3 = {'data_data': {'shape': int64_array([10, 40, 20, 10, 2]), 'value': None},
- 'indices_data': {'shape': int64_array([10, 40, 4]), 'value': None}}
-
-
-class TestGatherND_5(unittest.TestCase):
- def setUp(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 0
- nodes_attributes['gathernd_node']['version'] = 'opset5'
-
- def test_partial_infer_gather_element(self):
- graph = build_graph(nodes_attributes, edges, inputs)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = int64_array([3])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice(self):
- graph = build_graph(nodes_attributes, edges, inputs1)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = int64_array([3, 30])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs2)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = int64_array([400, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims3(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 3
- graph = build_graph(nodes_attributes, edges, inputs3)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = int64_array([4096, 1])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2_dynamic1(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs9)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = shape_array([dynamic_dimension_value, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(strict_compare_tensors(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2_dynamic2(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs10)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = shape_array([dynamic_dimension_value, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(strict_compare_tensors(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2_dynamic3(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs11)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = shape_array([dynamic_dimension_value, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(strict_compare_tensors(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_infer4(self):
- graph = build_graph(nodes_attributes, edges, inputs4)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output4, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output4, res_output_value))
-
- def test_infer5(self):
- graph = build_graph(nodes_attributes, edges, inputs5)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output5, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output5, res_output_value))
-
- def test_infer6(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 1
- graph = build_graph(nodes_attributes, edges, inputs6)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output6, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output6, res_output_value))
-
- def test_infer7(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs7)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- output = output7.reshape([6, 1])
- self.assertTrue(np.array_equal(output, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output, res_output_value))
-
- def test_infer8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs8)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output8, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output8, res_output_value))
-
- def test_infer9(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs8)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output8, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output8, res_output_value))
-
- def test_infer9_opset_5(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs8)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- output = output8.reshape([6, 3])
- self.assertTrue(np.array_equal(output, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output, res_output_value))
-
- def test_infer_invalid1(self):
- graph = build_graph(nodes_attributes, edges, inputs_inv1)
- gathernd_node = Node(graph, 'gathernd_node')
- self.assertRaises(AssertionError, GatherND.infer, gathernd_node)
-
- def test_infer_invalid2(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs_inv2)
- gathernd_node = Node(graph, 'gathernd_node')
- self.assertRaises(AssertionError, GatherND.infer, gathernd_node)
-
- def test_infer_invalid3(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- graph = build_graph(nodes_attributes, edges, inputs_inv3)
- gathernd_node = Node(graph, 'gathernd_node')
- self.assertRaises(AssertionError, GatherND.infer, gathernd_node)
-
-
- def test_partial_infer_gather_slice_batch_dims2_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs2)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = int64_array([10, 40, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims3_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 3
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs3)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = int64_array([1, 64, 64, 1])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2_dynamic1_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs9)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = shape_array([dynamic_dimension_value, 40, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(strict_compare_tensors(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2_dynamic2_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs10)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = shape_array([40, dynamic_dimension_value, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(strict_compare_tensors(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer_gather_slice_batch_dims2_dynamic3_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs11)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # prepare reference results
- ref_output_shape = shape_array([40, 40, 3, 5, 9])
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(strict_compare_tensors(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_infer7_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs7)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- output = output7.reshape([2, 3, 1])
-
- self.assertTrue(np.array_equal(output, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output, res_output_value))
-
- def test_infer8_opset8(self):
- nodes_attributes['gathernd_node']['batch_dims'] = 2
- nodes_attributes['gathernd_node']['version'] = 'opset8'
- graph = build_graph(nodes_attributes, edges, inputs8)
- gathernd_node = Node(graph, 'gathernd_node')
- GatherND.infer(gathernd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- output = output8.reshape([2, 3, 3])
-
- self.assertTrue(np.array_equal(output, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output, res_output_value))
diff --git a/tools/mo/unit_tests/mo/ops/grn_test.py b/tools/mo/unit_tests/mo/ops/grn_test.py
deleted file mode 100644
index 09c8f1ad89c991..00000000000000
--- a/tools/mo/unit_tests/mo/ops/grn_test.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'grn': {'type': 'GRN', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-class TestGRNOp(unittest.TestCase):
- def test_grn_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'grn'),
- ('grn', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'grn': {'bias': 1}
- })
-
- grn_node = Node(graph, 'grn')
- copy_shape_infer(grn_node)
- exp_shape = np.array([1, 3, 227, 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/instance_normalization_test.py b/tools/mo/unit_tests/mo/ops/instance_normalization_test.py
deleted file mode 100644
index bdf483b77c9e69..00000000000000
--- a/tools/mo/unit_tests/mo/ops/instance_normalization_test.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.ops.instance_normalization import InstanceNormalization
-from openvino.tools.mo.graph.graph import Graph
-
-
-class InstanceNormalizationOp(unittest.TestCase):
- def test_constructor_supported_attrs(self):
- graph = Graph()
- op = InstanceNormalization(graph, attrs={'epsilon': 0.1})
- self.assertEqual(op.supported_attrs(), ['epsilon'])
diff --git a/tools/mo/unit_tests/mo/ops/interpolate_test.py b/tools/mo/unit_tests/mo/ops/interpolate_test.py
deleted file mode 100644
index 48b1cdf7f9c279..00000000000000
--- a/tools/mo/unit_tests/mo/ops/interpolate_test.py
+++ /dev/null
@@ -1,269 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.interpolate import Interpolate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-graph_node_attrs_without_axes = {
- 'input': {'type': 'Parameter', 'kind': 'op'},
- 'input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sizes': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'sizes_data': {'kind': 'data', 'shape': None, 'value': None},
- 'scales': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'scales_data': {'kind': 'data', 'shape': None, 'value': None},
- 'interpolate': {
- 'type': 'Interpolate', 'kind': 'op', 'mode': 'nearest', 'shape_calculation_mode': 'sizes',
- 'coordinate_transformation_mode': 'half_pixel', 'version': 'opset4',
- 'nearest_mode': 'round_prefer_floor', 'antialias': 0,
- },
- 'interpolate_data': {'kind': 'data', 'value': None, 'shape': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges_without_axes = [
- ('input', 'input_data'),
- ('sizes', 'sizes_data'),
- ('scales', 'scales_data'),
- ('input_data', 'interpolate', {'in': 0}),
- ('sizes_data', 'interpolate', {'in': 1}),
- ('scales_data', 'interpolate', {'in': 2}),
- ('interpolate', 'interpolate_data'),
- ('interpolate_data', 'op_output'),
-]
-
-
-graph_nodes_attrs = {
- 'input': {'type': 'Parameter', 'kind': 'op'},
- 'input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'sizes': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'sizes_data': {'kind': 'data', 'shape': None, 'value': None},
- 'scales': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'scales_data': {'kind': 'data', 'shape': None, 'value': None},
- 'axes': {'type': 'Const', 'kind': 'op', 'shape': None, 'value': None},
- 'axes_data': {'kind': 'data', 'shape': None, 'value': None},
- 'interpolate': {
- 'type': 'Interpolate', 'kind': 'op', 'mode': 'nearest', 'shape_calculation_mode': 'sizes',
- 'coordinate_transformation_mode': 'half_pixel', 'version': 'opset4',
- 'nearest_mode': 'round_prefer_floor', 'antialias': 0,
- },
- 'interpolate_data': {'kind': 'data', 'value': None, 'shape': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
-}
-
-graph_edges = [
- ('input', 'input_data'),
- ('sizes', 'sizes_data'),
- ('scales', 'scales_data'),
- ('axes', 'axes_data'),
- ('input_data', 'interpolate', {'in': 0}),
- ('sizes_data', 'interpolate', {'in': 1}),
- ('scales_data', 'interpolate', {'in': 2}),
- ('axes_data', 'interpolate', {'in': 3}),
- ('interpolate', 'interpolate_data'),
- ('interpolate_data', 'op_output'),
-]
-
-
-class TestInterpolateOp():
- @pytest.mark.parametrize("pads_begin, pads_end, input_shape, output_shape, sizes, scales, axes",
- [([0], [0], [1, 3, 100, 200], [1, 3, 350, 150], [350, 150], [3.5, 150 / 200], [2, 3]),
- ([0, 3, 10, 10], [0], [16, 7, 190, 400], [8, 10, 390, 600],
- [8, 390, 600], [0.5, 390 / 200, 600 / 410], [0, 2, 3]),
- ([10, 5, 0, 10], [0, 4, 16, 18], [4, 33, 1024, 8000], [56, 42, 520, 8028],
- [56, 520], [4.0, 0.5], [0, 2]),
- ([0], [0], [1, 16, 85, 470, 690], [20, 16, 40, 470, 1380],
- [20, 40, 1380], [20.0, 40.0 / 85.0, 1380.0 / 690.0], [0, 2, 4]),
- ([4, 3, 11, 22, 5], [1, 3, 4, 8, 5], [1, 16, 85, 470, 690], [60, 22, 430, 500, 345],
- [60, 430, 345], [10.0, 4.3, 345.0 / 700.0], [0, 2, 4]),
- ([0], [0], [5, 77, 444, 88, 6050], [100, 308, 4440, 44, 6050],
- [100, 308, 4440, 44], [20.0, 4.0, 10.0, 0.5], [0, 1, 2, 3]),
- ([0], [0], [1, 100, 200], [1, 350, 150], [350, 150], [3.5, 150 / 200], [1, 2]),
- ([0, 3, 10], [0], [16, 7, 190], [8, 10, 390], [8, 390], [0.5, 390 / 200], [0, 2]),
- ([10, 0, 10], [0, 16, 18], [4, 1024, 8000], [56, 520, 8028], [56, 520], [4.0, 0.5], [0, 1]),
- ([0], [0], [1, 690], [20, 1380], [20, 1380], [20.0, 1380.0 / 690.0], [0, 1]),
- ([4, 3, 11, 22, 5, 0], [1, 3, 4, 8, 5, 0], [1, 16, 85, 470, 690, 349], [60, 22, 430, 500, 345, 349],
- [60, 430, 345], [10.0, 4.3, 345.0 / 700.0], [0, 2, 4])
- ])
- def test_interpolate4_using_sizes(self, pads_begin, pads_end, input_shape, output_shape, sizes, scales, axes):
- graph = build_graph(nodes_attrs=graph_nodes_attrs,
- edges=graph_edges,
- update_attributes={
- 'input_data': {'shape': input_shape},
- 'sizes': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'sizes_data': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'scales': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'scales_data': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'axes': {'shape': int64_array(axes).shape, 'value': int64_array(axes)},
- 'axes_data': {'shape': int64_array(axes).shape, 'value': int64_array(axes)},
- 'interpolate': {'pads_begin': int64_array(pads_begin),
- 'pads_end': int64_array(pads_end)}
- })
-
- node = Node(graph, 'interpolate')
- tested_class = Interpolate(graph=graph, attrs=node.attrs())
- tested_class.infer(node)
-
- msg = "Interpolate-4 infer failed for case: sizes={}, scales={}, pads_begin={}, pads_end={}, axes={}," \
- " expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['interpolate_data']['shape'], int64_array(output_shape)),\
- msg.format(sizes, scales, pads_begin, pads_end, axes, output_shape,
- graph.node['interpolate_data']['shape'])
-
- @pytest.mark.parametrize("pads_begin, pads_end, input_shape, output_shape, sizes, scales, axes",
- [([0], [0], [1, 3, 100, 200], [1, 3, 350, 150], [350, 150], [3.5, 150 / 200], [2, 3]),
- ([0, 3, 10, 10], [0], [16, 7, 190, 400], [8, 10, 390, 600],
- [8, 390, 600], [0.5, 390 / 200, 600 / 410], [0, 2, 3]),
- ([10, 5, 0, 10], [0, 4, 16, 18], [4, 33, 1024, 8000], [56, 42, 520, 8028],
- [56, 520], [4.0, 0.5], [0, 2]),
- ([0], [0], [1, 16, 85, 470, 690], [20, 16, 40, 470, 1380],
- [20, 40, 1380], [20.0, 40.0 / 85.0, 1380.0 / 690.0], [0, 2, 4]),
- ([4, 3, 11, 22, 5], [1, 3, 4, 8, 5], [1, 16, 85, 470, 690], [60, 22, 430, 500, 345],
- [60, 430, 345], [10.0, 4.3, 345.0 / 700.0], [0, 2, 4]),
- ([0], [0], [5, 77, 444, 88, 6050], [100, 308, 4440, 44, 6050],
- [100, 308, 4440, 44], [20.0, 4.0, 10.0, 0.5], [0, 1, 2, 3]),
- ([0], [0], [1, 100, 200], [1, 350, 150], [350, 150], [3.5, 150 / 200], [1, 2]),
- ([0, 3, 10], [0], [16, 7, 190], [8, 10, 390], [8, 390], [0.5, 390 / 200], [0, 2]),
- ([10, 0, 10], [0, 16, 18], [4, 1024, 8000], [56, 520, 8028], [56, 520], [4.0, 0.5], [0, 1]),
- ([0], [0], [1, 690], [20, 1380], [20, 1380], [20.0, 1380.0 / 690.0], [0, 1]),
- ([4, 3, 11, 22, 5, 0], [1, 3, 4, 8, 5, 0], [1, 16, 85, 470, 690, 349], [60, 22, 430, 500, 345, 349],
- [60, 430, 345], [10.0, 4.3, 345.0 / 700.0], [0, 2, 4]),
- ([4, 3, 11, 22, 5, 0, 0], [1, 3, 4, 8, 5, 0, 0], [1, 16, 85, 470, 690, 349, 3],
- [60, 22, 430, 500, 345, 349, 1],
- [60, 430, 345, 1], [10.0, 4.3, 345.0 / 700.0, 1 / 3], [0, 2, 4, 6]),
- ([4, 3, 11, 22, 5, 0, 0], [1, 3, 4, 8, 5, 0, 0], [1, 16, 85, 470, 690, 349, 3],
- [60, 22, 430, 500, 345, 349, 1],
- [60, 430, 345, 1], [10.0, 4.3, 345.0 / 700.0, 0.3333333], [0, 2, 4, 6]),
- ])
- def test_interpolate4_using_scales(self, pads_begin, pads_end, input_shape, output_shape, sizes, scales, axes):
- graph = build_graph(nodes_attrs=graph_nodes_attrs,
- edges=graph_edges,
- update_attributes={
- 'input_data': {'shape': input_shape},
- 'sizes': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'sizes_data': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'scales': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'scales_data': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'axes': {'shape': int64_array(axes).shape, 'value': int64_array(axes)},
- 'axes_data': {'shape': int64_array(axes).shape, 'value': int64_array(axes)},
- 'interpolate': {'pads_begin': int64_array(pads_begin),
- 'pads_end': int64_array(pads_end),
- 'shape_calculation_mode': 'scales'}
- })
-
- node = Node(graph, 'interpolate')
- tested_class = Interpolate(graph=graph, attrs=node.attrs())
- tested_class.infer(node)
-
- msg = "Interpolate-4 infer failed for case: sizes={}, scales={}, pads_begin={}, pads_end={}, axes={}," \
- " expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['interpolate_data']['shape'], int64_array(output_shape)),\
- msg.format(sizes, scales, pads_begin, pads_end, axes, output_shape,
- graph.node['interpolate_data']['shape'])
-
- @pytest.mark.parametrize("pads_begin, pads_end, input_shape, output_shape, sizes, scales",
- [([0], [0], [1, 3, 100, 200], [1, 3, 350, 150], [1, 3, 350, 150], [1.0, 1.0, 3.5, 150 / 200]),
- ([0, 3, 10, 10], [0], [16, 7, 190, 400], [8, 10, 390, 600],
- [8, 10, 390, 600], [0.5, 1.0, 390 / 200, 600 / 410]),
- ([10, 5, 0, 10], [0, 4, 16, 18], [4, 33, 1024, 8000], [56, 42, 520, 8028],
- [56, 42, 520, 8028], [4.0, 1.0, 0.5, 1.0]),
- ([0], [0], [1, 16, 85, 470, 690], [20, 16, 40, 470, 1380],
- [20, 16, 40, 470, 1380], [20.0, 1.0, 40.0 / 85.0, 1.0, 1380.0 / 690.0]),
- ([4, 3, 11, 22, 5], [1, 3, 4, 8, 5], [1, 16, 85, 470, 690], [60, 22, 430, 500, 345],
- [60, 22, 430, 500, 345], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0]),
- ([0], [0], [5, 77, 444, 88, 6050], [100, 308, 4440, 44, 6050],
- [100, 308, 4440, 44, 6050], [20.0, 4.0, 10.0, 0.5, 1.0]),
- ([0], [0], [1, 100, 200], [1, 350, 150], [1, 350, 150], [1.0, 3.5, 150 / 200]),
- ([0, 3, 10], [0], [16, 7, 190], [8, 10, 390], [8, 10, 390], [0.5, 1.0, 390 / 200]),
- ([10, 0, 10], [0, 16, 18], [4, 1024, 8000], [56, 520, 8028], [56, 520, 8028], [4.0, 0.5, 1.0]),
- ([0], [0], [1, 690], [20, 1380], [20, 1380], [20.0, 1380.0 / 690.0]),
- ([4, 3, 11, 22, 5, 0], [1, 3, 4, 8, 5, 0], [1, 16, 85, 470, 690, 349], [60, 22, 430, 500, 345, 349],
- [60, 22, 430, 500, 345, 349], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0, 1.0]),
- ([4, 3, 11, 22, 5, 0, 0], [1, 3, 4, 8, 5, 0, 0], [1, 16, 85, 470, 690, 349, 3],
- [60, 22, 430, 500, 345, 349, 1],
- [60, 22, 430, 500, 345, 349, 1], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0, 1.0, 1 / 3]),
- ])
- def test_interpolate4_using_sizes_without_axes(self, pads_begin, pads_end, input_shape, output_shape, sizes,
- scales):
- graph = build_graph(nodes_attrs=graph_node_attrs_without_axes,
- edges=graph_edges_without_axes,
- update_attributes={
- 'input_data': {'shape': input_shape},
- 'sizes': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'sizes_data': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'scales': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'scales_data': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'interpolate': {'pads_begin': int64_array(pads_begin),
- 'pads_end': int64_array(pads_end),
- 'shape_calculation_mode': 'sizes'}
- })
-
- node = Node(graph, 'interpolate')
- tested_class = Interpolate(graph=graph, attrs=node.attrs())
- tested_class.infer(node)
-
- msg = "Interpolate-4 infer failed for case: sizes={}, scales={}, pads_begin={}, pads_end={}," \
- " expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['interpolate_data']['shape'], int64_array(output_shape)),\
- msg.format(sizes, scales, pads_begin, pads_end, output_shape,
- graph.node['interpolate_data']['shape'])
-
- @pytest.mark.parametrize("pads_begin, pads_end, input_shape, output_shape, sizes, scales",
- [([0], [0], [1, 3, 100, 200], [1, 3, 350, 150], [1, 3, 350, 150], [1.0, 1.0, 3.5, 150 / 200]),
- ([0, 3, 10, 10], [0], [16, 7, 190, 400], [8, 10, 390, 600],
- [8, 10, 390, 600], [0.5, 1.0, 390 / 200, 600 / 410]),
- ([10, 5, 0, 10], [0, 4, 16, 18], [4, 33, 1024, 8000], [56, 42, 520, 8028],
- [56, 42, 520, 8028], [4.0, 1.0, 0.5, 1.0]),
- ([0], [0], [1, 16, 85, 470, 690], [20, 16, 40, 470, 1380],
- [20, 16, 40, 470, 1380], [20.0, 1.0, 40.0 / 85.0, 1.0, 1380.0 / 690.0]),
- ([4, 3, 11, 22, 5], [1, 3, 4, 8, 5], [1, 16, 85, 470, 690], [60, 22, 430, 500, 345],
- [60, 22, 430, 500, 345], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0]),
- ([0], [0], [5, 77, 444, 88, 6050], [100, 308, 4440, 44, 6050],
- [100, 308, 4440, 44, 6050], [20.0, 4.0, 10.0, 0.5, 1.0]),
- ([0], [0], [1, 100, 200], [1, 350, 150], [1, 350, 150], [1.0, 3.5, 150 / 200]),
- ([0, 3, 10], [0], [16, 7, 190], [8, 10, 390], [8, 10, 390], [0.5, 1.0, 390 / 200]),
- ([10, 0, 10], [0, 16, 18], [4, 1024, 8000], [56, 520, 8028], [56, 520, 8028], [4.0, 0.5, 1.0]),
- ([0], [0], [1, 690], [20, 1380], [20, 1380], [20.0, 1380.0 / 690.0]),
- ([4, 3, 11, 22, 5, 0], [1, 3, 4, 8, 5, 0], [1, 16, 85, 470, 690, 349], [60, 22, 430, 500, 345, 349],
- [60, 22, 430, 500, 345, 349], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0, 1.0]),
- ([4, 3, 11, 22, 5, 0, 0], [1, 3, 4, 8, 5, 0, 0], [1, 16, 85, 470, 690, 349, 3],
- [60, 22, 430, 500, 345, 349, 1],
- [60, 22, 430, 500, 345, 349, 1], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0, 1.0, 1 / 3]),
- ([4, 3, 11, 22, 5, 0, 0], [1, 3, 4, 8, 5, 0, 0], [1, 16, 85, 470, 690, 349, 3],
- [60, 22, 430, 500, 345, 349, 1],
- [60, 22, 430, 500, 345, 349, 1], [10.0, 1.0, 4.3, 1.0, 345.0 / 700.0, 1.0, 0.3333333]),
- ])
- def test_interpolate4_using_scales_without_axes(self, pads_begin, pads_end, input_shape, output_shape, sizes,
- scales):
- graph = build_graph(nodes_attrs=graph_node_attrs_without_axes,
- edges=graph_edges_without_axes,
- update_attributes={
- 'input_data': {'shape': input_shape},
- 'sizes': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'sizes_data': {'shape': int64_array(sizes).shape, 'value': int64_array(sizes)},
- 'scales': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'scales_data': {'shape': np.array(scales).shape, 'value': np.array(scales)},
- 'interpolate': {'pads_begin': int64_array(pads_begin),
- 'pads_end': int64_array(pads_end),
- 'shape_calculation_mode': 'scales'}
- })
-
- node = Node(graph, 'interpolate')
- tested_class = Interpolate(graph=graph, attrs=node.attrs())
- tested_class.infer(node)
-
- msg = "Interpolate-4 infer failed for case: sizes={}, scales={}, pads_begin={}, pads_end={}," \
- " expected_shape={}, actual_shape={}"
-
- assert np.array_equal(graph.node['interpolate_data']['shape'], int64_array(output_shape)),\
- msg.format(sizes, scales, pads_begin, pads_end, output_shape,
- graph.node['interpolate_data']['shape'])
diff --git a/tools/mo/unit_tests/mo/ops/merge_test.py b/tools/mo/unit_tests/mo/ops/merge_test.py
deleted file mode 100644
index 8130832f1536e0..00000000000000
--- a/tools/mo/unit_tests/mo/ops/merge_test.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.merge import Merge
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_attrs
-
-
-class TestMerge(unittest.TestCase):
- nodes = [
- ('first', {'value': np.ones((2, 2)), 'kind': 'data', 'executable': True, 'shape': np.array([2, 2]),
- 'is_partial_inferred': True}),
- ('second', {'value': np.zeros((2, 2)), 'kind': 'data', 'executable': False, 'shape': np.array([2, 2]),
- 'is_partial_inferred': True}),
- ('merge', {'type': 'Merge', 'kind': 'op', 'op': 'Merge'}),
- ('merge_output', {'value': None, 'kind': 'data', 'executable': True, 'shape': None}),
- ]
- edges = [
- ('first', 'merge', {'in': 0}),
- ('second', 'merge', {'in': 1}),
- ('merge', 'merge_output', {'out': 0}),
- ]
-
- def test_merge_infer_simple_case_one_executable(self):
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges)
-
- # We should propagate value of the first input since only this input is executable
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[('merge_output', {'shape': np.array([2, 2]),
- 'value': np.ones((2, 2))}),
- ('merge', {'is_not_fully_inferred': False})])
-
- tested_class = Merge(graph=graph, attrs={})
- node = Node(graph, 'merge')
- tested_class.merge_infer(node)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'merge_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_merge_infer_complex_case(self):
- """
- Case as in cycles when in first visit only one input are inferred and in the second -- both.
- """
- graph = build_graph_with_attrs(nodes_with_attrs=self.nodes, edges_with_attrs=self.edges,
- update_nodes_attributes=[('first', {'is_partial_inferred': False,
- 'value': None}),
- ('second', {'executable': True})])
-
- # In first visit we should propagate only shapes
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[('second', {'executable': True}),
- ('first', {'is_partial_inferred': False,
- 'value': None}),
- ('merge_output', {'shape': np.array([2, 2]),
- 'value': None}),
- ('merge', {'is_not_fully_inferred': True})])
- tested_class = Merge(graph=graph, attrs={})
- node = Node(graph, 'merge')
- tested_class.merge_infer(node)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'merge_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- # Imitate that inputs nodes now is inferred
- graph.node['first']['is_partial_inferred'] = True
-
- # Run infer second time
- tested_class = Merge(graph=graph, attrs={})
- node = Node(graph, 'merge')
- tested_class.merge_infer(node)
-
- graph_ref = build_graph_with_attrs(nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[('second', {'executable': True}),
- ('first', {'is_partial_inferred': True,
- 'value': None}),
- ('merge_output', {'shape': np.array([2, 2]),
- 'value': None}),
- ('merge', {'is_not_fully_inferred': False})])
- (flag, resp) = compare_graphs(graph, graph_ref, 'merge_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_merge_infer_only_second_executable(self):
- graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[
- ('first', {'executable': False, 'value': np.ones([2, 2]), 'shape': int64_array([2, 2])}),
- ('second', {'executable': True, 'value': np.zeros([4, 4]), 'shape': int64_array([4, 4])})
- ]
- )
-
- ref_graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[
- ('first', {'executable': False, 'value': np.ones([2, 2]), 'shape': int64_array([2, 2])}),
- ('second', {'executable': True, 'value': np.zeros([4, 4]), 'shape': int64_array([4, 4])}),
- ('merge', {'is_not_fully_inferred': False}),
- ('merge_output', {'shape': int64_array([4, 4]), 'value': np.zeros([4, 4])})
- ]
- )
-
- tested_class = Merge(graph=graph, attrs={})
- node = Node(graph, 'merge')
- tested_class.merge_infer(node)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'merge_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_merge_infer_no_executable(self):
- graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[
- ('first', {'executable': False, 'value': np.ones([2, 2]), 'shape': int64_array([2, 2])}),
- ('second', {'executable': False, 'value': np.zeros([4, 4]), 'shape': int64_array([4, 4])})
- ]
- )
-
- ref_graph = build_graph_with_attrs(
- nodes_with_attrs=self.nodes,
- edges_with_attrs=self.edges,
- update_nodes_attributes=[
- ('first', {'executable': False, 'value': np.ones([2, 2]), 'shape': int64_array([2, 2])}),
- ('second', {'executable': False, 'value': np.zeros([4, 4]), 'shape': int64_array([4, 4])}),
- ('merge', {'is_not_fully_inferred': False}),
- ('merge_output', {'shape': int64_array([2, 2]), 'value': None})
- ]
- )
-
- tested_class = Merge(graph=graph, attrs={})
- node = Node(graph, 'merge')
- tested_class.merge_infer(node)
-
- (flag, resp) = compare_graphs(graph, ref_graph, 'merge_output', check_op_attrs=True)
- self.assertTrue(flag, resp)
diff --git a/tools/mo/unit_tests/mo/ops/non_max_suppression_test.py b/tools/mo/unit_tests/mo/ops/non_max_suppression_test.py
deleted file mode 100644
index 5962772a7062b6..00000000000000
--- a/tools/mo/unit_tests/mo/ops/non_max_suppression_test.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.non_max_suppression import NonMaxSuppression
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op, regular_op_with_shaped_data, valued_const_with_data, result, connect, empty_data
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value
-
-
-class TestNonMaxSuppressionInfer(unittest.TestCase):
- def setUp(self):
- nodes = {
- **regular_op_with_shaped_data('boxes', [10, 100, 4], {'type': 'Parameter'}),
- **regular_op_with_shaped_data('scores', [10, 5, 100], {'type': 'Parameter'}),
- **valued_const_with_data('max_output_per_class', int64_array(7)),
- **regular_op('nms', {'op': 'NonMaxSuppression', 'type': 'NonMaxSuppression', 'name': 'nms'}),
-
- **empty_data('nms_data_0'),
- **empty_data('nms_data_1'),
- **empty_data('nms_data_2'),
- **result('output_0'),
- **result('output_1'),
- **result('output_2'),
- }
-
- self.graph = build_graph(nodes, [
- *connect('boxes', '0:nms'),
- *connect('scores', '1:nms'),
- *connect('max_output_per_class', '2:nms'),
- *connect('nms:0', 'nms_data_0', front_phase=True), # Use this WA for correct creating operation
- *connect('nms_data_0', 'output_0', front_phase=True), # with multiple outputs
- ], nodes_with_edges_only=True)
-
- self.graph_nms_5_2_outs = build_graph(nodes, [
- *connect('boxes', '0:nms'),
- *connect('scores', '1:nms'),
- *connect('max_output_per_class', '2:nms'),
- *connect('nms:0', 'nms_data_0', front_phase=True), # Use this WA for correct creating operation
- *connect('nms_data_0', 'output_0', front_phase=True), # with multiple outputs
- *connect('nms:1', 'nms_data_1', front_phase=True),
- *connect('nms_data_1', 'output_1', front_phase=True),
- ], nodes_with_edges_only=True)
-
- self.graph_nms_5_3_outs = build_graph(nodes, [
- *connect('boxes', '0:nms'),
- *connect('scores', '1:nms'),
- *connect('max_output_per_class', '2:nms'),
- *connect('nms:0', 'nms_data_0', front_phase=True), # Use this WA for correct creating operation
- *connect('nms_data_0', 'output_0', front_phase=True), # with multiple outputs
- *connect('nms:1', 'nms_data_1', front_phase=True),
- *connect('nms_data_1', 'output_1', front_phase=True),
- *connect('nms:2', 'nms_data_2', front_phase=True),
- *connect('nms_data_2', 'output_2', front_phase=True),
- ], nodes_with_edges_only=True)
-
- def test_nms_infer_opset1(self):
- 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.int64)
-
- def test_nms_infer_i64_opset3(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset3'
- nms_node['output_type'] = np.int64
- 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.int64)
-
- def test_nms_infer_i32_opset3(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset3'
- nms_node['output_type'] = np.int32
- 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_i32_opset4(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset4'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(), [10 * 5 * 7, 3]))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
-
- def test_nms_infer_i64_opset4(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset4'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(), [10 * 5 * 7, 3]))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
-
- def test_nms_infer_i32_opset5_1_out(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset5'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
-
- def test_nms_infer_i64_opset5_1_out(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset5'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
-
- def test_nms_infer_i32_opset5_2_outs(self):
- nms_node = Node(self.graph_nms_5_2_outs, 'nms')
- nms_node['version'] = 'opset5'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
-
- def test_nms_infer_i64_opset5_2_outs(self):
- nms_node = Node(self.graph_nms_5_2_outs, 'nms')
- nms_node['version'] = 'opset5'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
-
- def test_nms_infer_i32_opset5_3_outs(self):
- nms_node = Node(self.graph_nms_5_3_outs, 'nms')
- nms_node['version'] = 'opset5'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(2).data.get_shape(), [1]))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
- self.assertTrue(nms_node.out_port(2).get_data_type() == np.int64)
-
- def test_nms_infer_i64_opset5_3_outs(self):
- nms_node = Node(self.graph_nms_5_3_outs, 'nms')
- nms_node['version'] = 'opset5'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(2).data.get_shape(), [1]))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
- self.assertTrue(nms_node.out_port(2).get_data_type() == np.int64)
-
- def test_nms_infer_i32_opset9_1_out(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset9'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
-
- def test_nms_infer_i64_opset9_1_out(self):
- nms_node = Node(self.graph, 'nms')
- nms_node['version'] = 'opset9'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
-
- def test_nms_infer_i32_opset9_2_outs(self):
- nms_node = Node(self.graph_nms_5_2_outs, 'nms')
- nms_node['version'] = 'opset9'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
-
- def test_nms_infer_i64_opset9_2_outs(self):
- nms_node = Node(self.graph_nms_5_2_outs, 'nms')
- nms_node['version'] = 'opset9'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
-
- def test_nms_infer_i32_opset9_3_outs(self):
- nms_node = Node(self.graph_nms_5_3_outs, 'nms')
- nms_node['version'] = 'opset9'
- nms_node['output_type'] = np.int32
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(2).data.get_shape(), [1]))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int32)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
- self.assertTrue(nms_node.out_port(2).get_data_type() == np.int64)
-
- def test_nms_infer_i64_opset9_3_outs(self):
- nms_node = Node(self.graph_nms_5_3_outs, 'nms')
- nms_node['version'] = 'opset9'
- nms_node['output_type'] = np.int64
- NonMaxSuppression.infer(nms_node)
- NonMaxSuppression.type_infer(nms_node)
-
- self.assertTrue(np.array_equal(nms_node.out_port(0).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(1).data.get_shape(),
- shape_array([dynamic_dimension_value, 3])))
- self.assertTrue(np.array_equal(nms_node.out_port(2).data.get_shape(), [1]))
- self.assertTrue(nms_node.out_port(0).get_data_type() == np.int64)
- self.assertTrue(nms_node.out_port(1).get_data_type() == np.float32)
- self.assertTrue(nms_node.out_port(2).get_data_type() == np.int64)
diff --git a/tools/mo/unit_tests/mo/ops/normalize_test.py b/tools/mo/unit_tests/mo/ops/normalize_test.py
deleted file mode 100644
index d8967af423a65a..00000000000000
--- a/tools/mo/unit_tests/mo/ops/normalize_test.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.elemental import copy_shape_infer
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'norm': {'type': 'Normalize', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestNormalize(unittest.TestCase):
- def test_region_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'norm'),
- ('norm', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227]), 'value': None},
- 'norm': {}
- })
-
- norm_node = Node(graph, 'norm')
- copy_shape_infer(norm_node)
- exp_shape = np.array([1, 3, 227, 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/one_hot_test.py b/tools/mo/unit_tests/mo/ops/one_hot_test.py
deleted file mode 100644
index 5658e3f291a2d4..00000000000000
--- a/tools/mo/unit_tests/mo/ops/one_hot_test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.one_hot import OneHot
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, connect
-
-
-def generate_nodes(data, axis=-1, depth=4, on_value=1., off_value=0.):
- return {
- 'indices': {'Op': 'Parameter', 'value': data, 'shape': int64_array(data.shape)},
- 'indices_d': {'kind': 'data', 'value': data, 'shape': int64_array(data.shape)},
- **valued_const_with_data('depth', int64_array(depth)),
- **valued_const_with_data('on_value', float_array(on_value)),
- **valued_const_with_data('off_value', float_array(off_value)),
- **regular_op_with_shaped_data('one_hot', None, {'type': 'OneHot', 'axis': axis, 'Op': 'OneHot'})
- }
-
-
-edges = [
- *connect('indices:0', 'one_hot:0'),
- *connect('depth:0', 'one_hot:1'),
- *connect('on_value:0', 'one_hot:2'),
- *connect('off_value:0', 'one_hot:3'),
- ('one_hot', 'one_hot_d')
-]
-
-
-class TestOneHotInfer():
- @pytest.mark.parametrize("input_value, exp_value, axis",[
- # 0d input
- (1, [0, 1, 0, 0], -1),
- # 1d input
- ([1, 2], [[0, 1, 0, 0], [0, 0, 1, 0]], -1),
- # 2D input
- ([[1, 2], [3, 4]], [[[0, 1, 0, 0], [0, 0, 1, 0]],
- [[0, 0, 0, 1], [0, 0, 0, 0]]], -1),
- # 3d input
- ([[[0, 2], [1, 2]], [[2, 1], [3, 0]]],
- [[[[1, 0, 0, 0], [0, 0, 1, 0]], [[0, 1, 0, 0], [0, 0, 1, 0]]],
- [[[0, 0, 1, 0], [0, 1, 0, 0]], [[0, 0, 0, 1], [1, 0, 0, 0]]]], -1),
- # 1d input with negative indices
- ([-2, 2], [[0, 0, 1, 0], [0, 0, 1, 0]], -1),
- # check if axis is neither 0 nor -1
- ([[1, 2], [3, 4]], [[[0, 0], [1, 0], [0, 1], [0, 0]],
- [[0, 0], [0, 0], [0, 0], [1, 0]]], 1)
- ])
- def test_infer(self, input_value, exp_value, axis):
- graph = build_graph(generate_nodes(int64_array(input_value), axis), edges)
- onehot_node = Node(graph, 'one_hot')
- OneHot.infer(onehot_node)
- res_value = graph.node['one_hot_d']['value']
- assert np.array_equal(exp_value, int64_array(res_value))
diff --git a/tools/mo/unit_tests/mo/ops/op_test.py b/tools/mo/unit_tests/mo/ops/op_test.py
deleted file mode 100644
index 93bf9817f8d401..00000000000000
--- a/tools/mo/unit_tests/mo/ops/op_test.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.ops.lstm_cell import LSTMCell
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op
-
-nodes = {
- **regular_op('Op1', {'type': 'Op1', 'kind': 'op', 'op': 'Op1'}),
- **regular_op('Op2', {'type': 'Op2', 'kind': 'op', 'op': 'Op2'}),
- **regular_op('Op3', {'type': 'Op3', 'kind': 'op', 'op': 'Op3'}),
-}
-
-
-class TestOp(unittest.TestCase):
- def test_create_node(self):
- graph = build_graph(nodes, [('Op1', 'Op3', {'in': 0, 'out': 0, 'fw_tensor_debug_info': [('Op1', 'Op1')]}),
- ('Op2', 'Op3', {'in': 1, 'out': 0, 'fw_tensor_debug_info': [('Op2', 'Op2')]})])
- graph.stage = 'front'
- input1 = Node(graph, 'Op1')
- input2 = Node(graph, 'Op2')
- inputs = [(input1, 0), (input2, 0)]
-
- lstm_op = LSTMCell(graph, dict(name='LSTMCell'))
- _ = lstm_op.create_node(inputs)
-
- self.assertTrue(input1.out_edge(0)['fw_tensor_debug_info'] == [('Op1', 'Op1')])
- self.assertTrue(input2.out_edge(0)['fw_tensor_debug_info'] == [('Op2', 'Op2')])
diff --git a/tools/mo/unit_tests/mo/ops/pad_test.py b/tools/mo/unit_tests/mo/ops/pad_test.py
deleted file mode 100644
index df999ae88318da..00000000000000
--- a/tools/mo/unit_tests/mo/ops/pad_test.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, dynamic_dimension, \
- strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.pad import Pad, AttributedPad
-from unit_tests.utils.graph import build_graph
-
-
-class TestPadOps(unittest.TestCase):
- node_attrs = {
- 'data_in': {
- 'kind': 'data',
- 'shape': np.array([1, 3, 100, 200]),
- 'value': None,
- },
- 'pads_begin': {
- 'kind': 'data',
- 'value': np.array([0, 0, 1, 2], dtype=np.int64),
- 'shape': np.array([4], dtype=np.int64)
- },
- 'pads_end': {
- 'kind': 'data',
- 'value': np.array([0, 0, 3, 4], dtype=np.int64),
- 'shape': np.array([4], dtype=np.int64)
- },
- 'pad': {
- 'op': 'Pad',
- 'kind': 'op',
- 'pads': None,
- },
- 'data_out': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- }
- }
-
- edge_attrs = [
- ('data_in', 'pad'),
- ('pad', 'data_out')
- ]
-
- def test_attribute_pad_no_infer(self):
- graph = build_graph(
- self.node_attrs,
- self.edge_attrs,
- {'pad': {'pads': np.array([[0, 0], [0, 0], [1, 3], [2, 4]], dtype=np.int64)}},
- nodes_with_edges_only=True,
- )
- pad_node = Node(graph, 'pad')
- with self.assertRaisesRegex(AttributeError, ".*has no attribute 'infer'.*"):
- AttributedPad.infer(pad_node)
-
- def test_two_inputs(self):
- graph = build_graph(
- self.node_attrs,
- self.edge_attrs + [('pads_begin', 'pad'), ('pads_end', 'pad')],
- nodes_with_edges_only=True,
- )
- pad_node = Node(graph, 'pad')
- Pad.infer(pad_node)
- self.assertTrue(np.array_equal(Node(graph, 'data_out').shape, np.array([1, 3, 100 + 1 + 3, 200 + 2 + 4])))
-
- def test_not_enough_inputs(self):
- graph = build_graph(
- self.node_attrs,
- self.edge_attrs + [('pads_begin', 'pad')],
- nodes_with_edges_only=True,
- )
- pad_node = Node(graph, 'pad')
- with self.assertRaisesRegex(AssertionError, ".*must have 3 or 4 inputs.*"):
- Pad.infer(pad_node)
-
- def test_two_inputs_value_infer(self):
- in_value = np.random.rand(*self.node_attrs['data_in']['shape']).astype(np.float32)
- graph = build_graph(
- self.node_attrs,
- self.edge_attrs + [('pads_begin', 'pad'), ('pads_end', 'pad')],
- {'data_in': {'value': in_value}},
- nodes_with_edges_only=True,
- )
-
- pads = np.insert(self.node_attrs['pads_end']['value'],
- np.arange(len(self.node_attrs['pads_begin']['value'])), self.node_attrs['pads_begin']['value'])
- pads = np.reshape(pads, (len(self.node_attrs['pads_begin']['value']), 2))
- ref_value = np.pad(in_value, pads, constant_values=0, mode='constant')
-
- pad_node = Node(graph, 'pad')
- Pad.infer(pad_node)
-
- self.assertTrue(np.array_equal(Node(graph, 'data_out').shape, np.array([1, 3, 100 + 1 + 3, 200 + 2 + 4])))
- self.assertTrue(np.array_equal(Node(graph, 'data_out').value, ref_value))
- self.assertFalse(isinstance(Node(graph, 'data_out').value, np.ma.masked_array))
-
- def test_two_inputs_dynamic_value_infer(self):
- in_value = shape_array([dynamic_dimension_value, 3]).reshape((1, 1, 1, 2))
- graph = build_graph(
- self.node_attrs,
- self.edge_attrs + [('pads_begin', 'pad'), ('pads_end', 'pad')],
- {'data_in': {'value': in_value, 'shape': in_value.shape}},
- nodes_with_edges_only=True,
- )
- out_shape = (1, 1, 5, 8)
- mask = np.zeros(out_shape, dtype=bool)
- mask[0][0][1][2] = True
- ref_value = np.ma.masked_array(np.zeros(out_shape, dtype=np.int64), mask=mask, dtype=np.int64)
- ref_value[0][0][1][3] = 3
-
- pad_node = Node(graph, 'pad')
- Pad.infer(pad_node)
- output_value = Node(graph, 'data_out').value
- self.assertTrue(np.array_equal(Node(graph, 'data_out').shape, ref_value.shape))
- self.assertTrue(strict_compare_tensors(output_value, ref_value))
- self.assertTrue(isinstance(output_value, np.ma.masked_array))
- self.assertTrue(output_value[0][0][1][2] is dynamic_dimension)
diff --git a/tools/mo/unit_tests/mo/ops/pooling_test.py b/tools/mo/unit_tests/mo/ops/pooling_test.py
deleted file mode 100644
index b1d91c2c4cbeb9..00000000000000
--- a/tools/mo/unit_tests/mo/ops/pooling_test.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.pooling import Pooling
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'value': None, 'kind': 'data'},
- 'pool': {'type': 'Pooling', 'value': None, 'kind': 'op'},
- 'node_2': {'value': None, 'kind': 'data'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-class TestPoolingPartialInfer(unittest.TestCase):
- def test_pooling_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 256, 256])},
- 'pool': {'window': np.array([1, 1, 1, 1]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [3, 3], [3, 3]]),
- 'pad_spatial_shape': np.array([[3, 3], [3, 3]]),
- 'pool_method': 'avg', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full'}
- })
-
- pool_node = Node(graph, 'pool')
-
- Pooling.infer(pool_node)
- exp_shape = np.array([1, 3, 131, 131])
- res_shape = graph.node['node_2']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_pooling_dynamic_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': shape_array([1, dynamic_dimension_value, dynamic_dimension_value,
- 256])},
- 'pool': {'window': np.array([1, 1, 1, 1]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [3, 3], [3, 3]]),
- 'pad_spatial_shape': np.array([[3, 3], [3, 3]]),
- 'pool_method': 'avg', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full'}
- })
-
- pool_node = Node(graph, 'pool')
-
- Pooling.infer(pool_node)
- exp_shape = shape_array([1, dynamic_dimension_value, dynamic_dimension_value, 131])
- res_shape = graph.node['node_2']['shape']
- self.assertTrue(strict_compare_tensors(exp_shape, res_shape))
-
- def test_pooling_infer_decrement_input_spatial(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 224, 224])},
- 'pool': {'window': np.array([1, 1, 1, 1]), 'stride': np.array([1, 1, 3, 3]),
- 'pad': np.array([[0, 0], [0, 0], [3, 3], [3, 3]]),
- 'pad_spatial_shape': np.array([[1, 1], [1, 1]]),
- 'pool_method': 'avg', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full'}
- })
-
- pool_node = Node(graph, 'pool')
-
- Pooling.infer(pool_node)
- exp_shape = np.array([1, 3, 75, 75])
- res_shape = graph.node['node_2']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_pooling_infer_no_convention(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 256, 256])},
- 'pool': {'window': np.array([1, 1, 1, 1]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [3, 3], [3, 3]]),
- 'pad_spatial_shape': np.array([[3, 3], [3, 3]]),
- 'pool_method': 'avg', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0])}
- })
-
- pool_node = Node(graph, 'pool')
-
- Pooling.infer(pool_node)
- exp_shape = np.array([1, 3, 130, 130])
- res_shape = graph.node['node_2']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_pooling_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': None},
- 'pool': {'window': np.array([1, 1, 1, 1]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [3, 3], [3, 3]]),
- 'pad_spatial_shape': np.array([[3, 3], [3, 3]]),
- 'pool_method': 'avg', 'exclude_pad': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full'}
- })
-
- pool_node = Node(graph, 'pool')
- Pooling.infer(pool_node)
- res_shape = graph.node['node_2']['shape']
- self.assertIsNone(res_shape)
-
- def test_pooling_infer_wrong_input_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 1, 1])},
- 'pool': {'window': np.array([1, 1, 5, 5]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [1, 1], [1, 1]]),
- 'pad_spatial_shape': np.array([[1, 1], [1, 1]]),
- 'pool_method': 'avg', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([3, 3]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full'}
- })
-
- pool_node = Node(graph, 'pool')
-
- with self.assertRaises(Error):
- Pooling.infer(pool_node)
-
- def test_pooling_infer_with_dilations(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'pool'),
- ('pool', 'node_2'),
- ('node_2', 'op_output')
- ],
- {'node_2': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 256, 256])},
- 'pool': {'window': np.array([1, 1, 2, 2]), 'stride': np.array([1, 1, 2, 2]),
- 'pad': np.array([[0, 0], [0, 0], [0, 0], [1, 1]]),
- 'pad_spatial_shape': np.array([[0, 0], [1, 1]]),
- 'pool_method': 'max', 'exclude_pad': False, 'global_pool': False,
- 'output_spatial_shape': None, 'output_shape': None,
- 'kernel_spatial': np.array([2, 2]), 'spatial_dims': np.array([2, 3]),
- 'channel_dims': np.array([1]), 'batch_dims': np.array([0]),
- 'pooling_convention': 'full', 'dilation': np.array([1, 1, 2, 2]),
- 'auto_pad': 'valid'}
- })
-
- pool_node = Node(graph, 'pool')
-
- Pooling.infer(pool_node)
- exp_shape = np.array([1, 3, 127, 127])
- res_shape = graph.node['node_2']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/priorbox_clustered_test.py b/tools/mo/unit_tests/mo/ops/priorbox_clustered_test.py
deleted file mode 100644
index bb29f481330b8f..00000000000000
--- a/tools/mo/unit_tests/mo/ops/priorbox_clustered_test.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.priorbox_clustered import PriorBoxClusteredOp
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'value': None, 'kind': 'data'},
- 'node_2': {'type': 'Identity', 'value': None, 'kind': 'data'},
- 'pbc': {'type': 'PriorBoxClustered', 'value': None, 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'data'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestPriorBoxClusteredPartialInfer(unittest.TestCase):
- def test_caffe_priorboxclustered_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pbc'),
- ('node_2', 'pbc'),
- ('pbc', 'node_3'),
- ('node_3', 'op_output')
- ],
- {
- 'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 384, 19, 19])},
- 'node_2': {'shape': np.array([1, 3, 300, 300])},
- 'pbc': {'flip': 0, 'clip': 0, 'variance': [0.1, 0.1, 0.2, 0.2],
- 'step': 0, 'offset': 0.5, 'width': [1., 1., 1., 1., 1., 1., 1., 1., 1.],
- 'height': [2., 2., 2., 2., 2., 2., 2., 2., 2.]}
- })
- graph.graph['layout'] = 'NCHW'
-
- pbc_node = Node(graph, 'pbc')
- PriorBoxClusteredOp.priorbox_clustered_infer(pbc_node)
- exp_shape = np.array([1, 2, 12996])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_tf_priorboxclustered_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pbc'),
- ('node_2', 'pbc'),
- ('pbc', 'node_3'),
- ('node_3', 'op_output')
- ],
- {
- 'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 19, 19, 384])},
- 'node_2': {'shape': np.array([1, 300, 300, 3])},
- 'pbc': {'flip': 0, 'clip': 0, 'variance': [0.1, 0.1, 0.2, 0.2],
- 'step': 0, 'offset': 0.5, 'width': [1., 1., 1., 1., 1., 1., 1., 1., 1.],
- 'height': [2., 2., 2., 2., 2., 2., 2., 2., 2.]}
- })
- graph.graph['layout'] = 'NHWC'
-
- pbc_node = Node(graph, 'pbc')
- PriorBoxClusteredOp.priorbox_clustered_infer(pbc_node)
- exp_shape = np.array([1, 2, 12996])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/priorbox_test.py b/tools/mo/unit_tests/mo/ops/priorbox_test.py
deleted file mode 100644
index 8717624eff8247..00000000000000
--- a/tools/mo/unit_tests/mo/ops/priorbox_test.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.priorbox import PriorBoxOp
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'value': None, 'kind': 'data'},
- 'pb': {'type': 'PriorBox', 'value': None, 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'value': None, 'kind': 'data'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestPriorBoxPartialInfer(unittest.TestCase):
- def test_caffe_priorbox_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pb'),
- ('pb', 'node_3'),
- ('node_3', 'op_output')
- ],
- {
- 'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 384, 19, 19])},
- 'pb': {
- 'aspect_ratio': np.array([1]),
- 'flip': 0,
- 'min_size': np.array([1]),
- 'max_size': np.array([1])
- }
- })
- graph.graph['layout'] = 'NCHW'
- pb_node = Node(graph, 'pb')
- PriorBoxOp.priorbox_infer(pb_node)
- exp_shape = np.array([1, 2, 4 * 19 * 19 * 2])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_priorbox_flip_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pb'),
- ('pb', 'node_3'),
- ('node_3', 'op_output')
- ],
- {
- 'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 384, 19, 19])},
- 'pb': {
- 'aspect_ratio': np.array([1, 2, 0.5]),
- 'flip': 1,
- 'min_size': np.array([1]),
- 'max_size': np.array([1])
- }
- })
- graph.graph['layout'] = 'NCHW'
- pb_node = Node(graph, 'pb')
- PriorBoxOp.priorbox_infer(pb_node)
- exp_shape = np.array([1, 2, 4 * 19 * 19 * 4])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_tf_priorbox_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pb'),
- ('pb', 'node_3'),
- ('node_3', 'op_output')
- ],
- {
- 'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 19, 19, 384])},
- 'pb': {
- 'aspect_ratio': np.array([1]),
- 'flip': 0,
- 'min_size': np.array([1]),
- 'max_size': np.array([1])
- }
- })
- graph.graph['layout'] = 'NHWC'
- pb_node = Node(graph, 'pb')
- PriorBoxOp.priorbox_infer(pb_node)
- exp_shape = np.array([1, 2, 4 * 19 * 19 * 2])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_tf_priorbox_flip_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pb'),
- ('pb', 'node_3'),
- ('node_3', 'op_output')
- ],
- {
- 'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 19, 19, 384])},
- 'pb': {
- 'aspect_ratio': np.array([1, 2, 0.5]),
- 'flip': 1,
- 'min_size': np.array([1]),
- 'max_size': np.array([1])
- }
- })
- graph.graph['layout'] = 'NHWC'
- pb_node = Node(graph, 'pb')
- PriorBoxOp.priorbox_infer(pb_node)
- exp_shape = np.array([1, 2, 4 * 19 * 19 * 4])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_caffe_priorbox_density_infer(self):
- graph = build_graph(nodes_attributes,
- [
- ('node_1', 'pb'),
- ('pb', 'node_3')],
- {
- 'node_3': {'is_output': True, 'shape': None},
- 'node_1': {'shape': np.array([1, 128, 32, 32])},
- 'pb': {
- 'aspect_ratio': np.array([1]),
- 'flip': 1,
- 'min_size': np.array([]),
- 'max_size': np.array([]),
- 'fixed_size': np.array([32, 64, 128]),
- 'density': np.array([1, 2, 4]),
- }
- })
- graph.graph['layout'] = 'NCHW'
- pb_node = Node(graph, 'pb')
- PriorBoxOp.priorbox_infer(pb_node)
- exp_shape = np.array([1, 2, 4*32*32*21])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/proposal_test.py b/tools/mo/unit_tests/mo/ops/proposal_test.py
deleted file mode 100644
index b81c04da337e97..00000000000000
--- a/tools/mo/unit_tests/mo/ops/proposal_test.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.ops.proposal import ProposalOp
-from openvino.tools.mo.front.common.extractors.utils import layout_attrs
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'proposal_input': {'kind': 'data', 'shape': None, 'value': None},
- 'proposal': {'type': 'Proposal', 'kind': 'op'},
- 'proposal_out_data_1': {'kind': 'data', 'shape': None, 'value': None},
- 'proposal_out_data_2': {'kind': 'data', 'shape': None, 'value': None},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- 'op_output2': {'kind': 'op', 'op': 'Result'},
- }
-
-
-class TestProposal(unittest.TestCase):
- def test_proposal_infer_one_output(self):
- graph = build_graph(nodes_attributes,
- [('proposal_input', 'proposal'),
- ('proposal', 'proposal_out_data_1'),
- ('proposal_out_data_1', 'op_output')
- ],
- {'proposal_input': {'shape': int64_array([1, 3, 227, 227])},
- 'proposal': {'post_nms_topn': 2, **layout_attrs()}
- })
-
- proposal_node = Node(graph, 'proposal')
- ProposalOp.proposal_infer(proposal_node)
-
- self.assertListEqual([1 * 2, 5], list(graph.node['proposal_out_data_1']['shape']))
-
- def test_proposal_infer_two_outputs(self):
- graph = build_graph(nodes_attributes,
- [('proposal_input', 'proposal'),
- ('proposal', 'proposal_out_data_1'),
- ('proposal', 'proposal_out_data_2'),
- ('proposal_out_data_1', 'op_output'),
- ('proposal_out_data_2', 'op_output')
- ],
- {'proposal_input': {'shape': int64_array([1, 3, 227, 227])},
- 'proposal': {'post_nms_topn': 2, **layout_attrs()}
- })
-
- proposal_node = Node(graph, 'proposal')
- ProposalOp.proposal_infer(proposal_node)
-
- self.assertListEqual(list([1 * 2, 5]), list(graph.node['proposal_out_data_1']['shape']))
- self.assertListEqual(list([1 * 2]), list(graph.node['proposal_out_data_2']['shape']))
diff --git a/tools/mo/unit_tests/mo/ops/psroipooling_test.py b/tools/mo/unit_tests/mo/ops/psroipooling_test.py
deleted file mode 100644
index 1ea8dbf7f9425d..00000000000000
--- a/tools/mo/unit_tests/mo/ops/psroipooling_test.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.psroipooling import PSROIPoolingOp
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'node_2': {'type': 'Identity', 'kind': 'op'},
- 'psroipool': {'type': 'PSROIPooling', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestPSROIPooling(unittest.TestCase):
- def test_psroipool_infer_nchw(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'psroipool'),
- ('node_2', 'psroipool'),
- ('psroipool', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'node_2': {'shape': np.array([100, 5])},
- 'psroipool': {'output_dim': 4, 'group_size': 15}
- })
- graph.graph['layout'] = 'NCHW'
- psroipool_node = Node(graph, 'psroipool')
- PSROIPoolingOp.psroipooling_infer(psroipool_node)
- exp_shape = np.array([100, 4, 15, 15])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_psroipool_infer_nhwc(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'psroipool'),
- ('node_2', 'psroipool'),
- ('psroipool', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': np.array([1, 227, 227, 3])},
- 'node_2': {'shape': np.array([100, 5])},
- 'psroipool': {'output_dim': 4, 'group_size': 15}
- })
- graph.graph['layout'] = 'NHWC'
- psroipool_node = Node(graph, 'psroipool')
- PSROIPoolingOp.psroipooling_infer(psroipool_node)
- exp_shape = np.array([100, 15, 15, 4])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_psroipool_infer_no_shape(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'psroipool'),
- ('node_2', 'psroipool'),
- ('psroipool', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None},
- 'node_1': {'shape': None},
- 'node_2': {'shape': np.array([100, 5])},
- 'psroipool': {'output_dim': 4, 'group_size': 224}
- })
- graph.graph['layout'] = 'NCHW'
-
- psroipool_node = Node(graph, 'psroipool')
- PSROIPoolingOp.psroipooling_infer(psroipool_node)
- res_shape = graph.node['node_3']['shape']
- self.assertIsNone(res_shape)
diff --git a/tools/mo/unit_tests/mo/ops/quantize_test.py b/tools/mo/unit_tests/mo/ops/quantize_test.py
deleted file mode 100644
index 567c6574235b00..00000000000000
--- a/tools/mo/unit_tests/mo/ops/quantize_test.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.fakequantize import FakeQuantize, broadcastable
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-
-class TestBroadcastable(unittest.TestCase):
- def test_matching(self):
- self.assertTrue(broadcastable([1, 2, 3], [1, 2, 3]))
-
- def test_incomplete(self):
- self.assertTrue(broadcastable([1, 1, 1], [1, 2, 3]))
- self.assertTrue(broadcastable([2, 3], [1, 2, 3]))
- self.assertTrue(broadcastable([1, 3], [1, 2, 3]))
- self.assertTrue(broadcastable([1, 1], [1, 2, 3]))
- self.assertTrue(broadcastable([], [1, 2, 3]))
- self.assertTrue(broadcastable([1], [1, 2, 3]))
-
- def test_reverse_incomplete(self):
- self.assertFalse(broadcastable([1, 2, 3], [1, 1, 1]))
- self.assertFalse(broadcastable([1, 2, 3], [2, 3]))
- self.assertFalse(broadcastable([1, 2, 3], [1, 3]))
- self.assertFalse(broadcastable([1, 2, 3], [1, 1]))
- self.assertFalse(broadcastable([1, 2, 3], []))
- self.assertFalse(broadcastable([1, 2, 3], [1]))
-
- def test_invalid(self):
- self.assertFalse(broadcastable([3, 2, 1], [1, 2, 3]))
- self.assertFalse(broadcastable([5], [6]))
- self.assertFalse(broadcastable([5], [1]))
- self.assertFalse(broadcastable([64], [1, 55, 56, 56]))
-
-
-nodes_attributes = {'node_in_1': {'op': 'Identity', 'kind': 'op'},
- 'node_in_2': {'op': 'Identity', 'kind': 'op'},
- 'node_in_3': {'op': 'Identity', 'kind': 'op'},
- 'node_in_4': {'op': 'Identity', 'kind': 'op'},
- 'node_in_5': {'op': 'Identity', 'kind': 'op'},
- 'quantize': {'op': 'FakeQuantize', 'kind': 'op', 'levels': 2},
- 'node_out_1': {'op': 'Identity', 'kind': 'op'},
- 'op_output': {'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestFakeQuantizeOp(unittest.TestCase):
- def test_shape_only(self):
- graph = build_graph(nodes_attributes,
- [('node_in_1', 'quantize'),
- ('node_in_2', 'quantize'),
- ('node_in_3', 'quantize'),
- ('node_in_4', 'quantize'),
- ('node_in_5', 'quantize'),
- ('quantize', 'node_out_1'),
- ('node_out_1', 'op_output')
- ],
- {'node_out_1': {'shape': None},
- 'node_in_1': {'shape': np.array([1, 3, 10, 20])},
- 'node_in_2': {'shape': np.array([1, 3, 10, 20])},
- 'node_in_3': {'shape': np.array([1, 3, 10, 20])},
- 'node_in_4': {'shape': np.array([1, 3, 10, 20])},
- 'node_in_5': {'shape': np.array([1, 3, 10, 20])},
- })
-
- quantize_node = Node(graph, 'quantize')
- FakeQuantize.infer(quantize_node)
- quantize_shape = np.array([1, 3, 10, 20])
- res_shape = graph.node['node_out_1']['shape']
- for i in range(0, len(quantize_shape)):
- self.assertEqual(quantize_shape[i], res_shape[i])
-
- def test_shape_and_value(self):
- graph = build_graph(nodes_attributes,
- [('node_in_1', 'quantize'),
- ('node_in_2', 'quantize'),
- ('node_in_3', 'quantize'),
- ('node_in_4', 'quantize'),
- ('node_in_5', 'quantize'),
- ('quantize', 'node_out_1'),
- ('node_out_1', 'op_output')
- ],
- {
- 'node_out_1': {
- 'shape': None,
- 'value': None,
- },
- 'node_in_1': {
- 'shape': np.array([4]),
- 'value': np.array([5, 17, 0, 100], dtype=np.float32),
- },
- 'node_in_2': {
- 'shape': np.array([4]),
- 'value': np.array([0, 12, 12, 12], dtype=np.float32),
- },
- 'node_in_3': {
- 'shape': np.array([4]),
- 'value': np.array([10, 20, 20, 20], dtype=np.float32),
- },
- 'node_in_4': {
- 'shape': np.array([4]),
- 'value': np.array([0, 0, 0, 0], dtype=np.float32),
- },
- 'node_in_5': {
- 'shape': np.array([4]),
- 'value': np.array([1, 1, 1, 1], dtype=np.float32),
- },
- })
-
- exp_node = Node(graph, 'quantize')
- FakeQuantize.infer(exp_node)
- quantize_shape = np.array([4])
- quantize_value = np.array([1, 1, 0, 1], dtype=np.float32)
- res_shape = graph.node['node_out_1']['shape']
- res_value = graph.node['node_out_1']['value']
- for i in range(0, len(quantize_shape)):
- self.assertEqual(quantize_shape[i], res_shape[i])
- for i in range(0, len(quantize_value)):
- self.assertAlmostEqual(quantize_value[i], res_value[i], places=6)
diff --git a/tools/mo/unit_tests/mo/ops/regionyolo_test.py b/tools/mo/unit_tests/mo/ops/regionyolo_test.py
deleted file mode 100644
index b55a700342eede..00000000000000
--- a/tools/mo/unit_tests/mo/ops/regionyolo_test.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.regionyolo import RegionYoloOp
-from openvino.tools.mo.front.common.extractors.utils import layout_attrs
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'region': {'type': 'RegionYolo', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-class TestRegionYOLOCaffe(unittest.TestCase):
- def test_region_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'region': {'axis': 1, 'end_axis': -1, 'do_softmax': 1, **layout_attrs()}
- })
- graph.graph['layout'] = 'NCHW'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = np.array([1, 3 * 227 * 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_region_infer_flatten(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'region': {'end_axis': 1, 'axis': 0, 'do_softmax': 1, **layout_attrs()}
- })
- graph.graph['layout'] = 'NCHW'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = np.array([1 * 3, 227, 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_region_infer_dynamic_flatten(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': shape_array([1, dynamic_dimension_value, 227, 227])},
- 'region': {'end_axis': 1, 'axis': 0, 'do_softmax': 1, **layout_attrs()}
- })
- graph.graph['layout'] = 'NCHW'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = shape_array([dynamic_dimension_value, 227, 227])
- res_shape = graph.node['node_3']['shape']
- self.assertTrue(strict_compare_tensors(exp_shape, res_shape))
-
- def test_region_infer_flatten_again(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'region': {'end_axis': 2, 'axis': 0, 'do_softmax': 1, **layout_attrs()}
- })
- graph.graph['layout'] = 'NCHW'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = np.array([1 * 3 * 227, 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_region_infer_do_softmax(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227])},
- 'region': {'do_softmax': 0, 'end_axis': -1, 'axis': 1, 'classes': 80, 'coords': 4,
- 'mask': np.array([6, 7, 8]), **layout_attrs()}
- })
-
- graph.graph['layout'] = 'NCHW'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = np.array([1, (80 + 4 + 1) * 3, 227, 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
-
-class TestRegionYOLOTF(unittest.TestCase):
- def test_region_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 227, 227, 3])},
- 'region': {'axis': 1, 'end_axis': -1, 'do_softmax': 1, **layout_attrs()}
- })
- graph.graph['layout'] = 'NHWC'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = np.array([1, 3 * 227 * 227])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
-
- def test_region_infer_do_softmax(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'region'),
- ('region', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 227, 227, 3])},
- 'region': {'do_softmax': 0, 'end_axis': -1, 'axis': 1, 'classes': 80, 'coords': 4,
- 'mask': np.array([6, 7, 8]), **layout_attrs()}
- })
-
- graph.graph['layout'] = 'NHWC'
- reorg_node = Node(graph, 'region')
- RegionYoloOp.regionyolo_infer(reorg_node)
- exp_shape = np.array([1, 227, 227, (80 + 4 + 1) * 3])
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/reorgyolo_test.py b/tools/mo/unit_tests/mo/ops/reorgyolo_test.py
deleted file mode 100644
index ae269b28582e68..00000000000000
--- a/tools/mo/unit_tests/mo/ops/reorgyolo_test.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.reorgyolo import ReorgYoloOp
-from openvino.tools.mo.front.common.extractors.utils import layout_attrs
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'reorg': {'type': 'ReorgYolo', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': { 'kind': 'op', 'op': 'Result'}
- }
-
-
-def calculate_reorgyolo_output(input, stride):
- output = np.full_like(input, -1, dtype=np.int64)
- output[0] = input[0]
- output[1] = input[1] * stride ** 2
- output[2] = np.round(input[2] / stride)
- output[3] = np.round(input[3] / stride)
- return output
-
-
-class TestReorgYOLO(unittest.TestCase):
- def test_reorgyolo_infer(self):
- graph = build_graph(nodes_attributes,
- [('node_1', 'reorg'),
- ('reorg', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': np.array([1, 3, 227, 227]), 'value': None},
- 'reorg': {'stride': 2,
- **layout_attrs()}
- })
-
- reorg_node = Node(graph, 'reorg')
- ReorgYoloOp.reorgyolo_infer(reorg_node)
- exp_shape = calculate_reorgyolo_output(np.array([1, 3, 227, 227]), 2)
- res_shape = graph.node['node_3']['shape']
- for i in range(0, len(exp_shape)):
- self.assertEqual(exp_shape[i], res_shape[i])
diff --git a/tools/mo/unit_tests/mo/ops/reshape_test.py b/tools/mo/unit_tests/mo/ops/reshape_test.py
deleted file mode 100644
index 0a5298004b7a42..00000000000000
--- a/tools/mo/unit_tests/mo/ops/reshape_test.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.reshape import Reshape
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'input': {
- 'kind': 'op',
- 'op': 'Parameter',
- 'shape': None,
- 'value': None,
- },
- 'data': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- },
- 'output_shape': {
- 'kind': 'op',
- 'op': 'Const',
- 'value': None,
- 'shape': None,
- },
- 'output_shape_data': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- },
- 'reshape': {
- 'op': 'Reshape',
- 'kind': 'op',
- 'special_zero': True,
- },
- 'reshape_out': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- }
-}
-
-
-class TestReshapeShapeInfer():
- @pytest.mark.parametrize("input_value, input_shape, output_shape, ref_value, ref_shape",[
- (None, shape_array([1, 100, 4]), shape_array([-1, 25]), None, [16, 25]),
- (None, shape_array([5, 100, 4]), shape_array([0, -1, 25]), None, [5, 16, 25]),
- (None, shape_array([5, dynamic_dimension_value, 4]), shape_array([4, -1, 5]), None,
- shape_array([4, dynamic_dimension_value, 5])),
- (None, shape_array([5, dynamic_dimension_value, 4]), shape_array([4, dynamic_dimension_value, 5]), None,
- shape_array([4, dynamic_dimension_value, 5])),
- (None, shape_array([dynamic_dimension_value, 4, 5]), shape_array([0, -1]), None,
- shape_array([dynamic_dimension_value, 20])),
- (None, shape_array([dynamic_dimension_value, 4, 5]), shape_array([5, -1, dynamic_dimension_value]),
- None, shape_array([5, dynamic_dimension_value, dynamic_dimension_value])),
- (None, shape_array([dynamic_dimension_value, 1, 546]), shape_array([dynamic_dimension_value, -1, 91]),
- None, shape_array([dynamic_dimension_value, dynamic_dimension_value, 91])),
- (None, shape_array([5, dynamic_dimension_value, 8]), shape_array([4, -1]),
- None, shape_array([4, dynamic_dimension_value])),
- (None, shape_array([dynamic_dimension_value]), shape_array([5]), None, shape_array([5])),
- (None, shape_array([dynamic_dimension_value]), shape_array([0]), None, shape_array([dynamic_dimension_value])),
- (None, shape_array([dynamic_dimension_value]), shape_array([-1]), None, shape_array([dynamic_dimension_value])),
- (None, shape_array([dynamic_dimension_value]), shape_array([dynamic_dimension_value]), None,
- shape_array([dynamic_dimension_value])),
- # even though the target shape is dynamic since all the inputs are static so we can calculate output
- (None, shape_array([5, 3, 8]), shape_array([4, dynamic_dimension_value]), None, shape_array([4, 30])),
- (None, shape_array([3, 14, 5]), shape_array([dynamic_dimension_value, 2, 0]), None, shape_array([21, 2, 5])),
- (shape_array([1, 2, dynamic_dimension_value, 4, 5, 6]), shape_array([6]), shape_array([-1, 2]),
- shape_array([1, 2, dynamic_dimension_value, 4, 5, 6]).reshape((3, 2)), shape_array([3, 2])),
- ])
- def test_reshape_infer(self, input_value, input_shape, output_shape, ref_value, ref_shape):
- graph = build_graph(nodes_attributes,
- [('input', 'data'),
- ('data', 'reshape'),
- ('output_shape', 'output_shape_data'),
- ('output_shape_data', 'reshape'),
- ('reshape', 'reshape_out')],
- {'data': {'shape': input_shape, 'value': input_value},
- 'output_shape': {'value': output_shape, 'shape': output_shape.shape},
- 'output_shape_data': {'value': output_shape, 'shape': output_shape.shape},
- })
- node = Node(graph, 'reshape')
- Reshape.infer(node)
- if ref_value is not None:
- assert strict_compare_tensors(node.out_port(0).data.get_value(), shape_array(ref_value))
- assert strict_compare_tensors(node.out_port(0).data.get_shape(), shape_array(ref_shape))
diff --git a/tools/mo/unit_tests/mo/ops/roialign_test.py b/tools/mo/unit_tests/mo/ops/roialign_test.py
deleted file mode 100644
index 06144107937599..00000000000000
--- a/tools/mo/unit_tests/mo/ops/roialign_test.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, float32_array
-
-import numpy as np
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.roialign import ROIAlign
-from unit_tests.utils.graph import build_graph
-
-
-class TestROIAlignOps(unittest.TestCase):
- node_attrs = {
- # input 1
- "1_input": {"kind": "op", "type": "Parameter", "value": None},
- "input_data": {"shape": None, "kind": "data", "value": None},
- #input 2
- "2_rois": {"kind": "op", "type": "Parameter","value": None},
- "rois_data": {"shape": None,"kind": "data", "value": None},
- # input 3
- "3_indices": {"kind": "op","type": "Parameter"},
- "indices_data": {"shape": None, "kind": "data", "value": None},
- # ROIAlign
- "node": {
- "kind": "op",
- "type": "ROIAlign",
- "pooled_h": None,
- "pooled_w": None,
- "mode": None,
- "sampling_ratio": 2,
- "spatial_scale": 16,
- "aligned_mode": None,
- },
- "node_data": {"shape": None, "kind": "data", "value": None},
- # output
- "result": {"kind": "op","type": "Result"},
- }
-
- def test_roialignv1(self):
- graph = build_graph(
- self.node_attrs,
- [
- ("1_input", "input_data"),
- ("input_data", "node", {"in": 0}),
- ("2_rois", "rois_data"),
- ("rois_data", "node", {"in": 1}),
- ("3_indices", "indices_data"),
- ("indices_data", "node", {"in": 2}),
- ("node", "node_data"),
- ("node_data", "result"),
- ],
- {
- 'input_data': {'shape': int64_array([1, 256, 200, 272])},
- 'rois_data': {'shape': int64_array([1000, 4])},
- 'indices_data': {'shape': int64_array([1000])},
- 'node': {'mode': 'max', 'pooled_h': 7, 'pooled_w': 7, 'aligned_mode': 'asymmetric', 'version': 'opset9'},
- }
- )
- graph.graph["layout"] = "NCHW"
- node = Node(graph, "node")
- ROIAlign.infer(node)
- self.assertListEqual(list([1000, 256, 7, 7]), graph.node['node_data']['shape'].data.tolist())
-
- def test_roialignv2(self):
- graph = build_graph(
- self.node_attrs,
- [
- ("1_input", "input_data"),
- ("input_data", "node", {"in": 0}),
- ("2_rois", "rois_data"),
- ("rois_data", "node", {"in": 1}),
- ("3_indices", "indices_data"),
- ("indices_data", "node", {"in": 2}),
- ("node", "node_data"),
- ("node_data", "result"),
- ],
- {
- 'input_data': {'shape': int64_array([7, 256, 200, 200])},
- 'rois_data': {'shape': int64_array([300, 4])},
- 'indices_data': {'shape': int64_array([300])},
- 'node': {'mode': 'max', 'pooled_h': 5, 'pooled_w': 6, 'aligned_mode': 'half_pixel_for_nn', 'version':'opset9'},
- }
- )
- graph.graph["layout"] = "NCHW"
- node = Node(graph, "node")
-
- ROIAlign.infer(node)
- self.assertListEqual(list([300, 256, 5, 6]), graph.node['node_data']['shape'].data.tolist())
-
- def test_roialignv3(self):
- graph = build_graph(
- self.node_attrs,
- [
- ("1_input", "input_data"),
- ("input_data", "node", {"in": 0}),
- ("2_rois", "rois_data"),
- ("rois_data", "node", {"in": 1}),
- ("3_indices", "indices_data"),
- ("indices_data", "node", {"in": 2}),
- ("node", "node_data"),
- ("node_data", "result"),
- ],
- {
- 'input_data': {'shape': int64_array([2, 3, 5, 5])},
- 'rois_data': {'shape': int64_array([7, 4])},
- 'indices_data': {'shape': int64_array([7])},
- 'node': {'mode': 'max', 'pooled_h': 2, 'pooled_w': 2, 'aligned_mode': 'half_pixel', 'version': 'opset9'},
- }
- )
- graph.graph["layout"] = "NCHW"
- node = Node(graph, "node")
-
- ROIAlign.infer(node)
- self.assertListEqual(list([7, 3, 2, 2]), graph.node['node_data']['shape'].data.tolist())
-
-
- def test_roialign_wrong_aligned_mode(self):
- graph = build_graph(
- self.node_attrs,
- [
- ("1_input", "input_data"),
- ("input_data", "node", {"in": 0}),
- ("2_rois", "rois_data"),
- ("rois_data", "node", {"in": 1}),
- ("3_indices", "indices_data"),
- ("indices_data", "node", {"in": 2}),
- ("node", "node_data"),
- ("node_data", "result"),
- ],
- {
- 'input_data': {'shape': int64_array([2, 3, 5, 5])},
- 'rois_data': {'shape': int64_array([7, 4])},
- 'indices_data': {'shape': int64_array([7])},
- 'node': {'mode': 'max', 'pooled_h': 2, 'pooled_w': 2, 'aligned_mode': 'full_pixel', 'version': 'opset9'},
- }
- )
- graph.graph["layout"] = "NCHW"
- node = Node(graph, "node")
- self.assertRaises(AssertionError, ROIAlign.infer, node)
diff --git a/tools/mo/unit_tests/mo/ops/scatter_test.py b/tools/mo/unit_tests/mo/ops/scatter_test.py
deleted file mode 100644
index d61d69a2b52643..00000000000000
--- a/tools/mo/unit_tests/mo/ops/scatter_test.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.scatter import ScatterElementsUpdate, ScatterUpdate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph, regular_op_with_empty_data, result, connect, valued_const_with_data
-
-
-class TestScatterElementsInferTest():
- @pytest.mark.parametrize("data, indices, updates, axis, ref_res",[
- ([[0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0]],
- [[1, 0, 2],
- [0, 2, 1]],
- [[1.0, 1.1, 1.2],
- [2.0, 2.1, 2.2]],
- 0,
- [[2.0, 1.1, 0.0],
- [1.0, 0.0, 2.2],
- [0.0, 2.1, 1.2]]),
-
- ([[1.0, 2.0, 3.0, 4.0, 5.0]],
- [[1, 3]],
- [[1.1, 2.1]],
- 1,
- [[1.0, 1.1, 3.0, 2.1, 5.0]]),
-
- ([[1.0, 2.0, 3.0, 4.0, 5.0]],
- [[1, 3]],
- [[1.1, 2.1]],
- [1],
- [[1.0, 1.1, 3.0, 2.1, 5.0]]),
-
- ([ # 3D case
- [[1, 2],
- [3, 4]],
- [[5, 6],
- [7, 8]],
- [[9, 10],
- [11, 12]]
- ],
- [
- [[1, 0],
- [0, 1]],
- [[1, 0],
- [1, 0]],
- [[0, 1],
- [1, 0]]
- ],
- [
- [[21, 22],
- [23, 24]],
- [[25, 26],
- [27, 28]],
- [[29, 30],
- [31, 32]]
- ],
- -1, # axis
- [
- [[22, 21],
- [23, 24]],
- [[26, 25],
- [28, 27]],
- [[29, 30],
- [32, 31]]
- ]),
- ])
- def test_scatterelements_value_infer(self, data, indices, updates, axis, ref_res):
- nodes = {
- **valued_const_with_data('data', np.array(data)),
- **valued_const_with_data('indices', int64_array(indices)),
- **valued_const_with_data('updates', np.array(updates)),
- **valued_const_with_data('axis', int64_array(axis)),
- **regular_op_with_empty_data('scatter_elements', {'op': 'ScatterElementsUpdate', 'axis': axis}),
- **result()
- }
-
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect('data', '0:scatter_elements'),
- *connect('indices', '1:scatter_elements'),
- *connect('updates', '2:scatter_elements'),
- *connect('axis', '3:scatter_elements'),
- *connect('scatter_elements', 'output')
- ], nodes_with_edges_only=True)
- graph.stage = 'middle'
-
- scatter_el_node = Node(graph, 'scatter_elements')
- ScatterElementsUpdate.infer(scatter_el_node)
-
- res_output_shape = scatter_el_node.out_node().shape
- assert np.array_equal(int64_array(ref_res).shape, res_output_shape)
-
- res_output_value = scatter_el_node.out_node().value
- assert np.array_equal(ref_res, res_output_value)
-
-
-class TestScatterUpdateInferTest():
- @pytest.mark.parametrize("data, indices, updates, axis, ref_res",[
- ([[0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0]],
- [[1, 2]],
- [[[1.0, 1.1, 1.2],
- [2.0, 2.1, 2.2]]],
- 0,
- [[0.0, 0.0, 0.0],
- [1.0, 1.1, 1.2],
- [2.0, 2.1, 2.2]]),
-
- # negative axis
- ([[0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0]],
- [[1, 2]],
- [[[1.0, 1.1]],
- [[1.2, 2.0]],
- [[2.1, 2.2]]],
- -1,
- [[0.0, 1.0, 1.1],
- [0.0, 1.2, 2.0],
- [0.0, 2.1, 2.2]]),
-
- # one element
- ([[[0., 0.], [0., 0.], [0., 0.]],
- [[0., 0.], [0., 0.], [0., 0.]],
- [[0., 0.], [0., 0.], [0., 0.]]],
- [[1]],
- [[[[1., 2.], [3., 4.], [5., 6.]]]],
- 0,
- [[[0., 0.], [0., 0.], [0., 0.]],
- [[1., 2.], [3., 4.], [5., 6.]],
- [[0., 0.], [0., 0.], [0., 0.]]]),
-
- # shape [2,3,3]
- ([[[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]],
- [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]],
- # indices [3,2]
- [[1, 2], [0, 1], [1, 2]],
- # updates [2,3,2,3]
- [[[[1., 2., 3.], [4., 5., 6.]],
- [[7., 8., 9.], [9., 8., 7.]],
- [[6., 5., 4.], [3., 2., 1.]]],
- [[[1., 2., 3.], [4., 5., 6.]],
- [[7., 8., 9.], [9., 8., 7.]],
- [[6., 5., 4.], [3., 2., 1.]]]],
- # axis
- 1,
- # ref
- [[[7., 8., 9.], [6., 5., 4.], [3., 2., 1.]],
- [[7., 8., 9.], [6., 5., 4.], [3., 2., 1.]]]),
-
- # dynamic updates
- ([0, 0, 0],
- [2],
- shape_array([dynamic_dimension_value]),
- 0,
- shape_array([0, 0, dynamic_dimension_value])),
- ])
- def test_scatter_update_value_infer(self, data, indices, updates, axis, ref_res):
- nodes = {
- **valued_const_with_data('data', np.array(data)),
- **valued_const_with_data('indices', int64_array(indices)),
- **valued_const_with_data('updates', np.array(updates)),
- **valued_const_with_data('axis', int64_array(axis)),
- **regular_op_with_empty_data('scatter_update', {'op': 'ScatterUpdate', 'axis': axis}),
- **result()
- }
-
- graph = build_graph(nodes_attrs=nodes, edges=[
- *connect('data', '0:scatter_update'),
- *connect('indices', '1:scatter_update'),
- *connect('updates', '2:scatter_update'),
- *connect('axis', '3:scatter_update'),
- *connect('scatter_update', 'output')
- ], nodes_with_edges_only=True)
- graph.stage = 'middle'
-
- scatter_update_node = Node(graph, 'scatter_update')
- ScatterUpdate.infer(scatter_update_node)
-
- res_output_shape = scatter_update_node.out_node().shape
- assert np.array_equal(int64_array(ref_res).shape, res_output_shape)
-
- res_output_value = scatter_update_node.out_node().value
- assert np.array_equal(ref_res, res_output_value)
diff --git a/tools/mo/unit_tests/mo/ops/scatternd_test.py b/tools/mo/unit_tests/mo/ops/scatternd_test.py
deleted file mode 100644
index 2d5ef18af85b6d..00000000000000
--- a/tools/mo/unit_tests/mo/ops/scatternd_test.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.scatternd import ScatterNDUpdate
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'input': {'shape': None, 'value': None, 'kind': 'data'},
- 'indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'updates': {'shape': None, 'value': None, 'kind': 'data'},
- 'scatternd_node': {'op': 'ScatterNDUpdate', 'kind': 'op'},
- 'output': {'shape': None, 'value': None, 'kind': 'data'}}
-
-# graph 1
-edges = [('input', 'scatternd_node', {'in': 0}),
- ('indices', 'scatternd_node', {'in': 1}),
- ('updates', 'scatternd_node', {'in': 2}),
- ('scatternd_node', 'output', {'out': 0})]
-
-# test data for partial infer
-inputs1 = {'input': {'shape': int64_array([10, 40]), 'value': None},
- 'indices': {'shape': int64_array([3, 2]), 'value': None},
- 'updates': {'shape': int64_array([3]), 'value': None}}
-
-inputs2 = {'input': {'shape': int64_array([20, 30]), 'value': None},
- 'indices': {'shape': int64_array([2]), 'value': None},
- 'updates': {'shape': int64_array([]), 'value': None}}
-
-inputs3 = {'input': {'shape': int64_array([20, 30, 5]), 'value': None},
- 'indices': {'shape': int64_array([2]), 'value': None},
- 'updates': {'shape': int64_array([5]), 'value': None}}
-
-inputs4 = {'input': {'shape': int64_array([10, 40, 50]), 'value': None},
- 'indices': {'shape': int64_array([7, 3, 2]), 'value': None},
- 'updates': {'shape': int64_array([7, 3, 50]), 'value': None}}
-
-# test data for constant folding
-inputs5 = {'input': {'shape': int64_array([8]), 'value': int64_array([1, 2, 3, 4, 5, 6, 7, 8])},
- 'indices': {'shape': int64_array([4, 1]), 'value': int64_array([[4], [3], [1], [7]])},
- 'updates': {'shape': int64_array([4]), 'value': int64_array([9, 10, 11, 12])}}
-output5 = int64_array([1, 11, 3, 10, 9, 6, 7, 12])
-
-inputs6 = {'input': {'shape': int64_array([4, 4, 4]), 'value': int64_array([[[1, 2, 3, 4], [5, 6, 7, 8], [8, 7, 6, 5], [4, 3, 2, 1]],
- [[1, 2, 3, 4], [5, 6, 7, 8], [8, 7, 6, 5], [4, 3, 2, 1]],
- [[8, 7, 6, 5], [4, 3, 2, 1], [1, 2, 3, 4], [5, 6, 7, 8]],
- [[8, 7, 6, 5], [4, 3, 2, 1], [1, 2, 3, 4], [5, 6, 7, 8]]])},
- 'indices': {'shape': int64_array([2, 1]), 'value': int64_array([[0], [2]])},
- 'updates': {'shape': int64_array([2, 4, 4]), 'value': int64_array([[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]],
- [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]]])}}
-output6 = int64_array([[[5, 5, 5, 5], [6, 6, 6, 6], [7, 7, 7, 7], [8, 8, 8, 8]],
- [[1, 2, 3, 4], [5, 6, 7, 8], [8, 7, 6, 5], [4, 3, 2, 1]],
- [[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3], [4, 4, 4, 4]],
- [[8, 7, 6, 5], [4, 3, 2, 1], [1, 2, 3, 4], [5, 6, 7, 8]]])
-
-inputs7 = {'input': {'shape': int64_array([8]), 'value': int64_array([1, 2, 3, 4, 5, 6, 7, 8])},
- 'indices': {'shape': int64_array([1]), 'value': int64_array([4])},
- 'updates': {'shape': int64_array([]), 'value': 9}}
-output7 = int64_array([1, 2, 3, 4, 9, 6, 7, 8])
-
-inputs8 = {'input': {'shape': int64_array([3]), 'value': int64_array([1, 2, 3])},
- 'indices': {'shape': int64_array([1]), 'value': int64_array([2])},
- 'updates': {'shape': int64_array([1]), 'value': int64_array([9])}}
-output8 = int64_array([1, 2, 9])
-
-inputs9 = {'input': {'shape': int64_array([1, 5, 5, 1]), 'value': np.zeros([1, 5, 5, 1],dtype=np.int32)},
- 'indices': {'shape': int64_array([1, 2, 2, 1, 4]),
- 'value': np.array([[[[[0, 0, 0, 0]], [[0, 0, 1, 0]]], [[[0, 2, 1, 0]], [[0, 3, 4, 0]]]]])},
- 'updates': {'shape': int64_array([1, 2, 2, 1]), 'value': np.ones([1, 2, 2, 1])}}
-
-output9 = np.array([[[[1], [1], [0], [0], [0]], # shape [1, 5, 5, 1]
- [[0], [0], [0], [0], [0]],
- [[0], [1], [0], [0], [0]],
- [[0], [0], [0], [0], [1]],
- [[0], [0], [0], [0], [0]]]])
-
-class TestScatterNDUpdate(unittest.TestCase):
- def test_partial_infer1(self):
- graph = build_graph(nodes_attributes, edges, inputs1)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # prepare reference results
- ref_output_shape = np.array([10, 40], dtype=np.int32)
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer2(self):
- graph = build_graph(nodes_attributes, edges, inputs2)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # prepare reference results
- ref_output_shape = np.array([20, 30], dtype=np.int32)
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer3(self):
- graph = build_graph(nodes_attributes, edges, inputs3)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # prepare reference results
- ref_output_shape = np.array([20, 30, 5], dtype=np.int32)
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_partial_infer4(self):
- graph = build_graph(nodes_attributes, edges, inputs4)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # prepare reference results
- ref_output_shape = np.array([10, 40, 50], dtype=np.int32)
-
- # get the result
- res_output_shape = graph.node['output']['shape']
-
- self.assertTrue(np.array_equal(ref_output_shape, res_output_shape),
- 'values do not match expected: {} and given: {}'.format(ref_output_shape, res_output_shape))
-
- def test_infer5(self):
- graph = build_graph(nodes_attributes, edges, inputs5)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output5, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output5, res_output_value))
-
- def test_infer6(self):
- graph = build_graph(nodes_attributes, edges, inputs6)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output6, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output6, res_output_value))
-
- def test_infer7_scalar(self):
- graph = build_graph(nodes_attributes, edges, inputs7)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output7, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output7, res_output_value))
-
- def test_infer8(self):
- graph = build_graph(nodes_attributes, edges, inputs8)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output8, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output8, res_output_value))
-
- def test_infer9(self):
- graph = build_graph(nodes_attributes, edges, inputs9)
- scatternd_node = Node(graph, 'scatternd_node')
- ScatterNDUpdate.infer(scatternd_node)
-
- # get the result
- res_output_value = graph.node['output']['value']
-
- self.assertTrue(np.array_equal(output9, res_output_value),
- 'values do not match expected: {} and given: {}'.format(output8, res_output_value))
diff --git a/tools/mo/unit_tests/mo/ops/select_test.py b/tools/mo/unit_tests/mo/ops/select_test.py
deleted file mode 100644
index 63ebf459ba0159..00000000000000
--- a/tools/mo/unit_tests/mo/ops/select_test.py
+++ /dev/null
@@ -1,330 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.select import Select
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension, shape_array, dynamic_dimension_value
-from openvino.tools.mo.front.common.partial_infer.utils import strict_compare_tensors, int64_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph, valued_const_with_data, result, regular_op_with_empty_data, \
- connect
-
-
-class TestSelect(unittest.TestCase):
-
- @staticmethod
- def build_select_graph_and_infer(condition_value, then_value, else_value, out_value,
- condition_shape=None, then_shape=None, else_shape=None, out_shape=None,
- auto_broadcast='numpy', fw_format=None):
- if then_value is not None:
- then_shape = int64_array(then_value.shape)
- if else_value is not None:
- else_shape = int64_array(else_value.shape)
-
- nodes = {
- **valued_const_with_data('then', then_value, then_shape),
- **valued_const_with_data('else', else_value, else_shape),
- **valued_const_with_data('condition', condition_value, condition_shape),
- **regular_op_with_empty_data('select', {'op': 'Select', 'auto_broadcast': auto_broadcast, 'format': fw_format}),
- **result('out'),
- }
- edges = [
- *connect('condition', '0:select'),
- *connect('then', '1:select'),
- *connect('else', '2:select'),
- *connect('select', 'out'),
- ]
- graph = build_graph(nodes, edges)
-
- select_node = Node(graph, 'select')
- Select.infer(select_node)
-
- select_out_node = Node(graph, 'select_d')
-
- value_desc = 'values'
- ref_val = out_value
- actual_val = select_out_node['value']
- if out_shape is not None:
- value_desc = 'shapes'
- ref_val = out_shape
- actual_val = select_out_node['shape']
- assert select_out_node['value'] is None, "if 'out_shape' is defined manually 'value' must be None"
-
- flag = strict_compare_tensors(actual_val, ref_val)
- msg = '' if flag else 'reference {} and actual {} {} do not match\n'.format(ref_val, actual_val, value_desc)
- return flag, msg
-
- def test_1(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([5, 6], dtype=bool),
- then_value=np.ones([5, 6], dtype=float),
- else_value=np.zeros([5, 6], dtype=float),
- out_value=np.ones([5, 6], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([15, 3, 5], dtype=bool),
- then_value=np.ones([15, 3, 5], dtype=float),
- else_value=np.zeros([15, 1, 5], dtype=float),
- out_value=np.ones([15, 3, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_no_condition(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=[2],
- then_value=None, then_shape=[2],
- else_value=None, else_shape=[2],
- out_value=None, out_shape=[2])
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_true(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array([True, True], dtype=bool),
- then_value=np.array([1, 1], dtype=np.int8),
- else_value=np.array([2, 2], dtype=np.int8),
- out_value=np.array([1, 1], dtype=np.int8))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_false(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array([False, False], dtype=bool),
- then_value=np.array([1, 1], dtype=np.int8),
- else_value=np.array([2, 2], dtype=np.int8),
- out_value=np.array([2, 2], dtype=np.int8))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_true_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array([True], dtype=bool),
- then_value=np.ones([15, 3, 5], dtype=float),
- else_value=np.zeros([15, 1, 5], dtype=float),
- out_value=np.ones([15, 3, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_true_then_and_else_are_scalars(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array([True], dtype=bool),
- then_value=np.array(3, dtype=float),
- else_value=np.array(1, dtype=float),
- out_value=np.array([3], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_true_then_and_else_are_scalars_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array(True, dtype=bool),
- then_value=np.array(3, dtype=float),
- else_value=np.array(1, dtype=float),
- out_value=np.array(3, dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_false_then_and_else_are_scalars(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array([False], dtype=bool),
- then_value=np.array(3, dtype=float),
- else_value=np.array(1, dtype=float),
- out_value=np.array([1], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_false_then_and_else_are_scalars_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array(False, dtype=bool),
- then_value=np.array(3, dtype=float),
- else_value=np.array(1, dtype=float),
- out_value=np.array(1, dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_condition_false_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.array([False], dtype=bool),
- then_value=np.ones([15, 3, 5], dtype=float),
- else_value=np.zeros([15, 1, 5], dtype=float),
- out_value=np.zeros([15, 3, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- # if one of the branches is None then np.where shouldn't be used to avoid object dtype in output
- # res = np.where(condition, numpy_array_of_int[float]_dtype, None)
- # print(res.dtype) => object which is not compatible with other numeric dtypes, will fail further without
- # clear explanation, need to catch such cases as soon as possible
- def test_select_infer_None_then_branch_1(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.zeros([15, 3, 5], dtype=bool),
- then_value=None, then_shape=[15, 3, 5],
- else_value=np.ones([15, 1, 5], dtype=float),
- out_value=np.ones([15, 3, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_None_then_branch_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([15, 3, 5], dtype=bool),
- then_value=None, then_shape=[15, 3, 5],
- else_value=np.ones([15, 1, 5], dtype=float),
- out_value=None)
- self.assertTrue(flag, msg)
-
- def test_select_infer_None_else_branch_1(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([15, 3, 5], dtype=bool),
- then_value=np.ones([15, 1, 5], dtype=float),
- else_value=None, else_shape=[15, 3, 5],
- out_value=np.ones([15, 3, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_infer_None_else_branch_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.zeros([15, 3, 5], dtype=bool),
- then_value=np.ones([15, 1, 5], dtype=float),
- else_value=None, else_shape=[15, 3, 5],
- out_value=None)
- self.assertTrue(flag, msg)
-
- def test_select_broadcast_1(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 4, 5], dtype=bool),
- then_value=np.ones([], dtype=float),
- else_value=np.zeros([2, 3, 4, 5], dtype=float),
- out_value=np.ones([2, 3, 4, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_broadcast_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 4, 1], dtype=bool),
- then_value= np.ones([1, 3, 1, 5], dtype=float),
- else_value=np.zeros([2, 1, 1, 5], dtype=float),
- out_value=np.ones([2, 3, 4, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_broadcast_3(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 1, 1], dtype=bool),
- then_value= np.ones([2, 3, 4, 5], dtype=float),
- else_value=np.zeros([2, 1, 1, 5], dtype=float),
- out_value=np.ones([2, 3, 4, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- def test_select_broadcast_4(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ones([2, 3, 4, 5], dtype=bool),
- then_value= np.ones([5], dtype=float),
- else_value=np.zeros([2, 3, 4, 5], dtype=float),
- out_value=np.ones([2, 3, 4, 5], dtype=float))
- self.assertTrue(flag, msg)
-
- # when output shape is broadcasted from condition, then, and else shapes
- def test_select_broadcast_with_shape(self):
- flag, msg = self.build_select_graph_and_infer(condition_shape=[2, 3, 4, 1], condition_value=None,
- then_shape=[1, 3, 1, 5], then_value=None,
- else_shape=[2, 1, 1, 5], else_value=None,
- out_shape=[2, 3, 4, 5], out_value=None)
- self.assertTrue(flag, msg)
-
- def test_select_infer_assert_shapes(self):
- with self.assertRaisesRegex(AssertionError, "must be broadcastable"):
- self.build_select_graph_and_infer(condition_value=None, condition_shape=[2, 2],
- then_value=None, then_shape=[2, 2],
- else_value=None, else_shape=[3, 3],
- out_value=None, out_shape=[42, 42])
-
- def test_select_infer_assert_condition_shapes_are_compatible(self):
- with self.assertRaisesRegex(AssertionError, "must be broadcastable"):
- self.build_select_graph_and_infer(condition_value=None, condition_shape=[42, 3],
- then_value=None, then_shape=[1, 3],
- else_value=None, else_shape=[3, 3],
- out_value=None, out_shape=[3, 3])
-
- def test_select_infer_masked_1(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, True], mask=[1, 1]),
- # condition_value = [dynamic_dimension, dynamic_dimension])
- then_value=None, then_shape=[2],
- else_value=np.zeros((2, 2), dtype=np.int64),
- out_value=None)
- self.assertTrue(flag, msg)
-
- def test_select_infer_masked_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([False, False], mask=[1, 1]),
- # condition_value = [dynamic_dimension, dynamic_dimension])
- then_value=None, then_shape=[2],
- else_value=np.zeros((2, 2), dtype=np.int64),
- out_value=None)
- self.assertTrue(flag, msg)
-
- def test_select_infer_masked_3(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, True], mask=[1, 1]),
- # condition_value = [dynamic_dimension, dynamic_dimension])
- then_value=None, then_shape=[2],
- else_value=np.zeros((2, 2), dtype=np.int64),
- out_value=None)
- self.assertTrue(flag, msg)
-
- def test_select_infer_masked_4(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, False], mask=[0, 1]),
- # condition_value = [True, dynamic_dimension])
- then_value=np.ones((2, 2), dtype=np.int64),
- else_value=np.zeros((2, 2), dtype=np.int64),
- out_value=np.ma.array([[1, 42], [1, 42]], mask=[[0, 1], [0, 1]]))
- # out_value = [[1, dynamic_dimension], [1, dynamic_dimension]]
- self.assertTrue(flag, msg)
-
- def test_select_infer_masked_5(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([False, True], mask=[0, 1]),
- # condition_value = [True, dynamic_dimension])
- then_value=np.ones((2, 2), dtype=np.int64),
- else_value=np.zeros((2, 2), dtype=np.int64),
- out_value=np.ma.array([[0, 42], [0, 42]], mask=[[0, 1], [0, 1]]))
- # out_value = [[0, dynamic_dimension], [0, dynamic_dimension]]
- self.assertTrue(flag, msg)
-
- def test_select_infer_masked_6(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=np.ma.array([True, False], mask=[1, 0]),
- # condition_value = [True, dynamic_dimension])
- then_value=np.ones((2, 2), dtype=np.int64),
- else_value=np.zeros((2, 2), dtype=np.int64),
- out_value=np.ma.array([[42, 0], [42, 0]], mask=[[1, 0], [1, 0]]))
- # out_value = [[dynamic_dimension, 0], [dynamic_dimension, 0]]
- self.assertTrue(flag, msg)
-
- def test_select_infer_no_broadcast_dynamic_then_else_shapes(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100, 100]),
- then_value=None, then_shape=shape_array([100, dynamic_dimension_value]),
- else_value=None, else_shape=shape_array([dynamic_dimension_value, 100]),
- out_value=None, out_shape=shape_array([100, 100]),
- auto_broadcast='none')
- self.assertTrue(flag, msg)
-
- def test_select_infer_no_broadcast_dynamic_then_else_shapes_2(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100, 100]),
- then_value=None, then_shape=shape_array([dynamic_dimension_value, 100]),
- else_value=None, else_shape=shape_array([100, dynamic_dimension_value]),
- out_value=None, out_shape=shape_array([100, 100]),
- auto_broadcast='none')
- self.assertTrue(flag, msg)
-
- def test_select_infer_no_broadcast_dynamic_shapes(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100, 100]),
- then_value=None, then_shape=shape_array([100, dynamic_dimension_value]),
- else_value=None, else_shape=shape_array([dynamic_dimension_value, 100]),
- out_value=None, out_shape=shape_array([100, 100]),
- auto_broadcast='none')
- self.assertTrue(flag, msg)
-
- def test_select_infer_tf_condition(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([100]),
- then_value=None, then_shape=shape_array([100, 20]),
- else_value=None, else_shape=shape_array([100, 20]),
- out_value=None, out_shape=shape_array([100, 20]),
- auto_broadcast='numpy', fw_format='tf')
- self.assertTrue(flag, msg)
-
- def test_select_infer_tf_condition_dyn(self):
- flag, msg = self.build_select_graph_and_infer(condition_value=None,
- condition_shape=shape_array([dynamic_dimension_value]),
- then_value=None,
- then_shape=shape_array([dynamic_dimension_value, 20]),
- else_value=None,
- else_shape=shape_array([dynamic_dimension_value, 20]),
- out_value=None,
- out_shape=shape_array([dynamic_dimension_value, 20]),
- auto_broadcast='numpy', fw_format='tf')
- self.assertTrue(flag, msg)
-
- def test_select_infer_tf_condition_assert_raises(self):
- with self.assertRaisesRegex(AssertionError, "if 'condition' is a 1D tensor then it's size"):
- self.build_select_graph_and_infer(condition_value=None, condition_shape=shape_array([42]),
- then_value=None, then_shape=shape_array([100, 20]),
- else_value=None, else_shape=shape_array([100, 20]),
- out_value=None, out_shape=shape_array([100, 20]),
- auto_broadcast='numpy', fw_format='tf')
-
- def test_select_infer_assert_pdpd(self):
- with self.assertRaisesRegex(Error, "PDPD broadcasting rule is not implemented yet"):
- self.build_select_graph_and_infer(condition_value=None, condition_shape=[2, 2],
- then_value=None, then_shape=[2, 2],
- else_value=None, else_shape=[3, 3],
- out_value=None, out_shape=[42, 42],
- auto_broadcast='pdpd')
-
diff --git a/tools/mo/unit_tests/mo/ops/slice_like_test.py b/tools/mo/unit_tests/mo/ops/slice_like_test.py
deleted file mode 100644
index a45bb10830d0d5..00000000000000
--- a/tools/mo/unit_tests/mo/ops/slice_like_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.slice_like import SliceLike
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'input': {'kind': 'op', 'op': 'Const'},
- 'input_data': {'kind': 'data', 'shape': int64_array([3, 4]), 'value': np.arange(1, 13).reshape([3, 4])},
- 'shape_like': {'kind': 'op', 'op': 'Const', 'shape': int64_array([2, 3]), 'value': None},
- 'shape_like_data': {'kind': 'data', 'shape': int64_array([2, 3]), 'value': None},
- 'slice_like': {'kind': 'op', 'op': 'slice_data'},
- 'out_data': {'kind': 'data', 'shape': None, 'value': None}
-}
-
-edges = [
- ('input', 'input_data'),
- ('input_data', 'slice_like', {'in': 0}),
- ('shape_like', 'shape_like_data'),
- ('shape_like_data', 'slice_like', {'in': 1}),
- ('slice_like', 'out_data')
-]
-
-
-class SliceLikeTest(unittest.TestCase):
-
- def test_1(self):
- graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': None}})
- slice_like = Node(graph, 'slice_like')
- SliceLike.infer(slice_like)
- ref_shape = int64_array([2, 3])
- ref_value = np.array([[1, 2, 3], [5, 6, 7]])
- res_shape = graph.node['out_data']['shape']
- res_value = graph.node['out_data']['value']
- self.assertTrue(np.array_equal(res_shape, ref_shape))
- self.assertTrue(np.array_equal(res_value, ref_value))
-
- def test_2(self):
- graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': (0, 1)}})
- slice_like = Node(graph, 'slice_like')
- SliceLike.infer(slice_like)
- ref_shape = int64_array([2, 3])
- ref_value = np.array([[1, 2, 3], [5, 6, 7]])
- res_shape = graph.node['out_data']['shape']
- res_value = graph.node['out_data']['value']
- self.assertTrue(np.array_equal(res_shape, ref_shape))
- self.assertTrue(np.array_equal(res_value, ref_value))
-
- def test_3(self):
- graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': (0,)}})
- slice_like = Node(graph, 'slice_like')
- SliceLike.infer(slice_like)
- ref_shape = int64_array([2, 4])
- ref_value = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
- res_shape = graph.node['out_data']['shape']
- res_value = graph.node['out_data']['value']
- self.assertTrue(np.array_equal(res_shape, ref_shape))
- self.assertTrue(np.array_equal(res_value, ref_value))
-
- def test_4(self):
- graph = build_graph(nodes_attributes, edges, {'slice_like': {'axes': (-1,)}})
- slice_like = Node(graph, 'slice_like')
- SliceLike.infer(slice_like)
- ref_shape = int64_array([3, 3])
- ref_value = np.array([[1, 2, 3], [5, 6, 7], [9, 10, 11]])
- res_shape = graph.node['out_data']['shape']
- res_value = graph.node['out_data']['value']
- self.assertTrue(np.array_equal(res_shape, ref_shape))
- self.assertTrue(np.array_equal(res_value, ref_value))
diff --git a/tools/mo/unit_tests/mo/ops/slice_test.py b/tools/mo/unit_tests/mo/ops/slice_test.py
deleted file mode 100644
index 356a18b5f28b2c..00000000000000
--- a/tools/mo/unit_tests/mo/ops/slice_test.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension_value, shape_array, \
- strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.slice import Slice, OvSlice
-from unit_tests.utils.graph import build_graph, valued_const_with_data, valued_data, regular_op_with_empty_data, \
- connect, shaped_data, shaped_const_with_data
-
-
-class TestSliceOp():
- @pytest.mark.parametrize("inp_value, inp_shape, starts, ends, axes, steps, expected_value, expected_shape",[
- # standard case
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, 2], [0, 1], [1, 1],
- [[5], [3], [6]], [3, 1]),
- # negative bounds
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], [0, 1], [1, 1],
- [[5], [3], [6]], [3, 1]),
- # unusual order of axes
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], [1, 0], [1, 1],
- [[2, 3, 5]], [1, 3]),
- # when only input_shape is defined without values (one from bottom element is shape)
- (None, [4, 5, 6], [1, 2], [4, 3], [0, 1], [1, 1], None, [3, 1, 6]),
- # boundary case
- (None, [4, 5, 6], [0, 2], [np.iinfo(np.int32).max, 3], [0, 1], [1, 1], None, [4, 1, 6]),
- # boundary case
- (None, [4, 5, 6], [np.iinfo(np.int32).min, 2], [3, 3], [0, 1], [1, 1], None, [3, 1, 6],),
- # 1D input
- ([1, 3, 224, 224], [4], [1], [2], [0], [1], [3], [1]),
- # 1D input with negative starts
- (None, [4], [-1], [1], [0], [-1], None, [2]),
- # 1D input with negative ends
- (None, [4], [1], [-1], [0], [1], None, [2]),
- # with rounding (e.g. take from 1st to 3rd with step 4 should give shape 1 not 0)
- (None, [4], [1], [3], [0], [4], None, [1]),
- # with rounding and negative steps (e.g. take from 1st to 3rd with step 4 should give shape 1 not 0)
- (None, [10], [7], [3], [0], [-7], None, [1]),
- # reversing the sequence of elements
- (None, [10], [-1], [np.iinfo(np.int32).min], [0], [-1], None, [10]),
- # dynamic dimensions cases
- # starts are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], None, [3, 2], [0, 1], [1, 1], None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # ends are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], None, [0, 1], [1, 1], None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # axes are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], None, [1, 1], None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # steps are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], [0, 1], None, None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # negative steps and since after normalization starts < ends output shape has 0-size dimension
- (None, [20], [1], [-1], [0], [-2], None, [0]),
- # since starts == ends output shape has 0-size dimension
- (None, [4], [1], [1], [0], [1], None, [0]),
- # since starts > ends output shape has 0-size dimension
- (None, [4], [2], [1], [0], [1], None, [0])
- ])
- def test_slice_infer(self, inp_value, inp_shape, starts, ends, axes, steps, expected_value, expected_shape):
- if inp_value is None:
- input_node = shaped_data('data_1', int64_array(inp_shape))
- else:
- input_node = valued_data('data_1', int64_array(inp_value))
- if inp_value is not None and inp_shape is not None:
- assert np.array_equal(np.array(inp_value).shape, inp_shape)
-
- def convert_args(val, name=''):
- if val is not None:
- return valued_const_with_data(name, int64_array(val))
- else:
- return shaped_const_with_data(name, [0]) # fake shape
-
- starts = convert_args(starts, 'starts')
- ends = convert_args(ends, 'ends')
- axes = convert_args(axes, 'axes')
- steps = convert_args(steps, 'steps')
- if expected_shape is not None:
- expected_shape = shape_array(expected_shape)
-
- nodes = {
- **input_node,
- **regular_op_with_empty_data('slice', {'op': 'Slice'}),
- **starts,
- **ends,
- **axes,
- **steps,
- }
-
- graph = build_graph(nodes,
- [('data_1', 'slice'),
- *connect('starts', '1:slice'),
- *connect('ends', '2:slice'),
- *connect('axes', '3:slice'),
- *connect('steps', '4:slice'),
- *connect('slice', 'slice_d')])
-
- graph.stage = 'middle'
- slice_node = Node(graph, 'slice')
-
- Slice.infer(slice_node)
- if expected_value is not None:
- assert strict_compare_tensors(slice_node.out_node().value, expected_value)
- assert strict_compare_tensors(slice_node.out_node().shape, expected_shape)
-
-
-class TestOvSliceOp():
- @pytest.mark.parametrize("inp_value, inp_shape, starts, ends, axes, steps, expected_value, expected_shape",[
- # standard case
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, 2], [0, 1], [1, 1],
- [[5], [3], [6]], [3, 1]),
- # negative bounds
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], [0, 1], [1, 1],
- [[5], [3], [6]], [3, 1]),
- # unusual order of axes
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], [1, 0], [1, 1],
- [[2, 3, 5]], [1, 3]),
- # when only input_shape is defined without values (one from bottom element is shape)
- (None, [4, 5, 6], [1, 2], [4, 3], [0, 1], [1, 1], None, [3, 1, 6]),
- # boundary case
- (None, [4, 5, 6], [0, 2], [np.iinfo(np.int32).max, 3], [0, 1], [1, 1], None, [4, 1, 6]),
- # boundary case
- (None, [4, 5, 6], [np.iinfo(np.int32).min, 2], [3, 3], [0, 1], [1, 1], None, [3, 1, 6],),
- # 1D input
- ([1, 3, 224, 224], [4], [1], [2], [0], [1], [3], [1]),
- # 1D input with negative starts
- (None, [4], [-1], [1], [0], [-1], None, [2]),
- # 1D input with negative ends
- (None, [4], [1], [-1], [0], [1], None, [2]),
- # with rounding (e.g. take from 1st to 3rd with step 4 should give shape 1 not 0)
- (None, [4], [1], [3], [0], [4], None, [1]),
- # with rounding and negative steps (e.g. take from 1st to 3rd with step 4 should give shape 1 not 0)
- (None, [10], [7], [3], [0], [-7], None, [1]),
- # reversing the sequence of elements
- (None, [10], [-1], [np.iinfo(np.int32).min], [0], [-1], None, [10]),
- # dynamic dimensions cases
- # starts are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], None, [3, 2], [0, 1], [1, 1], None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # ends are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], None, [0, 1], [1, 1], None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # axes are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], None, [1, 1], None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # steps are non-constant
- ([[4, 5, 6, 7], [2, 3, 5, 6], [5, 6, 8, 9], [5, 6, 8, 9]], [4, 4], [0, 1], [3, -2], [0, 1], None, None,
- [dynamic_dimension_value, dynamic_dimension_value]),
- # negative steps and since after normalization starts < ends output shape has 0-size dimension
- (None, [20], [1], [-1], [0], [-2], None, [0]),
- # since starts == ends output shape has 0-size dimension
- (None, [4], [1], [1], [0], [1], None, [0]),
- # since starts > ends output shape has 0-size dimension
- (None, [4], [2], [1], [0], [1], None, [0])
- ])
- def test_ov_slice_infer(self, inp_value, inp_shape, starts, ends, axes, steps, expected_value, expected_shape):
- if inp_value is None:
- input_node = shaped_data('data_1', int64_array(inp_shape))
- else:
- input_node = valued_data('data_1', int64_array(inp_value))
- if inp_value is not None and inp_shape is not None:
- assert np.array_equal(np.array(inp_value).shape, inp_shape)
-
- def convert_args(val, name=''):
- if val is not None:
- return valued_const_with_data(name, int64_array(val))
- else:
- return shaped_const_with_data(name, [0]) # fake shape
-
- starts = convert_args(starts, 'starts')
- ends = convert_args(ends, 'ends')
- steps = convert_args(steps, 'steps')
- axes = convert_args(axes, 'axes')
- if expected_shape is not None:
- expected_shape = shape_array(expected_shape)
-
- nodes = {
- **input_node,
- **regular_op_with_empty_data('slice', {'op': 'OvSlice'}),
- **starts,
- **ends,
- **steps,
- **axes,
- }
-
- graph = build_graph(nodes,
- [('data_1', 'slice'),
- *connect('starts', '1:slice'),
- *connect('ends', '2:slice'),
- *connect('steps', '3:slice'),
- *connect('axes', '4:slice'),
- *connect('slice', 'slice_d')])
-
- graph.stage = 'middle'
- slice_node = Node(graph, 'slice')
-
- OvSlice.infer(slice_node)
- if expected_value is not None:
- assert strict_compare_tensors(slice_node.out_node().value, expected_value)
- assert strict_compare_tensors(slice_node.out_node().shape, expected_shape)
diff --git a/tools/mo/unit_tests/mo/ops/space_to_depth_test.py b/tools/mo/unit_tests/mo/ops/space_to_depth_test.py
deleted file mode 100644
index c8725e39ed0e5a..00000000000000
--- a/tools/mo/unit_tests/mo/ops/space_to_depth_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.space_to_depth import SpaceToDepth
-from openvino.tools.mo.front.common.partial_infer.utils import dynamic_dimension_value, shape_array, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-nodes = {
- 'in_data_node': {'value': None, 'kind': 'data', 'shape': np.array([1, 2048, 1152, 64])},
- 'StD': {'op': 'SpaceToDepth', 'kind': 'op', 'block_size': 2},
- 'out_data_node': {'value': None, 'kind': 'data', 'shape': None}
-}
-
-edges = [
- ('in_data_node', 'StD'),
- ('StD', 'out_data_node')
-]
-
-
-class TestSpaceToDepthPartialInfer(unittest.TestCase):
- def test_tf_space_to_depth_infer_nhwc(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NHWC'
- std_node = Node(graph, 'StD')
- SpaceToDepth.infer(std_node)
- exp_shape = np.array([1, 1024, 576, 256])
- res_shape = graph.node['out_data_node']['shape']
- self.assertTrue(np.array_equal(exp_shape, res_shape))
-
- def test_tf_space_to_depth_infer_nchw(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NCHW'
- graph.node['in_data_node']['shape'] = np.array([1, 64, 2048, 1152])
- std_node = Node(graph, 'StD')
- SpaceToDepth.infer(std_node)
- exp_shape = np.array([1, 256, 1024, 576])
- res_shape = graph.node['out_data_node']['shape']
- self.assertTrue(np.array_equal(exp_shape, res_shape))
-
- def test_tf_space_to_depth_infer_nchw_dynamic(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NCHW'
- graph.node['in_data_node']['shape'] = shape_array([1, 64, dynamic_dimension_value, 1152])
- std_node = Node(graph, 'StD')
- SpaceToDepth.infer(std_node)
- exp_shape = shape_array([1, 256, dynamic_dimension_value, 576])
- res_shape = graph.node['out_data_node']['shape']
- self.assertTrue(strict_compare_tensors(exp_shape, res_shape))
-
- def test_tf_space_to_depth_infer_shape_error(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NHWC'
- graph.node['in_data_node']['shape'] = np.array([1024, 576, 256])
- std_node = Node(graph, 'StD')
- self.assertRaises(Error, SpaceToDepth.infer, std_node)
-
- def test_tf_space_to_depth_infer_divisibility_error_1(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NHWC'
- graph.node['in_data_node']['shape'] = np.array([1, 1024, 577, 256])
- std_node = Node(graph, 'StD')
- self.assertRaises(Error, SpaceToDepth.infer, std_node)
-
- def test_tf_space_to_depth_infer_divisibility_error_2(self):
- graph = build_graph(nodes, edges)
- graph.graph['layout'] = 'NCHW'
- graph.node['in_data_node']['shape'] = np.array([1, 256, 1024, 577])
- std_node = Node(graph, 'StD')
- self.assertRaises(Error, SpaceToDepth.infer, std_node)
diff --git a/tools/mo/unit_tests/mo/ops/sparse_fill_empty_rows_test.py b/tools/mo/unit_tests/mo/ops/sparse_fill_empty_rows_test.py
deleted file mode 100644
index 2ade627b81942f..00000000000000
--- a/tools/mo/unit_tests/mo/ops/sparse_fill_empty_rows_test.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.sparse_fill_empty_rows import SparseFillEmptyRows
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_values': {'shape': None, 'value': None, 'kind': 'data'},
- 'dense_shape': {'shape': None, 'value': None, 'kind': 'data'},
- 'default_value': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_fill_empty_rows_node': {'op': 'SparseFillEmptyRows', 'kind': 'op'},
- 'output_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_values': {'shape': None, 'value': None, 'kind': 'data'},
- 'empty_row_indicator': {'shape': None, 'value': None, 'kind': 'data'},
- 'result_indices': {'kind': 'op', 'op': 'Result'},
- 'result_values': {'kind': 'op', 'op': 'Result'},
- 'result_empty_row_indicator': {'kind': 'op', 'op': 'Result'},
- }
-
-# graph 1
-edges1 = [('input_indices', 'sparse_fill_empty_rows_node', {'in': 0}),
- ('input_values', 'sparse_fill_empty_rows_node', {'in': 1}),
- ('dense_shape', 'sparse_fill_empty_rows_node', {'in': 2}),
- ('default_value', 'sparse_fill_empty_rows_node', {'in': 3}),
- ('sparse_fill_empty_rows_node', 'output_indices', {'out': 0}),
- ('sparse_fill_empty_rows_node', 'output_values', {'out': 1}),
- ('sparse_fill_empty_rows_node', 'empty_row_indicator', {'out': 2}),
- ('output_indices', 'result_indices', {'out': 0}),
- ('output_values', 'result_values', {'out': 0}),
- ('empty_row_indicator', 'result_empty_row_indicator', {'out': 0}),
- ]
-
-inputs1 = {'input_indices': {'shape': int64_array([20, 2]), 'value': None},
- 'input_values': {'shape': int64_array([20]), 'value': None},
- 'dense_shape': {'shape': int64_array([2]), 'value': np.array([4, 5])},
- 'default_value': {'shape': int64_array([]), 'value': None}}
-
-
-class TestSparseFillEmptyRows(unittest.TestCase):
- def test_partial_infer(self):
- graph = build_graph(nodes_attributes, edges1, inputs1)
-
- sparse_fill_empty_rows_node = Node(graph, 'sparse_fill_empty_rows_node')
- SparseFillEmptyRows.infer(sparse_fill_empty_rows_node)
-
- # prepare reference results
- ref_output_indices_shape = int64_array([20, 2])
- ref_output_values_shape = int64_array([20])
- ref_empty_row_indicator_shape = int64_array([4])
-
- # get resulted shapes
- res_output_indices_shape = graph.node['output_indices']['shape']
- res_output_values_shape = graph.node['output_values']['shape']
- res_empty_row_indicator_shape = graph.node['empty_row_indicator']['shape']
-
- self.assertTrue(np.array_equal(ref_output_indices_shape, res_output_indices_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_indices_shape, res_output_indices_shape))
-
- self.assertTrue(np.array_equal(ref_output_values_shape, res_output_values_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_values_shape, res_output_values_shape))
-
- self.assertTrue(np.array_equal(ref_empty_row_indicator_shape, res_empty_row_indicator_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_empty_row_indicator_shape, res_empty_row_indicator_shape))
-
- def test_partial_infer_for_some_out_ports(self):
- edges = [('input_indices', 'sparse_fill_empty_rows_node', {'in': 0}),
- ('input_values', 'sparse_fill_empty_rows_node', {'in': 1}),
- ('dense_shape', 'sparse_fill_empty_rows_node', {'in': 2}),
- ('default_value', 'sparse_fill_empty_rows_node', {'in': 3}),
- ('sparse_fill_empty_rows_node', 'output_indices', {'out': 0}),
- ('sparse_fill_empty_rows_node', 'empty_row_indicator', {'out': 2}),
- ('output_indices', 'result_indices', {'out': 0}),
- ('empty_row_indicator', 'result_empty_row_indicator', {'out': 0}),
- ]
- graph = build_graph(nodes_attributes, edges, inputs1)
-
- sparse_fill_empty_rows_node = Node(graph, 'sparse_fill_empty_rows_node')
- SparseFillEmptyRows.infer(sparse_fill_empty_rows_node)
-
- # prepare reference results
- ref_output_indices_shape = int64_array([20, 2])
- ref_empty_row_indicator_shape = int64_array([4])
-
- # get resulted shapes
- res_output_indices_shape = graph.node['output_indices']['shape']
- res_empty_row_indicator_shape = graph.node['empty_row_indicator']['shape']
-
- self.assertTrue(np.array_equal(ref_output_indices_shape, res_output_indices_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_indices_shape, res_output_indices_shape))
-
- self.assertTrue(np.array_equal(ref_empty_row_indicator_shape, res_empty_row_indicator_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_empty_row_indicator_shape, res_empty_row_indicator_shape))
-
- def test_incorrect_shape_of_default_value(self):
- inputs = {'input_indices': {'shape': int64_array([20, 2]), 'value': None},
- 'input_values': {'shape': int64_array([20]), 'value': None},
- 'dense_shape': {'shape': int64_array([2]), 'value': np.array([4, 5])},
- 'default_value': {'shape': int64_array([3]), 'value': None}}
- graph = build_graph(nodes_attributes, edges1, inputs)
- sparse_fill_empty_rows_node = Node(graph, 'sparse_fill_empty_rows_node')
- self.assertRaises(AssertionError, SparseFillEmptyRows.infer, sparse_fill_empty_rows_node)
-
- def test_no_value_of_dense_shape(self):
- inputs = {'input_indices': {'shape': int64_array([20, 2]), 'value': None},
- 'input_values': {'shape': int64_array([20]), 'value': None},
- 'dense_shape': {'shape': int64_array([2]), 'value': None},
- 'default_value': {'shape': int64_array([]), 'value': None}}
- graph = build_graph(nodes_attributes, edges1, inputs)
- sparse_fill_empty_rows_node = Node(graph, 'sparse_fill_empty_rows_node')
- self.assertRaises(AssertionError, SparseFillEmptyRows.infer, sparse_fill_empty_rows_node)
-
- def test_incorrect_shape_of_dense_shape(self):
- inputs = {'input_indices': {'shape': int64_array([20, 2]), 'value': None},
- 'input_values': {'shape': int64_array([20]), 'value': None},
- 'dense_shape': {'shape': int64_array([2, 2]), 'value': np.array([[4, 5],[1, 2]])},
- 'default_value': {'shape': int64_array([]), 'value': None}}
- graph = build_graph(nodes_attributes, edges1, inputs)
- sparse_fill_empty_rows_node = Node(graph, 'sparse_fill_empty_rows_node')
- self.assertRaises(AssertionError, SparseFillEmptyRows.infer, sparse_fill_empty_rows_node)
diff --git a/tools/mo/unit_tests/mo/ops/sparse_reshape_test.py b/tools/mo/unit_tests/mo/ops/sparse_reshape_test.py
deleted file mode 100644
index 57f5e92fd31e22..00000000000000
--- a/tools/mo/unit_tests/mo/ops/sparse_reshape_test.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-
-from openvino.tools.mo.ops.sparse_reshape import SparseReshape
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import valued_const_with_data, result, regular_op_with_empty_data, connect, \
- shaped_parameter, build_graph, empty_data
-
-dyn = dynamic_dimension
-
-
-class TestSparseReshape(UnitTestWithMockedTelemetry):
-
- def build_and_test_shape_inference(self, input_indices_sparse_shape, input_actual_shape, new_shape, ref_out_shape,
- input_indices=None, ref_out_indices=None):
- # sparse tensor is stored in COO format
- nodes = {
- **shaped_parameter('input_indices', shape_array(input_indices_sparse_shape), {'value': input_indices}),
- **valued_const_with_data('input_shape', shape_array(input_actual_shape)),
- **valued_const_with_data('new_shape', shape_array(new_shape)),
- **regular_op_with_empty_data('sparse_reshape_node', {'op': 'SparseReshape',
- 'special_zero': True,
- 'infer': SparseReshape.infer}),
- **empty_data('sparse_reshape_node_d:out_port_1'),
-
- **result('output_indices'),
- **result('output_shape'),
- }
-
- edges = [
- *connect('input_indices', '0:sparse_reshape_node'),
- *connect('input_shape', '1:sparse_reshape_node'),
- *connect('new_shape', '2:sparse_reshape_node'),
- *connect('sparse_reshape_node:0', 'output_indices'),
- ('sparse_reshape_node', 'sparse_reshape_node_d:out_port_1', {'out': 1}),
- ('sparse_reshape_node_d:out_port_1', 'output_shape', {'in': 0}),
- ]
-
- graph = build_graph(nodes, edges, update_attributes={'input_indices_d': {'value': input_indices}})
- graph.stage = 'middle'
- partial_infer(graph)
-
- node = Node(graph, 'sparse_reshape_node')
- output_indices = node.out_port(0).data.get_value()
- actual_output_shape = node.out_port(1).data.get_value()
- self.assertTrue(strict_compare_tensors(actual_output_shape, ref_out_shape))
- self.assertTrue(strict_compare_tensors(output_indices, ref_out_indices))
-
- def test_sparse_shape_1(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[4, 5],
- new_shape=[5, -1, 2],
- ref_out_shape=[5, 2, 2])
-
- def test_sparse_shape_2(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[dyn, 5, 6],
- new_shape=[5, -1],
- ref_out_shape=[5, dyn])
-
- def test_sparse_shape_3(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[5, 3, 8],
- new_shape=[4, dyn],
- ref_out_shape=[4, 30])
-
- def test_sparse_shape_4(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[1, 30],
- new_shape=[1, dyn],
- ref_out_shape=[1, 30])
-
- def test_sparse_shape_5(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[1, 30],
- new_shape=[3, dyn, dyn],
- ref_out_shape=[3, dyn, dyn])
-
- def test_sparse_shape_6(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[1, 30],
- new_shape=[dyn, 3, dyn],
- ref_out_shape=[dyn, 3, dyn])
-
- def test_sparse_shape_7(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[dyn, 30],
- new_shape=[dyn, dyn, 33],
- ref_out_shape=[dyn, dyn, 33])
-
- def test_sparse_shape_8(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[dyn, 30],
- new_shape=[dyn, 3, -1],
- ref_out_shape=[dyn, 3, dyn])
-
- def test_sparse_shape_9(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- self.build_and_test_shape_inference(input_indices_sparse_shape=[11, 2],
- input_actual_shape=[dyn, 30],
- new_shape=[1, dyn],
- ref_out_shape=[1, dyn])
-
- def test_sparse_shape_10(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- sparse_shape = [11, 2]
- input_indices_value = np.arange(0, np.prod(sparse_shape)).reshape(sparse_shape)
- self.build_and_test_shape_inference(input_indices_sparse_shape=sparse_shape,
- input_actual_shape=[1, 30],
- new_shape=[1, dyn],
- ref_out_shape=[1, 30],
- input_indices=input_indices_value,
- ref_out_indices=input_indices_value)
-
- def test_sparse_shape_11(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- sparse_shape = [11, 2]
- self.build_and_test_shape_inference(input_indices_sparse_shape=sparse_shape,
- input_actual_shape=[1, 30],
- new_shape=[1, 15, 2],
- ref_out_shape=[1, 15, 2])
-
- # negative test with uncompatible shapes
- def test_sparse_shape_12(self):
- # ref_output_indices_shape = np.array([11, 3], dtype=np.int32)
- sparse_shape = [11, 2]
- with self.assertRaisesRegex(Error, 'Stopped shape/value propagation'):
- self.build_and_test_shape_inference(input_indices_sparse_shape=sparse_shape,
- input_actual_shape=[1, 30],
- new_shape=[1, 64, 2],
- ref_out_shape=[1, 15, 2])
diff --git a/tools/mo/unit_tests/mo/ops/sparse_segment_mean_test.py b/tools/mo/unit_tests/mo/ops/sparse_segment_mean_test.py
deleted file mode 100644
index 680d37dfc6f8ac..00000000000000
--- a/tools/mo/unit_tests/mo/ops/sparse_segment_mean_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.sparse_segment_mean import SparseSegmentMean
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-# graph 1
-nodes_attributes1 = {'input_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_segment_ids': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_segment_mean_node': {'op': 'SparseSegmentMean', 'kind': 'op'},
- 'output_segments': {'shape': None, 'value': None, 'kind': 'data'},
- }
-
-edges1 = [('input_data', 'sparse_segment_mean_node', {'in': 0}),
- ('input_indices', 'sparse_segment_mean_node', {'in': 1}),
- ('input_segment_ids', 'sparse_segment_mean_node', {'in': 2}),
- ('sparse_segment_mean_node', 'output_segments', {'out': 0})]
-
-inputs1 = {'input_data': {'shape': int64_array([20, 4, 5]), 'value': None},
- 'input_indices': {'shape': int64_array([40]), 'value': None},
- 'input_segment_ids': {'shape': int64_array([40]), 'value': None}}
-
-# graph 2 with constant input, mean
-nodes_attributes2 = {'input_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_segment_ids': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_segment_mean_node': {'op': 'SparseSegmentMean', 'kind': 'op'},
- 'output_segments': {'shape': None, 'value': None, 'kind': 'data'},
- }
-
-edges2 = [('input_data', 'sparse_segment_mean_node', {'in': 0}),
- ('input_indices', 'sparse_segment_mean_node', {'in': 1}),
- ('input_segment_ids', 'sparse_segment_mean_node', {'in': 2}),
- ('sparse_segment_mean_node', 'output_segments', {'out': 0})]
-
-inputs2 = {'input_data': {'shape': int64_array([3, 4]), 'value': np.array([[1, 2, 3, 4], [-1, -2, -3, -4], [5, 6, 7, 8]], dtype=float)},
- 'input_indices': {'shape': int64_array([3]), 'value': np.array([0, 2, 1, 1, 2], dtype=float)},
- 'input_segment_ids': {'shape': int64_array([3]), 'value': np.array([0, 0, 1, 2, 2], dtype=float)}}
-
-class TestSparseSegmentMean(unittest.TestCase):
- def test_partial_infer(self):
- graph = build_graph(nodes_attributes1, edges1, inputs1)
-
- sparse_segment_mean_node = Node(graph, 'sparse_segment_mean_node')
- SparseSegmentMean.infer(sparse_segment_mean_node)
-
- # prepare reference results
- ref_output_segments_shape = int64_array([40, 4, 5])
-
- # get resulted shapes
- res_output_segments_shape = graph.node['output_segments']['shape']
-
- self.assertTrue(np.array_equal(ref_output_segments_shape, res_output_segments_shape),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_shape, res_output_segments_shape))
-
- def test_incorrect_shapes(self):
- inputs = {'input_data': {'shape': int64_array([20, 4, 5]), 'value': None},
- 'input_indices': {'shape': int64_array([39]), 'value': None},
- 'input_segment_ids': {'shape': int64_array([40]), 'value': None}}
- graph = build_graph(nodes_attributes1, edges1, inputs)
- sparse_segment_mean_node = Node(graph, 'sparse_segment_mean_node')
- self.assertRaises(AssertionError, SparseSegmentMean.infer, sparse_segment_mean_node)
-
- def test_infer_constant_input_mean(self):
- graph = build_graph(nodes_attributes2, edges2, inputs2)
-
- sparse_segment_mean_node = Node(graph, 'sparse_segment_mean_node')
- SparseSegmentMean.infer(sparse_segment_mean_node)
-
- # prepare reference results
- ref_output_segments_shape = int64_array([3, 4])
- ref_output_segments_value = np.array([[3, 4, 5, 6], [-1, -2, -3, -4], [2, 2, 2, 2]], dtype=float)
-
- # get resulted shapes
- res_output_segments_shape = graph.node['output_segments']['shape']
- res_output_segments_value = graph.node['output_segments']['value']
-
- self.assertTrue(np.array_equal(ref_output_segments_shape, res_output_segments_shape),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_shape, res_output_segments_shape))
- self.assertTrue(np.array_equal(ref_output_segments_value, res_output_segments_value),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_value, res_output_segments_value))
diff --git a/tools/mo/unit_tests/mo/ops/sparse_segment_sqrtn_test.py b/tools/mo/unit_tests/mo/ops/sparse_segment_sqrtn_test.py
deleted file mode 100644
index 5f7cf685ef30eb..00000000000000
--- a/tools/mo/unit_tests/mo/ops/sparse_segment_sqrtn_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.sparse_segment_sqrtn import SparseSegmentSqrtN
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-# graph 1
-nodes_attributes1 = {'input_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_segment_ids': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_segment_sqrtn_node': {'op': 'SparseSegmentSqrtN', 'kind': 'op'},
- 'output_segments': {'shape': None, 'value': None, 'kind': 'data'},
- }
-
-edges1 = [('input_data', 'sparse_segment_sqrtn_node', {'in': 0}),
- ('input_indices', 'sparse_segment_sqrtn_node', {'in': 1}),
- ('input_segment_ids', 'sparse_segment_sqrtn_node', {'in': 2}),
- ('sparse_segment_sqrtn_node', 'output_segments', {'out': 0})]
-
-inputs1 = {'input_data': {'shape': int64_array([20, 4, 5]), 'value': None},
- 'input_indices': {'shape': int64_array([40]), 'value': None},
- 'input_segment_ids': {'shape': int64_array([40]), 'value': None}}
-
-# graph 2 with constant input, sqrtn
-nodes_attributes2 = {'input_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_segment_ids': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_segment_sqrtn_node': {'op': 'SparseSegmentSqrtN', 'kind': 'op'},
- 'output_segments': {'shape': None, 'value': None, 'kind': 'data'},
- }
-
-edges2 = [('input_data', 'sparse_segment_sqrtn_node', {'in': 0}),
- ('input_indices', 'sparse_segment_sqrtn_node', {'in': 1}),
- ('input_segment_ids', 'sparse_segment_sqrtn_node', {'in': 2}),
- ('sparse_segment_sqrtn_node', 'output_segments', {'out': 0})]
-
-inputs2 = {'input_data': {'shape': int64_array([3, 4]), 'value': np.array([[1, 2, 3, 4], [-1, -2, -3, -4], [5, 6, 7, 8]], dtype=float)},
- 'input_indices': {'shape': int64_array([3]), 'value': np.array([0, 2, 1, 1, 2], dtype=float)},
- 'input_segment_ids': {'shape': int64_array([3]), 'value': np.array([0, 0, 0, 0, 2], dtype=float)}}
-
-class TestSparseSegmentSqrtN(unittest.TestCase):
- def test_partial_infer(self):
- graph = build_graph(nodes_attributes1, edges1, inputs1)
-
- sparse_segment_sqrtn_node = Node(graph, 'sparse_segment_sqrtn_node')
- SparseSegmentSqrtN.infer(sparse_segment_sqrtn_node)
-
- # prepare reference results
- ref_output_segments_shape = int64_array([40, 4, 5])
-
- # get resulted shapes
- res_output_segments_shape = graph.node['output_segments']['shape']
-
- self.assertTrue(np.array_equal(ref_output_segments_shape, res_output_segments_shape),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_shape, res_output_segments_shape))
-
- def test_incorrect_shapes(self):
- inputs = {'input_data': {'shape': int64_array([20, 4, 5]), 'value': None},
- 'input_indices': {'shape': int64_array([39]), 'value': None},
- 'input_segment_ids': {'shape': int64_array([40]), 'value': None}}
- graph = build_graph(nodes_attributes1, edges1, inputs)
- sparse_segment_sqrtn_node = Node(graph, 'sparse_segment_sqrtn_node')
- self.assertRaises(AssertionError, SparseSegmentSqrtN.infer, sparse_segment_sqrtn_node)
-
- def test_infer_constant_input_sqrtn(self):
- graph = build_graph(nodes_attributes2, edges2, inputs2)
-
- sparse_segment_sqrtn_node = Node(graph, 'sparse_segment_sqrtn_node')
- SparseSegmentSqrtN.infer(sparse_segment_sqrtn_node)
-
- # prepare reference results
- ref_output_segments_shape = int64_array([3, 4])
- ref_output_segments_value = np.array([[2, 2, 2, 2], [0, 0, 0, 0], [5, 6, 7, 8]], dtype=float)
-
- # get resulted shapes
- res_output_segments_shape = graph.node['output_segments']['shape']
- res_output_segments_value = graph.node['output_segments']['value']
-
- self.assertTrue(np.array_equal(ref_output_segments_shape, res_output_segments_shape),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_shape, res_output_segments_shape))
- self.assertTrue(np.array_equal(ref_output_segments_value, res_output_segments_value),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_value, res_output_segments_value))
diff --git a/tools/mo/unit_tests/mo/ops/sparse_segment_sum_test.py b/tools/mo/unit_tests/mo/ops/sparse_segment_sum_test.py
deleted file mode 100644
index b33ca570e17bb3..00000000000000
--- a/tools/mo/unit_tests/mo/ops/sparse_segment_sum_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.sparse_segment_sum import SparseSegmentSum
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-# graph 1
-nodes_attributes1 = {'input_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_segment_ids': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_segment_sum_node': {'op': 'SparseSegmentSum', 'kind': 'op'},
- 'output_segments': {'shape': None, 'value': None, 'kind': 'data'},
- }
-
-edges1 = [('input_data', 'sparse_segment_sum_node', {'in': 0}),
- ('input_indices', 'sparse_segment_sum_node', {'in': 1}),
- ('input_segment_ids', 'sparse_segment_sum_node', {'in': 2}),
- ('sparse_segment_sum_node', 'output_segments', {'out': 0})]
-
-inputs1 = {'input_data': {'shape': int64_array([20, 4, 5]), 'value': None},
- 'input_indices': {'shape': int64_array([40]), 'value': None},
- 'input_segment_ids': {'shape': int64_array([40]), 'value': None}}
-
-# graph 2 with constant input, sum
-nodes_attributes2 = {'input_data': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'input_segment_ids': {'shape': None, 'value': None, 'kind': 'data'},
- 'sparse_segment_sum_node': {'op': 'SparseSegmentSum', 'kind': 'op'},
- 'output_segments': {'shape': None, 'value': None, 'kind': 'data'},
- }
-
-edges2 = [('input_data', 'sparse_segment_sum_node', {'in': 0}),
- ('input_indices', 'sparse_segment_sum_node', {'in': 1}),
- ('input_segment_ids', 'sparse_segment_sum_node', {'in': 2}),
- ('sparse_segment_sum_node', 'output_segments', {'out': 0})]
-
-inputs2 = {'input_data': {'shape': int64_array([3, 4]), 'value': np.array([[1, 2, 3, 4], [-1, -2, -3, -4], [5, 6, 7, 8]], dtype=float)},
- 'input_indices': {'shape': int64_array([3]), 'value': np.array([0, 1, 2], dtype=float)},
- 'input_segment_ids': {'shape': int64_array([3]), 'value': np.array([0, 0, 1], dtype=float)}}
-
-class TestSparseSegmentSum(unittest.TestCase):
- def test_partial_infer(self):
- graph = build_graph(nodes_attributes1, edges1, inputs1)
-
- sparse_segment_sum_node = Node(graph, 'sparse_segment_sum_node')
- SparseSegmentSum.infer(sparse_segment_sum_node)
-
- # prepare reference results
- ref_output_segments_shape = int64_array([40, 4, 5])
-
- # get resulted shapes
- res_output_segments_shape = graph.node['output_segments']['shape']
-
- self.assertTrue(np.array_equal(ref_output_segments_shape, res_output_segments_shape),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_shape, res_output_segments_shape))
-
- def test_incorrect_shapes(self):
- inputs = {'input_data': {'shape': int64_array([20, 4, 5]), 'value': None},
- 'input_indices': {'shape': int64_array([39]), 'value': None},
- 'input_segment_ids': {'shape': int64_array([40]), 'value': None}}
- graph = build_graph(nodes_attributes1, edges1, inputs)
- sparse_segment_sum_node = Node(graph, 'sparse_segment_sum_node')
- self.assertRaises(AssertionError, SparseSegmentSum.infer, sparse_segment_sum_node)
-
- def test_infer_constant_input_sum(self):
- graph = build_graph(nodes_attributes2, edges2, inputs2)
-
- sparse_segment_sum_node = Node(graph, 'sparse_segment_sum_node')
- SparseSegmentSum.infer(sparse_segment_sum_node)
-
- # prepare reference results
- ref_output_segments_shape = int64_array([2, 4])
- ref_output_segments_value = np.array([[0, 0, 0, 0], [5, 6, 7, 8]], dtype=float)
-
- # get resulted shapes
- res_output_segments_shape = graph.node['output_segments']['shape']
- res_output_segments_value = graph.node['output_segments']['value']
-
- self.assertTrue(np.array_equal(ref_output_segments_shape, res_output_segments_shape),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_shape, res_output_segments_shape))
- self.assertTrue(np.array_equal(ref_output_segments_value, res_output_segments_value),
- 'Shapes do not match expected: {} and given: {}'.format(ref_output_segments_value, res_output_segments_value))
diff --git a/tools/mo/unit_tests/mo/ops/split_test.py b/tools/mo/unit_tests/mo/ops/split_test.py
deleted file mode 100644
index 255bec213a4f86..00000000000000
--- a/tools/mo/unit_tests/mo/ops/split_test.py
+++ /dev/null
@@ -1,414 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-import pytest
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, \
- dynamic_dimension_value, dynamic_dimension, strict_compare_tensors, mo_array
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.split import AttributedSplit, AttributedVariadicSplit, VariadicSplit
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class TestSplitOp(unittest.TestCase):
- nodes = {
- 'input': {'kind': 'op'},
- 'split_input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'split_op': {'kind': 'op', 'axis': None, 'num_splits': None, 'op': 'AttributedSplit'},
- 'split_output_0_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_0': {'kind': 'op'},
- 'split_output_1_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_1': {'kind': 'op'},
- }
- edges = [
- ('input', 'split_input_data'),
- ('split_input_data', 'split_op'),
- ('split_op', 'split_output_0_data'),
- ('split_output_0_data', 'output_0'),
- ('split_op', 'split_output_1_data'),
- ('split_output_1_data', 'output_1'),
- ]
-
- def test_split_shape_infer(self):
- # test configuration
- input_shape = [2, 10]
- input_value = None
- axis = 1
- num_splits = 2
- output_shape = [2, 5]
- output_value = [None, None]
-
- # action
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array(input_shape),
- 'value': input_value},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- }
- )
-
- split_op = Node(graph, 'split_op')
- AttributedSplit.infer(split_op)
-
- # reference
- graph_ref = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array(input_shape),
- 'value': input_value},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- 'split_output_0_data': {'shape': int64_array(output_shape),
- 'value': output_value[0]},
- 'split_output_1_data': {'shape': int64_array(output_shape),
- 'value': output_value[1]},
- }
- )
-
- # check
- (flag, resp) = compare_graphs(graph, graph_ref, 'split_input_data')
- self.assertTrue(flag, resp)
-
- def test_split_dynamic_shape_infer(self):
- # test configuration
- input_shape = [2, dynamic_dimension_value]
- input_value = None
- axis = 1
- num_splits = 2
- output_shape = [2, dynamic_dimension_value]
- output_value = [None, None]
-
- # action
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': shape_array(input_shape),
- 'value': input_value},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- }
- )
-
- split_op = Node(graph, 'split_op')
- AttributedSplit.infer(split_op)
-
- # reference
- graph_ref = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': shape_array(input_shape),
- 'value': input_value},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- 'split_output_0_data': {'shape': shape_array(output_shape),
- 'value': output_value[0]},
- 'split_output_1_data': {'shape': shape_array(output_shape),
- 'value': output_value[1]},
- }
- )
-
- # check
- (flag, resp) = compare_graphs(graph, graph_ref, 'split_input_data')
- self.assertTrue(flag, resp)
- self.assertTrue(strict_compare_tensors(Node(graph, 'split_output_0_data').shape, shape_array(output_shape)))
-
- def test_split_value_infer(self):
- # test configuration
- input_shape = [2, 10]
- input_value = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
- axis = 1
- num_splits = 2
- output_shape = [2, 5]
- output_value = [[[0, 1, 2, 3, 4], [10, 11, 12, 13, 14]], [[5, 6, 7, 8, 9], [15, 16, 17, 18, 19]]]
-
- # action
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array(input_shape),
- 'value': int64_array(input_value)},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- }
- )
-
- split_op = Node(graph, 'split_op')
- AttributedSplit.infer(split_op)
-
- # reference
- graph_ref = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array(input_shape),
- 'value': int64_array(input_value)},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- 'split_output_0_data': {'shape': int64_array(output_shape),
- 'value': int64_array(output_value[0])},
- 'split_output_1_data': {'shape': int64_array(output_shape),
- 'value': int64_array(output_value[1])},
- }
- )
-
- # check
- (flag, resp) = compare_graphs(graph, graph_ref, 'split_input_data')
- self.assertTrue(flag, resp)
-
-
-class TestAttributedVariadicSplitOp(unittest.TestCase):
- nodes = {
- 'input': {'kind': 'op'},
- 'split_input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'split_op': {'kind': 'op', 'axis': None, 'split_lengths': None, 'op': 'AttributedVariadicSplit'},
- 'split_output_0_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_0': {'kind': 'op'},
- 'split_output_1_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_1': {'kind': 'op'},
- 'split_output_2_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_2': {'kind': 'op'},
- }
- edges = [
- ('input', 'split_input_data'),
- ('split_input_data', 'split_op'),
- ('split_op', 'split_output_0_data'),
- ('split_output_0_data', 'output_0'),
- ('split_op', 'split_output_1_data'),
- ('split_output_1_data', 'output_1'),
- ('split_op', 'split_output_2_data'),
- ('split_output_2_data', 'output_2'),
- ]
-
- def test_splitv_zero(self):
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array([2, 12, 25, 30])},
- 'split_op': {'axis': np.array(2), 'split_lengths': np.array([2, 13, 10, 0]),
- 'out_ports_count': 4},
- }
- )
- node = Node(graph, 'split_op')
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- AttributedVariadicSplit.infer(node)
-
- self.assertTrue(len(node.out_edges()) == 3)
- self.assertTrue(np.all(node.split_lengths == np.array([2, 13, 10])))
-
- def test_splitv_dynamic_input(self):
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': shape_array([2, 12, dynamic_dimension_value, 30])},
- 'split_op': {'axis': np.array(2), 'split_lengths': np.array([2, 13, 10]),
- 'out_ports_count': 4},
- }
- )
- node = Node(graph, 'split_op')
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- AttributedVariadicSplit.infer(node)
-
- self.assertTrue(len(node.out_edges()) == 3)
- self.assertTrue(np.all(node.split_lengths == np.array([2, 13, 10])))
-
- def test_splitv_zero_not_last(self):
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array([2, 12, 25, 30])},
- 'split_op': {'axis': np.array(2), 'split_lengths': np.array([2, 13, 0, 10]),
- 'out_ports_count': 4},
- }
- )
- node = Node(graph, 'split_op')
-
- # extractor should do it
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
- node.out_port(2).get_connection().set_source(node.out_port(3))
-
- AttributedVariadicSplit.infer(node)
-
- self.assertTrue(node.out_port(3).disconnected())
- self.assertTrue(np.all(node.split_lengths == np.array([2, 13, 10])))
-
- def test_splitv_2_zero_not_last(self):
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array([2, 12, 25, 30])},
- 'split_op': {'axis': np.array(2), 'split_lengths': np.array([2, 13, 0, 0, 10]),
- 'out_ports_count': 5},
- }
- )
- node = Node(graph, 'split_op')
-
- # extractor should do it
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
- node.out_port(2).get_connection().set_source(node.out_port(4))
-
- AttributedVariadicSplit.infer(node)
-
- self.assertTrue(node.out_port(4).disconnected())
- self.assertTrue(node.out_port(3).disconnected())
- self.assertTrue(np.all(node.split_lengths == np.array([2, 13, 10])))
-
-
-class TestVariadicSplitOp():
- nodes = {
- 'input': {'kind': 'op'},
- 'split_input_data': {'kind': 'data', 'shape': None, 'value': None},
- 'split_axis': {'kind': 'op', 'op': 'Const'},
- 'split_axis_data': {'kind': 'data', 'shape': None, 'value': None},
- 'split_lengths': {'kind': 'op', 'op': 'Const'},
- 'split_lengths_data': {'kind': 'data', 'shape': None, 'value': None},
- 'split_op': {'kind': 'op', 'op': 'VariadicSplit'},
- 'split_output_0_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_0': {'kind': 'op'},
- 'split_output_1_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_1': {'kind': 'op'},
- 'split_output_2_data': {'kind': 'data', 'shape': None, 'value': None},
- 'output_2': {'kind': 'op'},
- }
- edges = [
- ('input', 'split_input_data'),
- ('split_input_data', 'split_op'),
- ('split_axis', 'split_axis_data'),
- ('split_axis_data', 'split_op'),
- ('split_lengths', 'split_lengths_data'),
- ('split_lengths_data', 'split_op'),
- ('split_op', 'split_output_0_data'),
- ('split_output_0_data', 'output_0'),
- ('split_op', 'split_output_1_data'),
- ('split_output_1_data', 'output_1'),
- ('split_op', 'split_output_2_data'),
- ('split_output_2_data', 'output_2'),
- ]
-
- @pytest.mark.parametrize("axis",[int64_array(2),
- int64_array([2])])
- def test_variadic_split_axis(self, axis):
- lengths = int64_array([2, 13, 10])
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array([2, 12, 25, 30])},
- 'split_axis_data': {'value': axis},
- 'split_lengths_data': {'value': lengths},
- 'split_op': {'out_ports_count': 4},
- }
- )
- node = Node(graph, 'split_op')
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- VariadicSplit.infer(node)
-
- ont_nodes_count = len(node.out_edges())
- assert ont_nodes_count == 3
- for out in range(ont_nodes_count):
- assert np.all(node.out_node(out).shape == int64_array([2, 12, lengths[out], 30]))
-
- def test_variadic_split_value_inference_with_uint32(self):
- axis = int64_array(2)
- # because sum of Python int and Numpy np.uint64 gives float64
-
- # but np.split accepts only integers and raises error for floats
- # therefore needed to explicitly cast np.split arguments into integer
- # added this test for that case
- lengths = mo_array([2, 13, 10], dtype=np.uint64)
- input_shape = mo_array([2, 12, 25, 30])
- input_value = np.zeros(input_shape)
-
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': input_shape, 'value': input_value},
- 'split_axis_data': {'value': axis},
- 'split_lengths_data': {'value': lengths},
- 'split_op': {'out_ports_count': 4},
- }
- )
- node = Node(graph, 'split_op')
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- VariadicSplit.infer(node)
-
- ont_nodes_count = len(node.out_edges())
- assert ont_nodes_count == 3
- for out in range(ont_nodes_count):
- assert np.all(node.out_node(out).shape == int64_array([2, 12, lengths[out], 30]))
-
- @pytest.mark.parametrize("axis",[int64_array([[2], [2]]),
- int64_array([2, 2])])
- def test_negative_variadic_split_axis(self, axis):
- lengths = int64_array([2, 13, 10])
- graph = build_graph(self.nodes, self.edges,
- {
- 'split_input_data': {'shape': int64_array([2, 12, 25, 30])},
- 'split_axis_data': {'value': axis},
- 'split_lengths_data': {'value': lengths},
- 'split_op': {'out_ports_count': 4},
- }
- )
- node = Node(graph, 'split_op')
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- try:
- VariadicSplit.infer(node)
- except AssertionError as e:
- assert e.args[0] == 'VariadicSplit `axis` should be scalar or tensor with shape [1], '\
- 'but it`s not for node split_op'
-
-
-class TestSplitReverseInfer(unittest.TestCase):
-
- def test_split_reverse_infer(self):
- ref_input_shape = [7, 4, 6]
- axis = 2
- num_splits = 2
- output_shape_1 = [dynamic_dimension, 4, 3]
- output_shape_2 = [7, dynamic_dimension, 3]
-
- graph = build_graph(TestSplitOp.nodes, TestSplitOp.edges,
- {
- 'split_input_data': {'shape': None,
- 'value': None},
- 'split_op': {'axis': np.array(axis), 'num_splits': np.array(num_splits)},
- 'split_output_0_data': {'shape': shape_array(output_shape_1),
- 'value': None},
- 'split_output_1_data': {'shape': shape_array(output_shape_2),
- 'value': None},
- })
-
- split_node = Node(graph, 'split_op')
- AttributedSplit.reverse_infer(split_node)
- actual_input_shape = split_node.in_port(0).data.get_shape()
- self.assertTrue(strict_compare_tensors(ref_input_shape, actual_input_shape))
-
-
-class TestAttributedVariadicSplitReverseInfer(unittest.TestCase):
-
- def test_splitv_dynamic_input(self):
- ref_input_shape = [7, 4, 11]
- axis = 2
- num_splits = 2
- output_shape_1 = [dynamic_dimension, 4, 3]
- output_shape_2 = [7, dynamic_dimension, 3]
- output_shape_3 = [7, dynamic_dimension, 5]
-
- graph = build_graph(TestAttributedVariadicSplitOp.nodes, TestAttributedVariadicSplitOp.edges,
- {
- 'split_input_data': {'shape': None},
- 'split_op': {'axis': np.array(2), 'split_lengths': np.array([3, 3, 5]),
- 'out_ports_count': 2},
- 'split_output_0_data': {'shape': shape_array(output_shape_1),
- 'value': None},
- 'split_output_1_data': {'shape': shape_array(output_shape_2),
- 'value': None},
- 'split_output_2_data': {'shape': shape_array(output_shape_3),
- 'value': None},
- }
- )
- node = Node(graph, 'split_op')
- for p in range(len(node.out_edges()), node.out_ports_count):
- node.add_output_port(p)
-
- AttributedVariadicSplit.reverse_infer(node)
-
- actual_input_shape = node.in_port(0).data.get_shape()
- self.assertTrue(strict_compare_tensors(ref_input_shape, actual_input_shape))
diff --git a/tools/mo/unit_tests/mo/ops/squeeze_test.py b/tools/mo/unit_tests/mo/ops/squeeze_test.py
deleted file mode 100644
index 49b70dce8fdece..00000000000000
--- a/tools/mo/unit_tests/mo/ops/squeeze_test.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.squeeze import Squeeze
-from openvino.tools.mo.utils.error import Error
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'data': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- },
- 'squeeze_dims': {
- 'kind': 'op',
- 'op': 'Const',
- 'value': np.array([]),
- 'shape': None,
- },
- 'squeeze_dims_data': {
- 'kind': 'data',
- 'shape': None,
- 'value': np.array([]),
- },
- 'squeeze': {
- 'op': 'Squeeze',
- 'kind': 'op',
- },
- 'data_out': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- }
-}
-
-
-class TestSqueezeInfer():
- @pytest.mark.parametrize("input_value, input_shape, squeeze_dims, ref_value, ref_shape",[
- (None, shape_array([1, 2, 1, 4]), shape_array([2]), None, [1, 2, 4]),
- # allow squeezing dynamic dimensions
- (None, shape_array([1, 2, dynamic_dimension_value, 4]), shape_array([2]), None, [1, 2, 4]),
- (None, shape_array([1, 2, 1, 4]), shape_array([]), None, [2, 4]),
- (None, shape_array([1, dynamic_dimension_value, 1, 4]), shape_array([]), None,
- shape_array([dynamic_dimension_value, 4])),
- # do not allow squeeze dimensions not equal to 1
- (None, shape_array([1, 2, 1, 4]), shape_array([1]), None, None),
- # do not allow squeeze input shape to be None
- (None, None, shape_array([1]), None, None),
- ])
- def test_squeeze_squeeze_dims(self, input_value, input_shape, squeeze_dims, ref_value, ref_shape):
- graph = build_graph(nodes_attributes,
- [('data', 'squeeze'),
- ('squeeze_dims', 'squeeze_dims_data'),
- ('squeeze_dims_data', 'squeeze'),
- ('squeeze', 'data_out')],
- {'data': {'shape': input_shape, 'value': input_value},
- 'squeeze_dims': {'value': squeeze_dims, 'shape': squeeze_dims.shape},
- 'squeeze_dims_data': {'value': squeeze_dims, 'shape': squeeze_dims.shape},
- })
- node = Node(graph, 'squeeze')
- if ref_shape is None: # the test should fail
- with pytest.raises(Error):
- Squeeze.infer(node)
- else:
- Squeeze.infer(node)
- if ref_value is not None:
- assert strict_compare_tensors(node.out_port(0).data.get_value(), ref_value)
- assert strict_compare_tensors(node.out_port(0).data.get_shape(), ref_shape)
diff --git a/tools/mo/unit_tests/mo/ops/strided_slice_test.py b/tools/mo/unit_tests/mo/ops/strided_slice_test.py
deleted file mode 100644
index 21d2b867681c2f..00000000000000
--- a/tools/mo/unit_tests/mo/ops/strided_slice_test.py
+++ /dev/null
@@ -1,1547 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from collections.abc import Iterable
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.strided_slice import StridedSlice
-from unit_tests.utils.graph import build_graph, valued_const_with_data, result, regular_op_with_empty_data, \
- shaped_const_with_data, connect
-
-
-class TestStridedSliceInfer(unittest.TestCase):
-
- def run_test(self, inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask):
- if is_shape:
- input_node = shaped_const_with_data('input', shape_array(inp))
- else:
- input_node = valued_const_with_data('input', shape_array(inp))
-
- nodes = {
- **input_node,
- **regular_op_with_empty_data('sslice',
- {'op': 'StridedSlice', 'begin_mask': begin_mask, 'end_mask': end_mask,
- 'shrink_axis_mask': shrink_axis_mask, 'ellipsis_mask': ellipsis_mask,
- 'new_axis_mask': new_axis_mask}),
- **valued_const_with_data('begin', shape_array(begin)),
- **valued_const_with_data('end', shape_array(end)),
- **valued_const_with_data('strides', shape_array(strides)),
- **result('res'),
- }
-
- edges = [
- *connect('input', '0:sslice'),
- *connect('begin', '1:sslice'),
- *connect('end', '2:sslice'),
- *connect('strides', '3:sslice'),
- *connect('sslice', 'res')
- ]
-
- graph = build_graph(nodes, edges)
- node = Node(graph, 'sslice')
- StridedSlice.infer(node)
- res = node.out_port(0).data.get_shape() if is_shape else node.out_port(0).data.get_value()
- if isinstance(ref_res, Iterable):
- self.assertTrue(strict_compare_tensors(res, shape_array(ref_res)))
- else:
- self.assertEqual(res, ref_res)
-
- def test_slice_infer_value_1( self, # out = inp[:4:1]
- inp=(1, 34, 34, 62), ref_res=(1, 34, 34, 62), is_shape=False,
- begin=(0,), end=(4,), strides=(1,), begin_mask=(0,), end_mask=(1,),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_2(self, # inp[1:3:1] = [34, 34]
- inp=(1, 34, 34, 62), ref_res=(34, 34), is_shape=False,
- begin=(1,), end=(3,), strides=(1,), begin_mask=(1,), end_mask=(1,),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_3(self, # inp[np.newaxis, :4:1] = [[1, 34, 34, 62]]
- inp=(1, 34, 34, 62), ref_res=((1, 34, 34, 62),), is_shape=False,
- begin=(0, 0,), end=(0, 4,), strides=(1, 1), begin_mask=(0, 0), end_mask=(1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(1,), ellipsis_mask=(0,)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_4(self, # inp[1] = 34
- inp=(1, 34, 34, 62), ref_res=34, is_shape=False,
- begin=(1,), end=(4,), strides=(1,), begin_mask=(1,), end_mask=(1,),
- shrink_axis_mask=(1,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_5(self, # inp[::-1] = [62, 34, 34, 1]
- inp=(1, 34, 34, 62), ref_res=(62, 34, 34, 1), is_shape=False,
- begin=(0,), end=(4,), strides=(-1,), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_6(self, # inp[0, 0:4:1]
- inp=((1, 34, 34, 62),), ref_res=(1, 34, 34, 62), is_shape=False,
- begin=(0, 0), end=(0, 4), strides=(1, 1), begin_mask=(0, 1), end_mask=(0, 1),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_7(self, # inp[:-1:1] = [1, 34, 34], since begin_mask is [0], begin can be of any value
- inp=(1, 34, 34, 62), ref_res=(1, 34, 34), is_shape=False,
- begin=(0,), end=(-1,), strides=(1,), begin_mask=(0,), end_mask=(1,),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_value_8(
- self, # inp_shape = (1, 2, 4), out = inp[..., :2, None] => out_shape = (1, 2, 2, 1)
- inp=(((0, 1, 2, 3), (4, 5, 6, 7)),), ref_res=((((0.,), (1.,)), ((4.,), (5.,))),), is_shape=False,
- begin=(0, 0, 0), end=(0, 2, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 1, 0),
- shrink_axis_mask=(0, 0, 0), new_axis_mask=(0, 0, 1), ellipsis_mask=(1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_1(
- self, # inp[0:3, 0:1, 0:5]
- inp=(10, 10, 10, 10), ref_res=(3, 1, 5, 10), is_shape=True,
- begin=(0, 0, 0), end=(3, 1, 5), strides=(1, 1, 1), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_2(
- self, # inp[0:3, 0:1, 5:0:-1]
- inp=(10, 10, 10, 10), ref_res=(3, 1, 5, 10), is_shape=True,
- begin=(0, 0, 5), end=(3, 1, 0), strides=(1, 1, -1), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_3(
- self, # inp[1:34, 0, :, :2]
- inp=(1, 35, 35, 3), ref_res=(1, 35, 2), is_shape=True,
- begin=(0, 0, 0, 0), end=(1, 34, 0, 2), strides=(1, 1, 1, 1), begin_mask=(1, 1, 0, 0), end_mask=(1, 0, 0, 1),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_4(
- self, # inp[1:34, :, :, :2] begin mask is (1,) so only one value can be specified
- inp=(1, 35, 35, 3), ref_res=(1, 35, 2), is_shape=True,
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(1, 0, 0, ), end_mask=(1, 0, 0, 1),
- shrink_axis_mask=(0, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_5(
- self, # inp[:, :, :, :] since all begin and end masks are zero
- inp=(1, 35, 35, 3), ref_res=(1, 35, 35, 3), is_shape=True,
- begin=(1, 10, 10, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_6(
- self, # inp[0]
- inp=(1, 35, 35, 3), ref_res=(35, 35, 3), is_shape=True,
- begin=(0,), end=(1,), strides=(1,), begin_mask=(1,), end_mask=(0,),
- shrink_axis_mask=(1,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_7(
- self, # inp[0, 20], ends can be of any value
- inp=(1, 35, 35, 3), ref_res=(35, 3), is_shape=True,
- begin=(0, 20), end=(1, 9999), strides=(1, 1), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_8(
- self, # inp[0, 0:34, 20:22, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(34, 2, 1, 3), is_shape=True,
- begin=(0, 0, 20, 0), end=(1, 34, 22, 2), strides=(1, 1, 1, 1), begin_mask=(0,), end_mask=(0,),
- shrink_axis_mask=(1,), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_9(
- self, # inp[:, 0:4, 20, new_axis], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(1, 4, 1, 3), is_shape=True,
- begin=(0, 0, 20, 0), end=(0, 4, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 1, 0, 0), end_mask=(0, 1, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_10(
- self, # inp[:, 0:4, new_axis, 20], both new_axis and shrink_axis are present
- inp=(1, 35, 35, 3), ref_res=(1, 4, 1, 3), is_shape=True,
- begin=(0, 0, 0, 20), end=(0, 4, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 1, 0, 0), end_mask=(0, 1, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_11(
- self, # inp[0, :, 0:34, 20:22, new_axis], both new_axis and shrink_axis are present
- inp=(1, 3, 35, 35), ref_res=(3, 34, 2, 1), is_shape=True,
- begin=(0, 0, 0, 20, 0), end=(1, 0, 34, 22, 0), strides=(1, 1, 1, 1, 1),
- begin_mask=(1, 0, 1, 1, 1), end_mask=(1, 0, 1, 1, 1),
- shrink_axis_mask=(1,), new_axis_mask=(0, 0, 0, 0, 1), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_12(
- self, # inp[0, :34, 20, :2]
- inp=(1, 35, 35, 3), ref_res=(34, 2), is_shape=True,
- begin=(0, 0, 0, 0), end=(1, 34, 20, 2), strides=(1, 1, 1, 1), begin_mask=(0, 1, 1, 1), end_mask=(0, 1, 1, 1),
- shrink_axis_mask=(1, 0, 1, 0), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_13(
- self, # inp[0, 0, 0], since it's shrink_axis ends can be of any value
- inp=(1, 35, 35, 3), ref_res=(3,), is_shape=True,
- begin=(0, 0, 0), end=(1, 34444, 20), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 1, 1), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_14(
- self, # inp[0, 0, 0], since begin_mask is [0], begin can be of any value
- inp=(1, 35, 35, 3), ref_res=(1, 18, 18, 3), is_shape=True,
- begin=(0, 0, 0), end=(1, 35, 35), strides=(2, 2, 2), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0, 0, 0), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- # with ellipsis
- def test_slice_infer_shape_15(
- self, # inp[..., np.newaxis]
- inp=(1, 35, 35), ref_res=(1, 35, 35, 1), is_shape=True,
- begin=(101, 0), end=(0, 0), strides=(-1, -1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_16(
- self, # inp_shape = (1, 720, 1080), out = inp[..., :100, None] => out_shape = (1, 720, 100, 1)
- inp=(1, 720, 1080), ref_res=(1, 720, 100, 1), is_shape=True,
- begin=(0, 0, 0), end=(0, 100, 0), strides=(1, 1, 1), begin_mask=(0, 1, 0), end_mask=(0, 1, 0),
- shrink_axis_mask=(0,), new_axis_mask=(0, 0, 1), ellipsis_mask=(1,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_17(
- self, # inp_shape = (1, 720, 1080, 3), out = inp[..., :-1] => out_shape = (1, 720, 100, 2)
- inp=(1, 720, 1080, 3), ref_res=(1, 720, 1080, 2), is_shape=True,
- begin=(0, 0), end=(0, -1), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 1),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_18(
- self, # inp_shape = (1, 720, 1080, 3), out = inp[..., -2] => out_shape = (1, 720, 1080)
- inp=(1, 720, 1080, 3), ref_res=(1, 720, 1080), is_shape=True,
- begin=(0, -2), end=(0, 0), strides=(1, 1), begin_mask=(0, 1), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_shape_19(
- self, # inp_shape = (1, 720, 1080, 3), out = input[..., 0:10, 0:3] => out_shape = (1, 720, 10, 3)
- inp=(1, 720, 1080, 3), ref_res=(1, 720, 10, 3), is_shape=True,
- begin=(0, 0, 0), end=(0, 10, 3), strides=(1, 1, 1), begin_mask=(0, 1, 1), end_mask=(0, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(1,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_dynamic_shape_1(
- self, # inp[0:3, 0:1, 0:5]
- inp=(dynamic_dimension_value, 10, 10, 10), ref_res=(dynamic_dimension_value, 1, 5, 10), is_shape=True,
- begin=(0, 0, 0), end=(3, 1, 5), strides=(1, 1, 1), begin_mask=(1, 1, 1), end_mask=(1, 1, 1),
- shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_dynamic_shape_2(
- self, # inp[0:d, 0:1, 0:5]
- inp=(10, 10, 10, 10), ref_res=(dynamic_dimension_value, 1, 5, 10), is_shape=True,
- begin=(0, 0, 0), end=(dynamic_dimension_value, 1, 5), strides=(1, 1, 1), begin_mask=(1, 1, 1),
- end_mask=(1, 1, 1), shrink_axis_mask=(0,), new_axis_mask=(0,), ellipsis_mask=(0,)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_slice_infer_dynamic_shape_3(
- self, # inp[1:34, 0, :, :d]
- inp=(1, 35, 35, 3), ref_res=(1, 35, dynamic_dimension_value), is_shape=True,
- begin=(0, 0, 0, 0), end=(1, 34, 0, dynamic_dimension_value), strides=(1, 1, 1, 1), begin_mask=(1, 1, 0, 0),
- end_mask=(1, 0, 0, 1), shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_0(
- self, # inp_shape = (1, 100, 200, 3), out = inp[np.newaxis, ..., 0, :], out_shape=(1, 1, 100, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_1(
- self, # inp_shape = (1, 100, 200, 3), out = inp[..., np.newaxis, 0, :], out_shape=(1, 100, 1, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_2(
- self, # inp_shape = (1, 100, 200, 3), out = inp[0, np.newaxis, ..., :], out_shape=(1, 100, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_3(
- self, # inp_shape = (1, 100, 200, 3), out = inp[0, ..., np.newaxis, :], out_shape=(100, 200, 1, 3)
- inp=(1, 100, 200, 3), ref_res=(100, 200, 1, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_4(
- self, # inp_shape = (1, 100, 200, 3), out = inp[np.newaxis, 0, ..., :], out_shape=(1, 100, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_5(
- self, # inp_shape = (1, 100, 200, 3), out = inp[..., 0, np.newaxis, :], out_shape=(1, 100, 1, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_6(
- self, # inp_shape = (1, 100, 200, 3), out = inp[np.newaxis, ..., :, 0], out_shape=(1, 1, 100, 200)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_7(
- self, # inp_shape = (1, 100, 200, 3), out = inp[..., np.newaxis, :, 0], out_shape=(1, 100, 1, 200)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 1, 200), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_8(
- self, # inp_shape = (1, 100, 200, 3), out = inp[0, np.newaxis, :, ...], out_shape=(1, 100, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_9(
- self, # inp_shape = (1, 100, 200, 3), out = inp[0, ..., :, np.newaxis], out_shape=(100, 200, 3, 1)
- inp=(1, 100, 200, 3), ref_res=(100, 200, 3, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_10(
- self, # inp_shape = (1, 100, 200, 3), out = inp[np.newaxis, 0, :, ...], out_shape=(1, 100, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_11(
- self, # inp_shape = (1, 100, 200, 3), out = inp[..., 0, :, np.newaxis], out_shape=(1, 100, 3, 1)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 3, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(1, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_12(
- self, # inp_shape = (1, 100, 200, 3), out = inp[np.newaxis, :, ..., 0], out_shape=(1, 1, 100, 200)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_13(
- self, # inp_shape = (1, 100, 200, 3), out = inp[..., :, np.newaxis, 0], out_shape=(1, 100, 200, 1)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_14(
- self, # inp_shape = (1, 100, 200, 3), out = inp[0, :, np.newaxis, ...], out_shape=(100, 1, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(100, 1, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 0, 0, 1)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_15(
- self, # inp_shape = (1, 100, 200, 3), out = inp[0, :, ..., np.newaxis], out_shape=(100, 200, 3, 1)
- inp=(1, 100, 200, 3), ref_res=(100, 200, 3, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 0, 1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_16(
- self, # inp_shape = (1, 100, 200, 3), out = inp[np.newaxis, :, 0, ...], out_shape=(1, 1, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_17(
- self, # inp_shape = (1, 100, 200, 3), out = inp[..., :, 0, np.newaxis], out_shape=(1, 100, 200, 1)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(1, 0, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_18(
- self, # inp_shape = (1, 100, 200, 3), out = inp[:, np.newaxis, ..., 0], out_shape=(1, 1, 100, 200)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 100, 200), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_19(
- self, # inp_shape = (1, 100, 200, 3), out = inp[:, ..., np.newaxis, 0], out_shape=(1, 100, 200, 1)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_20(
- self, # inp_shape = (1, 100, 200, 3), out = inp[:, 0, np.newaxis, ...], out_shape=(1, 1, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 0, 0, 1)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_21(
- self, # inp_shape = (1, 100, 200, 3), out = inp[:, 0, ..., np.newaxis], out_shape=(1, 200, 3, 1)
- inp=(1, 100, 200, 3), ref_res=(1, 200, 3, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 0, 1, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_22(
- self, # inp_shape = (1, 100, 200, 3), out = inp[:, np.newaxis, 0, ...], out_shape=(1, 1, 200, 3)
- inp=(1, 100, 200, 3), ref_res=(1, 1, 200, 3), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- def test_strided_slice_23(
- self, # inp_shape = (1, 100, 200, 3), out = inp[:, ..., 0, np.newaxis], out_shape=(1, 100, 200, 1)
- inp=(1, 100, 200, 3), ref_res=(1, 100, 200, 1), is_shape=True,
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 1, 0, 0)
- ):
- self.run_test(inp, is_shape, ref_res, begin, end, strides,
- begin_mask, end_mask, shrink_axis_mask, new_axis_mask, ellipsis_mask)
-
- # automatically generated the whole range of 2d slices over 2d, 3d and 4d input tensors
- def test_auto_infer_strided_slice_2d_over_2d_0(self):
- """
- inp_shape = (1, 100), out = inp[:, :] => out_shape = (1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_1(self):
- """
- inp_shape = (1, 100), out = inp[:, None] => out_shape = (1, 1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_2(self):
- """
- inp_shape = (1, 100), out = inp[:, 0] => out_shape = (1,)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_3(self):
- """
- inp_shape = (1, 100), out = inp[..., :] => out_shape = (1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_4(self):
- """
- inp_shape = (1, 100), out = inp[..., None] => out_shape = (1, 100, 1)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 100, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_5(self):
- """
- inp_shape = (1, 100), out = inp[..., 0] => out_shape = (1,)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_6(self):
- """
- inp_shape = (1, 100), out = inp[None, :] => out_shape = (1, 1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_7(self):
- """
- inp_shape = (1, 100), out = inp[None, None] => out_shape = (1, 1, 1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 1, 1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_8(self):
- """
- inp_shape = (1, 100), out = inp[None, 0] => out_shape = (1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_9(self):
- """
- inp_shape = (1, 100), out = inp[0, :] => out_shape = (100,)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(100,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_10(self):
- """
- inp_shape = (1, 100), out = inp[0, None] => out_shape = (1, 100)
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_2d_11(self):
- """
- inp_shape = (1, 100), out = inp[0, 0] => out_shape = ()
- """
- self.run_test(
- inp=(1, 100), is_shape=True, ref_res=(),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_0(self):
- """
- inp_shape = (1, 100, 200), out = inp[:, :] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_1(self):
- """
- inp_shape = (1, 100, 200), out = inp[:, None] => out_shape = (1, 1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_2(self):
- """
- inp_shape = (1, 100, 200), out = inp[:, 0] => out_shape = (1, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_3(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., :] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_4(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., None] => out_shape = (1, 100, 200, 1)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_5(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., 0] => out_shape = (1, 100)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_6(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, :] => out_shape = (1, 1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_7(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, None] => out_shape = (1, 1, 1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 1, 1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_8(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, 0] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_9(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, :] => out_shape = (100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_10(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, None] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_3d_11(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, 0] => out_shape = (200,)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(200,),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, :] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, None] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, 0] => out_shape = (1, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None] => out_shape = (1, 100, 200, 3, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3, 1),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(0, 1), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(0, 0), ellipsis_mask=(1, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_6(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_7(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, None] => out_shape = (1, 1, 1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 0), new_axis_mask=(1, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_8(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(0, 1), new_axis_mask=(1, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_9(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, :] => out_shape = (100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_10(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 0), new_axis_mask=(0, 1), ellipsis_mask=(0, 0)
- )
-
- def test_auto_infer_strided_slice_2d_over_4d_11(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, 0] => out_shape = (200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(200, 3),
- begin=(0, 0), end=(0, 0), strides=(1, 1), begin_mask=(0, 0), end_mask=(0, 0),
- shrink_axis_mask=(1, 1), new_axis_mask=(0, 0), ellipsis_mask=(0, 0)
- )
-
- # automatically generated slices from 3d to 5d d input tensors
- # fixed number of ellipsis, newaxis and shrink_axis
- def test_auto_infer_strided_slice_3d_over_3d_0(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, ..., 0] => out_shape = (1, 1, 100)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 1, 100),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 0, 1), new_axis_mask=(1, 0, 0), ellipsis_mask=(0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_3d_1(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., None, 0] => out_shape = (1, 100, 1)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 1),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 0, 1), new_axis_mask=(0, 1, 0), ellipsis_mask=(1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_3d_2(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, None, ...] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 0, 0), new_axis_mask=(0, 1, 0), ellipsis_mask=(0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_3d_over_3d_3(self):
- """
- inp_shape = (1, 100, 200), out = inp[0, ..., None] => out_shape = (100, 200, 1)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(100, 200, 1),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(1, 0, 0), new_axis_mask=(0, 0, 1), ellipsis_mask=(0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_3d_4(self):
- """
- inp_shape = (1, 100, 200), out = inp[None, 0, ...] => out_shape = (1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 200),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 1, 0), new_axis_mask=(1, 0, 0), ellipsis_mask=(0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_3d_over_3d_5(self):
- """
- inp_shape = (1, 100, 200), out = inp[..., 0, None] => out_shape = (1, 100, 1)
- """
- self.run_test(
- inp=(1, 100, 200), is_shape=True, ref_res=(1, 100, 1),
- begin=(0, 0, 0), end=(0, 0, 0), strides=(1, 1, 1), begin_mask=(0, 0, 0), end_mask=(0, 0, 0),
- shrink_axis_mask=(0, 1, 0), new_axis_mask=(0, 0, 1), ellipsis_mask=(1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, ..., 0, :] => out_shape = (1, 1, 100, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None, 0, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, ..., None, :] => out_shape = (100, 200, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(100, 200, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0, None, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_5d_0(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, ..., 0, :, :] => out_shape = (1, 1, 100, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 100, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_5d_1(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., None, 0, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_5d_2(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, None, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_5d_3(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, ..., None, :, :] => out_shape = (100, 200, 1, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(100, 200, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_5d_4(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, 0, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_3d_over_5d_5(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., 0, None, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_0(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, ..., 0, :] => out_shape = (1, 1, 100, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_1(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None, 0, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_2(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_3(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, ..., None, :] => out_shape = (100, 200, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(100, 200, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_4(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0, ..., :] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_5(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0, None, :] => out_shape = (1, 100, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 1, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_6(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, ..., :, 0] => out_shape = (1, 1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_7(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., None, :, 0] => out_shape = (1, 100, 1, 200)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 1, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_8(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, None, :, ...] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_9(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, ..., :, None] => out_shape = (100, 200, 3, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(100, 200, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_10(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, 0, :, ...] => out_shape = (1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_11(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., 0, :, None] => out_shape = (1, 100, 3, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_12(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, :, ..., 0] => out_shape = (1, 1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_13(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., :, None, 0] => out_shape = (1, 100, 200, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_14(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, :, None, ...] => out_shape = (100, 1, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(100, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_15(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[0, :, ..., None] => out_shape = (100, 200, 3, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(100, 200, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_16(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[None, :, 0, ...] => out_shape = (1, 1, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_17(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[..., :, 0, None] => out_shape = (1, 100, 200, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_18(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, None, ..., 0] => out_shape = (1, 1, 100, 200)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 100, 200),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_19(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, ..., None, 0] => out_shape = (1, 100, 200, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_20(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, 0, None, ...] => out_shape = (1, 1, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 1, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_21(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, 0, ..., None] => out_shape = (1, 200, 3, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 200, 3, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_22(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, None, 0, ...] => out_shape = (1, 1, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 1, 200, 3),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1)
- )
-
- def test_auto_infer_strided_slice_4d_over_4d_23(self):
- """
- inp_shape = (1, 100, 200, 3), out = inp[:, ..., 0, None] => out_shape = (1, 100, 200, 1)
- """
- self.run_test(
- inp=(1, 100, 200, 3), is_shape=True, ref_res=(1, 100, 200, 1),
- begin=(0, 0, 0, 0), end=(0, 0, 0, 0), strides=(1, 1, 1, 1), begin_mask=(0, 0, 0, 0), end_mask=(0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0), new_axis_mask=(0, 0, 0, 1), ellipsis_mask=(0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_0(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, ..., 0, :, :] => out_shape = (1, 1, 100, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 100, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_1(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., None, 0, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_2(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, None, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_3(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, ..., None, :, :] => out_shape = (100, 200, 1, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(100, 200, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_4(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, 0, ..., :, :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_5(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., 0, None, :, :] => out_shape = (1, 100, 1, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 1, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_6(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, ..., :, 0, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_7(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., None, :, 0, :] => out_shape = (1, 100, 1, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 1, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_8(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, None, :, ..., :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_9(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, ..., :, None, :] => out_shape = (100, 200, 10, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(100, 200, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_10(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, 0, :, ..., :] => out_shape = (1, 100, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_11(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., 0, :, None, :] => out_shape = (1, 100, 10, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_12(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, :, ..., 0, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_13(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., :, None, 0, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_14(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, :, None, ..., :] => out_shape = (100, 1, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(100, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_15(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[0, :, ..., None, :] => out_shape = (100, 200, 10, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(100, 200, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(1, 0, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_16(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[None, :, 0, ..., :] => out_shape = (1, 1, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(1, 0, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_17(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[..., :, 0, None, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(1, 0, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_18(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, None, ..., 0, :] => out_shape = (1, 1, 100, 200, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 100, 200, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_19(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, ..., None, 0, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 0, 1, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_20(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, 0, None, ..., :] => out_shape = (1, 1, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 1, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_21(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, 0, ..., None, :] => out_shape = (1, 200, 10, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 200, 10, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 1, 0, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 0, 1, 0, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_22(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, None, 0, ..., :] => out_shape = (1, 1, 200, 10, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 1, 200, 10, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 1, 0, 0, 0), ellipsis_mask=(0, 0, 0, 1, 0)
- )
-
- def test_auto_infer_strided_slice_4d_over_5d_23(self):
- """
- inp_shape = (1, 100, 200, 10, 3), out = inp[:, ..., 0, None, :] => out_shape = (1, 100, 200, 1, 3)
- """
- self.run_test(
- inp=(1, 100, 200, 10, 3), is_shape=True, ref_res=(1, 100, 200, 1, 3),
- begin=(0, 0, 0, 0, 0), end=(0, 0, 0, 0, 0), strides=(1, 1, 1, 1, 1), begin_mask=(0, 0, 0, 0, 0), end_mask=(0, 0, 0, 0, 0),
- shrink_axis_mask=(0, 0, 1, 0, 0), new_axis_mask=(0, 0, 0, 1, 0), ellipsis_mask=(0, 1, 0, 0, 0)
- )
diff --git a/tools/mo/unit_tests/mo/ops/switch_test.py b/tools/mo/unit_tests/mo/ops/switch_test.py
deleted file mode 100644
index db05b7508ec9bc..00000000000000
--- a/tools/mo/unit_tests/mo/ops/switch_test.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import Mock, call
-
-import numpy as np
-
-from openvino.tools.mo.ops.switch import Switch
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph_with_edge_attrs, build_graph_with_attrs
-
-
-class TestSwitch(unittest.TestCase):
- def test_switch_infer_with_condition(self):
- nodes = [
- ('tensor', {'value': np.zeros((3, 3)), 'kind': 'data', 'executable': True, 'shape': np.array([3, 3])}),
- ('pred_id', {'value': True, 'kind': 'data', 'executable': True}),
- ('switch', {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'infer': Switch.infer}),
- ('switch_data_0', {'value': None, 'kind': 'data', 'executable': True, 'shape': None}),
- ('switch_data_1', {'value': None, 'kind': 'data', 'executable': True, 'shape': None}),
- ('result_0', {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'}),
- ('result_1', {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'}),
- ]
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_0', 'result_0'),
- ('switch_data_1', 'result_1'),
- ]
- graph = build_graph_with_attrs(nodes_with_attrs=nodes, edges_with_attrs=edges)
-
- # We should propagate shapes and values
- graph_ref = build_graph_with_attrs(nodes_with_attrs=nodes,
- edges_with_attrs=edges,
- update_nodes_attributes=[('switch_data_0', {'shape': np.array([3, 3]),
- 'value': np.zeros((3, 3))}),
- ('switch_data_1', {'shape': np.array([3, 3]),
- 'value': np.zeros((3, 3))})])
-
- node = Node(graph, 'switch')
- node.infer(node)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'switch_data_0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_switch_infer_no_condition(self):
- nodes = [
- ('tensor', {'value': None, 'kind': 'data', 'executable': True, 'shape': np.array([1, 2, 1])}),
- ('pred_id', {'value': None, 'kind': 'data', 'executable': True}),
- ('switch', {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'infer': Switch.infer}),
- ('switch_data_0', {'value': None, 'kind': 'data', 'executable': True, 'shape': None}),
- ('switch_data_1', {'value': None, 'kind': 'data', 'executable': True, 'shape': None}),
- ('result_0', {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'}),
- ('result_1', {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'}),
- ]
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_0', 'result_0'),
- ('switch_data_1', 'result_1'),
- ]
- graph = build_graph_with_attrs(nodes_with_attrs=nodes, edges_with_attrs=edges)
-
- # We should propagate only shapes
- graph_ref = build_graph_with_attrs(nodes_with_attrs=nodes,
- edges_with_attrs=edges,
- update_nodes_attributes=[('switch_data_0', {'shape': np.array([1, 2, 1])}),
- ('switch_data_1', {'shape': np.array([1, 2, 1])})])
-
- node = Node(graph, 'switch')
- node.infer(node)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'switch_data_0', check_op_attrs=True)
- self.assertTrue(flag, resp)
-
- def test_switch_cf_infer_no_condition(self):
- me_mock = Mock()
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': None, 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_0': {'value': None, 'kind': 'data', 'executable': True},
- 'switch_data_1': {'value': None, 'kind': 'data', 'executable': True},
- 'result_0': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- 'result_1': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_0', 'result_0', {'in': 0}),
- ('switch_data_1', 'result_1', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
-
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- # In this case we should mark all ports as executable
- me_mock.assert_has_calls([call('switch_data_0', True), call('switch_data_1', True)], any_order=True)
-
- def test_switch_cf_true_both_ports(self):
- me_mock = Mock()
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': np.array(True), 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_0': {'value': None, 'kind': 'data', 'executable': True},
- 'switch_data_1': {'value': None, 'kind': 'data', 'executable': True},
- 'result_0': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- 'result_1': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_0', 'result_0', {'in': 0}),
- ('switch_data_1', 'result_1', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- me_mock.assert_has_calls([call('switch_data_0', False), call('switch_data_1', True)], any_order=True)
-
- def test_switch_cf_false_both_ports(self):
- me_mock = Mock()
-
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': np.array(False), 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_0': {'value': None, 'kind': 'data', 'executable': True},
- 'switch_data_1': {'value': None, 'kind': 'data', 'executable': True},
- 'result_0': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- 'result_1': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_0', 'result_0', {'in': 0}),
- ('switch_data_1', 'result_1', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- me_mock.assert_has_calls([call('switch_data_0', True), call('switch_data_1', False)], any_order=True)
-
- def test_switch_cf_true_one_exec_port(self):
- me_mock = Mock()
-
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': np.array(True), 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_1': {'value': None, 'kind': 'data', 'executable': True},
- 'result_1': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_1', 'result_1', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- me_mock.assert_has_calls([call('switch_data_1', True)], any_order=True)
-
- def test_switch_cf_false_one_exec_port(self):
- me_mock = Mock()
-
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': np.array(False), 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_0': {'value': None, 'kind': 'data', 'executable': True},
- 'result_0': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch_data_0', 'result_0', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- me_mock.assert_has_calls([call('switch_data_0', True)], any_order=True)
-
- def test_switch_cf_true_no_exec(self):
- me_mock = Mock()
-
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': np.array(True), 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_0': {'value': None, 'kind': 'data', 'executable': True},
- 'result_0': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_0', {'out': 0}),
- ('switch_data_0', 'result_0', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- me_mock.assert_has_calls([call('switch_data_0', False)], any_order=True)
-
- def test_switch_cf_false_no_exec(self):
- me_mock = Mock()
-
- nodes = {
- 'tensor': {'value': True, 'kind': 'data', 'executable': True},
- 'pred_id': {'value': np.array(False), 'kind': 'data', 'executable': True},
- 'switch': {'type': 'Switch', 'kind': 'op', 'op': 'Switch', 'control_flow_infer': Switch.control_flow_infer},
- 'switch_data_1': {'value': None, 'kind': 'data', 'executable': True},
- 'result_1': {'value': None, 'kind': 'op', 'executable': True, 'type': 'Result', 'op': 'Result'},
- }
- edges = [
- ('tensor', 'switch', {'in': 0}),
- ('pred_id', 'switch', {'in': 1}),
- ('switch', 'switch_data_1', {'out': 1}),
- ('switch_data_1', 'result_1', {'in': 0}),
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- node = Node(graph, 'switch')
- node.control_flow_infer(node, True, me_mock)
- me_mock.assert_has_calls([call('switch_data_1', False)], any_order=True)
diff --git a/tools/mo/unit_tests/mo/ops/tile_test.py b/tools/mo/unit_tests/mo/ops/tile_test.py
deleted file mode 100644
index 31833c3ad43800..00000000000000
--- a/tools/mo/unit_tests/mo/ops/tile_test.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.tile import Tile, AttributedTile
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {
- 'op': {'kind': 'op'},
- 'data': {'value': None, 'shape': np.array([10, 20, 30, 40]), 'kind': 'data'},
- 'const': {'kind': 'op'},
- 'tile_values': {'value': None, 'shape': np.array([4]), 'kind': 'data'},
- 'tile': {'type': 'AttributedTile', 'kind': 'op'},
- 'tile_out': {'value': None, 'shape': None, 'kind': 'data'},
-
-}
-
-edges = [
- ('op', 'data'),
- ('data', 'tile'),
- ('const', 'tile_values'),
- ('tile_values', 'tile'),
- ('tile', 'tile_out'),
-]
-
-attributed_edges = [
- ('op', 'data'),
- ('data', 'tile'),
- ('tile', 'tile_out'),
-]
-
-
-class TestTileInfer(unittest.TestCase):
- def test_tile_infer_correct(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': np.array([7, 1, 1, 1])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([70, 20, 30, 40]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_correct_2(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': np.array([1, 7, 1, 1])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([10, 140, 30, 40]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_correct_2d_tensor(self):
- graph = build_graph(nodes_attributes, edges,
- {'data': {'shape': np.array([3, 7])},
- 'tile_values': {'value': np.array([5, 1])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([15, 7]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_all_ones(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': np.array([1, 1, 1, 1])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([10, 20, 30, 40]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_two_non_one(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': np.array([2, 1, 1, 2])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([20, 20, 30, 80]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_three_non_one(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': np.array([2, 1, 5, 2])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([20, 20, 150, 80]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_none_input_shape(self):
- graph = build_graph(nodes_attributes, edges,
- {'data': {'shape': None},
- 'tile_values': {'value': np.array([1, 7, 1, 1])}})
- tile_node = Node(graph, 'tile')
- self.assertRaises(AssertionError, Tile.infer, tile_node)
-
- def test_tile_infer_values_test(self):
- input_data = np.arange(-30, 60, 0.25).reshape([2, 4, 3, -1])
- tile_values = np.array([3, 1, 1, 1])
- graph = build_graph(nodes_attributes, edges,
- {'data': {'shape': np.array(input_data.shape), 'value': input_data},
- 'tile_values': {'value': tile_values}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.tile(input_data, tile_values) == graph.node['tile_out']['value']))
-
- def test_tile_infer_values_const_propagation(self):
- """
- Test for constant propagation even if tile with multiple tile indices is not supported
- """
- input_data = np.arange(-30, 60, 0.25).reshape([2, 4, 3, -1])
- tile_values = np.array([4, 3, 2, 5])
- graph = build_graph(nodes_attributes, edges,
- {'data': {'shape': np.array(input_data.shape), 'value': input_data},
- 'tile_values': {'value': tile_values}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.tile(input_data, tile_values) == graph.node['tile_out']['value']))
-
- def test_tile_infer_undefined_tile_values(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': None}})
- tile_node = Node(graph, 'tile')
- self.assertRaises(AssertionError, Tile.infer, tile_node)
-
- def test_tile_infer_shapes_alignment(self):
- graph = build_graph(nodes_attributes, edges,
- {'tile_values': {'value': np.array([1, 2, 3]), 'shape': np.array([3])}})
- tile_node = Node(graph, 'tile')
- Tile.infer(tile_node)
- self.assertTrue(np.all(np.array([10, 20, 60, 120]) == graph.node['tile_out']['shape']))
-
- def test_tile_infer_one_input_correct(self):
- graph = build_graph(nodes_attributes, attributed_edges,
- {'tile': {'axis': 1, 'tiles': 7}})
- tile_node = Node(graph, 'tile')
- AttributedTile.infer(tile_node)
- self.assertTrue(np.all(np.array([10, 140, 30, 40]) == graph.node['tile_out']['shape']))
- self.assertEqual(tile_node.axis, 1)
- self.assertEqual(tile_node.tiles, 7)
-
- def test_tile_infer_one_input_correct_missing_axis(self):
- graph = build_graph(nodes_attributes, attributed_edges,
- {'tile': {'tiles': 7}})
- tile_node = Node(graph, 'tile')
- self.assertRaises(AssertionError, AttributedTile.infer, tile_node)
-
- def test_tile_infer_one_input_correct_missing_tiles(self):
- graph = build_graph(nodes_attributes, attributed_edges,
- {'tile': {'axis': 1}})
- tile_node = Node(graph, 'tile')
- self.assertRaises(AssertionError, AttributedTile.infer, tile_node)
diff --git a/tools/mo/unit_tests/mo/ops/topk_test.py b/tools/mo/unit_tests/mo/ops/topk_test.py
deleted file mode 100644
index 98cd4e834a660b..00000000000000
--- a/tools/mo/unit_tests/mo/ops/topk_test.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.topk import TopK
-from unit_tests.utils.graph import build_graph, regular_op_with_shaped_data, valued_const_with_data, result, connect
-
-
-class TestTopKInfer(unittest.TestCase):
- def setUp(self):
- nodes = {
- **regular_op_with_shaped_data('data', [20, 100, 4], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.float32}}),
- **valued_const_with_data('k', int64_array(10)),
- **regular_op_with_shaped_data('topk', None, {'op': 'TopK', 'type': 'TopK', 'name': 'topk', 'axis': 1}),
- 'topk_d2': {'kind': 'data', 'shape': None, 'value': None},
- **result('output_1'),
- **result('output_2'),
- }
- self.graph = build_graph(nodes, [
- *connect('data', '0:topk'),
- *connect('k', '1:topk'),
- ('topk', 'topk_d', {'out': 0}),
- ('topk', 'topk_d2', {'out': 1}),
- ('topk_d', 'output_1'),
- ('topk_d2', 'output_2'),
- ], nodes_with_edges_only=True)
-
- nodes2 = {
- **regular_op_with_shaped_data('data', [4, 10, 8], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.float32}}),
- **regular_op_with_shaped_data('k', [], {'type': 'Parameter', 'value': None,
- '_out_port_data_type': {0: np.int64}}),
- **regular_op_with_shaped_data('topk', None, {'op': 'TopK', 'type': 'TopK', 'name': 'topk', 'axis': 2}),
- 'topk_d2': {'kind': 'data', 'shape': None, 'value': None},
- **result('output_1'),
- **result('output_2'),
- }
- self.graph2 = build_graph(nodes2, [
- *connect('data', '0:topk'),
- *connect('k', '1:topk'),
- ('topk', 'topk_d', {'out': 0}),
- ('topk', 'topk_d2', {'out': 1}),
- ('topk_d', 'output_1'),
- ('topk_d2', 'output_2'),
- ], nodes_with_edges_only=True)
-
- def test_topk_infer_opset1(self):
- 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_i64_opset3(self):
- topk_node = Node(self.graph, 'topk')
- topk_node['version'] = 'opset3'
- topk_node['index_element_type'] = np.int64
- 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.int64)
-
- def test_topk_infer_i32_opset3(self):
- topk_node = Node(self.graph, 'topk')
- topk_node['version'] = 'opset3'
- topk_node['index_element_type'] = np.int32
- 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_with_dynamic_k(self):
- topk_node = Node(self.graph2, 'topk')
- topk_node['version'] = 'opset3'
- topk_node['index_element_type'] = np.int32
- TopK.infer(topk_node)
- TopK.type_infer(topk_node)
-
- self.assertTrue(
- np.array_equal(topk_node.out_port(0).data.get_shape(), shape_array([4, 10, dynamic_dimension_value])))
- self.assertTrue(
- np.array_equal(topk_node.out_port(1).data.get_shape(), shape_array([4, 10, dynamic_dimension_value])))
- self.assertTrue(topk_node.out_port(0).get_data_type() == np.float32)
- self.assertTrue(topk_node.out_port(1).get_data_type() == np.int32)
diff --git a/tools/mo/unit_tests/mo/ops/transpose_test.py b/tools/mo/unit_tests/mo/ops/transpose_test.py
deleted file mode 100644
index 544eda98eaf93a..00000000000000
--- a/tools/mo/unit_tests/mo/ops/transpose_test.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import itertools
-import unittest
-import pytest
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, strict_compare_tensors, \
- dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.middle.passes.infer import partial_infer
-from openvino.tools.mo.ops.parameter import Parameter
-from openvino.tools.mo.ops.transpose import Transpose
-from unit_tests.utils.graph import valued_const_with_data, result, regular_op_with_empty_data, connect, \
- build_graph, shaped_parameter
-
-input_shape = np.array([1, 3, 224, 224])
-
-
-class TestTransposeOp():
- nodes_attributes = {
- 'parameter': {
- 'kind': 'op',
- 'op': 'Parameter',
- 'shape': input_shape
- },
- 'data_1': {
- 'kind': 'data',
- 'shape': input_shape,
- 'value': None
- },
- 'order_const': {
- 'kind': 'op',
- 'op': 'Const',
- 'shape': np.array([4])
- },
- 'order_data': {
- 'kind': 'data',
- 'shape': np.array([4])
- },
- 'transpose': {
- 'type': 'Transpose',
- 'op': 'Transpose',
- 'reverse_order': False,
- 'kind': 'op',
- },
- 'data_2': {
- 'kind': 'data',
- 'shape': None,
- 'value': None
- }
- }
-
- def _create_graph_with_transpose(self, order):
- if order is None:
- graph = build_graph(self.nodes_attributes,
- [('parameter', 'data_1'),
- ('data_1', 'transpose'),
- ('transpose', 'data_2')])
- else:
- graph = build_graph(self.nodes_attributes,
- [('parameter', 'data_1'),
- ('data_1', 'transpose'),
- ('order_const', 'order_data'),
- ('order_data', 'transpose'),
- ('transpose', 'data_2')],
- {'order_data': {'value': order}})
- graph.graph['layout'] = 'NCHW'
- return graph
-
- @pytest.mark.parametrize("order",[list(order) for order in list(itertools.permutations(np.arange(4)))])
- def test_transpose_infer_1(self, order):
- graph = self._create_graph_with_transpose(order)
- transpose_node = Node(graph, 'transpose')
-
- Transpose.infer(transpose_node)
-
- ref = [transpose_node.in_node().shape[i] for i in order]
- assert np.array_equal(transpose_node.out_node().shape, np.array(ref))
-
- def test_transpose_infer_2(self):
- order = None
- graph = self._create_graph_with_transpose(order)
- transpose_node = Node(graph, 'transpose')
- transpose_node['reverse_order'] = True
- Transpose.infer(transpose_node)
-
- ref = np.array([x for x in reversed(transpose_node.in_node().shape)])
- assert np.array_equal(transpose_node.out_node().shape, ref),\
- "Shapes are not the same: {} and {}".format(transpose_node.out_node().shape, ref)
-
- def test_transpose_infer_neg_1(self):
- order = np.array([0, 1, 2, 3])
- graph = self._create_graph_with_transpose(order)
- transpose_node = Node(graph, 'transpose')
- transpose_node['reverse_order'] = True
- with pytest.raises(AssertionError):
- Transpose.infer(transpose_node)
-
- def test_transpose_infer_neg_2(self):
- order = None
- graph = self._create_graph_with_transpose(order)
- transpose_node = Node(graph, 'transpose')
- transpose_node['reverse_order'] = False
- with pytest.raises(AssertionError):
- Transpose.infer(transpose_node)
-
-
-dyn = dynamic_dimension_value
-
-
-class TestTransposeReverseInfer(unittest.TestCase):
- @staticmethod
- def build_and_test_reverse_inference(order, out_shape, ref_shape):
- nodes = {
- **shaped_parameter('data', None, {'reverse_infer': Parameter.reverse_infer}),
- **valued_const_with_data('order', int64_array(order)),
- **regular_op_with_empty_data('transpose', {'op': 'Transpose',
- 'infer': Transpose.infer,
- 'reverse_infer': Transpose.reverse_infer}),
- **result('res'),
- }
-
- edges = [
- *connect('data', '0:transpose'),
- *connect('order', '1:transpose'),
- *connect('transpose', 'res')
- ]
-
- graph = build_graph(nodes, edges)
- graph.stage = 'middle'
- Node(graph, 'transpose').out_port(0).data.set_shape(shape_array(out_shape))
-
- partial_infer(graph)
- actual_shape = Node(graph, 'data').out_port(0).data.get_shape()
- assert strict_compare_tensors(actual_shape, shape_array(ref_shape))
-
- def test_reverse_infer_1(self):
- self.build_and_test_reverse_inference(order=[0, 3, 1, 2],
- out_shape=[dyn, dyn, dyn, dyn],
- ref_shape=[dyn, dyn, dyn, dyn])
-
- def test_reverse_infer_2(self):
- self.build_and_test_reverse_inference(order=[0, 3, 1, 2],
- out_shape=[44, 32, 77, 1],
- ref_shape=[44, 77, 1, 32])
-
- def test_reverse_infer_3(self):
- self.build_and_test_reverse_inference(order=[0, 2, 3, 1],
- out_shape=[44, 32, 77, 1],
- ref_shape=[44, 1, 32, 77])
diff --git a/tools/mo/unit_tests/mo/ops/unique_test.py b/tools/mo/unit_tests/mo/ops/unique_test.py
deleted file mode 100644
index dd61980375093d..00000000000000
--- a/tools/mo/unit_tests/mo/ops/unique_test.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-import numpy as np
-
-from openvino.tools.mo.ops.unique import Unique
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-# graph 1 with two outputs: uniques and indices
-nodes_attributes = {'input': {'shape': None, 'value': None, 'kind': 'data'},
- 'unique_node': {'op': 'Unique', 'kind': 'op'},
- 'output_uniques': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_indices': {'shape': None, 'value': None, 'kind': 'data'},
- }
-edges1 = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_uniques', {'out': 0}),
- ('unique_node', 'output_indices', {'out': 1})]
-inputs1 = {'input': {'shape': int64_array([20]), 'value': None},
- 'unique_node': {
- 'sorted': 'false',
- 'return_inverse': 'true',
- 'return_counts': 'false'
- }
- }
-
-# graph 2 with three outputs: uniques, indices and counts
-nodes_attributes2 = {'input': {'shape': None, 'value': None, 'kind': 'data'},
- 'unique_node': {'op': 'Unique', 'kind': 'op'},
- 'output_uniques': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_counts': {'shape': None, 'value': None, 'kind': 'data'}
- }
-edges2 = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_uniques', {'out': 0}),
- ('unique_node', 'output_indices', {'out': 1}),
- ('unique_node', 'output_counts', {'out': 2})]
-inputs2 = {'input': {'shape': int64_array([20]), 'value': None},
- 'unique_node': {
- 'sorted': 'false',
- 'return_inverse': 'true',
- 'return_counts': 'true'
- }
- }
-
-
-class TestUnique(unittest.TestCase):
- # case 1: a graph with two outputs: uniques and indices
- def test_partial_infer1(self):
- graph = build_graph(nodes_attributes, edges1, inputs1)
-
- unique_node = Node(graph, 'unique_node')
- Unique.infer(unique_node)
-
- # prepare reference results
- ref_output_uniques_shape = int64_array([20])
- ref_output_indices_shape = int64_array([20])
-
- # get resulted shapes
- res_output_uniques_shape = graph.node['output_uniques']['shape']
- res_output_indices_shape = graph.node['output_indices']['shape']
-
- self.assertTrue(np.array_equal(ref_output_uniques_shape, res_output_uniques_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_uniques_shape, res_output_uniques_shape))
-
- self.assertTrue(np.array_equal(ref_output_indices_shape, res_output_indices_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_indices_shape, res_output_indices_shape))
-
- # case 2: a graph with three outputs: uniques, indices and counts
- def test_partial_infer2(self):
- graph = build_graph(nodes_attributes2, edges2, inputs2)
-
- unique_node = Node(graph, 'unique_node')
- Unique.infer(unique_node)
-
- # prepare reference results
- ref_output_uniques_shape = int64_array([20])
- ref_output_indices_shape = int64_array([20])
- ref_output_counts_shape = int64_array([20])
-
- # get resulted shapes
- res_output_uniques_shape = graph.node['output_uniques']['shape']
- res_output_indices_shape = graph.node['output_indices']['shape']
- res_output_counts_shape = graph.node['output_counts']['shape']
-
- self.assertTrue(np.array_equal(ref_output_uniques_shape, res_output_uniques_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_uniques_shape, res_output_uniques_shape))
-
- self.assertTrue(np.array_equal(ref_output_indices_shape, res_output_indices_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_indices_shape, res_output_indices_shape))
-
- self.assertTrue(np.array_equal(ref_output_counts_shape, res_output_counts_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_counts_shape, res_output_counts_shape))
-
- # case 3: a graph with just unique output
- def test_partial_infer_just_unique(self):
- edges = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_uniques', {'out': 0})]
- graph = build_graph(nodes_attributes, edges, inputs1)
-
- unique_node = Node(graph, 'unique_node')
- Unique.infer(unique_node)
-
- # prepare reference results
- ref_output_uniques_shape = int64_array([20])
-
- # get resulted shapes
- res_output_uniques_shape = graph.node['output_uniques']['shape']
-
- self.assertTrue(np.array_equal(ref_output_uniques_shape, res_output_uniques_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_uniques_shape, res_output_uniques_shape))
-
- # case 4: an invalid graph with 2D input
- def test_incorrect_input_shape(self):
- inputs = {'input': {'shape': int64_array([20, 2]), 'value': None}}
-
- graph = build_graph(nodes_attributes, edges1, inputs)
-
- unique_node = Node(graph, 'unique_node')
- self.assertRaises(AssertionError, Unique.infer, unique_node)
-
- # case 5: an invalid graph with return_counts = false and three outputs
- def test_more_output_ports(self):
- nodes_attributes1 = {'input': {'shape': None, 'value': None, 'kind': 'data'},
- 'unique_node': {'op': 'Unique', 'kind': 'op'},
- 'output_uniques': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'output3': {'shape': None, 'value': None, 'kind': 'data'},
- }
- edges = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_uniques', {'out': 0}),
- ('unique_node', 'output_indices', {'out': 1}),
- ('unique_node', 'output3', {'out': 2})]
- graph = build_graph(nodes_attributes1, edges, inputs1)
-
- unique_node = Node(graph, 'unique_node')
- self.assertRaises(AssertionError, Unique.infer, unique_node)
-
- # case 6: an invalid graph without unique output
- def test_no_uniques_output(self):
- edges = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_indices', {'out': 1})]
- graph = build_graph(nodes_attributes, edges, inputs1)
-
- unique_node = Node(graph, 'unique_node')
- self.assertRaises(AssertionError, Unique.infer, unique_node)
-
- # case 7: infer for constant input
- # graph with a constant input, three outputs, sorted = 'false'
- def test_constant_input(self):
- nodes_attributes_ = {'input': {'shape': None, 'value': None, 'kind': 'data'},
- 'unique_node': {'op': 'Unique', 'kind': 'op'},
- 'output_uniques': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_counts': {'shape': None, 'value': None, 'kind': 'data'}
- }
- edges_ = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_uniques', {'out': 0}),
- ('unique_node', 'output_indices', {'out': 1}),
- ('unique_node', 'output_counts', {'out': 2})]
- inputs_ = {'input': {'shape': int64_array([10]),
- 'value': np.array([8.0, 1.0, 2.0, 1.0, 8.0, 5.0, 1.0, 5.0, 0.0, 0.0], dtype=float)},
- 'unique_node': {
- 'sorted': 'false',
- 'return_inverse': 'true',
- 'return_counts': 'true'
- }
- }
- graph = build_graph(nodes_attributes_, edges_, inputs_)
- unique_node = Node(graph, 'unique_node')
- Unique.infer(unique_node)
-
- # prepare reference results
- ref_output_uniques_shape = int64_array([5])
- ref_output_uniques_value = np.array([8.0, 1.0, 2.0, 5.0, 0.0], dtype=float)
- ref_output_indices_shape = int64_array([10])
- ref_output_indices_value = np.array([0.0, 1.0, 2.0, 1.0, 0.0, 3.0, 1.0, 3.0, 4.0, 4.0], dtype=float)
- ref_output_counts_shape = int64_array([5])
- ref_output_counts_value = np.array([2.0, 3.0, 1.0, 2.0, 2.0], dtype=float)
-
- # get resulted shapes
- res_output_uniques_shape = graph.node['output_uniques']['shape']
- res_output_uniques_value = graph.node['output_uniques']['value']
- res_output_indices_shape = graph.node['output_indices']['shape']
- res_output_indices_value = graph.node['output_indices']['value']
- res_output_counts_shape = graph.node['output_counts']['shape']
- res_output_counts_value = graph.node['output_counts']['value']
-
- # verify the results
- self.assertTrue(np.array_equal(ref_output_uniques_shape, res_output_uniques_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_uniques_shape, res_output_uniques_shape))
- self.assertTrue(np.array_equal(ref_output_uniques_value, res_output_uniques_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_uniques_value, res_output_uniques_value))
- self.assertTrue(np.array_equal(ref_output_indices_shape, res_output_indices_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_indices_shape, res_output_indices_shape))
- self.assertTrue(np.array_equal(ref_output_indices_value, res_output_indices_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_indices_value, res_output_indices_value))
- self.assertTrue(np.array_equal(ref_output_counts_shape, res_output_counts_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_counts_shape, res_output_counts_shape))
- self.assertTrue(np.array_equal(ref_output_counts_value, res_output_counts_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_counts_value, res_output_counts_value))
-
- # case 8: infer for constant input
- # graph with a constant input, three outputs, sorted = 'true'
- def test_constant_input(self):
- nodes_attributes_ = {'input': {'shape': None, 'value': None, 'kind': 'data'},
- 'unique_node': {'op': 'Unique', 'kind': 'op'},
- 'output_uniques': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_indices': {'shape': None, 'value': None, 'kind': 'data'},
- 'output_counts': {'shape': None, 'value': None, 'kind': 'data'}
- }
- edges_ = [('input', 'unique_node', {'in': 0}),
- ('unique_node', 'output_uniques', {'out': 0}),
- ('unique_node', 'output_indices', {'out': 1}),
- ('unique_node', 'output_counts', {'out': 2})]
- inputs_ = {'input': {'shape': int64_array([10]),
- 'value': np.array([8.0, 1.0, 2.0, 1.0, 8.0, 5.0, 1.0, 5.0, 0.0, 0.0], dtype=float)},
- 'unique_node': {
- 'sorted': 'true',
- 'return_inverse': 'true',
- 'return_counts': 'true'
- }
- }
- graph = build_graph(nodes_attributes_, edges_, inputs_)
- unique_node = Node(graph, 'unique_node')
- Unique.infer(unique_node)
-
- # prepare reference results
- ref_output_uniques_shape = int64_array([5])
- ref_output_uniques_value = np.array([0.0, 1.0, 2.0, 5.0, 8.0], dtype=float)
- ref_output_indices_shape = int64_array([10])
- ref_output_indices_value = np.array([4.0, 1.0, 2.0, 1.0, 4.0, 3.0, 1.0, 3.0, 0.0, 0.0], dtype=float)
- ref_output_counts_shape = int64_array([5])
- ref_output_counts_value = np.array([2.0, 3.0, 1.0, 2.0, 2.0], dtype=float)
-
- # get resulted shapes
- res_output_uniques_shape = graph.node['output_uniques']['shape']
- res_output_uniques_value = graph.node['output_uniques']['value']
- res_output_indices_shape = graph.node['output_indices']['shape']
- res_output_indices_value = graph.node['output_indices']['value']
- res_output_counts_shape = graph.node['output_counts']['shape']
- res_output_counts_value = graph.node['output_counts']['value']
-
- # verify the results
- self.assertTrue(np.array_equal(ref_output_uniques_shape, res_output_uniques_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_uniques_shape, res_output_uniques_shape))
- self.assertTrue(np.array_equal(ref_output_uniques_value, res_output_uniques_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_uniques_value, res_output_uniques_value))
- self.assertTrue(np.array_equal(ref_output_indices_shape, res_output_indices_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_indices_shape, res_output_indices_shape))
- self.assertTrue(np.array_equal(ref_output_indices_value, res_output_indices_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_indices_value, res_output_indices_value))
- self.assertTrue(np.array_equal(ref_output_counts_shape, res_output_counts_shape),
- 'shapes do not match expected: {} and given: {}'.format(ref_output_counts_shape, res_output_counts_shape))
- self.assertTrue(np.array_equal(ref_output_counts_value, res_output_counts_value),
- 'values do not match expected: {} and given: {}'.format(ref_output_counts_value, res_output_counts_value))
diff --git a/tools/mo/unit_tests/mo/ops/unsqueeze_test.py b/tools/mo/unit_tests/mo/ops/unsqueeze_test.py
deleted file mode 100644
index f21dcbfc3205e1..00000000000000
--- a/tools/mo/unit_tests/mo/ops/unsqueeze_test.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.ops.unsqueeze import Unsqueeze
-from openvino.tools.mo.utils.ir_engine.compare_graphs import compare_graphs
-from unit_tests.utils.graph import build_graph
-
-
-class TestUnsqueezeOp():
- nodes_attributes = {
- 'data_1': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- },
- 'unsq': {
- 'op': 'Unsqueeze',
- 'kind': 'op',
- },
- 'unsq_dims_const': {
- 'op': 'Const',
- 'kind': 'op',
- },
- 'unsq_dims': {
- 'kind': 'data',
- },
- 'data_2': {
- 'kind': 'data',
- 'shape': None,
- 'value': None,
- }
- }
-
- @pytest.mark.parametrize("input_shape, unsq_dims, output_shape, ref_uns_dims, input_value, output_value",
- [(shape_array([1, 3, 64, 64]), int64_array([0, 4]), shape_array([1, 1, 3, 64, 1, 64]),
- int64_array([0, 4]), None, None),
- (shape_array([2, 3, 64, 64]), int64_array([-1]), shape_array([2, 3, 64, 64, 1]), int64_array([4]), None,
- None),
- (shape_array([2, 3, dynamic_dimension_value, 64]), int64_array([0]),
- shape_array([1, 2, 3, dynamic_dimension_value, 64]), int64_array([0]), None, None),
- (shape_array([1, 2]), int64_array([-1]), shape_array([1, 2, 1]), int64_array([2]),
- shape_array([5, dynamic_dimension_value]).reshape((1, 2)),
- shape_array([5, dynamic_dimension_value]).reshape((1, 2, 1))),
- ])
- def test_unsqueeze_infer(self, input_shape, unsq_dims, output_shape, ref_uns_dims, input_value, output_value):
- graph = build_graph(self.nodes_attributes,
- [('data_1', 'unsq'),
- ('unsq_dims_const', 'unsq_dims'),
- ('unsq_dims', 'unsq'),
- ('unsq', 'data_2')],
- {'data_1': {'shape': input_shape, 'value': input_value},
- 'unsq_dims': {'value': unsq_dims, 'shape': unsq_dims.shape},
- 'unsq_dims_const': {'value': unsq_dims, 'shape': unsq_dims.shape},
- })
-
- graph_ref = build_graph(self.nodes_attributes,
- [('data_1', 'unsq'),
- ('unsq_dims_const', 'unsq_dims'),
- ('unsq_dims', 'unsq'),
- ('unsq', 'data_2')],
- {'data_1': {'shape': input_shape, 'value': input_value},
- 'unsq_dims': {'value': ref_uns_dims, 'shape': ref_uns_dims.shape},
- 'unsq_dims_const': {'value': ref_uns_dims, 'shape': ref_uns_dims.shape},
- 'data_2': {'shape': output_shape, 'value': output_value},
- })
-
- unsqueeze_node = Node(graph, 'unsq')
- Unsqueeze.infer(unsqueeze_node)
-
- (flag, resp) = compare_graphs(graph, graph_ref, 'data_2')
- assert flag, resp
- assert strict_compare_tensors(Node(graph, 'data_2').shape, Node(graph_ref, 'data_2').shape)
- if Node(graph_ref, 'data_2').value is not None:
- assert strict_compare_tensors(Node(graph, 'data_2').value, Node(graph_ref, 'data_2').value)
diff --git a/tools/mo/unit_tests/mo/ops/upsample_test.py b/tools/mo/unit_tests/mo/ops/upsample_test.py
deleted file mode 100644
index c0fc50225ca92f..00000000000000
--- a/tools/mo/unit_tests/mo/ops/upsample_test.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.ops.upsample import UpsampleOp
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from unit_tests.utils.graph import build_graph
-
-nodes_attributes = {'node_1': {'type': 'Identity', 'kind': 'op'},
- 'upsample': {'type': 'Upsample', 'kind': 'op'},
- 'node_3': {'type': 'Identity', 'kind': 'op'},
- 'op_output': {'kind': 'op', 'op': 'Result'},
- }
-
-
-class TestUpsampleOp():
- @pytest.mark.parametrize("scales, input_shape, expected_shape",[
- (np.array([1., 1., 2., 2.]), shape_array([1, 3, 227, 227]), shape_array([1, 3, 454, 454])),
- (np.array([1., 1., 2.5, 1.5]), shape_array([1, 5, 227, 227]), shape_array([1, 5, 567, 340])),
- (np.array([1., 1., 1.3, 0.7]), shape_array([1, 14, 1023, 713]), shape_array([1, 14, 1329, 499])),
- (np.array([1., 1., 1.3, 0.7]), shape_array([1, 14, dynamic_dimension_value, 713]),
- shape_array([1, 14, dynamic_dimension_value, 499])),
- (np.array([1., 1., 1.3, 0.7]), shape_array([1, 14, 1023, dynamic_dimension_value]),
- shape_array([1, 14, 1329, dynamic_dimension_value])),
- ])
- def test_upsample_with_scales_infer(self, scales, input_shape, expected_shape):
- graph = build_graph(nodes_attributes,
- [('node_1', 'upsample'),
- ('upsample', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': input_shape},
- 'upsample': {'mode': 'linear',
- 'height_scale': scales[2],
- 'width_scale': scales[3]}
- })
-
- graph.graph['layout'] = 'NCHW'
- upsample_node = Node(graph, 'upsample')
- UpsampleOp.upsample_infer(upsample_node)
- res_shape = graph.node['node_3']['shape']
- assert strict_compare_tensors(expected_shape, res_shape)
-
- @pytest.mark.parametrize("scales, input_shape, expected_shape",[
- (np.array([1., 1., 2., 2.]), shape_array([1, 3, 227, 227]), shape_array([1, 3, 454, 454])),
- (np.array([1., 1., 2.5, 1.5]), shape_array([1, 5, 227, 227]), shape_array([1, 5, 567, 340])),
- (np.array([1., 1., 1.3, 0.7]), shape_array([1, 14, 1023, 713]), shape_array([1, 14, 1329, 499])),
- (np.array([1., 1., 1.3, 0.7]), shape_array([1, 14, dynamic_dimension_value, 713]),
- shape_array([1, 14, dynamic_dimension_value, 499])),
- (np.array([1., 1., 1.3, 0.7]), shape_array([1, 14, 1023, dynamic_dimension_value]),
- shape_array([1, 14, 1329, dynamic_dimension_value])),
- ])
- def test_upsample_with_second_input_infer(self, scales, input_shape, expected_shape):
- nodes_attributes['scales'] = {'kind': 'data', 'value': scales}
- graph = build_graph(nodes_attributes,
- [('node_1', 'upsample'),
- ('scales', 'upsample'),
- ('upsample', 'node_3'),
- ('node_3', 'op_output')
- ],
- {'node_3': {'shape': None, 'value': None},
- 'node_1': {'shape': input_shape},
- 'upsample': {'mode': 'linear',
- 'height_scale': None,
- 'width_scale': None}
- })
-
- graph.graph['layout'] = 'NCHW'
- upsample_node = Node(graph, 'upsample')
- UpsampleOp.upsample_infer(upsample_node)
- res_shape = graph.node['node_3']['shape']
- assert strict_compare_tensors(expected_shape, res_shape)
diff --git a/tools/mo/unit_tests/mo/pipeline/__init__.py b/tools/mo/unit_tests/mo/pipeline/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/pipeline/common_test.py b/tools/mo/unit_tests/mo/pipeline/common_test.py
deleted file mode 100644
index 220f409f23a936..00000000000000
--- a/tools/mo/unit_tests/mo/pipeline/common_test.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-import pytest
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.pipeline.common import determined_sort, get_fw_tensor_debug_info, get_sorted_outputs
-from unit_tests.utils.graph import build_graph_with_edge_attrs
-
-
-class TestTopologicalSort():
- @pytest.mark.parametrize( "edges",[
- [('A', 'Ad', {'out': 0}),
- ('Ad', 'B', {'in': 0}),
- ('B', 'Bd', {'out': 0}),
- ('Bd', 'C', {'in': 0}),
- ('C', 'Cd', {'out': 0}),
- ('Cd', 'D', {'in': 0}),
- ('D', 'Dd', {'out': 0}),
- ('Dd', 'E', {'in': 0}),
- ('E', 'Ed', {'out': 0}),
- ('Ed', 'I', {'in': 0}),
- ('Cd', 'F', {'in': 0}),
- ('F', 'Fd', {'out': 0}),
- ('Fd', 'G', {'in': 0}),
- ('G', 'Gd', {'out': 0}),
- ('Gd', 'I', {'in': 1}),
- ('Cd', 'H', {'in': 0}),
- ('H', 'Hd', {'out': 0}),
- ('Hd', 'I', {'in': 2}),
- ('I', 'Id', {'out': 0}),
- ('Id', 'J', {'in': 0}),
- ('J', 'Jd', {'out': 0}),
- ('Jd', 'K', {'in': 0}),
- ('K', 'Kd', {'out': 0})],
-
- [('A', 'Ad', {'out': 0}),
- ('Ad', 'B', {'in': 0}),
- ('B', 'Bd', {'out': 0}),
- ('Bd', 'C', {'in': 0}),
- ('C', 'Cd', {'out': 0}),
- ('Cd', 'D', {'in': 0}),
- ('D', 'Dd', {'out': 0}),
- ('Dd', 'E', {'in': 0}),
- ('E', 'Ed', {'out': 0}),
- ('Ed', 'I', {'in': 0}),
- ('Cd', 'F', {'in': 0}),
- ('F', 'Fd', {'out': 0}),
- ('Fd', 'G', {'in': 0}),
- ('G', 'Gd', {'out': 0}),
- ('Gd', 'I', {'in': 1}),
- ('Cd', 'H', {'in': 0}),
- ('H', 'Hd', {'out': 0}),
- ('Hd', 'I', {'in': 2}),
- ('I', 'Id', {'out': 0}),
- ('Id', 'J', {'in': 0}),
- ('J', 'Jd', {'out': 0}),
- ('Jd', 'K', {'in': 0}),
- ('K', 'Kd', {'out': 0}),
- ('Ad', 'E', {'in': 1}),
- ('Bd', 'K', {'in': 1}),
- ('Hd', 'J', {'in': 1})],
-
- [('A', 'Ad', {'out': 0}),
- ('Ad', 'B', {'in': 0}),
- ('B', 'Bd', {'out': 0}),
- ('Bd', 'C', {'in': 0}),
- ('C', 'Cd', {'out': 0}),
- ('Cd', 'D', {'in': 0}),
- ('D', 'Dd', {'out': 0}),
- ('Dd', 'E', {'in': 0}),
- ('E', 'Ed', {'out': 0}),
- ('Ed', 'I', {'in': 0}),
- ('Cd', 'F', {'in': 0}),
- ('F', 'Fd', {'out': 0}),
- ('Fd', 'G', {'in': 0}),
- ('G', 'Gd', {'out': 0}),
- ('Gd', 'I', {'in': 1}),
- ('Cd', 'H', {'in': 0}),
- ('H', 'Hd', {'out': 0}),
- ('Hd', 'I', {'in': 2}),
- ('I', 'Id', {'out': 0}),
- ('Id', 'J', {'in': 0}),
- ('J', 'Jd', {'out': 0}),
- ('Jd', 'K', {'in': 0}),
- ('K', 'Kd', {'out': 0}),
- ('Ad', 'E', {'in': 1}),
- ('Bd', 'K', {'in': 1}),
- ('Hd', 'J', {'in': 1}),
- ('Dd', 'F', {'in': 1}),
- ('Fd', 'H', {'in': 1}),
- ('Gd', 'H', {'in': 0})]]
- )
- def test_determined_topological_sort(self, edges):
- nodes = {'A': {'type': 'Identity', 'kind': 'op'},
- 'B': {'type': 'Identity', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op'},
- 'D': {'type': 'Identity', 'kind': 'op'},
- 'E': {'type': 'Identity', 'kind': 'op'},
- 'F': {'type': 'Identity', 'kind': 'op'},
- 'G': {'type': 'Identity', 'kind': 'op'},
- 'H': {'type': 'Identity', 'kind': 'op'},
- 'I': {'type': 'Identity', 'kind': 'op'},
- 'J': {'type': 'Identity', 'kind': 'op'},
- 'K': {'type': 'Identity', 'kind': 'op'},
- 'Ad': {'value': None, 'kind': 'data'},
- 'Bd': {'value': None, 'kind': 'data'},
- 'Cd': {'value': None, 'kind': 'data'},
- 'Dd': {'value': None, 'kind': 'data'},
- 'Ed': {'value': None, 'kind': 'data'},
- 'Fd': {'value': None, 'kind': 'data'},
- 'Gd': {'value': None, 'kind': 'data'},
- 'Hd': {'value': None, 'kind': 'data'},
- 'Id': {'value': None, 'kind': 'data'},
- 'Jd': {'value': None, 'kind': 'data'},
- 'Kd': {'value': None, 'kind': 'data'},
- }
-
- graph = build_graph_with_edge_attrs(nodes, edges)
- outputs = [Node(graph, 'Kd')]
- for i in range(100):
- op_order, data_order = determined_sort(outputs)
- assert op_order == ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']
- assert data_order == ['Ad', 'Bd', 'Cd', 'Dd', 'Ed', 'Fd', 'Gd', 'Hd', 'Id', 'Jd', 'Kd']
-
-
-class TestGetFWTensorName(unittest.TestCase):
- def test_get_fw_tensor_debug_info(self):
- nodes = {
- 'A': {'type': 'Identity', 'kind': 'op'},
- 'B': {'type': 'Identity', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op'},
- 'Ad': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('A', 0)]},
- 'Bd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('B', 0)]},
- 'Cd': {'value': None, 'kind': 'data'},
- }
- edges = [
- ('A', 'Ad', {'out': 0}),
- ('Ad', 'B', {'in': 0}),
- ('B', 'Bd', {'out': 0}),
- ('Bd', 'C', {'in': 0}),
- ('C', 'Cd', {'out': 0})
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- fw_debug_info = get_fw_tensor_debug_info(Node(graph, 'Cd'))
- self.assertEqual(len(fw_debug_info), 1)
- self.assertEqual(fw_debug_info[0], ('B', 0))
-
-
-class TestOutputSort(unittest.TestCase):
- def test_get_sorted_outputs(self):
- nodes = {'A': {'type': 'Identity', 'kind': 'op'},
- 'B': {'type': 'Identity', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op'},
- 'D': {'type': 'Identity', 'kind': 'op'},
- 'E': {'type': 'Identity', 'kind': 'op'},
- 'F': {'type': 'Identity', 'kind': 'op'},
- 'G': {'type': 'Identity', 'kind': 'op'},
- 'H': {'type': 'Identity', 'kind': 'op'},
- 'Ad': {'value': None, 'kind': 'data'},
- 'Bd': {'value': None, 'kind': 'data'},
- 'Cd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('C', 0)]},
- 'Dd': {'value': None, 'kind': 'data'},
- 'Ed': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('E', 0)]},
- 'Fd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('F', 0)]},
- 'Gd': {'value': None, 'kind': 'data'},
- 'Hd': {'value': None, 'kind': 'data'}
- }
- edges = [
- ('A', 'Ad', {'out': 0}),
- ('Ad', 'B', {'in': 0}),
- ('B', 'Bd', {'out': 0}),
- ('Bd', 'C', {'in': 0}),
- ('C', 'Cd', {'out': 0}),
- ('Cd', 'D', {'in': 0}),
- ('D', 'Dd', {'out': 0}),
- ('Dd', 'E', {'in': 0}),
- ('E', 'Ed', {'out': 0}),
- ('Cd', 'F', {'in': 0}),
- ('F', 'Fd', {'out': 0}),
- ('Fd', 'G', {'in': 0}),
- ('G', 'Gd', {'out': 0}),
- ('Cd', 'H', {'in': 0}),
- ('H', 'Hd', {'out': 0})
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- self.assertListEqual([node.id for node in get_sorted_outputs(graph)], ['Hd', 'Ed', 'Gd'])
-
- def test_get_sorted_outputs_fine_situation(self):
- nodes = {'A': {'type': 'Identity', 'kind': 'op'},
- 'B': {'type': 'Identity', 'kind': 'op'},
- 'C': {'type': 'Identity', 'kind': 'op'},
- 'D': {'type': 'Identity', 'kind': 'op'},
- 'E': {'type': 'Identity', 'kind': 'op'},
- 'F': {'type': 'Identity', 'kind': 'op'},
- 'G': {'type': 'Identity', 'kind': 'op'},
- 'H': {'type': 'Identity', 'kind': 'op'},
- 'Ad': {'value': None, 'kind': 'data'},
- 'Bd': {'value': None, 'kind': 'data'},
- 'Cd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('C', 0)]},
- 'Dd': {'value': None, 'kind': 'data'},
- 'Ed': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('E', 0)]},
- 'Fd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('F', 0)]},
- 'Gd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('G', 0)]},
- 'Hd': {'value': None, 'kind': 'data', 'fw_tensor_debug_info': [('H', 0)]}
- }
- edges = [
- ('A', 'Ad', {'out': 0}),
- ('Ad', 'B', {'in': 0}),
- ('B', 'Bd', {'out': 0}),
- ('Bd', 'C', {'in': 0}),
- ('C', 'Cd', {'out': 0}),
- ('Cd', 'D', {'in': 0}),
- ('D', 'Dd', {'out': 0}),
- ('Dd', 'E', {'in': 0}),
- ('E', 'Ed', {'out': 0}),
- ('Cd', 'F', {'in': 0}),
- ('F', 'Fd', {'out': 0}),
- ('Fd', 'G', {'in': 0}),
- ('G', 'Gd', {'out': 0}),
- ('Cd', 'H', {'in': 0}),
- ('H', 'Hd', {'out': 0})
- ]
- graph = build_graph_with_edge_attrs(nodes, edges)
- self.assertListEqual([node.id for node in get_sorted_outputs(graph)], ['Ed', 'Gd', 'Hd'])
diff --git a/tools/mo/unit_tests/mo/unit_test_with_mocked_telemetry.py b/tools/mo/unit_tests/mo/unit_test_with_mocked_telemetry.py
deleted file mode 100644
index 9cedc52921341a..00000000000000
--- a/tools/mo/unit_tests/mo/unit_test_with_mocked_telemetry.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import Mock
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-class UnitTestWithMockedTelemetry(unittest.TestCase):
- def setUp(self):
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
- tm.Telemetry.start_session = Mock()
- tm.Telemetry.end_session = Mock()
- tm.Telemetry.force_shutdown = Mock()
diff --git a/tools/mo/unit_tests/mo/utils/__init__.py b/tools/mo/unit_tests/mo/utils/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/utils/args_to_string_test.py b/tools/mo/unit_tests/mo/utils/args_to_string_test.py
deleted file mode 100644
index 572e8971f1c519..00000000000000
--- a/tools/mo/unit_tests/mo/utils/args_to_string_test.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-from openvino.runtime import Layout, Dimension
-
-from openvino.tools.mo import LayoutMap
-from openvino.tools.mo.utils.cli_parser import mean_scale_value_to_str, \
- transform_param_to_str, str_list_to_str, source_target_layout_to_str, layout_param_to_str
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-
-
-class TestConvertingConvertArgumentsToString(UnitTestWithMockedTelemetry):
- def test_mean_scale_value_to_str(self):
- values = [0.5, 1.3, 0.67]
- self.assertTrue(mean_scale_value_to_str(values) == "[0.5,1.3,0.67]")
-
- values = {"input": [0.5, 1.3, 0.67]}
- self.assertTrue(mean_scale_value_to_str(values) == "input[0.5,1.3,0.67]")
-
- values = {"input1": [0.5, 1.3, 0.67], "input2": [4.2, 6.7, 3.15], "input3": [0.757, 4.6, 7.3]}
- self.assertTrue(mean_scale_value_to_str(values) ==
- "input1[0.5,1.3,0.67],input2[4.2,6.7,3.15],input3[0.757,4.6,7.3]")
-
- self.assertRaises(Exception, mean_scale_value_to_str, **{"value": {("a", "b"): [0.5, 1.3, 0.67]}})
- self.assertRaises(Exception, mean_scale_value_to_str, **{"value": {"name": Dimension(1)}})
- self.assertRaises(Exception, mean_scale_value_to_str, **{"value": Dimension(1)})
-
- def test_transform_param_to_str(self):
- transform = 'MakeStateful'
- self.assertTrue(transform_param_to_str(transform) == "MakeStateful")
-
- transform1 = ('LowLatency2', {'use_const_initializer': False})
- self.assertTrue(transform_param_to_str(transform1) ==
- "LowLatency2[use_const_initializer=False]")
-
- transform2 = ('MakeStateful', {'param_res_names': {
- 'input_name_1': 'output_name_1', 'input_name_2': 'output_name_2'}})
- self.assertTrue(transform_param_to_str(transform2) ==
- "MakeStateful[param_res_names={\'input_name_1\':\'output_name_1\',"
- "\'input_name_2\':\'output_name_2\'}]")
-
- transform = [transform1, transform2]
-
- self.assertTrue(transform_param_to_str(transform) == "LowLatency2[use_const_initializer=False],"
- "MakeStateful[param_res_names={"
- "\'input_name_1\':\'output_name_1\',"
- "\'input_name_2\':\'output_name_2\'}]")
-
- self.assertRaises(Exception, transform_param_to_str, **{"value": ('LowLatency2',
- {'use_const_initializer': False},
- "param")})
- self.assertRaises(Exception, transform_param_to_str, **{"value": (("a", "b"), {})})
- self.assertRaises(Exception, transform_param_to_str, **{"value": ('LowLatency2', Dimension(1))})
- self.assertRaises(Exception, transform_param_to_str, **{"value": ('LowLatency2',
- {('a', 'b'): False})})
- self.assertRaises(Exception, transform_param_to_str, **{"value": Dimension(1)})
-
- def test_str_list_to_str(self):
- list_str = ["data1", "data2", "data3"]
- self.assertTrue(str_list_to_str(list_str) == "data1,data2,data3")
-
- list_str = "data1"
- self.assertTrue(str_list_to_str(list_str) == "data1")
-
- self.assertRaises(Exception, str_list_to_str, **{"values": [int, 1]})
- self.assertRaises(Exception, str_list_to_str, **{"values": Dimension(1)})
-
- def test_source_target_layout_to_str(self):
- layout = {"input1": Layout("nhwc"), "input2": Layout("n??"), "input3": "nchw"}
- self.assertTrue(source_target_layout_to_str(layout) == "input1([N,H,W,C]),input2([N,?,?]),input3(nchw)")
-
- self.assertRaises(Exception, source_target_layout_to_str, **{"value": {"op": Dimension(1)}})
- self.assertRaises(Exception, source_target_layout_to_str, **{"value": {("a", "b"): Layout("nhwc")}})
- self.assertRaises(Exception, source_target_layout_to_str, **{"value": Dimension(1)})
-
- def test_layout_param_to_str_to_str(self):
- layout = {"input1": Layout("nhwc"), "input2": Layout("n??"), "input3": "nchw"}
- self.assertTrue(layout_param_to_str(layout) == "input1([N,H,W,C]),input2([N,?,?]),input3(nchw)")
-
- layout_map1 = LayoutMap(source_layout=Layout("n??"), target_layout=None)
- layout_map2 = LayoutMap(source_layout=Layout("nhwc"), target_layout=("nchw"))
- layout_map3 = LayoutMap(source_layout="abc", target_layout="cab")
-
- layout = {"input1": layout_map1, "input2": layout_map2, "input3": layout_map3, "input4": Layout("nhwc"),
- "input5": "n?"}
-
- self.assertTrue(layout_param_to_str(layout) == "input1([N,?,?]),input2([N,H,W,C]->nchw),"
- "input3(abc->cab),input4([N,H,W,C]),input5(n?)")
-
- self.assertRaises(Exception, layout_param_to_str, **{"value": {"op": Dimension(1)}})
- self.assertRaises(Exception, layout_param_to_str, **{"value": {("a", "b"): Layout("nhwc")}})
- self.assertRaises(Exception, layout_param_to_str, **{"value": Dimension(1)})
-
- layout = ["nhwc", "[n,c]"]
- self.assertTrue(layout_param_to_str(layout) == "nhwc,[n,c]")
-
- layout = ["abc->cab", "..nc"]
- self.assertTrue(layout_param_to_str(layout) == "abc->cab,..nc")
-
- layout_map1 = LayoutMap(source_layout=Layout("n??"), target_layout=None)
- layout = [layout_map1, "..nc"]
- self.assertTrue(layout_param_to_str(layout) == "[N,?,?],..nc")
-
- layout_map2 = LayoutMap(source_layout=Layout("nhwc"), target_layout=("nchw"))
- layout_map3 = LayoutMap(source_layout="abc", target_layout="cab")
- layout = [layout_map2, layout_map3]
- self.assertTrue(layout_param_to_str(layout) == "[N,H,W,C]->nchw,abc->cab")
diff --git a/tools/mo/unit_tests/mo/utils/broadcasting_test.py b/tools/mo/unit_tests/mo/utils/broadcasting_test.py
deleted file mode 100644
index 5432f4a27eea0a..00000000000000
--- a/tools/mo/unit_tests/mo/utils/broadcasting_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import pytest
-
-import numpy as np
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, dynamic_dimension_value, shape_array, strict_compare_tensors
-from openvino.tools.mo.utils.broadcasting import uni_directional_broadcasting, uni_directional_shape_broadcasting, \
- bi_directional_shape_broadcasting
-
-
-class TestingBroadcasting():
- @pytest.mark.parametrize("input_shape, target_shape, expected_shape",[([], [20, 30, 10], [20, 30, 10]),
- ([1], [20, 30, 10], [20, 30, 10]),
- ([1, 1, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 1, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 30, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 30, 10], [5, 7, 20, 30, 10], [5, 7, 20, 30, 10]),
- ([1, 2], [20, 3, 10, 2], [20, 3, 10, 2]),
- ([1, 1], [1], None),
- ([5, 10], [1, 10], None),
- ])
- def test_uni_directional_broadcasting(self, input_shape, target_shape, expected_shape):
- assert np.array_equal(uni_directional_shape_broadcasting(input_shape, target_shape), expected_shape)
-
- input_value = np.array(np.random.rand(*input_shape))
- if expected_shape is not None:
- expected_value = np.broadcast_to(input_value, int64_array(target_shape))
- assert np.array_equal(uni_directional_broadcasting(input_value, int64_array(target_shape)),
- expected_value)
- else:
- with pytest.raises(Exception,match = '.*cannot be uni-directionally broadcasted.*'):
- uni_directional_broadcasting(input_value, int64_array(target_shape))
-
- @pytest.mark.parametrize("input_shape, target_shape, expected_shape",[([], [20, 30, 10], [20, 30, 10]),
- ([1], [20, 30, 10], [20, 30, 10]),
- ([1, 1, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 1, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 30, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 30, 10], [5, 7, 20, 30, 10], [5, 7, 20, 30, 10]),
- ([1, 2], [20, 3, 10, 2], [20, 3, 10, 2]),
- ([1, 1], [1], None),
- ([5, 10], [1, 10], None),
- ([10, 2], shape_array([dynamic_dimension_value, 3, 10, 2]),
- shape_array([dynamic_dimension_value, 3, 10, 2])),
- (shape_array([10, dynamic_dimension_value]), shape_array([dynamic_dimension_value, 3, 10, 2]),
- shape_array([dynamic_dimension_value, 3, 10, 2])),
- (shape_array([dynamic_dimension_value, 2]), shape_array([dynamic_dimension_value, 3, 10, 2]),
- shape_array([dynamic_dimension_value, 3, 10, 2])),
- (shape_array([dynamic_dimension_value]), shape_array([1]), shape_array([1])),
- (shape_array([1]), shape_array([dynamic_dimension_value]), shape_array([dynamic_dimension_value])),
- (shape_array([dynamic_dimension_value]), shape_array([6]), shape_array([6])),
- (shape_array([6]), shape_array([dynamic_dimension_value]), shape_array([6])),
- ])
- def test_uni_directional_shape_broadcasting(self, input_shape, target_shape, expected_shape):
- result = uni_directional_shape_broadcasting(input_shape, target_shape)
- if expected_shape is None:
- assert result is None
- else:
- assert strict_compare_tensors(result, expected_shape)
-
- @pytest.mark.parametrize("input_shape, target_shape, expected_shape",[([], [20, 30, 10], [20, 30, 10]),
- ([1], [20, 30, 10], [20, 30, 10]),
- ([1, 1, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 1, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 30, 10], [20, 30, 10], [20, 30, 10]),
- ([20, 30, 10], [5, 7, 20, 30, 10], [5, 7, 20, 30, 10]),
- ([1, 2], [20, 3, 10, 2], [20, 3, 10, 2]),
- ([3, 2], [3], None),
- ([5, 10], [1, 20], None),
- ([10, 2], shape_array([dynamic_dimension_value, 3, 1, 2]),
- shape_array([dynamic_dimension_value, 3, 10, 2])),
- (shape_array([10, dynamic_dimension_value]), shape_array([dynamic_dimension_value, 3, 1, 2]),
- shape_array([dynamic_dimension_value, 3, 10, 2])),
- (shape_array([dynamic_dimension_value, 2]), shape_array([dynamic_dimension_value, 3, 10, 1]),
- shape_array([dynamic_dimension_value, 3, 10, 2])),
- (shape_array([dynamic_dimension_value]), shape_array([1]), shape_array([dynamic_dimension_value])),
- (shape_array([1]), shape_array([dynamic_dimension_value]), shape_array([dynamic_dimension_value])),
- (shape_array([dynamic_dimension_value]), shape_array([6]), shape_array([6])),
- (shape_array([6]), shape_array([dynamic_dimension_value]), shape_array([6])),
- ])
- def test_bi_directional_shape_broadcasting(self, input_shape, target_shape, expected_shape):
- result = bi_directional_shape_broadcasting(input_shape, target_shape)
- if expected_shape is None:
- assert result is None
- else:
- assert strict_compare_tensors(result, expected_shape)
diff --git a/tools/mo/unit_tests/mo/utils/cli_parser_test.py b/tools/mo/unit_tests/mo/utils/cli_parser_test.py
deleted file mode 100644
index 7413845bd7ece7..00000000000000
--- a/tools/mo/unit_tests/mo/utils/cli_parser_test.py
+++ /dev/null
@@ -1,2071 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import numpy
-import os
-import shutil
-import sys
-import tempfile
-import unittest
-from unittest.mock import patch
-
-import numpy as np
-
-from openvino.tools.mo.utils.cli_parser import get_placeholder_shapes, get_tuple_values, get_mean_scale_dictionary, \
- get_model_name, \
- parse_tuple_pairs, check_positive, writable_dir, readable_dirs, \
- readable_file, get_freeze_placeholder_values, parse_transform, check_available_transforms, get_layout_values, get_all_cli_parser, \
- get_mo_convert_params
-from openvino.tools.mo.convert_impl import pack_params_to_args_namespace
-from openvino.tools.mo.utils.error import Error
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from openvino.runtime import PartialShape, Dimension, Layout
-from openvino.tools.mo import LayoutMap, InputCutInfo
-
-
-class TestingMeanScaleGetter(UnitTestWithMockedTelemetry):
- def test_tuple_parser(self):
- tuple_values = "data(1.1,22.22,333.333),info[2.2,33.33,444.444]"
- result = parse_tuple_pairs(tuple_values)
- exp_res = {
- 'data': np.array([1.1, 22.22, 333.333]),
- 'info': np.array([2.2, 33.33, 444.444])
- }
- for el in exp_res.keys():
- assert np.array_equal(result[el], exp_res[el])
-
- def test_tuple_parser_name_digits_only(self):
- tuple_values = "0448(1.1,22.22,333.333),0449[2.2,33.33,444.444]"
- result = parse_tuple_pairs(tuple_values)
- exp_res = {
- '0448': np.array([1.1, 22.22, 333.333]),
- '0449': np.array([2.2, 33.33, 444.444])
- }
- for el in exp_res.keys():
- assert np.array_equal(result[el], exp_res[el])
-
- def test_tuple_parser_same_values(self):
- tuple_values = "data(1.1,22.22,333.333),info[1.1,22.22,333.333]"
- result = parse_tuple_pairs(tuple_values)
- exp_res = {
- 'data': np.array([1.1, 22.22, 333.333]),
- 'info': np.array([1.1, 22.22, 333.333])
- }
- for el in exp_res.keys():
- assert np.array_equal(result[el], exp_res[el])
-
- def test_tuple_parser_no_inputs(self):
- tuple_values = "(1.1,22.22,333.333),[2.2,33.33,444.444]"
- result = parse_tuple_pairs(tuple_values)
- exp_res = [np.array([1.1, 22.22, 333.333]),
- np.array([2.2, 33.33, 444.444])]
- for i in range(0, len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_tuple_parser_error_mixed_with_and_without_name(self):
- tuple_values = "(1.1,22.22,333.333),data[2.2,33.33,444.444]"
- self.assertRaises(Error, parse_tuple_pairs, tuple_values)
-
- def test_tuple_parser_error_mixed_with_and_without_name_1(self):
- tuple_values = "data(1.1,22.22,333.333),[2.2,33.33,444.444]"
- self.assertRaises(Error, parse_tuple_pairs, tuple_values)
-
- def test_tuple_parser_error_mixed_with_and_without_name_digits(self):
- tuple_values = "(0.1,22.22,333.333),0448[2.2,33.33,444.444]"
- self.assertRaises(Error, parse_tuple_pairs, tuple_values)
-
- def test_tuple_parser_error_mixed_with_and_without_name_digits_1(self):
- tuple_values = "447(1.1,22.22,333.333),[2.2,33.33,444.444]"
- self.assertRaises(Error, parse_tuple_pairs, tuple_values)
-
- def test_mean_scale_no_input(self):
- mean_values = "data(1.1,22.22,333.333)"
- scale_values = "info[1.1,22.22,333.333]"
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(scale_values), None)
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': None
- },
- 'info': {
- 'mean': None,
- 'scale': np.array([1.1, 22.22, 333.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_mean_scale_no_input_diff_len(self):
- mean_values = "data(1.1,22.22,333.333),info(2.1,33.22,333.333)"
- scale_values = "info[1.1,22.22,333.333]"
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(scale_values), None)
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': None
- },
- 'info': {
- 'mean': np.array([2.1, 33.22, 333.333]),
- 'scale': np.array([1.1, 22.22, 333.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_mean_only_input(self):
- mean_values = "data(1.1,22.22,333.333)"
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(''), None)
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': None
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_scale_only_input(self):
- scale_values = "data(1.1,22.22,333.333)"
- result = get_mean_scale_dictionary(parse_tuple_pairs(''), parse_tuple_pairs(scale_values), None)
- exp_res = {
- 'data': {
- 'mean': None,
- 'scale': np.array([1.1, 22.22, 333.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_scale_only_no_input(self):
- scale_values = "(1.1,22.22,333.333)"
- mean_values = ""
- mean = parse_tuple_pairs(mean_values)
- scale = parse_tuple_pairs(scale_values)
- result = get_mean_scale_dictionary(mean, scale, None)
- exp_res = [
- [
- None,
- np.array([1.1, 22.22, 333.333])
- ]
- ]
- for i in range(len(exp_res)):
- for j in range(len(exp_res[i])):
- if type(exp_res[i][j]) is np.ndarray:
- assert np.array_equal(exp_res[i][j], result[i][j])
- else:
- self.assertEqual(exp_res[i][j], result[i][j])
-
- def test_scale_only_with_input(self):
- scale_values = "(1.1,22.22,333.333)"
- mean_values = ""
- mean = parse_tuple_pairs(mean_values)
- scale = parse_tuple_pairs(scale_values)
- result = get_mean_scale_dictionary(mean, scale, 'data')
- exp_res = {
- 'data': {
- 'mean': None,
- 'scale': np.array([1.1, 22.22, 333.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_2_scale_only_with_input(self):
- scale_values = "(1.1,22.22,333.333),(1.2,22.33,333.444)"
- mean_values = ""
- mean = parse_tuple_pairs(mean_values)
- scale = parse_tuple_pairs(scale_values)
- result = get_mean_scale_dictionary(mean, scale, 'data,info')
- exp_res = {
- 'data': {
- 'mean': None,
- 'scale': np.array([1.1, 22.22, 333.333])
- },
- 'info': {
- 'mean': None,
- 'scale': np.array([1.2, 22.33, 333.444])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_2_mean_only_with_input(self):
- scale_values = ""
- mean_values = "(1.1,22.22,333.333),(1.2,22.33,333.444)"
- mean = parse_tuple_pairs(mean_values)
- scale = parse_tuple_pairs(scale_values)
- result = get_mean_scale_dictionary(mean, scale, 'data,info')
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': None,
- },
- 'info': {
- 'mean': np.array([1.2, 22.33, 333.444]),
- 'scale': None,
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_mean_only_with_input(self):
- scale_values = ""
- mean_values = "(1.1,22.22,333.333)"
- mean = parse_tuple_pairs(mean_values)
- scale = parse_tuple_pairs(scale_values)
- result = get_mean_scale_dictionary(mean, scale, 'data')
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': None
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_mean_scale_diff_no_input(self):
- scale_values = "(1.1,22.22,333.333),(1.1,22.22,333.333)"
- mean_values = "(2.1,11.22,444.333)"
- mean = parse_tuple_pairs(mean_values)
- scale = parse_tuple_pairs(scale_values)
- result = get_mean_scale_dictionary(mean, scale, None)
- exp_res = [
- [
- np.array([2.1, 11.22, 444.333]), # mean
- np.array([1.1, 22.22, 333.333]) # scale
- ],
- [
- None, # mean
- np.array([1.1, 22.22, 333.333]) # scale
- ]
- ]
- for i in range(len(exp_res)):
- for j in range(len(exp_res[i])):
- if type(exp_res[i][j]) is np.ndarray:
- assert np.array_equal(exp_res[i][j], result[i][j])
- else:
- self.assertEqual(exp_res[i][j], result[i][j])
-
- def test_multi_mean_scale_no_input(self):
- mean_values = "data(1.1,22.22,333.333),info(2.1,33.22,444.333)"
- scale_values = "data[1.1,22.22,333.333],info[2.1,33.22,444.333]"
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(scale_values), None)
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': np.array([1.1, 22.22, 333.333])
- },
- 'info': {
- 'mean': np.array([2.1, 33.22, 444.333]),
- 'scale': np.array([2.1, 33.22, 444.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_multi_mean_scale_input(self):
- mean_values = "data(1.1,22.22,333.333),info(2.1,33.22,444.333)"
- scale_values = "data[1.1,22.22,333.333],info[2.1,33.22,444.333]"
- input_names = 'data,info'
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(scale_values), input_names)
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': np.array([1.1, 22.22, 333.333])
- },
- 'info': {
- 'mean': np.array([2.1, 33.22, 444.333]),
- 'scale': np.array([2.1, 33.22, 444.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_multi_mean_scale_input_arrays(self):
- mean_values = "(1.1,22.22,333.333),(2.1,33.22,444.333)"
- scale_values = "[1.1,22.22,333.333],[2.1,33.22,444.333]"
- input_names = 'data,info'
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(scale_values), input_names)
- exp_res = {
- 'data': {
- 'mean': np.array([1.1, 22.22, 333.333]),
- 'scale': np.array([1.1, 22.22, 333.333])
- },
- 'info': {
- 'mean': np.array([2.1, 33.22, 444.333]),
- 'scale': np.array([2.1, 33.22, 444.333])
- }
- }
- for input in exp_res.keys():
- for key in exp_res[input].keys():
- if type(exp_res[input][key]) is np.ndarray:
- assert np.array_equal(exp_res[input][key], result[input][key])
- else:
- self.assertEqual(exp_res[input][key], result[input][key])
-
- def test_multi_mean_scale_arrays_no_input(self):
- mean_values = "(1.1,22.22,333.333),(2.1,33.22,444.333)"
- scale_values = "[1.1,22.22,333.333],[2.1,33.22,444.333]"
- result = get_mean_scale_dictionary(parse_tuple_pairs(mean_values), parse_tuple_pairs(scale_values), None)
- exp_res = [
- [
- np.array([1.1, 22.22, 333.333]), # mean
- np.array([1.1, 22.22, 333.333]) # scale
- ],
- [
- np.array([2.1, 33.22, 444.333]), # mean
- np.array([2.1, 33.22, 444.333]) # scale
- ]
- ]
- for i in range(0, len(exp_res)):
- for j in range(0, len(exp_res[i])):
- assert np.array_equal(exp_res[i][j], result[i][j])
-
- def test_scale_do_not_match_input(self):
- scale_values = parse_tuple_pairs("input_not_present(255),input2(255)")
- mean_values = parse_tuple_pairs("input1(255),input2(255)")
- self.assertRaises(Error, get_mean_scale_dictionary, mean_values, scale_values, "input1,input2")
-
- def test_mean_do_not_match_input(self):
- scale_values = parse_tuple_pairs("input1(255),input2(255)")
- mean_values = parse_tuple_pairs("input_not_present(255),input2(255)")
- self.assertRaises(Error, get_mean_scale_dictionary, mean_values, scale_values, "input1,input2")
-
- def test_values_match_input_name(self):
- # to be sure that we correctly processes complex names
- res_values = parse_tuple_pairs("input255(255),input255.0(255.0),multi-dotted.input.3.(255,128,64)")
- exp_res = {'input255': np.array([255.0]),
- 'input255.0': np.array([255.0]),
- 'multi-dotted.input.3.': np.array([255., 128., 64.])}
- self.assertEqual(len(exp_res), len(res_values))
- for i, j in zip(exp_res, res_values):
- self.assertEqual(i, j)
- assert np.array_equal(exp_res[i], res_values[j])
-
- def test_input_without_values(self):
- self.assertRaises(Error, parse_tuple_pairs, "input1,input2")
-
-
-class TestSingleTupleParsing(UnitTestWithMockedTelemetry):
- def test_get_values_ideal(self):
- values = "(1.11, 22.22, 333.333)"
- result = get_tuple_values(values)
- exp_res = ['1.11, 22.22, 333.333']
- self.assertEqual(exp_res, result)
-
- def test_get_values_ideal_spaces(self):
- values = "(1 , 22 ,333)"
- result = get_tuple_values(values)
- exp_res = ['1 , 22 ,333']
- self.assertEqual(exp_res, result)
-
- def test_get_values_ideal_square(self):
- values = "[1,22,333]"
- result = get_tuple_values(values)
- exp_res = ['1,22,333']
- self.assertEqual(exp_res, result)
-
- def test_get_values_ideal_square_spaces(self):
- values = "[1 , 22 ,333]"
- result = get_tuple_values(values)
- exp_res = ['1 , 22 ,333']
- self.assertEqual(exp_res, result)
-
- def test_get_neg_values_ideal(self):
- values = "(-1,-22,-333)"
- result = get_tuple_values(values)
- exp_res = ['-1,-22,-333']
- self.assertEqual(exp_res, result)
-
- def test_get_neg_values_minus(self):
- values = "(-1,--22,-3-33)"
- self.assertRaises(Error, get_tuple_values, values)
-
- def test_get_values_unbalanced(self):
- values = "(1,22,333]"
- self.assertRaises(Error, get_tuple_values, values)
-
- def test_get_values_unbalanced2(self):
- values = "[1,22,333)"
- self.assertRaises(Error, get_tuple_values, values)
-
- def test_get_values_exactly_3(self):
- values = "[1,22,333,22]"
- self.assertRaises(Error, get_tuple_values, values)
-
- def test_get_values_exactly_3_1(self):
- values = "[1,22]"
- self.assertRaises(Error, get_tuple_values, values)
-
- def test_get_values_empty(self):
- values = ""
- self.assertRaises(Error, get_tuple_values, values)
-
- def test_get_values_empty_tuple(self):
- values = ()
- result = get_tuple_values(values)
- exp_res = ()
- self.assertEqual(exp_res, result)
-
-
-class TestShapesParsing(UnitTestWithMockedTelemetry):
- def test_get_shapes_several_inputs_several_shapes(self):
- argv_input = "inp1,inp2"
- input_shapes = "(1,22,333,123), (-1,45,7,1)"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': np.array([1, 22, 333, 123]), 'inp2': np.array([-1, 45, 7, 1])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_shapes_several_inputs_several_shapes2(self):
- # shapes specified using --input command line parameter and no values
- argv_input = "inp1[1 22 333 123],inp2[-1 45 7 1]"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': np.array([1, 22, 333, 123]), 'inp2': np.array([-1, 45, 7, 1])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {}
- input_node_names_ref = "inp1,inp2"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_and_freezing_with_scalar_and_without_shapes_in_input(self):
- # shapes and value for freezing specified using --input command line parameter
- argv_input = "inp1,inp2->157"
- input_list, result_shapes, _ = get_placeholder_shapes(argv_input, None)
- ref_shapes = {'inp1': None, 'inp2': None}
- self.assertEqual(list(ref_shapes.keys()), list(result_shapes.keys()))
- self.assertEqual(input_list, ["inp1","inp2"])
- for i in ref_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_shapes[i])
-
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp2': 157}
-
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- for i in placeholder_values_ref.keys():
- self.assertEqual(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_and_freezing_with_scalar(self):
- # shapes and value for freezing specified using --input command line parameter
- argv_input = "inp1,inp2[]->157"
- input_list, result_shapes, _ = get_placeholder_shapes(argv_input, None)
- ref_shapes = {'inp1': None, 'inp2': ()}
- self.assertEqual(list(ref_shapes.keys()), list(result_shapes.keys()))
- for i in ref_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_shapes[i])
- self.assertEqual(input_list, ["inp1","inp2"])
-
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp2': 157}
-
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- for i in placeholder_values_ref.keys():
- self.assertEqual(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_shapes3(self):
- # shapes and value for freezing specified using --input command line parameter
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3': np.array([5])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
- 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(input_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_shapes3_comma_sep(self):
- # shapes and value for freezing specified using --input command line parameter
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[5]->[1.0, 1.0, 2.0, 3.0,5.0]"
- input_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3': np.array([5])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
- 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(input_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_shapes4(self):
- # shapes specified using --input_shape and values for freezing using --input command line parameter
- argv_input = "inp1->[1.0 2.0 3.0],inp2,inp3->[1.0 1.0 2.0 3.0 5.0]"
- input_shapes = "(3,1), (3,2,3), (5)"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3': np.array([5])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
- 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
- self.assertEqual(input_node_names_ref, input_node_names_res)
-
- def test_get_shapes_several_inputs_several_shapes5(self):
- # some values for freezing specified using --freeze_placeholder_with_value
- argv_input = "inp1->[1.0 2.0 3.0],inp2,inp3->[1.0 1.0 2.0 3.0 5.0]"
- input_shapes = "(3,1), (3,2,3), (5)"
- argv_freeze_placeholder_with_value = "inp2->[5.0 7.0 3.0],inp4->[100.0 200.0]"
-
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3': np.array([5])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input,
- argv_freeze_placeholder_with_value)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
- 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'], ),
- 'inp2': np.array(['5.0', '7.0', '3.0']), 'inp4': np.array(['100.0', '200.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(sorted(list(placeholder_values_res.keys())), sorted(list(placeholder_values_ref.keys())))
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
- self.assertEqual(input_node_names_ref, input_node_names_res)
-
- def test_get_shapes_several_inputs_several_shapes6(self):
- # 0D value for freezing specified using --input command line parameter without shape
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3->False"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([3, 1]), 'inp2': PartialShape([3, 2, 3]), 'inp3': None}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': False}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_shapes7(self):
- # 0D shape and value for freezing specified using --input command line parameter
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[]->True"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3': np.array(False).shape}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': True}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_and_data_types1(self):
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{i32},inp3[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3': np.array([5])}
- ref_result_data_types = {'inp2': np.int32, 'inp3': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1","inp2","inp3"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_with_input_ports(self):
- argv_input = "1:inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{i32},0:inp3[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'1:inp1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), '0:inp3': np.array([5])}
- ref_result_data_types = {'inp2': np.int32, '0:inp3': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["1:inp1","inp2","0:inp3"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_with_output_ports(self):
- argv_input = "inp1:1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1:1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3:4': np.array([5])}
- ref_result_data_types = {'inp2': np.int32, 'inp3:4': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1:1","inp2","inp3:4"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_with_output_ports_comma_sep(self):
- argv_input = "inp1:1[3,1]->[1.0,2.0 ,3.0],inp2[3,2, 3]{i32},inp3:4[5]{f32}->[1.0, 1.0,2.0, 3.0,5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1:1': np.array([3, 1]), 'inp2': np.array([3, 2, 3]), 'inp3:4': np.array([5])}
- ref_result_data_types = {'inp2': np.int32, 'inp3:4': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1:1","inp2","inp3:4"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_shape_only(self):
- argv_input = "placeholder1[3 1],placeholder2,placeholder3"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'placeholder1': np.array([3, 1]), 'placeholder2': None,
- 'placeholder3': None}
- ref_result_data_types = {}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["placeholder1","placeholder2","placeholder3"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_shape_with_ports_only(self):
- argv_input = "placeholder1:4[3 1],placeholder2,2:placeholder3"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'placeholder1:4': np.array([3, 1]), 'placeholder2': None,
- '2:placeholder3': None}
- ref_result_data_types = {}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["placeholder1:4","placeholder2","2:placeholder3"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_when_no_freeze_value(self):
- argv_input = "placeholder1{i32}[3 1],placeholder2,placeholder3{i32}"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'placeholder1': np.array([3, 1]), 'placeholder2': None,
- 'placeholder3': None}
- ref_result_data_types = {'placeholder1': np.int32, 'placeholder3': np.int32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["placeholder1","placeholder2","placeholder3"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_wrong_data_types(self):
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3]{abracadabra},inp3[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
- def test_shapes_specified_using_both_params(self):
- # shapes specified using both command line parameter --input and --input_shape
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
- input_shapes = "(3,1), (3,2,3), (5)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_shape_and_value_shape_mismatch(self):
- # size of value tensor does not correspond to specified shape for the third node
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3 2 3],inp3[5 3]->[2.0 3.0 5.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, None)
-
- def test_wrong_data_for_input_cmd_param(self):
- # test that wrongly formatted data specified in --input is handled properly
- argv_input = "abc->[1.0"
- self.assertRaises(Error, get_freeze_placeholder_values, argv_input, None)
- argv_input = "def[2 2]->[1.0 2.0 3.0 4.0],abc->1.0 34]"
- self.assertRaises(Error, get_freeze_placeholder_values, argv_input, None)
-
- def test_get_shapes_several_inputs_several_shapes_not_equal(self):
- argv_input = "inp1,inp2,inp3"
- input_shapes = "(1,22,333,123), (-1,45,7,1)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_several_shapes_one_input(self):
- argv_input = "inp1"
- input_shapes = "(1,22,333,123), (-1,45,7,1), (-1,456,7,1)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_one_shape(self):
- argv_input = "inp1"
- input_shapes = "(1,22,333,123)"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': np.array([1, 22, 333, 123])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_shapes_no_input_no_shape(self):
- argv_input = ""
- input_shapes = ""
- _, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = None
- assert np.array_equal(result, exp_res)
-
- def test_get_shapes_no_input_one_shape(self):
- argv_input = ""
- input_shapes = "(12,4,1)"
- _, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = np.array([12, 4, 1])
- assert np.array_equal(result, exp_res)
-
- def test_get_shapes_no_input_one_shape2(self):
- argv_input = ""
- input_shapes = "[12,4,1]"
- _, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = np.array([12, 4, 1])
- assert np.array_equal(result, exp_res)
-
-
- def test_get_shapes_one_input_no_shape(self):
- argv_input = "inp1"
- input_shapes = ""
- input_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': None}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(input_list, ["inp1"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_shapes_one_input_wrong_shape8(self):
- argv_input = "inp1"
- input_shapes = "[2,4,1)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape9(self):
- argv_input = "inp1"
- input_shapes = "(2,4,1]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape10(self):
- argv_input = "inp1"
- input_shapes = "(2,,,4,1]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape2(self):
- argv_input = "inp1"
- input_shapes = "(2,4,1"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape3(self):
- argv_input = "inp1"
- input_shapes = "2,4,1"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape4(self):
- argv_input = "inp1"
- input_shapes = "2;4;1"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape5(self):
- argv_input = "inp1"
- input_shapes = "2, 4,1"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape6(self):
- argv_input = "inp1"
- input_shapes = "(2, 4,1),[4,6,8]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_wrong_shape7(self):
- argv_input = "inp1"
- input_shapes = "[2,4,1],(4,6,8)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_several_shapes(self):
- argv_input = "inp1"
- input_shapes = "(2,4,1),(4,6,8)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_first_neg_shape1(self):
- argv_input = "inp1,inp2"
- input_shapes = "(-1,4,1),(4,6,8)"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': np.array([-1, 4, 1]), 'inp2': np.array([4, 6, 8])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_shapes_one_input_first_neg_shape_not_one(self):
- argv_input = "inp1"
- input_shapes = "(-12,4,1),(4,6,8)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_long_dimension_with_invalid_character(self):
- # test for regular expression denial of service
- argv_input = "inp1,inp2"
- input_shapes = "(222222222222222222222222222222222222222222!,4,1),(4,6,8)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_one_input_any_neg_shape(self):
- argv_input = "inp1, inp2"
- input_shapes = "(12,4,1),(4,-6,8)"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_several_inputs_several_partial_shapes(self):
- argv_input = "inp1,inp2"
- input_shapes = "(1,..22,1..100,?), (-1,45..,7,1)"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': PartialShape([1, Dimension(0, 22), Dimension(1, 100), -1]), 'inp2': PartialShape([-1, Dimension(45, -1), 7, 1])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2"])
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes2(self):
- # shapes specified using --input command line parameter and no values
- argv_input = "inp1[1 ? 50..100 123],inp2[-1 45.. ..7 1]"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([1, -1, (50, 100), 123]), 'inp2': PartialShape([-1, Dimension(45,-1), Dimension(0, 7), 1])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {}
- input_node_names_ref = "inp1,inp2"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes3(self):
- # shapes and value for freezing specified using --input command line parameter
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3.. ..2 5..10 ? -1],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': (3, 1), 'inp2': PartialShape([Dimension(3, -1), Dimension(0, 2), Dimension(5, 10), -1, -1]), 'inp3': (5,)}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes4(self):
- # shapes specified using --input_shape and values for freezing using --input command line parameter
- argv_input = "inp1->[1.0 2.0 3.0],inp2,inp3->[1.0 1.0 2.0 3.0 5.0]"
- input_shapes = "(3,1), (3..,..2,5..10,?,-1), (5)"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': (3, 1), 'inp2': PartialShape([Dimension(3, -1), Dimension(0, 2), Dimension(5, 10), -1, -1]), 'inp3': (5,)}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
- self.assertEqual(input_node_names_ref, input_node_names_res)
-
- def test_get_shapes_several_inputs_several_partial_shapes5(self):
- # some values for freezing specified using --freeze_placeholder_with_value
- argv_input = "inp1->[1.0 2.0 3.0],inp2,inp3->[1.0 1.0 2.0 3.0 5.0]"
- input_shapes = "(3,1), (3..,..2,5..10,?,-1), (5)"
- argv_freeze_placeholder_with_value = "inp2->[5.0 7.0 3.0],inp4->[100.0 200.0]"
-
- inputs_list, result, _ = get_placeholder_shapes(argv_input, input_shapes)
- exp_res = {'inp1': PartialShape([3, 1]), 'inp2': PartialShape([(3, np.iinfo(np.int64).max), (0, 2), (5, 10), -1, -1]), 'inp3': PartialShape([5])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, argv_freeze_placeholder_with_value)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'],),
- 'inp2': np.array(['5.0', '7.0', '3.0']), 'inp4': np.array(['100.0', '200.0'])}
- input_node_names_ref = "inp1,inp2,inp3"
- self.assertEqual(sorted(list(placeholder_values_res.keys())), sorted(list(placeholder_values_ref.keys())))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
- self.assertEqual(input_node_names_ref, input_node_names_res)
-
- def test_get_shapes_several_inputs_several_partial_shapes6(self):
- # 0D value for freezing specified using --input command line parameter without shape
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3.. ..2 5..10 ? -1],inp3->False"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([3, 1]), 'inp2': PartialShape([(3, np.iinfo(np.int64).max), (0, 2), (5, 10), -1, -1]), 'inp3': None}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': False}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes7(self):
- # 0D shape and value for freezing specified using --input command line parameter
- argv_input = "inp1[3 1]->[1.0 2.0 3.0],inp2[3.. ..2 5..10 ? -1],inp3[]->True"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([3, 1]), 'inp2': PartialShape([(3, np.iinfo(np.int64).max), (0, 2), (5, 10), -1, -1]), 'inp3': np.array(False).shape}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': True}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1","inp2","inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_and_data_types_partial_shape_with_input_port(self):
- argv_input = "inp1:1[3 1]->[1.0 2.0 3.0],0:inp2[3.. ..2 5..10 ? -1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1:1': PartialShape([3, 1]), '0:inp2': PartialShape([Dimension(3, -1), Dimension(-1, 2), Dimension(5, 10), -1, -1]), 'inp3:4': np.array([5])}
- ref_result_data_types = {'0:inp2': np.int32, 'inp3:4': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1:1","0:inp2","inp3:4"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_partial_shape_with_output_port(self):
- argv_input = "inp1:1[3 1]->[1.0 2.0 3.0],inp2:3[3.. ..2 5..10 ? -1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1:1': PartialShape([3, 1]), 'inp2:3': PartialShape([Dimension(3, -1), Dimension(0, 2), Dimension(5, 10), -1, -1]), 'inp3:4': PartialShape([5])}
- ref_result_data_types = {'inp2:3': np.int32, 'inp3:4': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1:1","inp2:3","inp3:4"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_partial_shapes_negative_case(self):
- argv_input = "inp1"
- input_shapes = "[6754fg..23ed]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_partial_shapes_freeze_dynamic_negative_case1(self):
- argv_input = "inp1:1[3 1..10]->[1.0 2.0 3.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
- def test_partial_shapes_freeze_dynamic_negative_case2(self):
- argv_input = "inp1:1[1 2 -1]->[1.0 2.0 3.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
- def test_partial_shapes_freeze_dynamic_negative_case3(self):
- # some values for freezing specified using --freeze_placeholder_with_value
- argv_input = "inp1->[1.0 2.0 3.0]"
- input_shapes = "[3,1..10]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, input_shapes)
-
- def test_get_shapes_several_inputs_several_partial_shapes2_comma_separator(self):
- # shapes specified using --input command line parameter and no values
- argv_input = "inp1[1,?,50..100,123],inp2[-1,45..,..7,1]"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([1, -1, (50, 100), 123]),
- 'inp2': PartialShape([-1, Dimension(45, -1), Dimension(0, 7), 1])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1", "inp2"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes3_comma_separator(self):
- # shapes and value for freezing specified using --input command line parameter
- argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3..,..2,5..10,?,-1],inp3[5]->[1.0 1.0 2.0 3.0 5.0]"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([3, 1]), 'inp2': PartialShape([Dimension(3, -1), Dimension(0, 2), Dimension(5, 10), -1, -1]),
- 'inp3': PartialShape([5])}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']),
- 'inp3': np.array(['1.0', '1.0', '2.0', '3.0', '5.0'])}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1", "inp2", "inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes6_comma_separator(self):
- # 0D value for freezing specified using --input command line parameter without shape
- argv_input = "inp1[3, 1]->[1.0 2.0 3.0],inp2[3.., ..2, 5..10, ?,-1],inp3->False"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([3, 1]),
- 'inp2': PartialShape([(3, np.iinfo(np.int64).max), (0, 2), (5, 10), -1, -1]), 'inp3': None}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': False}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1", "inp2", "inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_several_inputs_several_partial_shapes7_comma_separator(self):
- # 0D shape and value for freezing specified using --input command line parameter
- argv_input = "inp1[3,1]->[1.0 2.0 3.0],inp2[3.., ..2,5..10, ?,-1],inp3[]->True"
- inputs_list, result, _ = get_placeholder_shapes(argv_input, None)
- exp_res = {'inp1': PartialShape([3, 1]),
- 'inp2': PartialShape([(3, np.iinfo(np.int64).max), (0, 2), (5, 10), -1, -1]),
- 'inp3': np.array(False).shape}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
- placeholder_values_res, input_node_names_res = get_freeze_placeholder_values(argv_input, None)
- placeholder_values_ref = {'inp1': np.array(['1.0', '2.0', '3.0']), 'inp3': True}
- self.assertEqual(list(placeholder_values_res.keys()), list(placeholder_values_ref.keys()))
- self.assertEqual(inputs_list, ["inp1", "inp2", "inp3"])
- for i in placeholder_values_ref.keys():
- assert np.array_equal(placeholder_values_res[i], placeholder_values_ref[i])
-
- def test_get_shapes_and_data_types_partial_shape_with_input_port_comma_separator(self):
- argv_input = "inp1:1[3,1]->[1.0 2.0 3.0],0:inp2[ 3.. ,..2, 5..10, ?,-1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1:1': PartialShape([3, 1]),
- '0:inp2': PartialShape([Dimension(3, -1), Dimension(-1, 2), Dimension(5, 10), -1, -1]),
- 'inp3:4': np.array([5])}
- ref_result_data_types = {'0:inp2': np.int32, 'inp3:4': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1:1", "0:inp2", "inp3:4"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_get_shapes_and_data_types_partial_shape_with_output_port_comma_separator(self):
- argv_input = "inp1:1[3,1]->[1.0 2.0 3.0],inp2:3[3..,..2,5..10,?,-1]{i32},inp3:4[5]{f32}->[1.0 1.0 2.0 3.0 5.0]"
- input_list, result_shapes, result_data_types = get_placeholder_shapes(argv_input, "")
- ref_result_shapes = {'inp1:1': PartialShape([3, 1]),
- 'inp2:3': PartialShape([Dimension(3, -1), Dimension(0, 2), Dimension(5, 10), -1, -1]),
- 'inp3:4': PartialShape([5])}
- ref_result_data_types = {'inp2:3': np.int32, 'inp3:4': np.float32}
- self.assertEqual(list(ref_result_shapes.keys()), list(result_shapes.keys()))
- for i in ref_result_shapes.keys():
- assert np.array_equal(result_shapes[i], ref_result_shapes[i])
- self.assertEqual(list(ref_result_data_types.keys()), list(result_data_types.keys()))
- self.assertEqual(input_list, ["inp1:1", "inp2:3", "inp3:4"])
- for i in ref_result_data_types.keys():
- np.testing.assert_equal(result_data_types[i], ref_result_data_types[i])
-
- def test_partial_shapes_freeze_dynamic_negative_case1_comma_separator(self):
- argv_input = "inp1:1[3,1..10]->[1.0 2.0 3.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
- def test_partial_shapes_freeze_dynamic_negative_case2_comma_separator(self):
- argv_input = "inp1:1[1,2,-1]->[1.0 2.0 3.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
- def test_partial_shapes_freeze_dynamic_negative_case3_comma_separator(self):
- argv_input = "inp1:1[3,1..10]->[1.0 2.0 3.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
- def test_partial_shapes_freeze_dynamic_negative_case4_comma_separator(self):
- argv_input = "inp1:1[1, 2, -1]->[1.0 2.0 3.0]"
- self.assertRaises(Error, get_placeholder_shapes, argv_input, "")
-
-
-class TestModelNameParsing(unittest.TestCase):
- def test_model_name_ideal(self):
- model_name = '/home/models/mymodel.caffemodel'
- res = get_model_name(model_name)
- exp_res = 'mymodel'
- self.assertEqual(exp_res, res)
-
- def test_model_name_no_name(self):
- model_name = '/home/models/.caffemodel'
- res = get_model_name(model_name)
- exp_res = 'model'
- self.assertEqual(exp_res, res)
-
- def test_model_name_no_ext(self):
- model_name = '/home/models/caffemodel'
- res = get_model_name(model_name)
- exp_res = 'caffemodel'
- self.assertEqual(exp_res, res)
-
- def test_model_name_no_name_no_path(self):
- model_name = '.caffemodel'
- res = get_model_name(model_name)
- exp_res = 'model'
- self.assertEqual(exp_res, res)
-
- @patch("openvino.tools.mo.utils.cli_parser.os")
- def test_model_name_win(self, old_os):
- old_os.path.basename.return_value = "caffemodel"
- old_os.path.splitext.return_value = ("caffemodel", "")
- model_name = r'\home\models\caffemodel'
- res = get_model_name(model_name)
-
- exp_res = 'caffemodel'
- self.assertEqual(exp_res, res)
-
- def test_model_name_dots(self):
- model_name = r'/home/models/squeezenet_v1.1.caffemodel'
- res = get_model_name(model_name)
- exp_res = 'squeezenet_v1.1'
- self.assertEqual(exp_res, res)
-
-
-class PositiveChecker(unittest.TestCase):
- def test_positive_checker_batch(self):
- res = check_positive('1')
- self.assertEqual(res, 1)
-
- def test_positive_checker_batch_negative(self):
- self.assertRaises(argparse.ArgumentTypeError, check_positive, '-1')
-
- def test_positive_checker_batch_not_int(self):
- self.assertRaises(argparse.ArgumentTypeError, check_positive, 'qwe')
-
-
-class PathCheckerFunctions(unittest.TestCase):
- READABLE_DIR = tempfile.gettempdir()
- WRITABLE_DIR = os.path.join(tempfile.gettempdir(), 'writable_dir')
- WRITABLE_NON_EXISTING_DIR = os.path.join(WRITABLE_DIR, 'non_existing_dir')
- NOT_WRITABLE_DIR = os.path.join(tempfile.gettempdir(), 'not_writable_dir')
- NOT_WRITABLE_SUB_DIR = os.path.join(tempfile.gettempdir(), 'another_not_writable_dir', 'not_existing_dir')
- EXISTING_FILE = tempfile.NamedTemporaryFile(mode='r+', delete=False).name
- NOT_EXISTING_FILE = '/abcd/efgh/ijkl'
-
- @classmethod
- def setUpClass(cls):
- if not os.path.exists(__class__.WRITABLE_DIR):
- os.makedirs(__class__.WRITABLE_DIR)
- if os.path.exists(__class__.WRITABLE_NON_EXISTING_DIR):
- os.removedirs(__class__.WRITABLE_NON_EXISTING_DIR)
-
- if not os.path.exists(__class__.NOT_WRITABLE_DIR):
- os.makedirs(__class__.NOT_WRITABLE_DIR)
- os.chmod(__class__.NOT_WRITABLE_DIR, 0)
-
- if not os.path.exists(os.path.dirname(__class__.NOT_WRITABLE_SUB_DIR)):
- os.makedirs(os.path.dirname(__class__.NOT_WRITABLE_SUB_DIR))
- os.chmod(os.path.dirname(__class__.NOT_WRITABLE_SUB_DIR), 0)
- if os.path.exists(__class__.NOT_EXISTING_FILE):
- os.remove(__class__.NOT_EXISTING_FILE)
-
- @classmethod
- def tearDownClass(cls):
- if os.path.exists(__class__.WRITABLE_DIR):
- os.removedirs(__class__.WRITABLE_DIR)
- if os.path.exists(__class__.NOT_WRITABLE_DIR):
- shutil.rmtree(__class__.NOT_WRITABLE_DIR, ignore_errors=True)
- if os.path.exists(os.path.dirname(__class__.NOT_WRITABLE_SUB_DIR)):
- shutil.rmtree(os.path.dirname(__class__.NOT_WRITABLE_SUB_DIR), ignore_errors=True)
- if os.path.exists(__class__.EXISTING_FILE):
- os.remove(__class__.EXISTING_FILE)
-
- def test_single_writable_dir(self):
- self.assertEqual(__class__.WRITABLE_DIR, writable_dir(__class__.WRITABLE_DIR))
-
- @unittest.skipIf(sys.platform.startswith("win"), "chmod() on Windows do nor support not writable dir")
- @unittest.skipIf(sys.platform.startswith("lin") and os.geteuid() == 0, "root user does not support not writable dir")
- def test_single_non_writable_dir(self):
- with self.assertRaises(Error) as cm:
- writable_dir(__class__.NOT_WRITABLE_DIR)
-
- @unittest.skipIf(sys.platform.startswith("win"), "chmod() on Windows do nor support not writable dir")
- @unittest.skipIf(sys.platform.startswith("lin") and os.geteuid() == 0, "root user does not support not writable dir")
- def test_single_non_writable_sub_dir(self):
- with self.assertRaises(Error) as cm:
- writable_dir(__class__.NOT_WRITABLE_SUB_DIR)
-
- def test_multiple_writable_dirs(self):
- dirs_str = ','.join([__class__.WRITABLE_DIR, __class__.WRITABLE_NON_EXISTING_DIR])
- self.assertEqual(dirs_str, writable_dir(dirs_str))
-
- def test_single_writable_non_existing_dir(self):
- self.assertEqual(__class__.WRITABLE_NON_EXISTING_DIR, writable_dir(__class__.WRITABLE_NON_EXISTING_DIR))
-
- def test_readable_dirs(self):
- dirs_str = ','.join([__class__.WRITABLE_DIR, __class__.READABLE_DIR])
- self.assertEqual(dirs_str, readable_dirs(dirs_str))
-
- def test_not_readable_dirs(self):
- dirs_str = ','.join([__class__.WRITABLE_DIR, __class__.WRITABLE_NON_EXISTING_DIR])
- with self.assertRaises(Error) as cm:
- readable_dirs(dirs_str)
-
- def test_readable_file(self):
- self.assertEqual(__class__.EXISTING_FILE, readable_file(__class__.EXISTING_FILE))
-
- def test_non_readable_file(self):
- with self.assertRaises(Error) as cm:
- readable_file(__class__.NOT_EXISTING_FILE)
-
-
-class TransformChecker(unittest.TestCase):
- def test_empty(self):
- self.assertEqual(parse_transform(""), [])
-
- def test_single_pass(self):
- self.assertEqual(parse_transform("LowLatency2"), [("LowLatency2", {})])
-
- def test_single_pass_with_args(self):
- self.assertEqual(parse_transform("LowLatency2[use_const_initializer=True]"),
- [("LowLatency2", {"use_const_initializer": True})])
-
- def test_single_pass_with_multiple_args(self):
- self.assertEqual(parse_transform("LowLatency2[use_const_initializer=True;dummy_attr=3.14]"),
- [("LowLatency2", {"use_const_initializer": True, "dummy_attr": 3.14})])
-
- def test_multiple_passes_with_args(self):
- self.assertEqual(parse_transform("LowLatency2[use_const_initializer=True],DummyPass[type=ReLU]"),
- [("LowLatency2", {"use_const_initializer": True}),
- ("DummyPass", {"type": "ReLU"})])
-
- def test_multiple_passes_with_args2(self):
- self.assertEqual(parse_transform("LowLatency2[use_const_initializer=True,False],DummyPass1,"
- "DummyPass2[types=ReLU,PReLU;values=1,2,3]"),
- [("LowLatency2", {"use_const_initializer": [True, False]}),
- ("DummyPass1", {}),
- ("DummyPass2", {"types": ["ReLU", "PReLU"], "values": [1, 2, 3]})])
-
- def test_multiple_passes_no_args(self):
- self.assertEqual(parse_transform("DummyPass,LowLatency22"),
- [("DummyPass", {}), ("LowLatency22", {})])
-
- def test_single_pass_neg(self):
- self.assertRaises(Error, parse_transform, "LowLatency2!")
-
- def test_multiple_passes_neg(self):
- self.assertRaises(Error, parse_transform, "LowLatency2;DummyPass")
-
- def test_single_pass_with_args_neg1(self):
- self.assertRaises(Error, parse_transform, "LowLatency2[=2]")
-
- def test_single_pass_with_args_neg2(self):
- self.assertRaises(Error, parse_transform, "LowLatency2[key=]")
-
- def test_single_pass_with_args_neg3(self):
- self.assertRaises(Error, parse_transform, "LowLatency2[]")
-
- def test_single_pass_with_args_neg4(self):
- self.assertRaises(Error, parse_transform, "LowLatency2[key=value;]")
-
- def test_single_pass_with_args_neg5(self):
- self.assertRaises(Error, parse_transform, "LowLatency2[value]")
-
- def test_single_pass_with_args_neg6(self):
- self.assertRaises(Error, parse_transform, "LowLatency2[key=value")
-
- @patch("openvino.tools.mo.back.offline_transformations.get_available_transformations")
- def test_check_low_latency_is_available(self, available_transformations):
- available_transformations.return_value = {"LowLatency2": None}
- try:
- check_available_transforms([("LowLatency2", "")])
- except Error as e:
- self.assertTrue(False, "Exception \"{}\" is unexpected".format(e))
-
- @patch("openvino.tools.mo.back.offline_transformations.get_available_transformations")
- def test_check_dummy_pass_is_available(self, available_transformations):
- available_transformations.return_value = {"LowLatency2": None}
- self.assertRaises(Error, check_available_transforms, [("DummyPass", "")])
-
-
-class TestLayoutParsing(unittest.TestCase):
- def test_get_layout_1(self):
- argv_layout = "name1([n,h,w,c]),name2([n,h,w,c]->[n,c,h,w])"
- result = get_layout_values(argv_layout)
- exp_res = {'name1': {'source_layout': '[n,h,w,c]', 'target_layout': None},
- 'name2': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_2(self):
- argv_layout = "name1(nhwc),name2(nhwc->nchw)"
- result = get_layout_values(argv_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': None},
- 'name2': {'source_layout': 'nhwc', 'target_layout': 'nchw'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_3(self):
- argv_layout = "name1(n...c),name2(n...c->nc...)"
- result = get_layout_values(argv_layout)
- exp_res = {'name1': {'source_layout': 'n...c', 'target_layout': None},
- 'name2': {'source_layout': 'n...c', 'target_layout': 'nc...'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_4(self):
- argv_layout = "nhwc"
- result = get_layout_values(argv_layout)
- exp_res = {'': {'source_layout': 'nhwc', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_5(self):
- argv_layout = "[n,h,w,c]"
- result = get_layout_values(argv_layout)
- exp_res = {'': {'source_layout': '[n,h,w,c]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_6(self):
- argv_layout = "nhwc->nchw"
- result = get_layout_values(argv_layout)
- exp_res = {'': {'source_layout': 'nhwc', 'target_layout': 'nchw'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_7(self):
- argv_layout = "[n,h,w,c]->[n,c,h,w]"
- result = get_layout_values(argv_layout)
- exp_res = {'': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_8(self):
- argv_layout = "name1-0(n...c),name2-0(n...c->nc...)"
- result = get_layout_values(argv_layout)
- exp_res = {'name1-0': {'source_layout': 'n...c', 'target_layout': None},
- 'name2-0': {'source_layout': 'n...c', 'target_layout': 'nc...'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_scalar(self):
- argv_layout = "name1(nhwc),name2([])"
- result = get_layout_values(argv_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': None},
- 'name2': {'source_layout': '[]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_1(self):
- argv_source_layout = "[n,h,w,c]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'': {'source_layout': '[n,h,w,c]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_2(self):
- argv_source_layout = "nhwc"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'': {'source_layout': 'nhwc', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_3(self):
- argv_source_layout = "name1(nhwc),name2(nchw)"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': None},
- 'name2': {'source_layout': 'nchw', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_4(self):
- argv_source_layout = "name1([n,h,w,c]),name2([n,c,h,w])"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'name1': {'source_layout': '[n,h,w,c]', 'target_layout': None},
- 'name2': {'source_layout': '[n,c,h,w]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_5(self):
- argv_source_layout = "name1(nhwc),name2([n,c,h,w])"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': None},
- 'name2': {'source_layout': '[n,c,h,w]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_6(self):
- argv_source_layout = "name1(nhwc),name2[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': None},
- 'name2': {'source_layout': '[n,c,h,w]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_scalar(self):
- argv_source_layout = "name1(nhwc),name2([])"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': None},
- 'name2': {'source_layout': '[]', 'target_layout': None}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_1(self):
- argv_target_layout = "[n,h,w,c]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'': {'source_layout': None, 'target_layout': '[n,h,w,c]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_2(self):
- argv_target_layout = "nhwc"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'': {'source_layout': None, 'target_layout': 'nhwc'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_3(self):
- argv_target_layout = "name1(nhwc),name2(nchw)"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': None, 'target_layout': 'nhwc'},
- 'name2': {'source_layout': None, 'target_layout': 'nchw'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_4(self):
- argv_target_layout = "name1([n,h,w,c]),name2([n,c,h,w])"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': None, 'target_layout': '[n,h,w,c]'},
- 'name2': {'source_layout': None, 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_5(self):
- argv_target_layout = "name1(nhwc),name2([n,c,h,w])"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': None, 'target_layout': 'nhwc'},
- 'name2': {'source_layout': None, 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_6(self):
- argv_target_layout = "name1(nhwc),name2[n,c,h,w]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': None, 'target_layout': 'nhwc'},
- 'name2': {'source_layout': None, 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_scalar(self):
- argv_target_layout = "name1(nhwc),name2[]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': None, 'target_layout': 'nhwc'},
- 'name2': {'source_layout': None, 'target_layout': '[]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_1(self):
- argv_source_layout = "[n,h,w,c]"
- argv_target_layout = "[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_2(self):
- argv_source_layout = "nhwc"
- argv_target_layout = "nchw"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'': {'source_layout': 'nhwc', 'target_layout': 'nchw'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_3(self):
- argv_source_layout = "name1(nhwc),name2(nhwc)"
- argv_target_layout = "name1(nchw),name2(nchw)"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': 'nchw'},
- 'name2': {'source_layout': 'nhwc', 'target_layout': 'nchw'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_4(self):
- argv_source_layout = "name1([n,h,w,c]),name2([n,h,w,c])"
- argv_target_layout = "name1([n,c,h,w]),name2([n,c,h,w])"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'},
- 'name2': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_5(self):
- argv_source_layout = "name1(nhwc),name2[n,h,w,c]"
- argv_target_layout = "name1(nchw),name2[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': 'nchw'},
- 'name2': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_6(self):
- argv_source_layout = "name1.0:a/b(nhwc),name2\\d\\[n,h,w,c]"
- argv_target_layout = "name1.0:a/b(nchw),name2\\d\\[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'name1.0:a/b': {'source_layout': 'nhwc', 'target_layout': 'nchw'},
- 'name2\\d\\': {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_7(self):
- argv_source_layout = "name1-0[n,h,w,c],name2-1(?c??)"
- argv_target_layout = "name1-0(nchw),name2-1[?,?,?,c]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'name1-0': {'source_layout': '[n,h,w,c]', 'target_layout': 'nchw'},
- 'name2-1': {'source_layout': '?c??', 'target_layout': '[?,?,?,c]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_scalar(self):
- argv_source_layout = "name1(nhwc),name2[]"
- argv_target_layout = "name1(nchw),name2[]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = {'name1': {'source_layout': 'nhwc', 'target_layout': 'nchw'},
- 'name2': {'source_layout': '[]', 'target_layout': '[]'}}
- self.assertEqual(list(exp_res.keys()), list(result.keys()))
- for i in exp_res.keys():
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_raises_if_layout_and_source_layout_provided(self):
- argv_layout = "nhwc"
- argv_source_layout = "nhwc"
- with self.assertRaises(Error):
- get_layout_values(argv_layout=argv_layout, argv_source_layout=argv_source_layout)
-
- def test_get_layout_raises_if_layout_and_target_layout_provided(self):
- argv_layout = "nhwc->nchw"
- argv_target_layout = "nchw"
- with self.assertRaises(Error):
- get_layout_values(argv_layout=argv_layout, argv_target_layout=argv_target_layout)
-
- def test_get_layout_raises_if_layout_with_source_and_target_layout_provided(self):
- argv_layout = "nhwc->nchw"
- argv_source_layout = "nhwc"
- argv_target_layout = "nchw"
- with self.assertRaises(Error):
- get_layout_values(argv_layout=argv_layout, argv_source_layout=argv_source_layout,
- argv_target_layout=argv_target_layout)
-
- def test_get_layout_raises_incorrect_format(self):
- argv_layout = "name[n,h,w,c]->nchw"
- with self.assertRaises(Error):
- res = get_layout_values(argv_layout=argv_layout)
- print(res)
-
-
-class TestLayoutParsingEmptyNames(unittest.TestCase):
- def test_get_layout_1(self):
- argv_layout = "([n,h,w,c]),([n,h,w,c]->[n,c,h,w])"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': '[n,h,w,c]', 'target_layout': None},
- {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_2(self):
- argv_layout = "(nhwc),(nhwc->nchw)"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': 'nhwc', 'target_layout': 'nchw'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_3(self):
- argv_layout = "(n...c),(n...c->nc...)"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': 'n...c', 'target_layout': None},
- {'source_layout': 'n...c', 'target_layout': 'nc...'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_scalar(self):
- argv_layout = "(nhwc),([])"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_3(self):
- argv_source_layout = "(nhwc),(nchw)"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': 'nchw', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_4(self):
- argv_source_layout = "([n,h,w,c]),([n,c,h,w])"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': '[n,h,w,c]', 'target_layout': None},
- {'source_layout': '[n,c,h,w]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_5(self):
- argv_source_layout = "(nhwc),([n,c,h,w])"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[n,c,h,w]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_6(self):
- argv_source_layout = "(nhwc),[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[n,c,h,w]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_scalar(self):
- argv_source_layout = "(nhwc),([])"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_3(self):
- argv_target_layout = "(nhwc),(nchw)"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': 'nchw'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_4(self):
- argv_target_layout = "([n,h,w,c]),([n,c,h,w])"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': '[n,h,w,c]'},
- {'source_layout': None, 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_5(self):
- argv_target_layout = "(nhwc),([n,c,h,w])"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_6(self):
- argv_target_layout = "(nhwc),[n,c,h,w]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_scalar(self):
- argv_target_layout = "(nhwc),[]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': '[]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_3(self):
- argv_source_layout = "(nhwc),(nhwc)"
- argv_target_layout = "(nchw),(nchw)"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': 'nchw'},
- {'source_layout': 'nhwc', 'target_layout': 'nchw'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_4(self):
- argv_source_layout = "([n,h,w,c]),([n,h,w,c])"
- argv_target_layout = "([n,c,h,w]),([n,c,h,w])"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'},
- {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_5(self):
- argv_source_layout = "(nhwc),[n,h,w,c]"
- argv_target_layout = "(nchw),[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': 'nchw'},
- {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_scalar(self):
- argv_source_layout = "(nhwc),[]"
- argv_target_layout = "(nchw),[]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': 'nchw'},
- {'source_layout': '[]', 'target_layout': '[]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
-
-class TestLayoutParsingEmptyNamesNoBrackets(unittest.TestCase):
- def test_get_layout_1(self):
- argv_layout = "[n,h,w,c],[n,h,w,c]->[n,c,h,w]"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': '[n,h,w,c]', 'target_layout': None},
- {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_2(self):
- argv_layout = "nhwc,nhwc->nchw"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': 'nhwc', 'target_layout': 'nchw'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_3(self):
- argv_layout = "n...c,n...c->nc..."
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': 'n...c', 'target_layout': None},
- {'source_layout': 'n...c', 'target_layout': 'nc...'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_scalar(self):
- argv_layout = "nhwc,[]"
- result = get_layout_values(argv_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_3(self):
- argv_source_layout = "nhwc,nchw"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': 'nchw', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_4(self):
- argv_source_layout = "[n,h,w,c],[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': '[n,h,w,c]', 'target_layout': None},
- {'source_layout': '[n,c,h,w]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_5(self):
- argv_source_layout = "nhwc,[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[n,c,h,w]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_6(self):
- argv_source_layout = "nhwc,[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[n,c,h,w]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_layout_scalar(self):
- argv_source_layout = "nhwc,[]"
- result = get_layout_values(argv_source_layout=argv_source_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': None},
- {'source_layout': '[]', 'target_layout': None}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_3(self):
- argv_target_layout = "nhwc,nchw"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': 'nchw'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_4(self):
- argv_target_layout = "[n,h,w,c],[n,c,h,w]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': '[n,h,w,c]'},
- {'source_layout': None, 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_5(self):
- argv_target_layout = "nhwc,[n,c,h,w]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_6(self):
- argv_target_layout = "nhwc,[n,c,h,w]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_target_layout_scalar(self):
- argv_target_layout = "nhwc,[]"
- result = get_layout_values(argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': None, 'target_layout': 'nhwc'},
- {'source_layout': None, 'target_layout': '[]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_3(self):
- argv_source_layout = "nhwc,nhwc"
- argv_target_layout = "nchw,nchw"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': 'nchw'},
- {'source_layout': 'nhwc', 'target_layout': 'nchw'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_4(self):
- argv_source_layout = "[n,h,w,c],[n,h,w,c]"
- argv_target_layout = "[n,c,h,w],[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'},
- {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_5(self):
- argv_source_layout = "nhwc,[n,h,w,c]"
- argv_target_layout = "nchw,[n,c,h,w]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': 'nchw'},
- {'source_layout': '[n,h,w,c]', 'target_layout': '[n,c,h,w]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def test_get_layout_source_target_layout_scalar(self):
- argv_source_layout = "nhwc,[]"
- argv_target_layout = "nchw,[]"
- result = get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout)
- exp_res = [{'source_layout': 'nhwc', 'target_layout': 'nchw'},
- {'source_layout': '[]', 'target_layout': '[]'}]
- self.assertEqual(exp_res, result)
- for i in range(len(exp_res)):
- assert np.array_equal(result[i], exp_res[i])
-
- def wrong_case_1(self):
- argv_source_layout = "[n,h,w,c]),[n,h,w,c]"
- argv_target_layout = "[n,c,h,w],[n,c,h,w]"
- self.assertRaises(get_layout_values(argv_source_layout=argv_source_layout, argv_target_layout=argv_target_layout))
-
- def wrong_case_2(self):
- argv_source_layout = "[nchv"
- self.assertRaises(get_layout_values(argv_source_layout=argv_source_layout))
-
- def wrong_case_3(self):
- argv_source_layout = "nchv->"
- self.assertRaises(get_layout_values(argv_source_layout=argv_source_layout))
-
-class TestPackParamsToArgsNamespace(unittest.TestCase):
- def test_mo_convert_params(self):
- from openvino.frontend import ConversionExtension
- args = {'input_model': os.path.dirname(__file__),
- 'input_shape': [PartialShape([1,100,100,3]), [2,3]],
- 'extensions': ConversionExtension("Ext", lambda x: x),
- 'reverse_input_channels': True,
- 'scale': 0.5,
- 'input': ['name', InputCutInfo("a", [1,2,3], numpy.float32, [5, 6, 7])],
- 'batch': 1,
- 'output': ["a", "b", "c"],
- 'mean_values': [0.5, 0.3],
- 'scale_values': {"a": np.array([0.4]), "b": [0.5, 0.6]},
- 'source_layout': Layout("nchw"),
- 'layout': {"a": LayoutMap("nchw","nhwc"), "b": "nc"},
- 'transform': ('LowLatency2', {'use_const_initializer': False})}
-
- cli_parser = get_all_cli_parser()
- argv = pack_params_to_args_namespace(args, cli_parser)
-
- assert argv.input_model == args['input_model']
- assert argv.extensions == [args['extensions']]
- assert argv.reverse_input_channels == args['reverse_input_channels']
- assert argv.scale == 0.5
- assert argv.batch == 1
- assert argv.input_shape == [PartialShape([1,100,100,3]), [2,3]]
- assert argv.input == ['name', InputCutInfo("a", [1,2,3], numpy.float32, [5, 6, 7])]
- assert argv.output == "a,b,c"
- assert argv.mean_values == "[0.5,0.3]"
- assert argv.scale_values == "a[0.4],b[0.5,0.6]"
- assert argv.source_layout == "[N,C,H,W]"
- assert argv.layout == "a(nchw->nhwc),b(nc)"
- assert argv.transform == "LowLatency2[use_const_initializer=False]"
-
- for arg, value in vars(argv).items():
- if arg not in args and arg != 'is_python_api_used':
- assert value == cli_parser.get_default(arg)
-
- def test_not_existing_dir(self):
- args = {"input_model": "abc"}
- cli_parser = get_all_cli_parser()
-
- with self.assertRaisesRegex(Error, "The \"abc\" is not existing file or directory"):
- pack_params_to_args_namespace(args, cli_parser)
-
- def test_unknown_params(self):
- args = {"input_model": os.path.dirname(__file__),
- "a": "b"}
- cli_parser = get_all_cli_parser()
-
- with self.assertRaisesRegex(Error, "Unrecognized argument: a"):
- pack_params_to_args_namespace(args, cli_parser)
-
-
-class TestConvertModelParamsParsing(unittest.TestCase):
- def test_mo_convert_params_parsing(self):
- ref_params = {
- 'Optional parameters:': {'help', 'framework'},
- 'Framework-agnostic parameters:': {'input_model', 'input_shape', 'scale', 'reverse_input_channels',
- 'log_level', 'input', 'output', 'mean_values', 'scale_values', 'source_layout',
- 'target_layout', 'layout', 'compress_to_fp16', 'transform', 'extensions',
- 'batch', 'silent', 'version', 'progress', 'stream_output',
- 'transformations_config', 'example_input', 'share_weights'},
- 'Caffe*-specific parameters:': {'input_proto', 'caffe_parser_path', 'k', 'disable_omitting_optional',
- 'enable_flattening_nested_params'},
- 'TensorFlow*-specific parameters:': {'input_model_is_text', 'input_checkpoint', 'input_meta_graph',
- 'saved_model_dir', 'saved_model_tags',
- 'tensorflow_custom_operations_config_update',
- 'tensorflow_object_detection_api_pipeline_config',
- 'tensorboard_logdir', 'tensorflow_custom_layer_libraries'},
- 'Kaldi-specific parameters:': {'counts', 'remove_output_softmax', 'remove_memory'},
- 'PaddlePaddle-specific parameters:': {'example_output'},
- }
-
- params = get_mo_convert_params()
- for group_name in ref_params:
- assert group_name in params
- assert params[group_name].keys() == ref_params[group_name]
-
- cli_parser = get_all_cli_parser()
- for group_name, params in ref_params.items():
- for param_name in params:
- param_name = '--' + param_name
- if group_name == 'PaddlePaddle-specific parameters:':
- assert param_name not in cli_parser._option_string_actions
- else:
- assert param_name in cli_parser._option_string_actions
-
diff --git a/tools/mo/unit_tests/mo/utils/convert_impl_tmp_irs_cleanup_test_actual.py b/tools/mo/unit_tests/mo/utils/convert_impl_tmp_irs_cleanup_test_actual.py
deleted file mode 100644
index 49ef37b62344f0..00000000000000
--- a/tools/mo/unit_tests/mo/utils/convert_impl_tmp_irs_cleanup_test_actual.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import unittest
-from unittest.mock import patch
-
-from openvino.tools.mo.convert import convert_model
-from openvino.tools.mo.utils.error import Error
-
-
-class TestConvertImplTmpIrsCleanup(unittest.TestCase):
- test_model_file = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
- "moc_tf_fe/test_models/mul_with_unknown_rank_y.pbtxt")
-
- @staticmethod
- def are_tmp_files_left(orig_model_name):
- for suf in [".xml", ".bin", ".mapping"]:
- path_to_file = orig_model_name.replace('.pbtxt', '_tmp' + suf)
- if os.path.exists(path_to_file):
- return True
- return False
-
- def test_tmp_irs_cleanup_convert_impl_1(self):
- with patch("openvino.tools.mo.back.offline_transformations.apply_offline_transformations") as emit_ir_func:
- emit_ir_func.side_effect = Error('offline transformations step has failed')
-
- params = {'input_model': self.test_model_file, 'input_model_is_text': True, 'input': 'x[3],y[1 3]',
- 'use_legacy_frontend': True}
- self.assertRaisesRegex(Error, 'offline transformations step has failed', convert_model, **params)
- self.assertFalse(self.are_tmp_files_left(self.test_model_file))
-
- def test_tmp_irs_cleanup_convert_impl_2(self):
- with patch("openvino.tools.mo.back.ie_ir_ver_2.emitter.add_net_rt_info") as emit_ir_func:
- emit_ir_func.side_effect = Error('emitting tmp IR has failed')
-
- params = {'input_model': self.test_model_file, 'input_model_is_text': True, 'input': 'x[3],y[1 3]',
- 'use_legacy_frontend': True}
- self.assertRaisesRegex(Error, 'emitting tmp IR has failed', convert_model, **params)
- self.assertFalse(self.are_tmp_files_left(self.test_model_file))
-
- def test_tmp_irs_cleanup_convert_impl_3(self):
- with patch("openvino.tools.mo.convert_impl.read_model") as emit_ir_func:
- emit_ir_func.side_effect = Exception('FEM read_model has failed')
-
- params = {'input_model': self.test_model_file, 'input_model_is_text': True, 'input': 'x[3],y[1 3]',
- 'use_legacy_frontend': True}
- self.assertRaisesRegex(Error, 'FEM read_model has failed', convert_model, **params)
- self.assertFalse(self.are_tmp_files_left(self.test_model_file))
diff --git a/tools/mo/unit_tests/mo/utils/custom_replacement_config_test.py b/tools/mo/unit_tests/mo/utils/custom_replacement_config_test.py
deleted file mode 100644
index fddb77599289ff..00000000000000
--- a/tools/mo/unit_tests/mo/utils/custom_replacement_config_test.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-from fnmatch import fnmatch
-
-from openvino.tools.mo.utils.custom_replacement_config import load_and_validate_json_config
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.utils import get_mo_root_dir
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-
-
-def get_json_configs(mo_root_dir):
- config_path = os.path.join(mo_root_dir, 'extensions', 'front')
- pattern = "*.json"
- config_files_list = []
- for path, subdirs, files in os.walk(config_path):
- for name in files:
- if fnmatch(name, pattern):
- config_files_list.append((os.path.join(path, name),))
- return config_files_list
-
-
-class TestSchema(UnitTestWithMockedTelemetry):
- base_dir = get_mo_root_dir()
- schema_file = os.path.join(base_dir, 'mo', 'utils', 'schema.json')
- transformation_configs = get_json_configs(base_dir)
- test_json1 = '[{"id": "", "match_kind": "general", "custom_attributes": {}}]'
- test_json2 = '[{"id": "someid", "match_kind": "abc", "custom_attributes": {}}]'
-
- def test_schema_file(self):
- for transformation_config in self.transformation_configs:
- self.assertTrue(load_and_validate_json_config(transformation_config))
-
- def test_schema_id_empty(self):
- self.assertRaises(Error, load_and_validate_json_config, self.test_json1)
-
- def test_schema_match_kind_wrong(self):
- self.assertRaises(Error, load_and_validate_json_config, self.test_json2)
diff --git a/tools/mo/unit_tests/mo/utils/error_test.py b/tools/mo/unit_tests/mo/utils/error_test.py
deleted file mode 100644
index 5a328808ecc924..00000000000000
--- a/tools/mo/unit_tests/mo/utils/error_test.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.utils.error import classify_error_type
-
-
-class TestingErrorClassifier(unittest.TestCase):
- def test_no_module(self):
- message = "No module named 'openvino._offline_transformations.offline_transformations_api'"
- self.assertEqual(classify_error_type(message), message)
-
- def test_no_module_neg(self):
- message = "No module 'openvino'"
- self.assertEqual(classify_error_type(message), "undefined")
-
- def test_cannot_import_name(self):
- message = "cannot import name 'IECore' from 'openvino.inference_engine' (unknown location)"
- self.assertEqual(classify_error_type(message), "cannot import name 'IECore'")
-
- def test_cannot_import_name_neg(self):
- message = "import name 'IECore' from 'openvino.inference_engine' (unknown location)"
- self.assertEqual(classify_error_type(message), "undefined")
diff --git a/tools/mo/unit_tests/mo/utils/freeze_placeholder_test.py b/tools/mo/unit_tests/mo/utils/freeze_placeholder_test.py
deleted file mode 100644
index af9d89d90b0c2c..00000000000000
--- a/tools/mo/unit_tests/mo/utils/freeze_placeholder_test.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import pytest
-from unittest.mock import patch, Mock
-
-import numpy as np
-import onnx
-from onnx.helper import make_graph, make_model, make_tensor_value_info
-
-from openvino.frontend import (
- FrontEndManager,
- FrontEnd,
-) # pylint: disable=no-name-in-module,import-error
-from openvino.runtime import Core
-from openvino.tools.mo.convert_impl import prepare_ir
-
-
-def base_args_config(use_legacy_fe: bool = None, use_new_fe: bool = None):
- args = argparse.Namespace()
- args.feManager = FrontEndManager()
- args.extensions = None
- args.use_legacy_frontend = use_legacy_fe
- args.use_new_frontend = use_new_fe
- args.framework = "onnx"
- args.model_name = None
- args.input_model = None
- args.input_checkpoint = None
- args.silent = True
- args.transform = []
- args.scale = None
- args.output = None
- args.input = None
- args.input_shape = None
- args.batch = None
- args.mean_values = None
- args.scale_values = None
- args.output_dir = os.getcwd()
- args.freeze_placeholder_with_value = None
- args.transformations_config = None
- args.static_shape = None
- args.reverse_input_channels = None
- args.data_type = None
- args.layout = None
- args.source_layout = None
- args.target_layout = None
- return args
-
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-def get_test_default_frontends():
- return {"onnx": "new", "tf": "legacy"}
-
-
-class TestMoFreezePlaceholder():
- @classmethod
- def setup_method(cls):
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
- FrontEnd.add_extension = Mock()
-
- cls.models = {}
- add = onnx.helper.make_node("Add", inputs=["in1", "in2"], outputs=["add_out"])
- input_tensors = [
- make_tensor_value_info("in1", onnx.TensorProto.FLOAT, (2, 2)),
- make_tensor_value_info("in2", onnx.TensorProto.FLOAT, (2, 2)),
- ]
- output_tensors = [
- make_tensor_value_info("add_out", onnx.TensorProto.FLOAT, (2, 2)),
- ]
- graph = make_graph([add], "test_graph", input_tensors, output_tensors)
- model = make_model(
- graph,
- producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)],
- )
- cls.models["test_model.onnx"] = model
-
- input_tensors_2 = [
- make_tensor_value_info("in1", onnx.TensorProto.FLOAT, (1, 1, 3)),
- make_tensor_value_info("in2", onnx.TensorProto.FLOAT, (1,)),
- ]
- output_tensors_2 = [
- make_tensor_value_info("mul_out", onnx.TensorProto.FLOAT, (1, 1, 3)),
- ]
- mul = onnx.helper.make_node("Mul", inputs=["in1", "in2"], outputs=["mul_out"])
- graph_2 = make_graph([mul], "test_graph_2", input_tensors_2, output_tensors_2)
- model_2 = make_model(
- graph_2,
- producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)],
- )
- cls.models["test_model_2.onnx"] = model_2
-
- input_tensors_3 = [
- make_tensor_value_info("in1", onnx.TensorProto.INT32, (2, 3)),
- make_tensor_value_info("in2", onnx.TensorProto.INT32, (3,)),
- ]
- output_tensors_3 = [
- make_tensor_value_info("mul_out", onnx.TensorProto.INT32, (2, 3)),
- ]
- mul = onnx.helper.make_node("Mul", inputs=["in1", "in2"], outputs=["mul_out"])
- graph_3 = make_graph([mul], "test_graph_3", input_tensors_3, output_tensors_3)
- model_3 = make_model(
- graph_3,
- producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)],
- )
- cls.models["test_model_int.onnx"] = model_3
-
- for name, model in cls.models.items():
- onnx.save(model, name)
- @classmethod
- def teardown_method(cls):
- for name in cls.models.keys():
- os.remove(name)
-
- @pytest.mark.parametrize(
- "input_freezing_value, use_new_fe, inputs, expected,dtype",[
- (
- "in1[1 4]{f32}->[1.0 2.0 3.0 4.0],in2[1 4]{f32}->[1.0 2.0 3.0 4.0]",
- True,
- {},
- np.array([2.0, 4.0, 6.0, 8.0]),
- np.float32,
- ),
- (
- "in2{f32}->[0.0 0.0 0.0 0.0]",
- True,
- {"in1": np.array([[1.0, 2.0], [3.0, 4.0]])},
- np.array([[1.0, 2.0], [3.0, 4.0]]),
- np.float32,
- ),
- (
- "in2{f32}->[1.0 15.0 15.5 1.0]",
- True,
- {"in1": np.array([[2.0, 4.0], [12.0, 8.0]])},
- np.array([[3.0, 19.0], [27.5, 9.0]]),
- np.float32,
- ),
- (
- "in1[1 4]{i32}->[1 2 3 4],in2[1 4]{i32}->[1 2 3 4]",
- True,
- {},
- np.array([2.0, 4.0, 6.0, 8.0]),
- np.int32,
- ),
- ],
- )
- def test_freeze_placeholder_with_value_onnx_fe(self, input_freezing_value, use_new_fe, inputs, expected,
- dtype):
- with patch("openvino.tools.mo.convert_impl.get_default_frontends") as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_new_fe=use_new_fe)
- args.input_model = "test_model.onnx"
- args.input = input_freezing_value
-
- _, model = prepare_ir(args)
-
- ie = Core()
- exec_net = ie.compile_model(model, "CPU")
- req = exec_net.create_infer_request()
- results = req.infer(inputs)
- values = list(results.values())[0]
- if dtype is not None:
- assert values.dtype == dtype
- assert np.allclose(values, expected)
-
- @pytest.mark.parametrize(
- "input_freezing_value, use_new_fe, inputs, expected, dtype",[
- (
- "in1{f32}->[1.0 15.0 1.0]",
- True,
- {"in2": np.array([2])},
- np.array([2.0, 30.0, 2.0]),
- np.float32,
- ),
- (
- "in1{f32}->[7.0 11.0 -1.0],in2{f32}->3.0",
- True,
- {},
- np.array([21.0, 33.0, -3.0]),
- np.float32,
- ),
- (
- None,
- True,
- {
- "in1": np.array([2.0, 2.0, 2.0]).reshape(1, 1, 3),
- "in2": np.array([-1.0]),
- },
- np.array([-2.0, -2.0, -2.0]),
- np.float32,
- ),
- (
- "in1[3 1]{f32}->[7.0 11.0 -1.0],in2{f32}->3.0",
- True,
- {},
- np.array([21.0, 33.0, -3.0]).reshape(3, 1),
- np.float32,
- ),
- (
- "in1[3 1]{f16}->[7.0 11.0 -1.0],in2{f16}->3.0",
- True,
- {},
- np.array([21.0, 33.0, -3.0]).reshape(3, 1),
- np.float16,
- ),
- (
- "in1[3 1]{i32}->[7 11 -1],in2{i32}->3.0",
- True,
- {},
- np.array([21, 33, -3]).reshape(3, 1),
- np.int32,
- ),
- ],
- )
- def test_freeze_placeholder_with_value_mul(self, input_freezing_value, use_new_fe, inputs, expected, dtype):
- with patch("openvino.tools.mo.convert_impl.get_default_frontends") as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_new_fe=use_new_fe)
- args.input_model = "test_model_2.onnx"
- args.input = input_freezing_value
-
- _, model = prepare_ir(args)
-
- ie = Core()
- exec_net = ie.compile_model(model, "CPU")
- req = exec_net.create_infer_request()
- results = req.infer(inputs)
- values = list(results.values())[0]
- if dtype is not None:
- assert values.dtype == dtype
- assert np.allclose(values, expected)
-
- @pytest.mark.parametrize(
- "input_freezing_value, use_new_fe, inputs, expected,dtype",[
- (
- "in1->[1.0 15.0 1.0]",
- True,
- {"in2": np.array([2])},
- np.array([2.0, 30.0, 2.0]),
- np.float32,
- ),
- ],
- )
- def test_value_without_type(self, input_freezing_value, use_new_fe, inputs, expected,
- dtype):
- with patch("openvino.tools.mo.convert_impl.get_default_frontends") as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_new_fe=use_new_fe)
- args.input_model = "test_model_2.onnx"
- args.input = input_freezing_value
-
- _, model = prepare_ir(args)
-
- ie = Core()
- exec_net = ie.compile_model(model, "CPU")
- req = exec_net.create_infer_request()
- results = req.infer(inputs)
- values = list(results.values())[0]
- if dtype is not None:
- assert values.dtype == dtype
- assert np.allclose(values, expected)
-
- @pytest.mark.parametrize(
- "input_freezing_value, use_new_fe, inputs, expected,dtype",[
- (
- "in2->[3 2 5]",
- True,
- {"in1": np.array([[2, 1, 3], [1, 5, 6]], dtype=np.int32)},
- np.array([[6, 2, 15], [3, 10, 30]], dtype=np.int32),
- np.int32,
- ),
- ],
- )
- def test_value_without_type_int32(self, input_freezing_value, use_new_fe, inputs, expected,
- dtype):
- with patch("openvino.tools.mo.convert_impl.get_default_frontends") as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_new_fe=use_new_fe)
- args.input_model = "test_model_int.onnx"
- args.input = input_freezing_value
-
- _, model = prepare_ir(args)
-
- ie = Core()
- exec_net = ie.compile_model(model, "CPU")
- req = exec_net.create_infer_request()
- results = req.infer(inputs)
- values = list(results.values())[0]
- if dtype is not None:
- assert values.dtype == dtype
- assert np.allclose(values, expected)
diff --git a/tools/mo/unit_tests/mo/utils/graph_test.py b/tools/mo/unit_tests/mo/utils/graph_test.py
deleted file mode 100644
index dd0d9c77ea13bd..00000000000000
--- a/tools/mo/unit_tests/mo/utils/graph_test.py
+++ /dev/null
@@ -1,362 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.graph import bfs_search, is_connected_component, sub_graph_between_nodes, backward_bfs_for_operation
-from unit_tests.mo.unit_test_with_mocked_telemetry import UnitTestWithMockedTelemetry
-from unit_tests.utils.graph import regular_op, result, build_graph_with_edge_attrs
-
-
-class TestGraphUtils(UnitTestWithMockedTelemetry):
- def test_simple_dfs(self):
- graph = Graph()
- graph.add_nodes_from(list(range(1, 5)))
- graph.add_edges_from([(1, 2), (1, 3), (3, 4)])
-
- visited = set()
- order = graph.dfs(1, visited)
- self.assertTrue(order == [4, 3, 2, 1] or order == [2, 4, 3, 1])
-
- def test_bfs_search_default_start_nodes(self):
- """
- Check that BFS automatically determines input nodes and start searching from them.
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 6)))
- graph.add_edges_from([(1, 3), (2, 3), (3, 4), (4, 5)])
-
- order = bfs_search(graph)
- self.assertTrue(order == [1, 2, 3, 4, 5] or order == [2, 1, 3, 4, 5])
-
- def test_bfs_search_specific_start_nodes(self):
- """
- Check that BFS stars from the user defined nodes and doesn't go in backward edge direction.
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 3), (2, 3), (3, 4), (4, 5), (6, 1)])
-
- order = bfs_search(graph, [1])
- self.assertTrue(order == [1, 3, 4, 5])
-
- def test_is_connected_component_two_separate_sub_graphs(self):
- """
- Check that if there are two separate sub-graphs the function returns False.
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 2), (2, 3), (4, 5), (5, 6)])
- self.assertFalse(is_connected_component(graph, list(range(1, 7))))
- self.assertFalse(is_connected_component(graph, [1, 3]))
- self.assertFalse(is_connected_component(graph, [6, 4]))
- self.assertFalse(is_connected_component(graph, [2, 5]))
-
- def test_is_connected_component_two_separate_sub_graphs_divided_by_ignored_node(self):
- """
- Check that if there are two separate sub-graphs the function connected by an edge going through the ignored node
- then the function returns False.
- """
- graph = Graph()
- node_names = list(range(1, 8))
- graph.add_nodes_from(node_names)
- graph.add_edges_from([(1, 2), (2, 3), (4, 5), (5, 6), (1, 7), (7, 4)])
- self.assertFalse(is_connected_component(graph, list(range(1, 7))))
-
- def test_is_connected_component_connected(self):
- """
- Check that if the sub-graph is connected.
- """
- graph = Graph()
- node_names = list(range(1, 8))
- graph.add_nodes_from(node_names)
- graph.add_edges_from([(1, 2), (2, 3), (4, 5), (5, 6), (1, 7), (7, 4)])
- self.assertTrue(is_connected_component(graph, list(range(1, 8))))
-
- def test_is_connected_component_edges_direction_is_ignored(self):
- """
- Check that edges direction is ignored when checking for the connectivity.
- """
- graph = Graph()
- node_names = list(range(1, 5))
- graph.add_nodes_from(node_names)
- graph.add_edges_from([(2, 1), (2, 3), (4, 3)])
- self.assertTrue(is_connected_component(graph, node_names))
- self.assertTrue(is_connected_component(graph, [2, 1]))
- self.assertTrue(is_connected_component(graph, [4, 2, 3]))
-
- def test_is_connected_component_edges_direction_is_ignored_not_connected(self):
- """
- Check that edges direction is ignored when checking for the connectivity. In this case the graph is not
- connected.
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 5)))
- graph.add_edges_from([(2, 1), (2, 3), (4, 3)])
- self.assertFalse(is_connected_component(graph, [1, 2, 4]))
- self.assertFalse(is_connected_component(graph, [1, 4]))
- self.assertFalse(is_connected_component(graph, [2, 4]))
- self.assertFalse(is_connected_component(graph, [3, 4, 1]))
-
- def test_sub_graph_between_nodes_include_incoming_edges_for_internal_nodes(self):
- """
- Check that the function adds input nodes for the internal nodes of the graph. For example, we need to add node 5
- and 6 in the case below if we find match from node 1 till node 4.
- 6 -> 5 ->
- \
- 1 -> 2 -> 3 -> 4
- :return:
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2), (6, 5)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4])
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), list(range(1, 7)))
-
- sub_graph_nodes = sub_graph_between_nodes(graph, [1], [2])
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), [1, 2, 5, 6])
-
- def test_sub_graph_between_nodes_do_not_include_incoming_edges_for_input_nodes(self):
- """
- Check that the function doesn't add input nodes for the start nodes of the sub-graph. For example, we do not
- need to add node 5 in the case below if we find match from node 1 till node 4.
- 5->
- \
- 1 -> 2 -> 3 -> 4
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 6)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [2], [4])
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), [2, 3, 4])
-
- def test_sub_graph_between_nodes_placeholder_included(self):
- """
- Check that the function doesn't allow to add Placeholders to the sub-graph. 5 is the Placeholder op.
- 5->
- \
- 1 -> 2 -> 3 -> 4
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 6)))
- graph.node[5]['op'] = 'Parameter'
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
- self.assertRaises(Error, sub_graph_between_nodes, graph, [1], [4])
-
- def test_sub_graph_between_nodes_placeholder_excluded(self):
- """
- Check that the function do not check that node is Placeholders for the nodes not included into the sub-graph.
- For example, node 5 is Placeholder but it is not included into the sub-graph, so this attribute is ignored.
- 5->
- \
- 1 -> 2 -> 3 -> 4
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 6)))
- graph.node[5]['op'] = 'Parameter'
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [2], [4])
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), [2, 3, 4])
-
- def test_sub_graph_between_nodes_multiple_inputs(self):
- """
- Check that the function works correctly when multiple inputs specified.
- 5->
- \
- 1 -> 2 -> 3 -> 4
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 6)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [2, 5], [4])
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), sorted([2, 3, 4, 5]))
-
- def test_sub_graph_between_nodes_branches_included(self):
- """
- Check that the function works correctly for tree like structures.
- 1 -> 2 -> 3 -> 4
- \
- 5 -> 6
- / \
- 9 -> -> 7 -> 8
- """
- graph = Graph()
- node_names = list(range(1, 10))
- graph.add_nodes_from(node_names)
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (2, 5), (5, 6), (5, 7), (7, 8), (9, 5)])
- self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [4])), node_names)
- self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [6])), node_names)
- self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [8])), node_names)
- # all nodes except 4 because it is a child of end node
- self.assertListEqual(sorted(sub_graph_between_nodes(graph, [1], [3])), [n for n in node_names if n != 4])
- # all nodes except 1 because it is a parent node child of start node. The nodes 3 and 4 must be added because
- # after merging node 2 into sub-graph the node 2 will be removed and it is not known how to calculate the tensor
- # between node 2 and 3.
- self.assertListEqual(sorted(sub_graph_between_nodes(graph, [2], [8])), [n for n in node_names if n != 1])
-
- def test_sub_graph_between_nodes_control_flow_included(self):
- """
- Check that the function works correctly for case when control flow edges must be traversed (edge 5 -> 2).
- 6 -> 5->
- \
- 1 -> 2 -> 3 -> 4
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2, {'control_flow_edge': True}), (6, 5)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4], include_control_flow=True)
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), sorted([1, 2, 3, 4, 5, 6]))
-
- def test_sub_graph_between_nodes_control_flow_not_included(self):
- """
- Check that the function works correctly for case when control flow edges should not be traversed (edge 5 -> 2).
- 6 -> 5->
- \
- 1 -> 2 -> 3 -> 4
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (5, 2, {'control_flow_edge': True}), (6, 5)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4], include_control_flow=False)
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), sorted([1, 2, 3, 4]))
-
- def test_sub_graph_between_nodes_control_flow_included_forward(self):
- """
- Check that the function works correctly for case when control flow edges should not be traversed (edge 3 -> 5).
- 1 -> 2 -> 3 -> 4
- \
- -> 5 -> 6
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (3, 5, {'control_flow_edge': True}), (5, 6)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4], include_control_flow=True)
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), sorted([1, 2, 3, 4, 5, 6]))
-
- def test_sub_graph_between_nodes_control_flow_not_included_forward(self):
- """
- Check that the function works correctly for case when control flow edges should not be traversed (edge 3 -> 5).
- 1 -> 2 -> 3 -> 4
- \
- -> 5 -> 6
- """
- graph = Graph()
- graph.add_nodes_from(list(range(1, 7)))
- graph.add_edges_from([(1, 2), (2, 3), (3, 4), (3, 5, {'control_flow_edge': True}), (5, 6)])
- sub_graph_nodes = sub_graph_between_nodes(graph, [1], [4], include_control_flow=False)
- self.assertIsNotNone(sub_graph_nodes)
- self.assertListEqual(sorted(sub_graph_nodes), sorted([1, 2, 3, 4]))
-
- def test_backward_bfs_for_op_no_ops_detected(self):
- nodes = {**regular_op('input', {'op': 'Parameter'}),
- **regular_op('hsigmoid', {'op': 'HSigmoid'}),
- **result('result'),
- }
- edges = [('input', 'hsigmoid', {'out': 0, 'in': 0}),
- ('hsigmoid', 'result', {'out': 0, 'in': 0}),
- ]
-
- graph = build_graph_with_edge_attrs(nodes, edges)
- graph.stage = 'front'
-
- found_nodes = backward_bfs_for_operation(Node(graph, 'result'), ['NonExistingOp'])
- self.assertEqual(len(found_nodes), 0)
-
- def test_backward_bfs_for_op_closest_op_detected(self):
- """
- input -> hsigmoid_1 -> hsigmoid_2 -> result
- The returned op should be first met HSigmoid which is hsigmoid_2
- """
- nodes = {**regular_op('input', {'op': 'Parameter'}),
- **regular_op('hsigmoid_1', {'op': 'HSigmoid'}),
- **regular_op('hsigmoid_2', {'op': 'HSigmoid'}),
- **result('result'),
- }
- edges = [('input', 'hsigmoid_1', {'out': 0, 'in': 0}),
- ('hsigmoid_1', 'hsigmoid_2', {'out': 0, 'in': 0}),
- ('hsigmoid_2', 'result', {'out': 0, 'in': 0}),
- ]
-
- graph = build_graph_with_edge_attrs(nodes, edges)
- graph.stage = 'front'
-
- found_nodes = backward_bfs_for_operation(Node(graph, 'result'), ['HSigmoid'])
- self.assertEqual(len(found_nodes), 1)
- self.assertEqual(found_nodes[0].id, 'hsigmoid_2')
-
- def test_backward_bfs_for_op_parallel_branch_op_detected(self):
- r"""
- input_1 -> hsigmoid_1 -> hsigmoid_2 ->
- \
- - Concat->result
- /
- input_2 -> hsigmoid_3 -> hsigmoid_4 ->
- The returned op should be first met HSigmoids which are hsigmoid_2 and hsigmoid_4
- """
- nodes = {**regular_op('input_1', {'op': 'Parameter'}),
- **regular_op('hsigmoid_1', {'op': 'HSigmoid'}),
- **regular_op('hsigmoid_2', {'op': 'HSigmoid'}),
- **regular_op('input_2', {'op': 'Parameter'}),
- **regular_op('hsigmoid_3', {'op': 'HSigmoid'}),
- **regular_op('hsigmoid_4', {'op': 'HSigmoid'}),
- **regular_op('concat', {'op': 'Concat'}),
- **result('result'),
- }
- edges = [('input_1', 'hsigmoid_1', {'out': 0, 'in': 0}),
- ('hsigmoid_1', 'hsigmoid_2', {'out': 0, 'in': 0}),
- ('hsigmoid_2', 'concat', {'out': 0, 'in': 0}),
- ('input_2', 'hsigmoid_3', {'out': 0, 'in': 0}),
- ('hsigmoid_3', 'hsigmoid_4', {'out': 0, 'in': 0}),
- ('hsigmoid_4', 'concat', {'out': 0, 'in': 1}),
- ('concat', 'result', {'out': 0, 'in': 0}),
- ]
-
- graph = build_graph_with_edge_attrs(nodes, edges)
- graph.stage = 'front'
-
- found_nodes = backward_bfs_for_operation(Node(graph, 'result'), ['HSigmoid'])
- self.assertEqual(len(found_nodes), 2)
- self.assertSetEqual({found_nodes[0].id, found_nodes[1].id}, {'hsigmoid_2', 'hsigmoid_4'})
-
- def test_backward_bfs_for_op_parallel_branch_stop_op(self):
- r"""
- input_1 -> hsigmoid_1 -> hsigmoid_2 ->
- \
- - Concat->result
- /
- input_2 -> hsigmoid_3 -> ShapeOf ->
- The returned op should be first met HSigmoids which is hsigmoid_2, but not the hsigmoid_3 located after banned
- operation of type "ShapeOf"
- """
- nodes = {**regular_op('input_1', {'op': 'Parameter'}),
- **regular_op('hsigmoid_1', {'op': 'HSigmoid'}),
- **regular_op('hsigmoid_2', {'op': 'HSigmoid'}),
- **regular_op('input_2', {'op': 'Parameter'}),
- **regular_op('hsigmoid_3', {'op': 'HSigmoid'}),
- **regular_op('shapeof', {'op': 'ShapeOf'}),
- **regular_op('concat', {'op': 'Concat'}),
- **result('result'),
- }
- edges = [('input_1', 'hsigmoid_1', {'out': 0, 'in': 0}),
- ('hsigmoid_1', 'hsigmoid_2', {'out': 0, 'in': 0}),
- ('hsigmoid_2', 'concat', {'out': 0, 'in': 0}),
- ('input_2', 'hsigmoid_3', {'out': 0, 'in': 0}),
- ('hsigmoid_3', 'shapeof', {'out': 0, 'in': 0}),
- ('shapeof', 'concat', {'out': 0, 'in': 1}),
- ('concat', 'result', {'out': 0, 'in': 0}),
- ]
-
- graph = build_graph_with_edge_attrs(nodes, edges)
- graph.stage = 'front'
-
- found_nodes = backward_bfs_for_operation(Node(graph, 'result'), ['HSigmoid'], ['ShapeOf'])
- self.assertEqual(len(found_nodes), 1)
- self.assertEqual(found_nodes[0].id, 'hsigmoid_2')
diff --git a/tools/mo/unit_tests/mo/utils/ir_engine/__init__.py b/tools/mo/unit_tests/mo/utils/ir_engine/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/mo/utils/ir_engine/ir_engine_test.py b/tools/mo/unit_tests/mo/utils/ir_engine/ir_engine_test.py
deleted file mode 100644
index 3f98741950bbbe..00000000000000
--- a/tools/mo/unit_tests/mo/utils/ir_engine/ir_engine_test.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import logging as log
-import numpy as np
-import os
-import sys
-import unittest
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, strict_compare_tensors
-from openvino.tools.mo.graph.graph import Node
-from openvino.tools.mo.utils.ir_engine.ir_engine import IREngine
-from unittest import mock
-
-log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.DEBUG, stream=sys.stdout)
-
-
-class TestFunction(unittest.TestCase):
- def setUp(self):
- path, _ = os.path.split(os.path.dirname(__file__))
- self.xml = os.path.join(path, os.pardir, os.pardir,
- "utils", "test_data", "mxnet_synthetic_gru_bidirectional_FP16_1_v6.xml")
- self.xml_negative = os.path.join(path, os.pardir, os.pardir,
- "utils", "test_data",
- "mxnet_synthetic_gru_bidirectional_FP16_1_v6_negative.xml")
- self.bin = os.path.splitext(self.xml)[0] + '.bin'
- self.assertTrue(os.path.exists(self.xml), 'XML file not found: {}'.format(self.xml))
- self.assertTrue(os.path.exists(self.bin), 'BIN file not found: {}'.format(self.bin))
-
- self.IR = IREngine(path_to_xml=str(self.xml), path_to_bin=str(self.bin))
- self.IR_ref = IREngine(path_to_xml=str(self.xml), path_to_bin=str(self.bin))
- self.IR_negative = IREngine(path_to_xml=str(self.xml_negative), path_to_bin=str(self.bin))
-
- def test_is_float(self):
- test_cases = [(4.4, True), ('aaaa', False)]
- for test_data, result in test_cases:
- test_data = test_data
- self.assertEqual(IREngine._IREngine__isfloat(test_data), result,
- "Function __isfloat is not working with value: {}".format(test_data))
- log.info(
- 'Test for function __is_float passed with value: {}, expected result: {}'.format(test_data, result))
-
- # TODO add comparison not for type IREngine
- def test_compare(self):
- flag, msg = self.IR.compare(self.IR_ref)
- self.assertTrue(flag, 'Comparing false, test compare function failed')
- log.info('Test for function compare passed')
-
- def test_compare_negative(self):
- # Reference data for test:
- reference_msg = 'Current node "2" with type "Const" and reference node "2" with type "Input" have different ' \
- 'attr "type" : Const and Input'
- # Check function:
- flag, msg = self.IR.compare(self.IR_negative)
- self.assertFalse(flag, 'Comparing flag failed, test compare function failed')
- self.assertEqual('\n'.join(msg), reference_msg, 'Comparing message failed, test compare negative failed')
-
- log.info('Test for function compare passed')
-
- def test_find_input(self):
- # Create references for this test:
- ref_nodes = [Node(self.IR.graph, '0')]
- # Check function:
- a = IREngine._IREngine__find_input(self.IR.graph)
- self.assertTrue(a == ref_nodes, 'Error')
-
- def test_get_inputs(self):
- # Reference data for test:
- ref_input_dict = {'data': shape_array([1, 10, 16])}
- # Check function:
- inputs_dict = self.IR.get_inputs()
- self.assertTrue(strict_compare_tensors(ref_input_dict['data'], inputs_dict['data']),
- 'Test on function get_inputs failed')
- log.info('Test for function get_inputs passed')
-
- def test_eq_function(self):
- self.assertTrue(self.IR == self.IR_ref, 'Comparing false, test eq function failed')
- log.info('Test for function eq passed')
-
- @unittest.mock.patch('numpy.savez_compressed')
- def test_generate_bin_hashes_file(self, numpy_savez):
- # Generate bin_hashes file in default directory
- self.IR.generate_bin_hashes_file()
- numpy_savez.assert_called_once()
- log.info('Test for function generate_bin_hashes_file with default folder passed')
-
- @unittest.mock.patch('numpy.savez_compressed')
- def test_generate_bin_hashes_file_custom_directory(self, numpy_savez):
- # Generate bin_hashes file in custom directory
- directory_for_file = os.path.join(os.path.split(os.path.dirname(__file__))[0], "utils", "test_data",
- "bin_hash")
- self.IR.generate_bin_hashes_file(path_for_file=directory_for_file)
- numpy_savez.assert_called_once()
- log.info('Test for function generate_bin_hashes_file with custom folder passed')
-
- def test_normalize_attr(self):
- test_cases = [({'order': '1,0,2'}, {'order': [1, 0, 2]}),
- ({'order': '1'}, {'order': 1})]
- for test_data, reference in test_cases:
- result_dict = IREngine._IREngine__normalize_attrs(attrs=test_data)
- self.assertTrue(reference == result_dict, 'Test on function normalize_attr failed')
- log.info('Test for function normalize_attr passed')
-
- def test_load_bin_hashes(self):
- path_for_file = self.IR.generate_bin_hashes_file()
- IR = IREngine(path_to_xml=str(self.xml), path_to_bin=str(path_for_file))
- is_ok = True
- # Check for constant nodes
- const_nodes = IR.graph.get_op_nodes(type='Const')
- for node in const_nodes:
- if not node.has_valid('hashes'):
- log.error('Constant node {} do not include hashes'.format(node.name))
- is_ok = False
-
- # Check for TensorIterator Body
- ti_nodes = IR.graph.get_op_nodes(type='TensorIterator')
- for ti in ti_nodes:
- if not ti.has_valid('body'):
- log.error("TensorIterator doesn't have body attribute for node: {}".format(ti.name))
- else:
- const_ti_nodes = ti.body.graph.get_op_nodes(type='Const')
- for node in const_ti_nodes:
- if not node.has_valid('hashes'):
- log.error('Constant node {} do not include hashes'.format(node.name))
- is_ok = False
-
- self.assertTrue(is_ok, 'Test for function load_bin_hashes failed')
- os.remove(path_for_file)
-
- def test_isint(self):
- test_cases = [
- ("0", True),
- ("1", True),
- ("-1", True),
- ("-", False),
- ("+1", True),
- ("+", False),
- ("1.0", False),
- ("-1.0", False),
- ("1.5", False),
- ("+1.5", False),
- ("abracadabra", False)]
- for value, result in test_cases:
- self.assertEqual(IREngine._IREngine__isint(value), result)
diff --git a/tools/mo/unit_tests/mo/utils/mo_fallback_test_actual.py b/tools/mo/unit_tests/mo/utils/mo_fallback_test_actual.py
deleted file mode 100644
index fcdf915788c5b2..00000000000000
--- a/tools/mo/unit_tests/mo/utils/mo_fallback_test_actual.py
+++ /dev/null
@@ -1,303 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import shutil
-from unittest.mock import patch, Mock
-
-import numpy as np
-import onnx
-import pytest
-from onnx.helper import make_graph, make_model, make_tensor_value_info
-from openvino.frontend import FrontEndManager, FrontEnd # pylint: disable=no-name-in-module,import-error
-
-from openvino.tools.mo.convert_impl import prepare_ir
-from openvino.tools.mo.utils.error import Error
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-try:
- import paddle
- paddle_imported = True
-except ImportError:
- paddle_imported = False
-
-
-def base_args_config(use_legacy_fe:bool=None, use_new_fe:bool=None):
- args = argparse.Namespace()
- args.feManager = FrontEndManager()
- args.extensions = None
- args.use_legacy_frontend = use_legacy_fe
- args.use_new_frontend = use_new_fe
- args.framework = 'onnx'
- args.model_name = None
- args.input_model = None
- args.silent = True
- args.transform=[]
- args.scale = None
- args.output=None
- args.input=None
- args.input_shape=None
- args.batch=None
- args.mean_values=None
- args.scale_values=None
- args.output_dir=os.getcwd()
- args.freeze_placeholder_with_value = None
- args.transformations_config = None
- args.static_shape = None
- args.reverse_input_channels = None
- args.data_type = None
- args.layout = None
- args.source_layout = None
- args.target_layout = None
- return args
-
-
-def get_test_default_frontends():
- return {
- 'onnx': 'new',
- 'tf': 'legacy'
- }
-
-
-def save_paddle_model(name, exe, feedkeys:list, fetchlist:list, target_dir:str):
- model_dir = os.path.join(target_dir, name)
- if not os.path.exists(model_dir):
- os.makedirs(model_dir)
-
- paddle.fluid.io.save_inference_model(model_dir, feedkeys, fetchlist, exe)
- paddle.fluid.io.save_inference_model(model_dir, feedkeys, fetchlist, exe, model_filename=name+".pdmodel", params_filename=name+".pdiparams")
-
-
-class TestMoFallback():
- def setup_method(self):
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
- FrontEnd.add_extension = Mock()
-
- self.models = {}
- add = onnx.helper.make_node("Add", inputs=["in1", "in2"], outputs=["add_out"])
- input_tensors = [
- make_tensor_value_info("in1", onnx.TensorProto.FLOAT, (2, 2)),
- make_tensor_value_info("in2", onnx.TensorProto.FLOAT, (2, 2)),
- ]
- output_tensors = [
- make_tensor_value_info("add_out", onnx.TensorProto.FLOAT, (1, 2)),
- ]
- graph = make_graph([add], "test_graph", input_tensors, output_tensors)
- model = make_model(graph, producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)])
- self.models["test_model.onnx"] = model
-
- for name, model in self.models.items():
- onnx.save(model, name)
-
- self.test_config_files = {}
- self.test_config_files['fake_config.json'] = '[]' # json format
-
- self.test_config_files['test_config.json'] = """[
- {
- "custom_attributes": {
- "test_attribute": true
- },
- "id": "TransformationName1",
- "match_kind": "scope"
- },
- {
- "custom_attributes": {
- },
- "id": "TransfromationName2",
- "match_kind": "scope"
- }
- ]"""
-
- self.test_config_files['onnx_fe_ext.so'] = 'binary_content'
- self.test_config_files['onnx_fe_ext_2.so'] = 'binary_content'
-
- for file, content in self.test_config_files.items():
- with open(file, 'w') as f:
- f.write(content)
-
- if paddle_imported:
- self.paddle_dir = "paddle_dir"
- paddle.enable_static()
- if not os.path.exists(self.paddle_dir):
- os.mkdir(self.paddle_dir)
- x = np.array([-2, 0, 1]).astype('float32')
- node_x = paddle.static.data(name='x', shape=x.shape, dtype='float32')
- out = paddle.nn.functional.relu(node_x)
-
- cpu = paddle.static.cpu_places(1)
- exe = paddle.static.Executor(cpu[0])
- exe.run(paddle.static.default_startup_program())
-
- save_paddle_model("relu", exe, feedkeys=['x'], fetchlist=[out], target_dir=self.paddle_dir)
-
- def teardown_method(self):
- for name in self.models.keys():
- os.remove(name)
- for name in self.test_config_files:
- os.remove(name)
- if paddle_imported:
- shutil.rmtree(self.paddle_dir)
-
- @pytest.mark.parametrize("extension, use_legacy, use_new_fe, conversion_method, fallback_reason", [
- (['dir_to_extension'], None, None, 'mo_legacy', 'extensions'), # fallback
- (['dir_to_extension'], None, True, None, None), # exception
- (['dir_to_extension'], True, None, 'mo_legacy', None),
- ([''], True, None, 'mo_legacy', None),
- ([''], None, True, 'onnx_frontend', None),
- (None, None, None, 'onnx_frontend', None)
- ])
- def test_fallback_if_extension_specified(self, extension, use_legacy, use_new_fe, conversion_method, fallback_reason):
- with patch('openvino.tools.mo.convert_impl.get_default_frontends') as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_legacy, use_new_fe)
- args.extensions = extension
- args.input_model = "test_model.onnx"
-
- if conversion_method:
- prepare_ir(args)
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', conversion_method)
- if fallback_reason:
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
- else:
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
- else:
- with pytest.raises(Error): # not supported extensions on new path
- prepare_ir(args)
-
- @pytest.mark.parametrize("use_legacy, use_new_fe, conversion_method", [
- (None, None, 'onnx_frontend'),
- (True, None, None), # exception
- (None, True, 'onnx_frontend'),
- ])
- def test_fallback_if_new_extension_specified(self, use_legacy, use_new_fe, conversion_method):
- with patch('openvino.tools.mo.convert_impl.get_default_frontends') as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_legacy, use_new_fe)
- args.extensions = ['onnx_fe_ext.so']
- args.input_model = "test_model.onnx"
-
- if conversion_method:
- prepare_ir(args)
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', conversion_method)
- else:
- with pytest.raises(Error):
- prepare_ir(args)
-
- @pytest.mark.parametrize("use_legacy, use_new_fe, conversion_method", [
- (None, None, 'onnx_frontend'),
- (True, None, None), # exception
- (None, True, 'onnx_frontend')
- ])
- def test_fallback_if_two_new_extension_specified(self, use_legacy, use_new_fe, conversion_method):
- with patch('openvino.tools.mo.convert_impl.get_default_frontends') as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_legacy, use_new_fe)
- args.extensions = ['onnx_fe_ext.so', 'onnx_fe_ext_2.so']
- args.input_model = "test_model.onnx"
-
- if conversion_method:
- prepare_ir(args)
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', conversion_method)
- else:
- with pytest.raises(Error):
- prepare_ir(args)
-
- @pytest.mark.parametrize("trans_config, use_legacy, use_new_fe, expected_path, fallback_reason", [
- ('fake_config.json', None, None, 'mo_legacy', 'transformations_config'), # fallback
- ('test_config.json', None, None, 'mo_legacy', 'transformations_config'), # fallback
- ('fake_config.json', True, None, 'mo_legacy', None),
- (None, None, True, 'onnx_frontend', None),
- (None, None, None, 'onnx_frontend', None)])
- def test_fallback_if_tranformations_config_specified(self, trans_config, use_legacy, use_new_fe, expected_path,
- fallback_reason):
- with patch('openvino.tools.mo.convert_impl.get_default_frontends') as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_legacy, use_new_fe)
- args.input_model = "test_model.onnx"
- args.transformations_config = trans_config
-
- with patch('openvino.tools.mo.utils.class_registration.apply_transform'): # skip applying transforms
- prepare_ir(args)
-
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', expected_path)
- if fallback_reason:
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
- else:
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
-
- @pytest.mark.parametrize("extension, trans_config, use_new_fe, expected_path, fallback_reason", [
- (['dir_to_extension'], 'fake_config.json', None, 'mo_legacy', 'extensions, transformations_config'), # fallback
- (None, 'fake_config.json', None, 'mo_legacy', 'transformations_config'), # fallback
- (['dir_to_extension'], None, None, 'mo_legacy', 'extensions'), # fallback
- (None, None, True, 'onnx_frontend', None)
- ])
- def test_fallback_if_both_extension_and_trans_config_specified(self, extension, trans_config, use_new_fe, expected_path, fallback_reason):
- with patch('openvino.tools.mo.convert_impl.get_default_frontends') as default_fe:
- default_fe.return_value = get_test_default_frontends()
- args = base_args_config(use_new_fe=use_new_fe)
- args.extensions = extension
- args.input_model = "test_model.onnx"
- args.transformations_config = trans_config
-
- prepare_ir(args)
-
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', expected_path)
- if fallback_reason:
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
- else:
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
-
- @pytest.mark.parametrize("trans_config, use_legacy, use_new_fe, expected_path",
- [('fake_config.json', None, None, 'mo_legacy'),
- ('fake_config.json', True, None, 'mo_legacy'),
- (None, None, True, 'onnx_frontend')])
- def test_fallback_if_legacy_set_as_default(self, trans_config, use_legacy, use_new_fe, expected_path):
- with patch('openvino.tools.mo.convert_impl.get_default_frontends') as default_fe:
- default_fe.return_value = {'onnx': 'legacy', 'tf': 'legacy'}
- args = base_args_config(use_legacy, use_new_fe)
- args.input_model = "test_model.onnx"
- args.transformations_config = trans_config
-
- prepare_ir(args)
-
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', expected_path)
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason')
-
- @pytest.mark.skipif(not paddle_imported, reason="PaddlePaddle is not installed")
- @pytest.mark.parametrize("use_new_fe, use_legacy, extension, expected_path",
- [(True, None, None, 'paddle_frontend'),
- (None, None, None, 'paddle_frontend')])
- def test_no_fallback_if_pdpd(self, use_new_fe, use_legacy, extension, expected_path):
- args = base_args_config(use_legacy, use_new_fe)
- args.framework = 'paddle'
- args.extensions = extension
- args.input_model = 'paddle_dir/relu/relu.pdmodel'
-
- prepare_ir(args)
-
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', expected_path)
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason')
-
- @pytest.mark.skipif(not paddle_imported, reason="PaddlePaddle is not installed")
- def test_exception_if_old_extensions_used_for_pdpd(self):
- args = base_args_config()
- args.framework = 'paddle'
- args.extensions = ['dir_to_extension']
- args.input_model = 'paddle_dir/relu/relu.pdmodel'
-
- with pytest.raises(Error) as ex: # not called
- prepare_ir(args)
- assert str(ex) == 'Legacy transformations configuration is not supported for the new frontend'
diff --git a/tools/mo/unit_tests/mo/utils/mo_fallback_test_tf_fe.py b/tools/mo/unit_tests/mo/utils/mo_fallback_test_tf_fe.py
deleted file mode 100644
index cb8a3339376254..00000000000000
--- a/tools/mo/unit_tests/mo/utils/mo_fallback_test_tf_fe.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import os
-import pytest
-import unittest
-from openvino.frontend import FrontEndManager, FrontEnd # pylint: disable=no-name-in-module,import-error
-from openvino.tools.mo.convert_impl import prepare_ir
-from unittest.mock import Mock
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-def base_args_config(use_legacy_fe: bool = None, use_new_fe: bool = None):
- args = argparse.Namespace()
- args.feManager = FrontEndManager()
- args.extensions = None
- args.use_legacy_frontend = use_legacy_fe
- args.use_new_frontend = use_new_fe
- args.framework = 'tf'
- args.model_name = None
- args.input_model = None
- args.silent = True
- args.transform = []
- args.scale = None
- args.output = None
- args.input = None
- args.input_shape = None
- args.batch = None
- args.mean_values = None
- args.scale_values = None
- args.output_dir = os.getcwd()
- args.freeze_placeholder_with_value = None
- args.transformations_config = None
- args.static_shape = None
- args.reverse_input_channels = None
- args.data_type = None
- args.layout = None
- args.source_layout = None
- args.target_layout = None
- args.input_model_is_text = False
- args.input_checkpoint = None
- args.saved_model_dir = None
- args.input_meta_graph = None
- args.saved_model_tags = None
- return args
-
-
-class TestMoFallback(unittest.TestCase):
- test_directory = os.path.dirname(os.path.realpath(__file__))
-
- def create_fake_json_file(self, output_dir):
- json_data = '[]' # json format
- json_path = os.path.join(output_dir, 'fake_config.json')
- with open(json_path, 'w') as f:
- f.write(json_data)
- return json_path
-
- def create_tensorflow_model_pb(self, output_dir):
- import tensorflow as tf
- try:
- import tensorflow.compat.v1 as tf_v1
- except ImportError:
- import tensorflow as tf_v1
-
- tf_v1.reset_default_graph()
- with tf_v1.Session() as sess:
- x = tf_v1.placeholder(tf.float32, [2, 3], 'x')
- y = tf_v1.placeholder(tf.float32, [2, 3], 'y')
- tf.add(x, y, name="add")
- tf_v1.global_variables_initializer()
- tf.io.write_graph(sess.graph, output_dir, 'model.pb', as_text=False)
- return os.path.join(output_dir, 'model.pb')
-
- def create_tensorflow_saved_model(self, output_dir):
- import tensorflow as tf
- inputs = tf.keras.Input(shape=(3,))
- x = tf.keras.layers.Dense(4, activation=tf.nn.relu)(inputs)
- outputs = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x)
- model = tf.keras.Model(inputs=inputs, outputs=outputs)
- model_path = os.path.join(output_dir, 'saved_model')
- model.save(model_path)
- return model_path
-
- def setUp(self):
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
- FrontEnd.add_extension = Mock()
-
- def test_transform_config_fallback_tf_fe_pb(self):
- import tempfile
- test_cases = [
- # transformation config fallback even for use_new_frontend in case TF FE
- # TODO: uncomment this case once TF FE is unbricked and obtains normal name openvino_tensorflow_frontend
- # (False, True, 'mo_legacy', 'transformations_config'),
- # no fallback since legacy FE is used
- (True, False, 'mo_legacy', None),
- # no fallback since legacy FE is default for TensorFlow
- (False, False, 'mo_legacy', None)
- ]
- for use_legacy_frontend, use_new_frontend, expected_frontend, fallback_reason in test_cases:
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmp_dir:
- args = base_args_config(use_legacy_frontend, use_new_frontend)
- model_path = self.create_tensorflow_model_pb(tmp_dir)
- args.input_model = model_path
- args.framework = 'tf'
- args.transformations_config = self.create_fake_json_file(tmp_dir)
-
- prepare_ir(args)
-
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', expected_frontend)
- if fallback_reason:
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
- else:
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
-
- def test_transform_config_fallback_tf_fe_saved_model(self):
- import tempfile
- test_cases = [
- # transformation config fallback even for use_new_frontend in case TF FE
- # TODO: uncomment this case once TF FE is unbricked and obtains normal name openvino_tensorflow_frontend
- # (False, True, 'mo_legacy', 'transformations_config'),
- # no fallback since legacy FE is used
- (True, False, 'mo_legacy', None),
- # no fallback since legacy FE is default for TensorFlow
- (False, False, 'mo_legacy', None),
- ]
- for use_legacy_frontend, use_new_frontend, expected_frontend, fallback_reason in test_cases:
- with tempfile.TemporaryDirectory(dir=self.test_directory) as tmp_dir:
- args = base_args_config(use_legacy_frontend, use_new_frontend)
- model_path = self.create_tensorflow_saved_model(tmp_dir)
- args.saved_model_dir = model_path
- args.framework = 'tf'
- args.transformations_config = self.create_fake_json_file(tmp_dir)
-
- print("args = ", args)
- prepare_ir(args)
-
- tm.Telemetry.send_event.assert_any_call('mo', 'conversion_method', expected_frontend)
- if fallback_reason:
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
- else:
- with pytest.raises(AssertionError): # not called
- tm.Telemetry.send_event.assert_any_call('mo', 'fallback_reason', fallback_reason)
diff --git a/tools/mo/unit_tests/mo/utils/pipeline_config_test.py b/tools/mo/unit_tests/mo/utils/pipeline_config_test.py
deleted file mode 100644
index 271cc7828b2cff..00000000000000
--- a/tools/mo/unit_tests/mo/utils/pipeline_config_test.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest.mock
-
-from openvino.tools.mo.utils.error import Error
-from openvino.tools.mo.utils.pipeline_config import PipelineConfig
-
-file_content = """model {
- faster_rcnn {
- num_classes: 90
- image_resizer {
- keep_aspect_ratio_resizer {
- min_dimension: 600
- max_dimension: 1024
- pad_to_max_dimension: true
- }
- }
- feature_extractor {
- type: "faster_rcnn_inception_v2"
- first_stage_features_stride: 16
- }
- first_stage_anchor_generator {
- grid_anchor_generator {
- height_stride: 16
- width_stride: 16
- scales: 0.25
- scales: 0.5
- scales: 1.0
- scales: 2.0
- aspect_ratios: 0.5
- aspect_ratios: 1.0
- aspect_ratios: 2.0
- }
- }
- first_stage_box_predictor_conv_hyperparams {
- op: CONV
- regularizer {
- l2_regularizer {
- weight: 0.0
- }
- }
- initializer {
- truncated_normal_initializer {
- stddev: 0.00999999977648
- }
- }
- }
- first_stage_nms_score_threshold: 0.0
- first_stage_nms_iou_threshold: 0.699999988079
- first_stage_max_proposals: 100
- first_stage_localization_loss_weight: 2.0
- first_stage_objectness_loss_weight: 1.0
- initial_crop_size: 14
- maxpool_kernel_size: 2
- maxpool_stride: 2
- second_stage_box_predictor {
- mask_rcnn_box_predictor {
- fc_hyperparams {
- op: FC
- regularizer {
- l2_regularizer {
- weight: 0.0
- }
- }
- initializer {
- variance_scaling_initializer {
- factor: 1.0
- uniform: true
- mode: FAN_AVG
- }
- }
- }
- use_dropout: false
- dropout_keep_probability: 1.0
- }
- }
- second_stage_post_processing {
- batch_non_max_suppression {
- score_threshold: 0.300000011921
- iou_threshold: 0.600000023842
- max_detections_per_class: 100
- max_total_detections: 200
- }
- score_converter: SOFTMAX
- }
- second_stage_localization_loss_weight: 2.0
- second_stage_classification_loss_weight: 1.0
- }
-}
-"""
-
-
-class TestingSimpleProtoParser(unittest.TestCase):
- def test_pipeline_config_not_existing_file(self):
- self.assertRaises(Error, PipelineConfig, "/abc/def")
-
- def test_pipeline_config_non_model_file(self):
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data="non_model {}")):
- self.assertRaises(Error, PipelineConfig, __file__)
-
- def test_pipeline_config_existing_file(self):
- with unittest.mock.patch('builtins.open', unittest.mock.mock_open(read_data=file_content)):
- pipeline_config = PipelineConfig(__file__)
- expected_result = {'resizer_min_dimension': 600,
- 'first_stage_nms_score_threshold': 0.0,
- 'anchor_generator_aspect_ratios': [0.5, 1.0, 2.0],
- 'num_classes': 90,
- 'anchor_generator_scales': [0.25, 0.5, 1.0, 2.0],
- 'first_stage_max_proposals': 100,
- 'first_stage_nms_iou_threshold': 0.699999988079,
- 'resizer_max_dimension': 1024,
- 'initial_crop_size': 14,
- 'frcnn_variance_height': 5.0,
- 'frcnn_variance_width': 5.0,
- 'frcnn_variance_x': 10.0,
- 'frcnn_variance_y': 10.0,
- 'ssd_anchor_generator_base_anchor_width': 1.0,
- 'ssd_anchor_generator_base_anchor_height': 1.0,
- 'anchor_generator_height': 256,
- 'anchor_generator_width': 256,
- 'anchor_generator_height_stride': 16,
- 'anchor_generator_width_stride': 16,
- 'ssd_anchor_generator_min_scale': 0.2,
- 'ssd_anchor_generator_max_scale': 0.95,
- 'ssd_anchor_generator_interpolated_scale_aspect_ratio': 1.0,
- 'use_matmul_crop_and_resize': False,
- 'add_background_class': True,
- 'share_box_across_classes': False,
- 'pad_to_max_dimension': True,
- 'postprocessing_score_threshold': 0.300000011921,
- 'postprocessing_score_converter': 'SOFTMAX',
- 'postprocessing_iou_threshold': 0.600000023842,
- 'postprocessing_max_detections_per_class': 100,
- 'postprocessing_max_total_detections': 200,
- }
- self.assertDictEqual(pipeline_config._model_params, expected_result)
diff --git a/tools/mo/unit_tests/mo/utils/simple_proto_parser_test.py b/tools/mo/unit_tests/mo/utils/simple_proto_parser_test.py
deleted file mode 100644
index c3964d8a58945a..00000000000000
--- a/tools/mo/unit_tests/mo/utils/simple_proto_parser_test.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import sys
-import tempfile
-import unittest
-
-from openvino.tools.mo.utils.simple_proto_parser import SimpleProtoParser
-
-correct_proto_message_1 = 'model { faster_rcnn { num_classes: 90 image_resizer { keep_aspect_ratio_resizer {' \
- ' min_dimension: 600 max_dimension: 1024 }}}}'
-
-correct_proto_message_2 = ' first_stage_anchor_generator {grid_anchor_generator {height_stride: 16 width_stride:' \
- ' 16 scales: 0.25 scales: 0.5 scales: 1.0 scales: 2.0 aspect_ratios: 0.5 aspect_ratios:' \
- ' 1.0 aspect_ratios: 2.0}}'
-
-correct_proto_message_3 = ' initializer \n{variance_scaling_initializer \n{\nfactor: 1.0 uniform: true bla: false ' \
- 'mode: FAN_AVG}}'
-
-correct_proto_message_4 = 'train_input_reader {label_map_path: "PATH_TO_BE_CONFIGURED/mscoco_label_map.pbtxt"' \
- ' tf_record_input_reader { input_path: "PATH_TO_BE_CONFIGURED/ mscoco_train.record" }}'
-
-correct_proto_message_5 = ' initializer \n # abc \n{variance_scaling_initializer \n{\nfactor: 1.0 \n # sd ' \
- '\nuniform: true bla: false mode: FAN_AVG}}'
-
-correct_proto_message_6 = ' first_stage_anchor_generator {grid_anchor_generator {height_stride: 16 width_stride:' \
- ' 16 scales: [ 0.25, 0.5, 1.0, 2.0] aspect_ratios: 0.5 aspect_ratios:' \
- ' 1.0 aspect_ratios: 2.0}}'
-
-correct_proto_message_7 = ' first_stage_anchor_generator {grid_anchor_generator {height_stride: 16 width_stride:' \
- ' 16 scales: [ 0.25, 0.5, 1.0, 2.0] aspect_ratios: [] }}'
-
-correct_proto_message_8 = 'model {good_list: [3.0, 5.0, ]}'
-
-correct_proto_message_9 = ' first_stage_anchor_generator {grid_anchor_generator {height_stride: 16, width_stride:' \
- ' 16 scales: [ 0.25, 0.5, 1.0, 2.0], aspect_ratios: [] }}'
-
-correct_proto_message_10 = r'train_input_reader {label_map_path: "C:\mscoco_label_map.pbtxt"' \
- ' tf_record_input_reader { input_path: "PATH_TO_BE_CONFIGURED/ mscoco_train.record" }}'
-
-correct_proto_message_11 = r'model {path: "C:\[{],}" other_value: [1, 2, 3, 4]}'
-
-incorrect_proto_message_1 = 'model { bad_no_value }'
-
-incorrect_proto_message_2 = 'model { abc: 3 { }'
-
-incorrect_proto_message_3 = 'model { too_many_values: 3 4 }'
-
-incorrect_proto_message_4 = 'model { missing_values: '
-
-incorrect_proto_message_5 = 'model { missing_values: aa bb : }'
-
-incorrect_proto_message_6 = 'model : '
-
-incorrect_proto_message_7 = 'model : {bad_list: [3.0, 4, , 4.0]}'
-
-
-class TestingSimpleProtoParser(unittest.TestCase):
- def test_correct_proto_reader_from_string_1(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_1)
- expected_result = {'model': {'faster_rcnn': {'num_classes': 90, 'image_resizer': {
- 'keep_aspect_ratio_resizer': {'min_dimension': 600, 'max_dimension': 1024}}}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_2(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_2)
- expected_result = {'first_stage_anchor_generator': {
- 'grid_anchor_generator': {'height_stride': 16, 'width_stride': 16, 'scales': [0.25, 0.5, 1.0, 2.0],
- 'aspect_ratios': [0.5, 1.0, 2.0]}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_3(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_3)
- expected_result = {
- 'initializer': {
- 'variance_scaling_initializer': {'factor': 1.0, 'uniform': True, 'bla': False, 'mode': 'FAN_AVG'}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_4(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_4)
- expected_result = {
- 'train_input_reader': {'label_map_path': "PATH_TO_BE_CONFIGURED/mscoco_label_map.pbtxt",
- 'tf_record_input_reader': {
- 'input_path': "PATH_TO_BE_CONFIGURED/ mscoco_train.record"}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_comments(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_5)
- expected_result = {
- 'initializer': {
- 'variance_scaling_initializer': {'factor': 1.0, 'uniform': True, 'bla': False, 'mode': 'FAN_AVG'}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_lists(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_6)
- expected_result = {'first_stage_anchor_generator': {
- 'grid_anchor_generator': {'height_stride': 16, 'width_stride': 16, 'scales': [0.25, 0.5, 1.0, 2.0],
- 'aspect_ratios': [0.5, 1.0, 2.0]}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_empty_list(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_7)
- expected_result = {'first_stage_anchor_generator': {
- 'grid_anchor_generator': {'height_stride': 16, 'width_stride': 16, 'scales': [0.25, 0.5, 1.0, 2.0],
- 'aspect_ratios': []}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_comma_trailing_list(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_8)
- expected_result = {'model': {'good_list': [3.0, 5.0]}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_redundant_commas(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_9)
- expected_result = {'first_stage_anchor_generator': {
- 'grid_anchor_generator': {'height_stride': 16, 'width_stride': 16, 'scales': [0.25, 0.5, 1.0, 2.0],
- 'aspect_ratios': []}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_windows_path(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_10)
- expected_result = {
- 'train_input_reader': {'label_map_path': r"C:\mscoco_label_map.pbtxt",
- 'tf_record_input_reader': {
- 'input_path': "PATH_TO_BE_CONFIGURED/ mscoco_train.record"}}}
- self.assertDictEqual(result, expected_result)
-
- def test_correct_proto_reader_from_string_with_special_characters_in_string(self):
- result = SimpleProtoParser().parse_from_string(correct_proto_message_11)
- expected_result = {'model': {'path': r"C:\[{],}",
- 'other_value': [1, 2, 3, 4]}}
- self.assertDictEqual(result, expected_result)
-
- @unittest.skip
- def test_incorrect_proto_reader_from_string_1(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_1)
- self.assertIsNone(result)
-
- def test_incorrect_proto_reader_from_string_2(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_2)
- self.assertIsNone(result)
-
- def test_incorrect_proto_reader_from_string_3(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_3)
- self.assertIsNone(result)
-
- def test_incorrect_proto_reader_from_string_4(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_4)
- self.assertIsNone(result)
-
- def test_incorrect_proto_reader_from_string_5(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_5)
- self.assertIsNone(result)
-
- def test_incorrect_proto_reader_from_string_6(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_6)
- self.assertIsNone(result)
-
- def test_incorrect_proto_reader_from_string_7(self):
- result = SimpleProtoParser().parse_from_string(incorrect_proto_message_7)
- self.assertIsNone(result)
-
- def test_correct_proto_reader_from_file(self):
- file = tempfile.NamedTemporaryFile('wt', delete=False)
- file.write(correct_proto_message_1)
- file_name = file.name
- file.close()
-
- result = SimpleProtoParser().parse_file(file_name)
- expected_result = {'model': {'faster_rcnn': {'num_classes': 90, 'image_resizer': {
- 'keep_aspect_ratio_resizer': {'min_dimension': 600, 'max_dimension': 1024}}}}}
- self.assertDictEqual(result, expected_result)
- os.unlink(file_name)
-
- @unittest.skip("Temporary disabled since chmod() is temporary not working on Linux. (Windows do not support not writable dir at all)")
- def test_proto_reader_from_non_readable_file(self):
- file = tempfile.NamedTemporaryFile('wt', delete=False)
- file.write(correct_proto_message_1)
- file_name = file.name
- file.close()
- os.chmod(file_name, 0000)
-
- result = SimpleProtoParser().parse_file(file_name)
- self.assertIsNone(result)
- os.unlink(file_name)
-
- def test_proto_reader_from_non_existing_file(self):
- result = SimpleProtoParser().parse_file('/non/existing/file')
- self.assertIsNone(result)
diff --git a/tools/mo/unit_tests/mo/utils/summarize_graph_test.py b/tools/mo/unit_tests/mo/utils/summarize_graph_test.py
deleted file mode 100644
index d9076d7e42cdb9..00000000000000
--- a/tools/mo/unit_tests/mo/utils/summarize_graph_test.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch, mock_open
-
-from openvino.tools.mo.front.tf.loader import load_tf_graph_def
-from openvino.tools.mo.utils.summarize_graph import summarize_graph
-
-pbtxt = 'node{name:"Placeholder"op:"Placeholder"attr{key:"dtype"value{type:DT_FLOAT}}attr{key:"shape"value{shape{dim' + \
- '{size:1}dim{size:227}dim{size:227}dim{size:3}}}}}node{name:"Output/Identity"op:"Identity"input:"Placeholder' + \
- '"attr{key:"T"value{type:DT_FLOAT}}}'
-
-
-class TestingSummarizeGraph(unittest.TestCase):
- def test_summarize_graph(self):
- with patch('openvino.tools.mo.front.tf.loader.open', mock_open(read_data=pbtxt)) as m:
- graph_def, _, _, _ = load_tf_graph_def('path', False)
- summary = summarize_graph(graph_def)
- self.assertEqual(len(summary['outputs']), 1)
- self.assertEqual(summary['outputs'][0], 'Output/Identity')
- self.assertEqual(len(summary['inputs']), 1)
- self.assertEqual('Placeholder' in summary['inputs'], True)
- self.assertEqual(str(summary['inputs']['Placeholder']['shape']), '(1,227,227,3)')
- self.assertEqual(str(summary['inputs']['Placeholder']['type']), 'float32')
diff --git a/tools/mo/unit_tests/mo/utils/telemetry_utils_test.py b/tools/mo/unit_tests/mo/utils/telemetry_utils_test.py
deleted file mode 100644
index c2021430eddd17..00000000000000
--- a/tools/mo/unit_tests/mo/utils/telemetry_utils_test.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from collections import Counter
-from unittest.mock import Mock
-
-from openvino.tools.mo.front.common.partial_infer.utils import int64_array, shape_array, dynamic_dimension_value
-from openvino.tools.mo.graph.graph import Graph, Node
-from openvino.tools.mo.utils.telemetry_utils import send_op_names_info, send_shapes_info
-from unit_tests.utils.graph import build_graph, regular_op
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-class TestTelemetryUtils(unittest.TestCase):
- @staticmethod
- def init_telemetry_mocks():
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
-
- def test_send_op_names_info(self):
- graph = Graph()
- graph.add_nodes_from(['node1'])
- graph.op_names_statistic = Counter(['a', 'a', 'a', 'b', 'b'])
-
- sub_graph1 = Graph()
- sub_graph1.add_nodes_from(['node2'])
- sub_graph1.op_names_statistic = Counter(['a', 'c', 'c'])
-
- sub_graph2 = Graph()
- sub_graph2.op_names_statistic = Counter(['a', 'd'])
-
- node1 = Node(graph, 'node1')
- node1['sub_graphs'] = ['sub_graph1']
- node1['sub_graph1'] = sub_graph1
-
- node2 = Node(sub_graph1, 'node2')
- node2['sub_graphs'] = ['sub_graph2']
- node2['sub_graph2'] = sub_graph2
-
- self.init_telemetry_mocks()
-
- send_op_names_info('framework', graph)
- tm.Telemetry.send_event.assert_any_call('mo', 'op_count', 'framework_a', 5)
- tm.Telemetry.send_event.assert_any_call('mo', 'op_count', 'framework_b', 2)
- tm.Telemetry.send_event.assert_any_call('mo', 'op_count', 'framework_c', 2)
- tm.Telemetry.send_event.assert_any_call('mo', 'op_count', 'framework_d', 1)
-
- def test_send_shapes_info(self):
- graph = build_graph({**regular_op('placeholder1', {'shape': int64_array([1, 3, 20, 20]), 'type': 'Parameter'}),
- **regular_op('placeholder2', {'shape': int64_array([2, 4, 10]), 'type': 'Parameter'}),
- **regular_op('mul', {'shape': int64_array([7, 8]), 'type': 'Multiply'})}, [])
-
- self.init_telemetry_mocks()
-
- send_shapes_info('framework', graph)
- tm.Telemetry.send_event.assert_any_call('mo', 'input_shapes', '{fw:framework,shape:"[ 1 3 20 20],[ 2 4 10]"}')
- tm.Telemetry.send_event.assert_any_call('mo', 'partially_defined_shape',
- '{partially_defined_shape:0,fw:framework}')
-
- def test_send_dynamic_shapes_case1(self):
- graph = build_graph({**regular_op('placeholder1', {'shape': shape_array([dynamic_dimension_value, 3, 20, 20]),
- 'type': 'Parameter'}),
- **regular_op('mul', {'shape': int64_array([7, 8]), 'type': 'Multiply'})}, [])
-
- self.init_telemetry_mocks()
-
- send_shapes_info('framework', graph)
- tm.Telemetry.send_event.assert_any_call('mo', 'input_shapes', '{fw:framework,shape:"[-1 3 20 20]"}')
- tm.Telemetry.send_event.assert_any_call('mo', 'partially_defined_shape',
- '{partially_defined_shape:1,fw:framework}')
-
- def test_send_undefined_shapes(self):
- graph = build_graph({**regular_op('placeholder1', {'shape': None,
- 'type': 'Parameter'}),
- **regular_op('mul', {'shape': int64_array([7, 8]), 'type': 'Multiply'})}, [])
-
- self.init_telemetry_mocks()
-
- send_shapes_info('framework', graph)
- tm.Telemetry.send_event.assert_any_call('mo', 'input_shapes', '{fw:framework,shape:"Undefined"}')
- tm.Telemetry.send_event.assert_any_call('mo', 'partially_defined_shape',
- '{partially_defined_shape:1,fw:framework}')
-
- def test_send_dynamic_shapes_case2(self):
- graph = build_graph({**regular_op('placeholder1', {'shape': int64_array([2, 3, 20, 20]), 'type': 'Parameter'}),
- **regular_op('placeholder2', {'shape': int64_array([7, 4, 10]), 'type': 'Parameter'}),
- **regular_op('placeholder3', {'shape': shape_array([5, 4, dynamic_dimension_value]),
- 'type': 'Parameter'}),
- **regular_op('mul', {'shape': int64_array([7, 8]), 'type': 'Multiply'})}, [])
-
- self.init_telemetry_mocks()
-
- send_shapes_info('framework', graph)
- tm.Telemetry.send_event.assert_any_call('mo', 'input_shapes',
- '{fw:framework,shape:"[ 2 3 20 20],[ 7 4 10],[ 5 4 -1]"}')
- tm.Telemetry.send_event.assert_any_call('mo', 'partially_defined_shape',
- '{partially_defined_shape:1,fw:framework}')
diff --git a/tools/mo/unit_tests/mo/utils/test_mo_model_analysis_actual.py b/tools/mo/unit_tests/mo/utils/test_mo_model_analysis_actual.py
deleted file mode 100644
index b8ed4f19b9f462..00000000000000
--- a/tools/mo/unit_tests/mo/utils/test_mo_model_analysis_actual.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# Copyright (C) 2022 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-from unittest.mock import patch, Mock
-import onnx
-from onnx.helper import make_graph, make_model, make_tensor_value_info
-import os
-from os import environ
-import json
-import argparse
-from openvino.tools.mo.convert_impl import prepare_ir
-from openvino.frontend import FrontEndManager # pylint: disable=no-name-in-module,import-error
-
-
-try:
- import openvino_telemetry as tm
- from openvino_telemetry.backend import backend_ga4
-except ImportError:
- import openvino.tools.mo.utils.telemetry_stub as tm
-
-
-def base_args_config():
- args = argparse.Namespace()
- args.feManager = FrontEndManager()
- args.extensions = None
- args.use_legacy_frontend = False
- args.use_new_frontend = True
- args.framework = 'onnx'
- args.model_name = None
- args.input_model = None
- args.input_checkpoint = None
- args.silent = True
- args.transform=[]
- args.scale = None
- args.output=None
- args.input=None
- args.input_shape=None
- args.batch=None
- args.mean_values=None
- args.scale_values=None
- args.output_dir=os.getcwd()
- args.freeze_placeholder_with_value = None
- args.transformations_config = None
- args.static_shape = None
- args.reverse_input_channels = None
- args.data_type = None
- args.layout = None
- args.source_layout = None
- args.target_layout = None
- args.frontend_defaults = {
- 'onnx': 'legacy',
- 'tf': 'legacy'
- }
- return args
-
-
-class TestMoFallback(unittest.TestCase):
- def setUp(self):
- environ.update({'MO_ENABLED_TRANSFORMS': 'ANALYSIS_JSON_PRINT'})
-
- tm.Telemetry.__init__ = Mock(return_value=None)
- tm.Telemetry.send_event = Mock()
-
- self.models = {}
- add = onnx.helper.make_node("Add", inputs=["in1", "in2"], outputs=["add_out"])
- input_tensors = [
- make_tensor_value_info("in1", onnx.TensorProto.FLOAT, (1, 2)),
- make_tensor_value_info("in2", onnx.TensorProto.FLOAT, (1, 2)),
- ]
- output_tensors = [
- make_tensor_value_info("add_out", onnx.TensorProto.FLOAT, (1, 2)),
- ]
- graph = make_graph([add], "test_graph", input_tensors, output_tensors)
- model = make_model(graph, producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)])
- self.models["test_model.onnx"] = model
-
- input_tensors_2 = [
- make_tensor_value_info("in1", onnx.TensorProto.INT64, (1, 'dyn_dim', 3)),
- make_tensor_value_info("in2", onnx.TensorProto.INT64, None),
- make_tensor_value_info("in3", onnx.TensorProto.INT64, ()),
- ]
- output_tensors_2 = [
- make_tensor_value_info("mul_out", onnx.TensorProto.FLOAT, None),
- ]
- mul = onnx.helper.make_node("Mul", inputs=["add_out", "in3"], outputs=["mul_out"])
- graph_2 = make_graph([add, mul], "test_graph_2", input_tensors_2, output_tensors_2)
- model_2 = make_model(graph_2, producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)])
- self.models["test_model_2.onnx"] = model_2
-
- split_1 = onnx.helper.make_node("Split", inputs=["add_out"],
- outputs=["out1", "out2"], axis=0)
- split_2 = onnx.helper.make_node("Split", inputs=["mul_out"],
- outputs=["out3", "out4"], axis=0)
- output_tensors_3 = [
- make_tensor_value_info("out1", onnx.TensorProto.FLOAT, 'dyn_dim'),
- make_tensor_value_info("out2", onnx.TensorProto.FLOAT, 'dyn_dim'),
- make_tensor_value_info("out3", onnx.TensorProto.FLOAT, 'dyn_dim'),
- make_tensor_value_info("out4", onnx.TensorProto.FLOAT, 'dyn_dim'),
- ]
- graph_3 = make_graph([add, mul, split_1, split_2], "test_graph_3", input_tensors_2, output_tensors_3)
- model_3 = make_model(graph_3, producer_name="MO tests",
- opset_imports=[onnx.helper.make_opsetid("", 13)])
- self.models["test_model_3.onnx"] = model_3
-
- for name, model in self.models.items():
- onnx.save(model, name)
-
- def tearDown(self):
- del environ['MO_ENABLED_TRANSFORMS']
- for name in self.models.keys():
- os.remove(name)
-
-
- @patch('openvino.tools.mo.moc_frontend.analysis.json_model_analysis_print')
- def test_model(self, json_print):
- args = base_args_config()
- args.input_model = "test_model.onnx"
-
- with patch('sys.exit') as exit_mock: # do not exit execution
- prepare_ir(args)
-
- result = json_print.call_args.args[0]
-
- assert 'inputs' in result
- assert result['inputs'] == json.loads('{"in1": {"shape": [1, 2], "data_type": "float32", "value": "None"}, \
- "in2": {"shape": [1, 2], "data_type": "float32", "value": "None"}}')
-
- assert 'intermediate' in result
- assert result['intermediate'] == json.loads('{"in1": {"shape": [1, 2], "data_type": "float32", "value": "None"}, \
- "in2": {"shape": [1, 2], "data_type": "float32", "value": "None"}, \
- "add_out": {"shape": "None", "data_type": "None", "value": "None"}}')
-
-
- @patch('openvino.tools.mo.moc_frontend.analysis.json_model_analysis_print')
- def test_model_with_dyn_shapes(self, json_print):
- args = base_args_config()
- args.input_model = "test_model_2.onnx"
-
- with patch('sys.exit') as exit_mock: # do not exit execution
- prepare_ir(args)
-
- result = json_print.call_args.args[0]
-
- assert 'inputs' in result
- print(result['inputs'])
- assert result['inputs'] == json.loads('{"in1": {"shape": [1, 0, 3], "data_type": "int64", "value": "None"}, \
- "in2": {"shape": "None", "data_type": "int64", "value": "None"}, \
- "in3": {"shape": [], "data_type": "int64", "value": "None"}}')
-
- assert 'intermediate' in result
- assert result['intermediate'] == json.loads('{"in1": {"shape": [1, 0, 3], "data_type": "int64", "value": "None"}, \
- "in2": {"shape": "None", "data_type": "int64", "value": "None"}, \
- "in3": {"shape": [], "data_type": "int64", "value": "None"}, \
- "mul_out": {"shape": "None", "data_type": "None", "value": "None"}, \
- "add_out": {"shape": "None", "data_type": "None", "value": "None"}}')
-
-
- @patch('openvino.tools.mo.moc_frontend.analysis.json_model_analysis_print')
- def test_multi_outputs_model(self, json_print):
- args = base_args_config()
- args.input_model = "test_model_3.onnx"
-
- with patch('sys.exit') as exit_mock: # do not exit execution
- prepare_ir(args)
-
- result = json_print.call_args.args[0]
-
- assert 'inputs' in result
- assert result['inputs'] == json.loads('{"in1": {"shape": [1, 0, 3], "data_type": "int64", "value": "None"}, \
- "in2": {"shape": "None", "data_type": "int64", "value": "None"}, \
- "in3": {"shape": [], "data_type": "int64", "value": "None"}}')
-
- assert 'intermediate' in result
- assert result['intermediate'] == json.loads('{"in1": {"shape": [1, 0, 3], "data_type": "int64", "value": "None"}, \
- "in2": {"shape": "None", "data_type": "int64", "value": "None"}, \
- "in3": {"shape": [], "data_type": "int64", "value": "None"}, \
- "mul_out": {"shape": "None", "data_type": "None", "value": "None"}, \
- "add_out": {"shape": "None", "data_type": "None", "value": "None"}, \
- "out1": {"shape": "None", "data_type": "None", "value": "None"}, \
- "out2": {"shape": "None", "data_type": "None", "value": "None"}, \
- "out3": {"shape": "None", "data_type": "None", "value": "None"}, \
- "out4": {"shape": "None", "data_type": "None", "value": "None"}}')
diff --git a/tools/mo/unit_tests/mo/utils/utils_test.py b/tools/mo/unit_tests/mo/utils/utils_test.py
deleted file mode 100644
index 3b534c502112eb..00000000000000
--- a/tools/mo/unit_tests/mo/utils/utils_test.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import unittest
-
-from openvino.tools.mo.front.common.partial_infer.utils import shape_array, dynamic_dimension_value
-from openvino.tools.mo.utils.utils import match_shapes
-
-
-class TestMatchShapes(unittest.TestCase):
- def run_match_shapes(self, pattern: list, shape: list):
- return match_shapes(shape_array(pattern), shape_array(shape))
-
- def test_positive(self):
- self.assertTrue(self.run_match_shapes([], []))
- self.assertTrue(self.run_match_shapes([1, 2, 3], [1, 2, 3]))
- self.assertTrue(self.run_match_shapes([dynamic_dimension_value, 2, 3], [1, 2, 3]))
- self.assertTrue(self.run_match_shapes([1, dynamic_dimension_value, 3], [1, 2, 3]))
- self.assertTrue(self.run_match_shapes([dynamic_dimension_value, dynamic_dimension_value,
- dynamic_dimension_value], [1, 2, 3]))
- self.assertTrue(self.run_match_shapes([dynamic_dimension_value], [2]))
-
- def test_negative(self):
- self.assertFalse(self.run_match_shapes([dynamic_dimension_value], []))
- self.assertFalse(self.run_match_shapes([dynamic_dimension_value], [1, 2, 3]))
- self.assertFalse(self.run_match_shapes([dynamic_dimension_value, 2, 3], [1, 3, 3]))
- self.assertFalse(self.run_match_shapes([1, dynamic_dimension_value, 3], [2, 2]))
- self.assertFalse(self.run_match_shapes([dynamic_dimension_value, dynamic_dimension_value,
- dynamic_dimension_value], [2, 3, 4, 5]))
diff --git a/tools/mo/unit_tests/mo/utils/version_test.py b/tools/mo/unit_tests/mo/utils/version_test.py
deleted file mode 100644
index 6d94ebc4fd7174..00000000000000
--- a/tools/mo/unit_tests/mo/utils/version_test.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import subprocess
-import sys
-import unittest
-import unittest.mock as mock
-from unittest.mock import mock_open
-from unittest.mock import patch
-
-from openvino.tools.mo.subprocess_main import setup_env
-from openvino.tools.mo.utils.version import get_version, extract_release_version, get_simplified_ie_version, \
- get_simplified_mo_version, extract_hash_from_version, VersionChecker
-
-
-class TestingVersion(unittest.TestCase):
- @patch('os.path.isfile')
- @mock.patch('builtins.open', new_callable=mock_open, create=True, read_data='2021.1.0-1028-55e4d5673a8')
- def test_get_version(self, mock_open, mock_isfile):
- mock_isfile.return_value = True
- mock_open.return_value.__enter__ = mock_open
- self.assertEqual(get_version(), '2021.1.0-1028-55e4d5673a8')
-
- @patch('os.path.isfile')
- @mock.patch('builtins.open', new_callable=mock_open, create=True, read_data='2021.1.0-1028-55e4d5673a8')
- def test_release_version_extractor(self, mock_open, mock_isfile):
- mock_isfile.return_value = True
- mock_open.return_value.__enter__ = mock_open
- self.assertEqual(extract_release_version(get_version()), ('2021', '1'))
-
- @patch('os.path.isfile')
- @mock.patch('builtins.open', new_callable=mock_open, create=True, read_data='custom_releases/2021/1_55e4d5673a8')
- def test_custom_release_version_extractor(self, mock_open, mock_isfile):
- mock_isfile.return_value = True
- mock_open.return_value.__enter__ = mock_open
- self.assertEqual(extract_release_version(get_version()), ('2021', '1'))
-
- @patch('os.path.isfile')
- @mock.patch('builtins.open', new_callable=mock_open, create=True, read_data='custom_my_branch/fix_55e4d5673a8')
- def test_release_version_extractor_neg(self, mock_open, mock_isfile):
- mock_isfile.return_value = True
- mock_open.return_value.__enter__ = mock_open
- self.assertEqual(extract_release_version(get_version()), (None, None))
-
- @patch('os.path.isfile')
- @mock.patch('builtins.open', new_callable=mock_open, create=True, read_data='custom_releases/2021/1_55e4d5673a8')
- def test_simplify_mo_version_release(self, mock_open, mock_isfile):
- mock_isfile.return_value = True
- mock_open.return_value.__enter__ = mock_open
- self.assertEqual(get_simplified_mo_version(), "2021.1")
-
- @patch('os.path.isfile')
- @mock.patch('builtins.open', new_callable=mock_open, create=True, read_data='custom_my_branch/fix_55e4d5673a8')
- def test_simplify_mo_version_custom(self, mock_open, mock_isfile):
- mock_isfile.return_value = True
- mock_open.return_value.__enter__ = mock_open
- self.assertEqual(get_simplified_mo_version(), "custom")
-
- def test_simplify_ie_version_release_legacy(self):
- self.assertEqual(get_simplified_ie_version(version="2.1.custom_releases/2021/3_4c8eae"), "2021.3")
-
- def test_simplify_ie_version_release(self):
- self.assertEqual(get_simplified_ie_version(version="custom_releases/2021/3_4c8eae"), "2021.3")
-
- def test_simplify_ie_version_custom_legacy(self):
- self.assertEqual(get_simplified_ie_version(version="2.1.custom_my/branch/3_4c8eae"), "custom")
-
- def test_simplify_ie_version_custom(self):
- self.assertEqual(get_simplified_ie_version(version="custom_my/branch/3_4c8eae"), "custom")
-
- def test_extracting_version_hash_full_with_build_number(self):
- self.assertEqual(extract_hash_from_version(full_version="2021.1.0-1028-55e4d5673a8"), "55e4d5673a8")
-
- def test_extracting_version_hash_full_with_build_number_dirty(self):
- self.assertEqual(extract_hash_from_version(full_version="2021.1.0-1028-55e4d5673a8-dirty"), "55e4d5673a8")
-
- def test_extracting_version_hash_full_with_build_number_private(self):
- self.assertEqual(extract_hash_from_version(full_version="2021.1.0-1028-55e4d5673a8-private"), "55e4d5673a8")
-
- def test_extracting_version_hash_custom_master(self):
- self.assertEqual(extract_hash_from_version(full_version="custom_master_55e4d5673a833abab638ee9837bc87a0b7c3a043"),
- "55e4d5673a833abab638ee9837bc87a0b7c3a043")
-
- def test_extracting_version_hash_mo_format(self):
- self.assertEqual(extract_hash_from_version(full_version="2022.1.custom_master_55e4d5673a833abab638ee9837bc87a0b7c3a043"),
- "55e4d5673a833abab638ee9837bc87a0b7c3a043")
-
- def test_negative_extracting_version_hash(self):
- self.assertEqual(extract_hash_from_version(full_version="2022.1.custom_master"),
- None)
-
- # format from the current nightly wheel
- def test_extracting_version_hash_from_old_format(self):
- self.assertEqual(extract_hash_from_version(full_version="2022.1.0-6311-a90bb1f"),
- "a90bb1f")
-
- def test_version_checker(self):
- setup_env()
- args = [sys.executable, '-m', 'pytest',
- os.path.join(os.path.dirname(os.path.dirname(__file__)), 'convert/version_checker_test_actual.py'), '-s']
-
- status = subprocess.run(args, env=os.environ, capture_output=True)
- assert not status.returncode
diff --git a/tools/mo/unit_tests/moc_tf_fe/__init__.py b/tools/mo/unit_tests/moc_tf_fe/__init__.py
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py b/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py
deleted file mode 100644
index 94729c0e8028db..00000000000000
--- a/tools/mo/unit_tests/moc_tf_fe/check_info_messages_test.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import argparse
-import io
-import os
-import unittest
-from contextlib import redirect_stdout
-from unittest.mock import patch
-
-from openvino.tools.mo.main import main
-from openvino.tools.mo.utils.get_ov_update_message import get_compression_message, \
- get_try_legacy_fe_message
-
-
-def arg_parse_helper(input_model,
- use_legacy_frontend,
- use_new_frontend,
- input_model_is_text,
- framework,
- compress_to_fp16=False,
- freeze_placeholder_with_value=None):
- path = os.path.dirname(__file__)
- input_model = os.path.join(path, "test_models", input_model)
-
- return argparse.Namespace(
- input_model=input_model,
- use_legacy_frontend=use_legacy_frontend,
- use_new_frontend=use_new_frontend,
- framework=framework,
- input_model_is_text=input_model_is_text,
- log_level='INFO',
- silent=True,
- model_name=None,
- transform=[],
- scale=None,
- output=None,
- input=None,
- input_shape=None,
- batch=None,
- input_checkpoint=None,
- saved_model_dir=None,
- input_meta_graph=None,
- saved_model_tags=None,
- output_dir='.',
- mean_values=(),
- scale_values=(),
- layout={},
- source_layout={},
- target_layout={},
- freeze_placeholder_with_value=freeze_placeholder_with_value,
- data_type=None,
- tensorflow_custom_operations_config_update=None,
- compress_to_fp16=compress_to_fp16,
- extensions=None,
- static_shape=False
- )
-
-
-class TestInfoMessagesTFFE(unittest.TestCase):
- @patch('openvino.tools.mo.convert_impl.driver', side_effect=Exception('MESSAGE'))
- def run_fail_tf_fe(self, mock_driver):
- from openvino.tools.mo import convert_model
- path = os.path.dirname(__file__)
- convert_model(os.path.join(path, "test_models", "model_int32.pbtxt"), silent=False)
-
- def test_suggest_legacy_fe(self):
- f = io.StringIO()
- with redirect_stdout(f):
- try:
- self.run_fail_tf_fe()
- except:
- pass
- std_out = f.getvalue()
- assert get_try_legacy_fe_message() in std_out
-
-
-class TestInfoMessagesCompressFP16(unittest.TestCase):
- @patch('argparse.ArgumentParser.parse_args',
- return_value=arg_parse_helper(input_model="model_int32.pbtxt",
- use_legacy_frontend=False, use_new_frontend=True,
- compress_to_fp16=True,
- framework=None, input_model_is_text=True))
- def test_compress_to_fp16(self, mock_argparse):
- f = io.StringIO()
- with redirect_stdout(f):
- main(argparse.ArgumentParser())
- std_out = f.getvalue()
- fp16_compression_message_found = get_compression_message() in std_out
- assert fp16_compression_message_found
diff --git a/tools/mo/unit_tests/moc_tf_fe/conversion_basic_models_test.py b/tools/mo/unit_tests/moc_tf_fe/conversion_basic_models_test.py
deleted file mode 100644
index 598a26218eb1a0..00000000000000
--- a/tools/mo/unit_tests/moc_tf_fe/conversion_basic_models_test.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import os
-import unittest
-from openvino.runtime import Core
-from openvino.tools.mo.convert import convert_model
-from sys import platform
-
-# TODO: Segfault on CPU CVS-154874
-@unittest.skip("Segfault on CPU CVS-154874")
-class TestMoFreezePlaceholderTFFE(unittest.TestCase):
- def basic(self, input_model, argv_input, inputs, dtype, expected, freeze_placeholder_with_value=None,
- input_shape=None, only_conversion=False, input_model_is_text=True, use_new_frontend=True,
- use_legacy_frontend=False):
- path = os.path.dirname(__file__)
- input_model = os.path.join(path, "test_models", input_model)
-
- try:
- model = convert_model(input_model, input=argv_input,
- freeze_placeholder_with_value=freeze_placeholder_with_value,
- input_shape=input_shape, input_model_is_text=input_model_is_text,
- use_new_frontend=use_new_frontend, use_legacy_frontend=use_legacy_frontend,
- framework="tf")
- except Exception as ex:
- self.fail("Model conversion failed due to error: {}".format(ex))
-
- if only_conversion:
- return
-
- ie = Core()
- exec_net = ie.compile_model(model, "CPU")
- req = exec_net.create_infer_request()
- results = req.infer(inputs)
- values = list(results.values())[0]
- if dtype is not None:
- assert values.dtype == dtype
- assert np.allclose(values, expected)
-
- def test_fp32(self):
- test_cases = [
- (
- "in1[1 4]->[1.0 2.0 3.0 4.0],in2[1 4]{f32}->[1.0 2.0 3.0 4.0]",
- {},
- np.array([2.0, 4.0, 6.0, 8.0]),
- np.float32,
- ),
- (
- "in2{f32}->[0.0 0.0 0.0 0.0]",
- {"in1:0": np.array([[1.0, 2.0], [3.0, 4.0]])},
- np.array([[1.0, 2.0], [3.0, 4.0]]),
- np.float32,
- ),
- (
- "in2->[1.0 15.0 15.5 1.0]",
- {"in1:0": np.array([[2.0, 4.0], [12.0, 8.0]])},
- np.array([[3.0, 19.0], [27.5, 9.0]]),
- np.float32,
- ),
- (
- "in1[1 4]{i32}->[1 2 3 4],in2[1 4]{i32}->[1 2 3 4]",
- {},
- np.array([2.0, 4.0, 6.0, 8.0]),
- np.int32,
- ),
- ]
- for input_freezing_value, inputs, expected, dtype in test_cases:
- self.basic("model_fp32.pbtxt", input_freezing_value, inputs, dtype, expected)
-
- def test_int32(self):
- test_cases = [
- (
- "in1[1 4]->[1 2 3 4],in2[1 4]{i32}->[1 2 3 4]",
- {},
- np.array([1, 4, 9, 16]),
- np.int32,
- ),
- (
- "in2->[2 5 6 7 3 2]",
- {"in1:0": np.array([[2, 4, 1], [1, 2, 8]])},
- np.array([[4, 20, 6], [7, 6, 16]]),
- np.int32,
- ),
- ]
- for input_freezing_value, inputs, expected, dtype in test_cases:
- self.basic("model_int32.pbtxt", input_freezing_value, inputs, dtype, expected)
-
- def test_bool(self):
- test_cases = [
- (
- "in1[2]->[True False],in2[2]->[True True]",
- {},
- np.array([True, False], dtype=bool),
- bool,
- ),
- (
- "in2[2,3]->[True,True,False,True,True,False]",
- {"in1:0": np.array([[False, True, True], [False, True, True]], dtype=bool)},
- np.array([[False, True, False], [False, True, False]], dtype=bool),
- bool,
- ),
- (
- "in2[]->True",
- {"in1:0": np.array([[False, True, True], [False, True, True]], dtype=bool)},
- np.array([[False, True, True], [False, True, True]], dtype=bool),
- bool,
- ),
- ]
- for input_freezing_value, inputs, expected, dtype in test_cases:
- self.basic("model_bool.pbtxt", input_freezing_value, inputs, dtype, expected)
-
- def test_bool2(self):
- test_cases = [
- (
- "in1[3]->[1 2 3],in2[3]->[4 5 6],cond->False",
- {},
- np.array([4, 5, 6], dtype=np.float32),
- np.float32,
- None,
- None,
- False
- ),
- (
- None,
- {"in1:0": np.array([2.0, 4.0, 6.0], dtype=np.float32),
- "in2:0": np.array([1.0, 3.0, 5.0], dtype=np.float32)},
- np.array([2, 4, 6], dtype=np.float32),
- np.float32,
- "cond:0->False",
- None,
- True # fill a bug to investigate why compilation of this model is hang on
- ),
- # case: input_shape + freeze_placeholder_with_value
- (
- None,
- {"in2:0": np.array([1.0, 3.0, 5.0], dtype=np.float32)},
- np.array([2, 4, 6], dtype=np.float32),
- np.float32,
- "in1:0->[2.0 4.0 6.0],cond:0->True",
- "[3]",
- False
- ),
- ]
- for input_freezing_value, inputs, expected, dtype, freeze_placeholder_with_value, \
- input_shape, only_conversion in test_cases:
- self.basic("model_bool2.pbtxt", input_freezing_value, inputs, dtype, expected,
- freeze_placeholder_with_value,
- input_shape, only_conversion)
-
- def test_cutting_fp32(self):
- test_cases = [
- (
- "add:0[3],z:0",
- {"add:0": np.array([4, 5, 6], dtype=np.float32), "z:0": np.array([1, 2, 3], dtype=np.float32)},
- np.array([4, 10, 18], dtype=np.float32),
- np.float32,
- None,
- None,
- False
- ),
- (
- "add:0{i32}[3],z:0{i32}",
- {"add:0": np.array([4, 5, 6], dtype=np.int32), "z:0": np.array([1, 2, 3], dtype=np.int32)},
- np.array([4, 10, 18], dtype=np.int32),
- np.int32,
- None,
- None,
- False
- ),
- ]
- for input_freezing_value, inputs, expected, dtype, freeze_placeholder_with_value, \
- input_shape, only_conversion in test_cases:
- self.basic("model_three_inputs.pbtxt", input_freezing_value, inputs, dtype, expected,
- freeze_placeholder_with_value,
- input_shape, only_conversion, True)
-
- def test_placeholder_with_default(self):
- test_cases = [
- (
- "x[1,4],y[4]",
- {"x": np.array([[3, 2, 1, 5]], dtype=np.int32), "y": np.array([0, -1, -7, 8], dtype=np.int32)},
- np.array([[3, 1, -6, 13]], dtype=np.int32),
- np.int32,
- None,
- None,
- False
- ),
- (
- "x,y",
- {"x": np.array([[-3, 20, 1]], dtype=np.int32), "y": np.array([[10, -11, -17]], dtype=np.int32)},
- np.array([[7, 9, -16]], dtype=np.int32),
- np.int32,
- None,
- None,
- False
- ),
- (
- "x",
- {"x": np.array([[-3, 20, 1]], dtype=np.int32)},
- np.array([[-2, 22, 4], [1, 25, 7]], dtype=np.int32),
- np.int32,
- None,
- None,
- False
- ),
- ]
- for inputs, inputs_data, expected, dtype, freeze_placeholder_with_value, \
- input_shape, only_conversion in test_cases:
- self.basic("placeholder_with_default.pbtxt", inputs, inputs_data, dtype, expected,
- freeze_placeholder_with_value,
- input_shape, only_conversion, True)
-
- def test_freeze_placeholder_with_unknown_rank(self):
- test_cases = [
- (
- "x[4],y->2.0",
- {"x": np.array([3, 2, 1, 5], dtype=np.float32)},
- np.array([6, 4, 2, 10], dtype=np.float32),
- np.float32,
- None,
- None,
- False
- ),
- (
- "x[1],y->[2.0,3.0]",
- {"x": np.array([3], dtype=np.float32)},
- np.array([6, 9], dtype=np.float32),
- np.float32,
- None,
- None,
- False
- ),
- ]
- for inputs, inputs_data, expected, dtype, freeze_placeholder_with_value, \
- input_shape, only_conversion in test_cases:
- self.basic("mul_with_unknown_rank_y.pbtxt", inputs, inputs_data, dtype, expected,
- freeze_placeholder_with_value,
- input_shape, only_conversion, True)
-
- def test_conversion_tf1_while_default(self):
- self.basic("ctc_model_based.pbtxt", None, None, None, None,
- None, None, True, True, False, False)
-
- def test_conversion_tf1_while_use_new_frontend(self):
- self.basic("ctc_model_based.pbtxt", None, None, None, None,
- None, None, True, True, True, False)
-
- @unittest.skip("88349: Fix auto-pruning in legacy FE")
- def test_conversion_model_oneshot_iterator_use_legacy_frontend(self):
- self.basic("model_oneshot_iterator.pbtxt", None, None, None, None,
- None, None, True, True, False, True)
-
- def test_conversion_model_oneshot_iterator_default(self):
- self.basic("model_oneshot_iterator.pbtxt", None, None, None, None,
- None, None, True, True, False, False)
-
- @unittest.skip("109220: Use generating script for this test model instead of Git LFS")
- def test_conversion_model_with_non_standard_extension(self):
- test_cases = [
- (
- "in2{f32}->[0.0 0.0 0.0 0.0]",
- {"in1": np.array([[1.0, 2.0], [3.0, 4.0]])},
- np.array([[1.0, 2.0], [3.0, 4.0]]),
- np.float32,
- ),
- (
- "in2->[1.0 15.0 15.5 1.0]",
- {"in1": np.array([[2.0, 4.0], [12.0, 8.0]])},
- np.array([[3.0, 19.0], [27.5, 9.0]]),
- np.float32,
- ),
- ]
- for input_freezing_value, inputs, expected, dtype in test_cases:
- self.basic("model_fp32.frozen", input_freezing_value, inputs, dtype, expected, only_conversion=False,
- input_model_is_text=False, use_new_frontend=True,
- use_legacy_frontend=False)
-
- @unittest.skip("109220: Make TF FE to return the error")
- def test_conversion_dir_model(self):
- with self.assertRaisesRegex(Exception,
- "Internal error or inconsistent input model: the frontend supports "
- "only frozen binary protobuf format."):
- self.basic(".", None, None, None, None,
- only_conversion=True, input_model_is_text=False, use_new_frontend=True,
- use_legacy_frontend=False)
-
- def test_conversion_pbtxt_model_with_inference(self):
- test_cases = [
- (
- {"x:0": np.array([1, 2], dtype=np.int32), "y:0": np.array([4], dtype=np.int32)},
- np.array([-3, -2], dtype=np.int32),
- np.int32,
- ),
- (
- {"x:0": np.array([20, 25], dtype=np.int32), "y:0": np.array([10], dtype=np.int32)},
- np.array([30, 35], dtype=np.int32),
- np.int32,
- )
- ]
- for inputs, expected, dtype in test_cases:
- self.basic("model_with_if.pbtxt", None, inputs, dtype, expected, only_conversion=False,
- input_model_is_text=False, use_new_frontend=True, use_legacy_frontend=False)
-
- def test_conversion_model_with_undefined_constant(self):
- test_cases = [
- # legacy frontend
- (
- "model_add_with_undefined_constant.pbtxt",
- "x[2,3]",
- {"x": np.array([[2, 3, 0], [1, 4, 6]], dtype=np.float32)},
- np.array([[2, 3, 0], [1, 4, 6]], dtype=np.float32),
- np.float32, False, True,
- ),
- (
- "model_mul_with_undefined_constant.pbtxt",
- "x[2]",
- {"x": np.array([-1, 2], dtype=np.int32)},
- np.array([0, 0], dtype=np.int32),
- np.int32, False, True,
- ),
- # new frontend
- (
- "model_add_with_undefined_constant.pbtxt",
- "x[2,3]",
- {"x": np.array([[12, 13, 10], [11, 14, 16]], dtype=np.float32)},
- np.array([[12, 13, 10], [11, 14, 16]], dtype=np.float32),
- np.float32, True, False,
- ),
- (
- "model_mul_with_undefined_constant.pbtxt",
- "x[2]",
- {"x": np.array([11, -12], dtype=np.int32)},
- np.array([0, 0], dtype=np.int32),
- np.int32, True, False,
- ),
- ]
- for model_name, argv_input, inputs, expected, dtype, use_new_frontend, use_legacy_frontend in test_cases:
- self.basic(model_name, argv_input, inputs, dtype, expected, only_conversion=False,
- input_model_is_text=True, use_new_frontend=use_new_frontend,
- use_legacy_frontend=use_legacy_frontend)
diff --git a/tools/mo/unit_tests/moc_tf_fe/conversion_incorrect_models_test.py b/tools/mo/unit_tests/moc_tf_fe/conversion_incorrect_models_test.py
deleted file mode 100644
index 3986cba4c10270..00000000000000
--- a/tools/mo/unit_tests/moc_tf_fe/conversion_incorrect_models_test.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import os
-import tempfile
-import unittest
-from openvino.tools.mo.convert import convert_model
-
-
-class TestMoFreezePlaceholderTFFE(unittest.TestCase):
- def test_conversion_fake_pb_model(self):
- test_cases = [
- # the default frontend
- (
- False, False, None
- ),
- (
- False, False, "tf"
- ),
- # new frontend
- (
- True, False, None
- ),
- (
- True, False, "tf"
- ),
- ]
- for use_new_frontend, use_legacy_frontend, framework in test_cases:
- with self.assertRaisesRegex(Exception,
- "Internal error or inconsistent input model: the frontend supports frozen formats"
- " \(.pb and .pbtxt\), SavedModel and MetaGraph \(.meta\), and v1 checkpoints."):
- path = os.path.dirname(__file__)
- input_model = os.path.join(path, "test_models", "fake.pb")
-
- convert_model(input_model,
- use_new_frontend=use_new_frontend, use_legacy_frontend=use_legacy_frontend,
- framework=framework)
-
- def test_conversion_empty_model(self):
- test_cases = [
- # the default frontend
- (
- False, False, None,
- r"Framework name can not be deduced from the given options"
- ),
- (
- False, False, "tf",
- r"Internal error or inconsistent input model: the frontend supports frozen formats"
- " \(.pb and .pbtxt\), SavedModel and MetaGraph \(.meta\), and v1 checkpoints."
- ),
- # new frontend
- (
- True, False, None,
- r"Option \-\-use_new_frontend is specified but the Model Optimizer is unable to find new frontend"
- ),
- (
- True, False, "tf",
- r"Internal error or inconsistent input model: the frontend supports frozen formats"
- " \(.pb and .pbtxt\), SavedModel and MetaGraph \(.meta\), and v1 checkpoints."
- ),
- ]
- for use_new_frontend, use_legacy_frontend, framework, exp_reg_exp in test_cases:
- with tempfile.NamedTemporaryFile(
- mode="w", delete=False
- ) as tmp, self.assertRaisesRegex(Exception, exp_reg_exp):
- tmp.write("")
- # on Windows tmp file must be not deleted on close to avoid remove it when reopened by MO
- convert_model(tmp.name,
- use_new_frontend=use_new_frontend, use_legacy_frontend=use_legacy_frontend,
- framework=framework)
- os.remove(tmp.name)
-
- def test_conversion_fake_model_with_no_ext(self):
- test_cases = [
- # the default frontend
- (
- False, False, None,
- r"Framework name can not be deduced from the given options"
- ),
- (
- False, False, "tf",
- r"Internal error or inconsistent input model: the frontend supports frozen formats"
- " \(.pb and .pbtxt\), SavedModel and MetaGraph \(.meta\), and v1 checkpoints."
- ),
- # new frontend
- (
- True, False, None,
- r"Option \-\-use_new_frontend is specified but the Model Optimizer is unable to find new frontend"
- ),
- (
- True, False, "tf",
- r"Internal error or inconsistent input model: the frontend supports frozen formats"
- " \(.pb and .pbtxt\), SavedModel and MetaGraph \(.meta\), and v1 checkpoints."
- ),
- ]
- for use_new_frontend, use_legacy_frontend, framework, exp_reg_exp in test_cases:
- with tempfile.NamedTemporaryFile(
- mode="w", delete=False
- ) as tmp, self.assertRaisesRegex(Exception, exp_reg_exp):
- tmp.write("1212234\n12312")
- # on Windows tmp file must be not deleted on close to avoid remove it when reopened by MO
- convert_model(
- tmp.name,
- use_new_frontend=use_new_frontend,
- use_legacy_frontend=use_legacy_frontend,
- framework=framework,
- )
- os.remove(tmp.name)
diff --git a/tools/mo/unit_tests/moc_tf_fe/conversion_with_checkpoint_v1_test.py b/tools/mo/unit_tests/moc_tf_fe/conversion_with_checkpoint_v1_test.py
deleted file mode 100644
index 6a731f20f03b3f..00000000000000
--- a/tools/mo/unit_tests/moc_tf_fe/conversion_with_checkpoint_v1_test.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import tempfile
-import unittest
-
-import numpy as np
-
-from unit_tests.moc_tf_fe.utils import basic_check
-
-
-class TestBasicConversion(unittest.TestCase):
- def prepare_checkpoint_v1(self):
- # quite old TensorFlow version can produce checkpoint v1 file
- # so have hard coded bytestream corresponding to checkpoint v1 content
- # this is a checkpoint v1 for Variable global_step with value = 14108582 of int64 type
- buffer_checkpoint = [
- 0x00, 0x00, 0x1B, 0x0A, 0x19, 0x0A, 0x13, 0x0A, 0x0B, 0x67, 0x6C, 0x6F,
- 0x62, 0x61, 0x6C, 0x5F, 0x73, 0x74, 0x65, 0x70, 0x12, 0x00, 0x18, 0x09,
- 0x22, 0x00, 0x12, 0x02, 0x08, 0x01, 0x00, 0x0F, 0x19, 0x00, 0x67, 0x6C,
- 0x6F, 0x62, 0x61, 0x6C, 0x5F, 0x73, 0x74, 0x65, 0x70, 0x00, 0x01, 0x00,
- 0x12, 0x17, 0x0A, 0x0B, 0x67, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x5F, 0x73,
- 0x74, 0x65, 0x70, 0x12, 0x00, 0x1A, 0x06, 0x52, 0x04, 0xA6, 0x8F, 0xDD,
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x62, 0x29,
- 0x33, 0xD3, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC0,
- 0xF2, 0xA1, 0xB0, 0x00, 0x01, 0x02, 0x01, 0x00, 0x51, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x13, 0xD9, 0x46, 0x56, 0x08,
- 0x63, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x57, 0xFB, 0x80, 0x8B, 0x24, 0x75, 0x47, 0xDB]
- return buffer_checkpoint
-
- def test_basic_checkpoint_v1(self):
- ckpt_file = tempfile.NamedTemporaryFile(delete=False)
- checkpoint_byte_stream = self.prepare_checkpoint_v1()
- ckpt_file.write(bytes(checkpoint_byte_stream))
- ckpt_file.close()
- basic_check(input_model="model_with_variable_v1.pbtxt", argv_input=None,
- input_data={'input1:0': np.array([[1]], dtype=np.int64)},
- expected_dtype=np.int64, expected_value=np.array([[14108583]], dtype=np.int64),
- use_new_frontend=True, use_legacy_frontend=False, input_checkpoint=ckpt_file.name)
diff --git a/tools/mo/unit_tests/moc_tf_fe/conversion_with_layout_test.py b/tools/mo/unit_tests/moc_tf_fe/conversion_with_layout_test.py
deleted file mode 100644
index 197ae5ce2764e4..00000000000000
--- a/tools/mo/unit_tests/moc_tf_fe/conversion_with_layout_test.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright (C) 2018-2024 Intel Corporation
-# SPDX-License-Identifier: Apache-2.0
-
-import numpy as np
-import openvino.runtime.opset11 as opset11
-import os
-import unittest
-from openvino.runtime import Model
-from openvino.runtime import PartialShape, Dimension
-from openvino.tools.mo.convert import convert_model
-from openvino.tools.mo.utils.error import Error
-
-
-class TestConversionWithBatchAndLayout(unittest.TestCase):
- def basic_check(self, model_name: str, batch: int, layout: str, refs_shapes: dict):
- path = os.path.dirname(__file__)
- input_model = os.path.join(path, "test_models", model_name)
- ov_model = convert_model(input_model, batch=batch, layout=layout)
-
- for ov_input in ov_model.inputs:
- input_name = ov_input.any_name
- assert input_name in refs_shapes, "No reference input shape is found for {}".format(input_name)
- input_shape = ov_input.get_partial_shape()
- ref_shape = refs_shapes[input_name]
- assert input_shape == ref_shape, "Incorrect shape for {} input:" \
- " expected shape - {}, actual shape - {}".format(input_name, ref_shape,
- input_shape)
-
- @unittest.skip("Fix importing of openvino.test_utils in Jenkins")
- def test_basic_model_no_layout(self):
- from openvino.test_utils import compare_functions
- path = os.path.dirname(__file__)
- input_model = os.path.join(path, "test_models", "model_fp32.pbtxt")
- ov_model = convert_model(input_model)
-
- # compare with the reference graph
- param1 = opset11.parameter([2, 2], name="in1", dtype=np.float32)
- param2 = opset11.parameter([2, 2], name="in2", dtype=np.float32)
- add = opset11.add(param1, param2, name="add")
- ref_model = Model(add, [param1, param2])
- flag, msg = compare_functions(ov_model, ref_model, compare_tensor_names=False)
- assert flag, msg
-
- def test_basic_model_with_layout(self):
- test_cases = [
- (
- "model_fp32.pbtxt", 5, "in1:0(cn),in2:0(cn)",
- {"in1:0": PartialShape([2, 5]), "in2:0": PartialShape([2, 5])},
- ),
- (
- "model_fp32.pbtxt", 9, "in1:0(nc),in2:0(nc)",
- {"in1:0": PartialShape([9, 2]), "in2:0": PartialShape([9, 2])},
- ),
- (
- "model_fp32.pbtxt", 7, "in1:0(?c),in2:0(?c)",
- {"in1:0": PartialShape([2, 2]), "in2:0": PartialShape([2, 2])},
- ),
- ]
- for model_name, batch, layout, refs_shapes in test_cases:
- self.basic_check(model_name, batch, layout, refs_shapes)
-
- def test_model_with_convolution_dynamic_rank(self):
- test_cases = [
- (
- "model_with_convolution_dynamic_rank.pbtxt", 7, "x:0(n???),kernel:0(????)",
- {"x:0": PartialShape([7, Dimension.dynamic(), Dimension.dynamic(), 3]),
- "kernel:0": PartialShape([2, 2, 3, 1])},
- ),
- (
- "model_with_convolution_dynamic_rank.pbtxt", 3, "x:0(???n),kernel:0(??n?)",
- {"x:0": PartialShape([Dimension.dynamic(), Dimension.dynamic(), Dimension.dynamic(), 3]),
- "kernel:0": PartialShape([2, 2, 3, 1])},
- ),
- ]
- for model_name, batch, layout, refs_shapes in test_cases:
- self.basic_check(model_name, batch, layout, refs_shapes)
-
- def test_model_expected_failure(self):
- test_cases = [
- (
- "model_fp32.pbtxt", 17, "",
- {},
- ),
- ]
- for model_name, batch, layout, refs_shapes in test_cases:
- # try to override batch size by default index (without specifying layout)
- with self.assertRaisesRegex(Error,
- "When you use -b \(--batch\) option, Model Optimizer applies its value to the first "
- "element of the shape if it is equal to -1, 0 or 1\."):
- self.basic_check(model_name, batch, layout, refs_shapes)
diff --git a/tools/mo/unit_tests/moc_tf_fe/test_models/ctc_model_based.pbtxt b/tools/mo/unit_tests/moc_tf_fe/test_models/ctc_model_based.pbtxt
deleted file mode 100644
index 935cb9190c3274..00000000000000
--- a/tools/mo/unit_tests/moc_tf_fe/test_models/ctc_model_based.pbtxt
+++ /dev/null
@@ -1,5245 +0,0 @@
-node {
- name: "inputs"
- op: "Placeholder"
- attr {
- key: "dtype"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "shape"
- value {
- shape {
- dim {
- size: 1
- }
- dim {
- size: 28
- }
- dim {
- size: 1
- }
- dim {
- size: 96
- }
- }
- }
- }
-}
-node {
- name: "reshape_to_rnn/shape"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 3
- }
- }
- tensor_content: "\377\377\377\377\034\000\000\000`\000\000\000"
- }
- }
- }
-}
-node {
- name: "reshape_to_rnn"
- op: "Reshape"
- input: "inputs"
- input: "reshape_to_rnn/shape"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "Tshape"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Rank"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 3
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/range/start"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 2
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/range/delta"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/range"
- op: "Range"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/range/start"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Rank"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/range/delta"
- attr {
- key: "Tidx"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/concat/values_0"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 2
- }
- }
- tensor_content: "\001\000\000\000\000\000\000\000"
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/concat/axis"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/concat"
- op: "ConcatV2"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/concat/values_0"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/range"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/concat/axis"
- attr {
- key: "N"
- value {
- i: 2
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "Tidx"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/transpose"
- op: "Transpose"
- input: "reshape_to_rnn"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/concat"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "Tperm"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Shape"
- op: "Shape"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/transpose"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "out_type"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice/stack"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice/stack_1"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 2
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice/stack_2"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice"
- op: "StridedSlice"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Shape"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice/stack"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice/stack_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice/stack_2"
- attr {
- key: "Index"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "begin_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "ellipsis_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "end_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "new_axis_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "shrink_axis_mask"
- value {
- i: 1
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/ExpandDims/dim"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/ExpandDims"
- op: "ExpandDims"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/ExpandDims/dim"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "Tdim"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/Const"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 96
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/concat/axis"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/concat"
- op: "ConcatV2"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/ExpandDims"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/Const"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/concat/axis"
- attr {
- key: "N"
- value {
- i: 2
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "Tidx"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/zeros/Const"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_FLOAT
- tensor_shape {
- }
- float_val: 0.0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/zeros"
- op: "Fill"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/concat"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/zeros/Const"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "index_type"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Shape_1"
- op: "Shape"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/transpose"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "out_type"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1/stack"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1/stack_1"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1/stack_2"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1"
- op: "StridedSlice"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Shape_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1/stack"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1/stack_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1/stack_2"
- attr {
- key: "Index"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "begin_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "ellipsis_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "end_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "new_axis_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "shrink_axis_mask"
- value {
- i: 1
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/time"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArray"
- op: "TensorArrayV3"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1"
- attr {
- key: "clear_after_read"
- value {
- b: true
- }
- }
- attr {
- key: "dtype"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "dynamic_size"
- value {
- b: false
- }
- }
- attr {
- key: "element_shape"
- value {
- shape {
- dim {
- size: -1
- }
- dim {
- size: 96
- }
- }
- }
- }
- attr {
- key: "identical_element_shapes"
- value {
- b: true
- }
- }
- attr {
- key: "tensor_array_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/dynamic_rnn/output_0"
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArray_1"
- op: "TensorArrayV3"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1"
- attr {
- key: "clear_after_read"
- value {
- b: true
- }
- }
- attr {
- key: "dtype"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "dynamic_size"
- value {
- b: false
- }
- }
- attr {
- key: "element_shape"
- value {
- shape {
- dim {
- size: -1
- }
- dim {
- size: 96
- }
- }
- }
- }
- attr {
- key: "identical_element_shapes"
- value {
- b: true
- }
- }
- attr {
- key: "tensor_array_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/dynamic_rnn/input_0"
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/Shape"
- op: "Shape"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/transpose"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "out_type"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice/stack"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice/stack_1"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice/stack_2"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- dim {
- size: 1
- }
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice"
- op: "StridedSlice"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/Shape"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice/stack"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice/stack_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice/stack_2"
- attr {
- key: "Index"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "begin_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "ellipsis_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "end_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "new_axis_mask"
- value {
- i: 0
- }
- }
- attr {
- key: "shrink_axis_mask"
- value {
- i: 1
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/range/start"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/range/delta"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/range"
- op: "Range"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/range/start"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/strided_slice"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/range/delta"
- attr {
- key: "Tidx"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3"
- op: "TensorArrayScatterV3"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArray_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/range"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/transpose"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArray_1:1"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "_class"
- value {
- list {
- s: "loc:@rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/transpose"
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Maximum/x"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Maximum"
- op: "Maximum"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Maximum/x"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Minimum"
- op: "Minimum"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Maximum"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/iteration_counter"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 0
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/iteration_counter"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: false
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter_1"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/time"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: false
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter_2"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArray:1"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: false
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter_3"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/GRUCellZeroState/zeros"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: false
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge"
- op: "Merge"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/NextIteration"
- attr {
- key: "N"
- value {
- i: 2
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_1"
- op: "Merge"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/NextIteration_1"
- attr {
- key: "N"
- value {
- i: 2
- }
- }
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_2"
- op: "Merge"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter_2"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/NextIteration_2"
- attr {
- key: "N"
- value {
- i: 2
- }
- }
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_3"
- op: "Merge"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Enter_3"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/NextIteration_3"
- attr {
- key: "N"
- value {
- i: 2
- }
- }
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less/Enter"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/strided_slice_1"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: true
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less"
- op: "Less"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less/Enter"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less_1/Enter"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/Minimum"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: true
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less_1"
- op: "Less"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less_1/Enter"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LogicalAnd"
- op: "LogicalAnd"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Less_1"
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LoopCond"
- op: "LoopCond"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LogicalAnd"
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch"
- op: "Switch"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LoopCond"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "_class"
- value {
- list {
- s: "loc:@rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge"
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch_1"
- op: "Switch"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LoopCond"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "_class"
- value {
- list {
- s: "loc:@rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_1"
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch_2"
- op: "Switch"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_2"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LoopCond"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "_class"
- value {
- list {
- s: "loc:@rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_2"
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch_3"
- op: "Switch"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_3"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/LoopCond"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "_class"
- value {
- list {
- s: "loc:@rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Merge_3"
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity"
- op: "Identity"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch:1"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity_1"
- op: "Identity"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch_1:1"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity_2"
- op: "Identity"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch_2:1"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity_3"
- op: "Identity"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Switch_3:1"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/add/y"
- op: "Const"
- input: "^rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity"
- attr {
- key: "dtype"
- value {
- type: DT_INT32
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_INT32
- tensor_shape {
- }
- int_val: 1
- }
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/add"
- op: "Add"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/add/y"
- attr {
- key: "T"
- value {
- type: DT_INT32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/TensorArrayReadV3/Enter"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArray_1"
- attr {
- key: "T"
- value {
- type: DT_RESOURCE
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: true
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/TensorArrayReadV3/Enter_1"
- op: "Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/TensorArrayUnstack/TensorArrayScatter/TensorArrayScatterV3"
- attr {
- key: "T"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "frame_name"
- value {
- s: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/while_context"
- }
- }
- attr {
- key: "is_constant"
- value {
- b: true
- }
- }
- attr {
- key: "parallel_iterations"
- value {
- i: 32
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/TensorArrayReadV3"
- op: "TensorArrayReadV3"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/TensorArrayReadV3/Enter"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/Identity_1"
- input: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/fw/while/TensorArrayReadV3/Enter_1"
- attr {
- key: "dtype"
- value {
- type: DT_FLOAT
- }
- }
-}
-node {
- name: "rnn/stack_bidirectional_rnn/cell_0/bidirectional_rnn/fw/gru_cell/gates/kernel"
- op: "Const"
- attr {
- key: "dtype"
- value {
- type: DT_FLOAT
- }
- }
- attr {
- key: "value"
- value {
- tensor {
- dtype: DT_FLOAT
- tensor_shape {
- dim {
- size: 192
- }
- dim {
- size: 192
- }
- }
- tensor_content: "\036,\342>\277h\337\275\'\200\226\276@r\036>Cv\367>\374\026|\277\244S\346\276\2604\240=\250\277\310\275\312\234\007?\264Ac\276\317Q\024>\337\242\361\276\326\265J=\311\243\312>;\303\037?\321\007\265>O;\236\276q\313\245=\230\272^=\211(\r\277\225Zi\276I\242\370=7\024\302\276\004\315X>]\217\013\277\332\035\203\274}\351@\275\314a{\276\270\264\000=\235\010\346\275\277\226\244<\234r\214\275\271\346\025<-d\361\276\275\277\r\277\346c\014\277\214\202\341\275\231\242\022?\253\376&\275\301Z\004\277\335\355R\276E\017\252>\034\234\314\274v\034\274=\255\212\200\275\022\030\271\2767D!\2760P\204>\316\037\312\275\310\007[>\212\201\337\276\206\\\331\276\340\361\200\275:\344\250\276Tz\r\276\t\306v>\016E@=\241\356\002\277V\322\222>>Jg\276\200\337\225\276t\210\006\277Q!$\276 \026\365\274\311,\335<\374c\225<\243\307Q=f\2624>V\216E\276\367v\001>\233\342\327\276 \2660\277\245S:\277\256\2537\276\n\375\">L\t\276\275\274\346i>>\355=\2777\026\363\275\275%\317=H2w\276G\336`\275\300(8\275\246\322\027?\3568\353>\305D\263\276\315AJ\276\024\202\023?\016\033!\277\213_\224\275\237\204p\276\212\200{\277\333\2314\276\343\203\\\275\252A\177>\026\333\253>\202m\001\276RsS\277\255\205\201\276\301\206\257>Q&\212\276jm\000\276AZ\034>\367W\224>\031\226\264>\014\326]>\306\003\014\276\275\255\343=\263\341\252>\344v%\276\300\026\227?\271\n\351\276?\234\260>\341\352\316\275 \345\314\276\023\345\303>B\014\315\276\021\245\241>\362u\001=X7m><\367\354\276\250z6=\260\206\333=\\\320\275>\304t\227>\024\3674\2765\210.?)\001\314\276\026\315[\276\204\355\037>ni\243\276\215*\230=\016\251\026<\371_\t>>\302\023\275-w\202\276\027R\023>\021\236\305>\024c\320\275\254\"\322>\355\"[\276\023]\304\276\224e\357\276\001\014\310\275\344M}>\321\021\266=\262M\277>\373\264\204>\245\311\000\277\251\342\357\2769\246\034?a\235@<\266\006\344\276\2616\217=\177\335>?;\351p\276\271\014\026>%\026g=\316/\255>\345\004\246\275\310\200\003\275\206-Z\276\264\302:>\351K\246\275Y$@=\377p\352>_\353#\275\006\320,\276\225\377\323\275T\242\034<#\r\322=\312s1\276\336\021\356\274\202\r6?gR\262\2765\275\030\275\212\317\266\276\321\r\205>g\"v\276}\\\301\275Z(\210\2764x\205\263{:>^Q\t>o\016\356\275\376\230\\\277{\226\375\2752+\006\276\\\367\033\275@\214\314\276\362\370\204>f\201\004>\250\217\t\277\"\202\200=#\204x=>\341\034>\276\251u\274\001\024\272\276\r\225\321\276\330\227\310\274H\334\242>\243%\314\276iP\303\275<\357\313\276\227\014\016\277\024\376]\276\363y\250\276\322\006V>\346{\220\276f\274#\277\014\014\214\276\343\275\312\276\312\357\034\277\351\237{\276\322|A\273\374!\274\276\362\367\232>^\305C>,3)>A\200\023?0\354b\276\315\354\332<\211#J\276\024\365\227\276b\337\017>a\254\223>\235\336\303=\327\323\'\273\243G\311>\277\327V\276\313\030\323>\0057\262\276)\231\322\275b\342y\275\202\361\266<|g\010\276\205D\277=\231\247W\277\225\321\t?\300\240\312\275\326\016\201>9)\025\277\002J\207\276M\267\376\276by\016\277\367\222\356\276Y\212(>x\342:>BA=\277\206\321\213>]L\307\274`R\001>.\001\325\275\332\242\323>\272o5\276/\006\231>wb\"\276y\306\200>\3534\240=\320\226\277\276&$j>d\2365\274\024\342\345\275\232\321d\276$]\226>\230\177\367>\200\332\204\2763\336D\276\004N\335>\311\006@>\3325k?\264\3109>]rU\276\275L\366>\300\352\036\274\276}\323\276|\341\355= \274!>\277\032\265>\321\255\337\275#\363\037\276F+\002\277\302\254\226=\346\2664\277B\021\231\276..\200\275ow\224>\374\312\000?\327@m>\'\230$>\364\214\243\274\354\354\331<\207\266\"\277\201\230\301>\306E2\276\017\017s=\352&\255\276\225$\n\277K\033\022?fU\256=w\036\302=n\227\245\276\337\202\000\277\302\002|\276\356\024\274=RT\211=\341)\014>\314\211\263\275leA=\262\355K\276\274\214\374\274s\316i\277\024\356;\276&\263\336\276\035H6=\350\"C>\034d\202\276\275n@=:i\243<\210\372\024>5\000\354\276\313\357\026>\301\010\007?^\220\372=\366\332\277=\323\352\002>\007L\207>\251\377\240>\353\200q\276\307\276\331>\256\370\247=\321\211\003>[\r\013\2771g\273>\242\016O>\232\365\301\276E\212\212\275x\321m>@\352\366\276\266\023\215>nP\336\275\247\032:\277K~4>\346\010\311\275\026\236\334>\277\261\3747?\357\rX\276si\253=\230\203\324>\245$\255>\022x\277=\345)\233\274;i\214<\227V\362\276\250Q4>\023\240a\276\2114\017?9\315\261\275\364*\222\276L\300\333>ix\332\275\243\360\335\275\333\321d>\'\253\022<\014r\177>\2463\026>\352\256=>\307\370\203=\354\327\223>u\304\231\274\273\"\"\277\252q\320>\017\247\222>\367b\353=\223\026\262=3\177\217\2763\353\270\276\332\263\331\275\004Z\231>\310\347 \276J\210.>\365?\260\276#\250\223\276Q\251\275>\001\n\372\275\237\331k\276\370$\227>\243\311\232\275\273\260\347\275\351K\006\277(\275\241\276\223\'\325\276\262.s\276\220Sc=W*\204\276\214<\260>4\302i=\335\224\222\275\265F\347\276\342\2214>\233<\350>\270\205\377>\275\223\351>jS\363\2751\273\221>\214n!\276\016\206\276>\030\246\234>Iu7=\2509\220>\374\036\364>\003\206\204>\304|:>G$\333>\2378\016>\375\334\006?p\277V=T~\002>{\310F>\360\245\r?\265\303(=9\r\037\277\335\265\007\276\237t\260>r\340\275\276\311\271(?#,\225>\367\224Y>\005\275\003>q\020]?*\254\316y\264\000\275\\w(\377\206\010\277=-\347>%c\202\276M\032J\276\305\005\026?I\336j\276\242W2\275\\f\270=N&e?\363\347\265=0\203\t?:\307n?s\247r>\245\233%> \337\252>\004t\211\276\207\340^\276\305\365\'\277j\263N\276\035\227\002\2777W<\276\240\310\224\231\020Q\2778C$?\020k;?\207\324\256\275\226\223\240>\225\273\337>v\002\242\276\313\035\270=S\375\202\276\203\374\313\276\251\025\346\276\342]\245=_\333\030>|\004x\275\315\267X>(\314\313>u\252\014>XH\206>\342\005\021>w\036\305=\n\337\267\275\220\031\200\276\262\350a>,\227>?\"a\002\276\313\314\231=s\263\027>R\236\271\275\030$Y=\027\357b>\030\217\245\276\0228\222\274\370\323\027?\232\035\301>t\212w>\367\032\022\277\325\242a\276#xV>\212C\241\274T\2511?,\315\347>\270RA=}\313\262>\342AA?-\223\224f\255\000=$VU\273\367\367;\276S\024%\276\034P\n>\352\206\231\275\024\014\201\276\347\261x\276\333\245\213=\340M\216\276&dw\276W\324)\275\220;\365=Xql\275\340\t!>\233\217\350\275\347:\246>\331\010\242\276x+\307>\331\221\223>?\2775\276\177\3115>\335\236\027?z\231L\276e-\252\276\004\244\256>\227\361F\276\022\350\200>\377\266\036\277VA&?\255u\265\276EX\n?X\013\203\276\366\315\252>V#\320>\366\222-\276\335\202\355\276\314\363Q=pd;>w\243N\276f\366\243\275\321\251\260\276&\314\007\274\311\335\321\274\305$!>n\270\230=\035\345\373\276a%\214=\317M\375\275_\277\370\273t(\270>\250\360\302\275\245X\312>YT\002?TE\021\277y\1773>T\016\221>`*)\277\252j\362\276\314\037Z\276:\225\246=L\324->i\367\361\275\307!\270>n\221\000?\267\246\024\276;\356@\277*I\'?\243\201\026\275FC\255>\247\265\371>\263\215\314=\034\262E>\r-\225\276\247L\311>\216\362J?\271D\300>\362\351\\\273\377\0027\276#\254\202>~*f=_.\204\273\3252\303=8\203h\276\322\314\322\275`E\245\276\365\344\025?\226P\017?\036\202\230\276h\271\344\277c\023x\276{\267\037>\261;\317\274\310\215\n\276f\024\370>K\347[\276\324\353~>\231\022G\276\360\336\252>q\t\321>9\327r\276X\305\331=\327E\215>\351x\037\277\301\3319\276)\201G\274\365a\340=Z\251\375\274\231\314:?\314\213\270\276\350(\300=\374\202\277>T\017\014\276c[\273\276\245\026%\277#\200o\275\353\347\3624\334\372>\302d\256\275 \276\203\275\221\327\336\276\323\004\'<4\204\241\276\237\304\026\277\306\230$>rg\206>\270\324#\2766\376\331>?\024#?\033\206\305\276FJ\035\275\036\014L\275S\367\264<\260\002S\2760\350\251>\367\306I\274\266\366\337>6\373H>0\027\312\276*\305\031\276s\325\260>\367\240r=\337\346\275>\201rI\276\006iO\277V\001\013?$\014n><\221&?\337?\233\275\266\323r\277q\366>\277\344\241\376\275\177\0376\276\032\013\333>\375\212w\275$-\352>H\221\014=-S\005>\313s\221=\354\206\250\276\024\306\361=\345g\305>g\216\342\276\"iU>\305\275\025=\260(\214>\224\222\312>\r\230\365>\241\250z\276\363\333\\\276 \033\243\276\271]&>\343y\300>\364\335\272>\210s\233>X\212\354<-c\016\277\373\017\236\274\345\\\r\277Li$\275\276\242\203>\000\344\002>Uo\223<\327\264\233>{t\025>\213&\273=\235\313\032\275:f\236>[\254_\276nWW>\226\376=<\231\235\230\275v\006+?\027\262t>\365\301\274=\252\217\266=,\201\022\277\035\017\207>\232L\240\276F(\313\276\274\3208?W^\002\277\272\334@>\247\276\254\275\242\270\327\275\367c\302=\331\037g\2762\004e\276G\245\267>\024\250\r=\267$\252\276\273\250m>q6B\276\363G\314\276\034!\016?y\321\311=\323j\r?!Q\326\274\260\271!\277P\325\302\276\304z\021>\352\256\035?\256h\212\276\2349\031\277\033vs>\315\316\357>\036\2274\276TSd>K\322\274>x\216\006\277D\r\330<\0005C>\210nQ\275\014\237\211\275\372A\004\277al8\275=\353k>\350\337\365\275\376\346\330;\004\372\217\2763h\367=\353+\303=@,n>K m=wy\002?\023=\217<#\203<>\257TM\277\031\211h\275\305\002.=y)(?\350\326:\276\316\212\342\275\305\362\220?\345\263\206\276\352?W>\257\362\030>\355tq\2765\\\300>9\245\010?\277\257\321=\r\262\032?\362\002\250\276\241\003\334\276\364\324\n\277N\261\2549\366\247\276)\340\214\276j\002\342\276\324h\237>A,\236\273R5\303=\371\256\306> \213\313>\207\370\360>\326\264\220\276Y\026\\>@Zx\276-\314\207>\325\224j?\310\322\252>C\235\203\2762:9\275\207\230a\275\332\307\010>1\333\"<\236\350\312\276\361\256y\275\036\226\355\276ZN#=\305[q>\014\247\223\277\261\002G\275\t\260v=\310S\273\276]\207c\276\214p;?\304{\314\276\312\260o>\276\376\'?S\237\355<\037f\005\276\2268 ? U\016\275\367}3>9\032h\276\235{\031=\236\277\020\276\246\250\003\277_$-?z:]=x\007u>\313\314G\2739\024#?\270\200s<\224\342\013?1_\366\2756\031E?)\033\037?\001X;?/\315\236>.\200\261>\333\"\206?`\206\300<\357:s?K\321B>Z\214\'>\232\356\317>)\341\200\276\205\361\271=\027K;\276\274X\260\276Z\335m\275\322;`?\312[\002?G\217l\276kC\370>\352\303\367>\016\351\325>kj\000\277]\031\373>\214\263U\276}\3575?S\262\264\275a\332\226=\307\215u\274\265b\213=6\331\335\274\1770n>\023\241\302\275kO\332>\222\036\244\276\367\205\237\276\'\306\375\275\214j\271>\301\n_>\014\353\371\275(\244\320\276\303J\022>\260\r\217\276\224*\007?<\277\226=\275R\345\276W\304\223\276y;\370>\006t]\276\210Zg>J\316\020?\211\214/>\301S\246>\325\326\366>+\373\214\277z\356\353>\007#\360\275\375c\253\271+\301>\230\035\214\276\325\261\006\276\317\262|\276\2237}?\206\002X\276*\213\264>\332\361L?]\354z\276\251uM?\265\326\002\277\256\266\272;H\321<>\0379\243\276\270P\310=\032\'\037\277\024\014\200>\344\371T>\037}\214>\201~\332;y\375\321>:w\306\276\221$\271\276\360\320\250>\223\t\333\276\314\000P\276\351\\\037>4\302]?\257\211\360\276MO\335\276\273\276.\277Ql\344<\343m\214>J\321a=\002\300\275>\206\243P?^\236M\276E\233`=\007?\377>S7\310\274{@\275\276!\245\010\277\205\354G?\21672>Q\007\307\276~\345\345>;k\234>\362\347\271\276\317\215(>\322\223H\276e\266\037\205\207\014?\r5\242=z?z>3\005)>+\337=\276\265\231<<\202VE\276%\207\023?*\271s\276\242\013\364>\363\243p\276\230\240\243><\357\307>\363\233(>\325]\031\277:0\036>\316\0051=\270(\203\276\243B\236=RB?\277;7\344\276\213\010b\276\365\033\000\277\006\202\017?\344\243\331\360\224\306\276\024G\263\274\367o\236\276\271\263H<\025\347\356\276\250\252A\276\253\203\261=\311\336(=\336Q!?\211\305\314=M\353*?\314\207\332>\303m\246>F\377\250>1\007}>\0132\322\276\006>\021?b\375\217>\001]\314=\224\020x\275\\\333\037\276?\246\367>\372\363\013\277\000s\036>~\254\340\275\231\266\235>Bj\212\2762/\244\275\262\242\r\276)(\006?M\250\337\275\265\276\240>e\033\204\276f\007\036?\330\252\010?\177\230\216>\031\302F>\013\273H\276\3567\r\277,\013\201\276\237\320A\276=a[\276\004\214W>\207!\366\274\303\337J>\331\t\375=\355H(=\035K\031>2\236\252=:\2316>\322N\314>\000.\346\275\206\216f?Q \327\274pq\230>\014lO\274t\300\256\275\247\020\201>\236H~>S\247\323>\225\346W>:l\267\276\211\354\n\277\327\025\210>x\337\022\276\322P\"?$L\244\276\261\316\231>\"\026Q>\373\234\361\274\352\316\245=\305\276\336>\377\323\024=y\217\036?wsG>\343\257\013\277\331\013:>\273\335]\276\264AP\276E\2138\276\201%\236=\\\205\245\276x\210\233=\206a\034\276&\306?\277\333X\355\276\3655\357>\013\216w\276\307\3304^l\276\214\'\210>\023\235\202\276\230\253\354\275\235\0104>\204\232\275>G\322\024\277\373/\301\276\267\2170\277\230,\306\276\275\237\327>e\245\355\276\331\324\001?P\207y>\032x\304\276\010\267\271>\024$\274\276\0106?\276\n\355\227=\315%\207=\306\016\305<3\204\260=\221E\333\276\347\267H\275\236F\210>t\375\214>\361\315\200\276d\370\035?\305\367\210>U\345\214>\203=J\276\021\327\330\274g]\016?\357\311-\276\243\310\255\275$C\374\274\357\235\257\275\014a\342\274\260\332z\277!\347\235>[\206\003>\300e\230>\221\267\266\276N\326\010\277\213\204#\277\261\275\"?\275\353\"?-^\376n\0269>\266\033\312>\326\347\332\275\376E\231>\013\003\207>}\033O>U\206\230>\2451\250>[\372\036\277\213\336\332>R\2237\276\344\207\n\277\263Od\276u\001\316i\253\321\275j\000W>\0101\036>&\225\321\276\373J\204=)\017\335\276\353\324\223>6\347\016>\023F\247>\370\343\357\274\0227=\276\245\023\242>4\340\256=\305U\315\276\336I\033\276\031\r\'\277D\246U?\375\253p?\014\031\000=\361@I\276\004\030\311>\271\340\014>\360\275\211\276\357\346V>,\006\322\276\333\317\247\276\265Xw>\260\357H>lj\335\276\034\334\010?\223\347\267\276\254:\341\275\246]\256\276\353T\272\276\2159\231\276d\023\246>t\261$\275\244\037\026?\\\273S>|} \276\245\353\025\277\266\276t\276R\022\033\276\372l\234>\010\267\006?s5,\277\323\253\250=ZUE>c]D\276(@\034<1\216\207>A\351\300\275\343\023B>ff\006?}\363\236>\342\256\342=\274\323\232\276\327u\014?\355\355^\276\353\027\222\276E\226h\276\320V\274>\376b\244>>\311\330\276K\3619\276\"\002\255\275yZ\222\276F\352\223\276\376Z\216\275\332\220D;\366\0149\277m\305\275\276`\226\205=*\261\254;\345d2\276si\321\276gl\304\275U\352\316>\352\316->\316@\322\276\266\321\277>H\266l\277%O\275>?\216\270>q\303\316\276\362\305\253>vv\217\2763\201 \276y0\353=\244t|\276\275\316\333\276o\342>\276\346\231\t\276\300\034\240\276K\023(>\242\2362\277\253\305-\276\363&&?\364RN\277\\W\317\276\376\022\014\277\364\221?>\237\332m\2759\034\021\273\316\246E\277\201\r\020\274O+\363=\271D\t\277\263\247\215\274\252}\037\277\353?\352\274\\\020\222\276\031v\224\276\'\224\251>\321\275+\276\243M2>\0171\244\275`p\026\276\232\371\350\275\r.\323\276\344o4>\206\301]\276\337\2635\276u\277\216=\311\024=\276\351\016Z=g\343\r\277\001#T\275w\212\230>o\326+\274\332\206w=\356A\001>\\I\010\277.\325D\276\327U#\276\214+\261>\001\345I\276\334\372\202;\227\032\315\2763\331\336\2750\224S\277U\360\026\276\275\004G=\320\261\030\277\037\254O>\244 \306\276\\\314\376\202*\232>#\255\225\275\275\177\335=\244-\357\2760S?\277\tZB\276\204\360\003\277\324#\005\277\257.\253\2761\243\n\275o\367\230\276\375\333\221>\316d\016\276!\302\203\276c\325\252=\372\355+\2768\017\217\276o\362\264=\021>!>k\323\202>\022\266\034>\256\'\235\276\224\007\003?{\005{\276\025W\220=u\237\346\276\303d\311\275\303v\261<\312Q\335\274\240\352\034=9\301\035\275\253\234\271=V\030F\275\r\352\315<\201\312\312\274I\343\231>eIl\276m\336\037>=\203\321\276\345(\324\275\334#\235\275\364|Y\274\364US\275M\232j\276\013\243\314>\200\324\220\276\t\263\255>\206\244\365\275\'\031\365\276\233\364I\276\347\023\262>W\245\316>\266MW\276,hY>z\214\341>\017\336\032>\364\n2\276;rV\277\354\377\244>\314\257B=,\330\334>\022\260\033?\207Or\276F\235\013?l~\r?\252)y\275\037/\340=\311J\250=F\367N>$\220t\276\344\002\273?\371\003\342\276\311\250\300\276|\177\"\276\231\365c=\237\373\266>K\350r\276\221\n\373\275\267\257{\275\217\256\221\275\267\374\315>\276\010 \277m\310\313>t\331\250>%\226B\275\2246#\277\0259i=\314\000\255\276\343\316?>\316\231\234\276\267\t[\275g\217\303>$\374\252=j0\033?#\030e?\335+;?\361\334\262>eqX?\357\002\262\276\277l\321\274\"I\376>\213\344F\277\302\235R\276&*-\276\2313\222>\314\035\232\276P\361\216\275\205lJ<\253\177F\276-\244\027\275\025\274*\275\226\\\337>Z\204\037\277\001\336m\276\250\222[\276\375Dk>Q\226\243\275\271\356\031\275WXI\276\034\214\273\276I\022 \276r\213\347\276\362\353\277>\013\3131?e\254&?\032\332z>f\364\246\275\224\365\221>e\355f>\246\3003>\272\216\210\276\251\231\216\275^\312\021>\265FR\277\334VL\276\002\350V\277O?\250>\302!\247>\017\217\351\276\327\201\255={\242\036\276\270Tn\277\323a\313>\327\236\356\276t\353\303\276\215\233,\277I\376?\276x\203\200\276\316\215\324>\272\366\207>h-\225\274T\335S\275K\264\216>\365\004d\275`\333\202\276[\234\232\276\276\235s>\275\004\305\274d\336\026\275Y\236\343>`\367*\276\\\364k>\3252I\276`\202\240\276:\211@>\266\235\201\274\027\327\032=?\341t\276\244z\335\274+\034\316\2767lN>\275\371e\275\263\031\306\276_\022\305\276jk6>\344\032\204\276\nJ\025\277\231;\376\274\310\3432>\035\277\323\2731\006\207\276dp\215\276\026t\n\277sz\217\276\007$\024\277\340\014\263\275Z\315\024\275\317Py>\2505\000\275<:\201>\025\036_\276\371\207\266\276\224)\204>\245\331\334>\205 \254>\326\221\227>\264\356\351>\371\013\221\275\244\276\033>\237j\026\277\016\373\250>\223l\351\276\202a\005\277[j}=\215F\360\276i\361\247\275\232{\220\276\325\262\227=1\273R\276 /\250>\343\267m>lj\025>\322\334\354=\205\031\004\276\232=\005\276\242\213\254=\344\226B>\035\212\261>\035\2772>\364I3<\\8$\277IiO>\307\366\273\276\253\306\016\277\207\311\334>#\3469?\336j\n\277\036%\321\275\'_i;\242\256i\276\307m\262>\306\250&\277\350\204\257\276n\356\250=\224,.\277 \370\370\275\037\367\312\276\327\022)\276\240\231>\276\320I]\276\351\353\305\276\177{H\276\307\006\246>L\001\224>\3209+\277\355\277J\275\t\377\261<\037\276e>\360G\354>\214\000S=\\\307\221=\340\230\035\277\354\364\337=\217\021\237\276\371\350\276\276\270\376q>\342\235\005>\325\313\200>\211\310\203\276\225\263b\275%B\374\276\202\3337\276\356^\251\276\354\263\214\276\240\320\374\276\353\226\242>\274`^\275\212\272\332>5\027\247\277wO\343\275\026\324\003?j\321g=G\035\364\273\033\230<\266T\020\276\206\273K=\255;;>\034@>\277\362A\221\275\375\243@\277^N\221?8\000\277\217\021\034=v\304\335=\322\354\304\276\276\3743>\366Xn\277CV;\277\177{\207?\212\353\357>j\263\355\276\310\030D\276G\254\230>\371=\001?\364\340\">\333I\343\276R\265\241\275%\213]>E\255\267\276h*\000>z\243\000>@AF>2\256\203\275\025?\322=\307\214\037>\025D\265\276\306\224\212\277s\031+\276\273\262\026?\361\376\271>u\361H\276A,\352>K\031}\276\220\230B\276\240\t\t\277\244\375\347\274<\224\255\276\026\'1>\024\360\004?\324\2008>\005~\370>\r&\315\276\374=K\276\270\314Z\275U\351h>~\213\223=um3\277q\031b\276\031{\214>\373\3638\276\375\202K\276_\304\272>\222\255\242=5\347\324=\265\237\307\275\303%\r\277B\034\346\275,\023\250>B{\n\277\233\021A>\026\200*\276\016\345\311=\375\004\316< r\022>\271\006\313=\251\014\035\2760)\301>i\322&\276%\021\276>\2719\n\277p,\n>\347\005\276\276\305H\365\256\340=\020\316U\277\371W\035>\247\363\201>8\026\321\276\302*\335=\363S\324\274\033\251\202\276\365\033 \277\341\270^>\304\315\314\275\335{2\275\224z\356\276\200\315\r\276\337\334\344\2759\020\261=|\250\365\276H\272q\275\225\315\347\276%\241\233>\315\262\024\275R\255,\277-\346\262\276\212)@\276-\256U\276n\245\205\275\323\301\251\275\031T\033>\210\t\002>O\207\223\276\321\356\225\275$\210\253>\302\262\030\276X\305\276>u\323\030>\365a\016\277\036Z\216\276\2077;>\253\231\375=\274V\244=S\303\360>\276\224\303>\030v\332;\207Q\267>\037\346\216\276\010\262L<\220z\230>(\375D>)\261t\275\032\305?>^\262U>:\261\215>`k\263>J\220[\276\017\220e>\374\024\264\276\300\316\250>\"\005\246\276\030f\t>i\366L\275^)\247\275Wf\'\275Z9\205>}5\346>\363\376\220\276\302\316b>\270\222;=\347\010\265>sF\375\274\333\032\372>\226\200\035>)\274\237=\317*\"\276\230\0233\276\3656\035=bX\316\276|\365\341\276q[\024\277\324\313+\277\367\031\037\276\256+\230=j\026K?W\235\002>d\225.\277F8\220?\227\017\024\276\203\324\267>\3234I\277G\232\223>2S^\276\376Lj\276\025\206\357\275\031%=\276U\235\213>\302\360W\277\001\234\303\276\017u\205>.o\020>~.{\275%\351\236\276,\376\340\275\321t4? \227\201>q\241\221\276T$\366:\356\362\237\276\245$N\276\226\221\376=\021\356V=\264V*\277\267\222\303\016\236\275\276)\261\221\275\\<\313<|r\331\275\271.\225\276\006\334G\277\037\270\202\276\324\3632\276,B\273\275\177\021D\276\253=\017>\340\215\023>3\210\234\275\220$b\276\341T\016\277x\242\267\275\271\236\207\276\262R_>\003\231\007\276@\340\032<\177\032\031\276uA\215>\301\202(>i=\354\276\240Mu>\371\323\256\276?S\246\2762\003\014>i\361\021>\024Z\217>\262 \n\275\215o\314=|+\230\276\270r\275\276\361\034\261<\257\200\227\276,\0003\276W\260\200\276\201er>\304\357[>\022\333\010?\372\016\000>V\0323\277\2122\003;5\337efhZ\2772\273Z?)x\376>=F\000>>1#\277|\203\331\273E\276\331\274#\315\006\277>\234\t\277\237\030X\276\201q\214\276\311O1\277\033\025N>U\266\301\276(8\225=\373T\252>~M8\276\226\220\203>\366\006\235>SL/\277\234\330\263\275Xi\n>\323\262\'>\213\345M\275\260\243U>\257\334\205=i\320\326\275\256\324\266\276\373\006`>e\227%\277\261F\t\277]\274&\276\000\265A>\223\257\277=\275K*\252\322\213\276\236w&=\177\365\271\275\351yy>\227\306\206\276%<-\276\204\026E>9\010\203\276\031!4\277!\324\036>SEA=\237\341\327\276U\020W\277\326\003\243\274\204\241*\275\365\274<\276$a\375\276<\204\371>\211\345J>$\026`=\371GC>\234\221\242\276O\224\206>\373\225\320\2768)\026\276\262f\325<\314\"\252>\351\243A\275\t\206\326\275\001o\227\276!K\313\276\362\207.>w?4\276\0312b\276\356\364\005?\301W\206\277C\234O\276\001\230\243>@\222\254>\371\037\034\277\206\334a>\217\344\377>\305f,\276\013\373\207>\246,\360=(+\306>\210\361\036\276\316\372\314=\331A\024\276t\037\273\275\255^\273>L\300\207\276\302)\017\276\357\036J\276\351\006\251\276\323o\010=8F\207=\247\223\317\276\332_b\273\233o\\\276y\377\210\276e\3728\276\230L\321\276\010\347/\277\352\235 \277\023JY=\317w\252\276\302\377\032\277\024\251\026>\225#\r\277*\305\370=bg\027>bP\313\275P\245\347\276\362r\236\276\023\224\307\275$\255\373=C\035\204\275\013\242\r\276\353(z\277\023Mm=\035\010z\276;\343\004=\013\020C\276\371Rx=\307b\274\276\244\206\"\277\312M\325\275^\022\264\276\262\243\t\275(\2534\277\331/6\276\334\372\362\2745\010\264\276\241\247\277\274\335\275\345=\266d\026>\001\204\232\275\267\305\322\276+\210\250\2765y\277=y;\037\277\031\240\027\274\352>\356>R\323o\277\345\322K\276\332.V\276\2227T\276\356CS>W{\213>_\230\373>\035\245\270>\2712,>G\241\000\277l)z?B\263\276\274t\346,\276\376\364\237\276\221uI\276\361y1>\327M\322\276\022\273\240\276\273\216\300>O\266\021>w\363\000?\241\310\216>\327\247>?`\0021\276M\303\276\276\275\023\272\275`\016\374\276(\032\007\277\205[\226\276\335{\355=\201\202\377\274#\316\375<\007n<\274\035W\370\276\035\220\321\274\265\373\234\276T\003\370\276<#\214\276\244\322k>\021E\225>\211[\212>\365L\334\276\277L\335>h\266\244\276\205g\225\276A\373#\276^@\226\275m$\246\276\307J<>\024\331\300\275\006\021\360>\356.\336=\200,u>\377L\356\275\222\216\021\277\377\213\272=HS\317=\327\026\231>.EC>\302\022f\276\301hB>\252u\213>!\007\230>\351\320\021\276\222\2607\27682\375=x\356\240>\001oH\274\034\352\220\276\317\211\033\276P\305d\276\236\354q>s\216\025\277\034\342\300>)R\n=\224\001`\275^\261\024\276\020\214?6G=A\276\367iS<\177h\310\276\035\262@=\357=\002\277\336\342\020:R\007\346=U\244/>\206\374B\276C.N>r\301\234>c\244>>\3761*>\351&\344\276f\373\212\276K{\003\276u\222\321\276\245\373$\276\'|i\2769,\220>2\365P\275<\310u>=\004\222\276\035\030\007?\374\001\325=\335\337 \275\262\355%\276\216I]\276\373\033\370>\267m\225=ll\014>\316\020\333>\314\0214\277\006\337\227>Y\251\002?\200\r\307\276\227\334Q\275\223\240;=OD\237>\235\246\006\277j\242\223=\303\313\216\276u\344\353>\303\324\226\276\005:\320\276\340\266\333\276\354\266\270\275gH\262\274\210\026*>-R\365>\244\267>>*o0\276p\332 >\373\2365>\000\362\316\276\247\377\235>~\351d>\211\256\250\276\254\333%\277\257\335\303\275.|\241\276\302\030\376\276\224\014\337\276b\006\375>%\002\212=\3225/>\307Z\256\276$@\006>\324O\017\277\315{\273=\r\250\217>\036c\241>Ph\263\276\027\377\002?\003|\375\276@\'5?k.0\274\030\213\223>\004\332\261>\327\210M?\354\202\022?\023g\373\275L\017X\277c\177\001?a4\215>\243\001\200=!\244\345<[\n\224=U[\234\275H5\372\2747\326\240>\240\313\203>m\241\241=\311\255\237\276g1\271\275H&&?R\220\271=\300\340\006\276\014Z\226\276\005\224\001\277\313\027\305>:\014\370\276P\215G>\241l\313\276\251\004\225=.\213)>\272\232\345\276@\2671?\376\215\305=i#\301=\351\353\002=\355\342\265=W4\316\275\374\216\205\276\361t\005\276\360\322a\276 %$\27674\363\276\311pS?\355\347-\276\356ws\276x\271\201=\323?\004\276\376\320\007>\266\363\241\275\335\201\310>\267h\013?\332\007l=\300\017\245>|B\305\276B\2620?L\231`=\2119V\276\337\372\227>\246\311\374> ?\373\276\263\031@\276\311,\232\276\207\t\313>\362\207\022?g{\251<\321\024\373\275\334\271\005?\344\271\234\276>&\202>\300\020\007\277\346\003\"\277\260\to\276s$\347<\005\000\362>\356s\027?2\017\354>\220\016\300\275\361\010\252=\260E\032\2779\211\'\277QZ]\277\232:\211>\025\223L\241\r\030\273\t\336f\276\312V\230>i\362\227>Lvf\276\027\361\036>\242\340M\277\270-\022?\242\302\246\273\3216E\275\340AZ\276\007\360\331=\363\335\003?\324dl=\227R\220\276#\201\325>\306K\254=^\203K>& \304\276\271\276\235\276\351\227\203\276wA\250\275\200D4\276\343v\217\276i\327Q>\3549\264\276\365\302%\277\232h9>\204;\262\274\2001\231>\307\305\230\276\031@]\276\266\021\030>|\246\322=\374\314\263\276d\303\035?\270\217\302\276\324\\!\276c\270L>;\315\367>d\232r>[\247\301=8\227J\2767\010\370\2741\314W\275\"\354\262>na;>\373}\250>\317\306\343=t\226\243>\325/\223\2763IV>\216\211\335=)\350 ?c\353\010;T\030\320\275EA:>>\274\274\276\221E_=.n\031>\247\245c>\340\'\304>\352t*\277\250\332\262>8\244\352\276\0016N;\323g\027\276\003\302\275\276\353\\\337=C@\212\275j\246\231>\306\261\326=D\270\031?\364\214)\277\325\203\230\275\334\206\023\277\036\337\340\276\236\372K\277\201\r\317<\233AF\277\235I\311\276\217\350\207>m\276N\277\\r\220\276\215I\020=\3049X\275vV\302=+#\217>^M\352\276\030\003\233\276\347\002\221\276\256-\230\275\300\\\242\276\316\003\206\276e\335->n\333\n\277\341\200U=F\002\366\276\247\331\335\275\374\"5\276\320\346M>\230\206\250\275\002\231?=\221b\265\274\'\310\212\277ba\227\276<,\001\276\366\307\026?k\035\301>pq\244>\222:\315>f\204\306>\027\275\230\276f\033+>Pe\324>\230\337\212=-;\336>\377\302\177\276\201\307\226\276r\356_=\022F4\272\331\203\214\277|\230\362\274\234\336\204\276P\035\274\275\302\n\372\276a\220p>\307\361\321\275\201\000\024\275\340\033N=\255\247s>\r\0219?\242L\235>\370\037\224\276FN\242<\350\2056\275\331>L\277\3004\017\277\370\300\023\276\241ug\273\326%\326\275\205/\302\276\017K\364=R\357\363>tT\361\275\017AG\275I\210m\276K\263[\276\374@\207\275\375\016\207\276qc\246\275Wt\227\275l\201\004>Eh\031\277\334\376N>\r\010\257\276~\302a\276\266X|\275\234\267\377\275\033\354\231\276~\2145\276<\340j\276\224\324\325=\201\322\032?\2606\360\274\033u\307\276\340\371\210\276`T\330>\221\355c\276\352\355V>[\220\013>\222l\213\276\314|B\276\300\3139>\252\317\260\275\242\215\275\275K\001 ?\330%\204\275\315\352\301\275\373\343:\276C\263\236>\024=\205\276\t\2411\276\203\3359\2760\3552\277p\375\270\276Z\347\372\275\275&\275\275C\252P=j\265\240>\333\206\355\276\275\234\270>R\252\207=~{\236=4\230\260\276;.\n\276\037\205\307\276\033\227\220=\004\241\330\275\373(7>\334\0163>\262_<\276\200y\373\275\242HZ\276\252~\212>\235\225q=`\217\263>cq(\276\277\237\207\276\271S\377\276\266\"p>Au\212\275>\000\316\275\316\212\177>\212uT;Z\026\250>\000\305\264\276\246\302\223\276\306\027\353>\255\020\001\277\273T\013\277:2H>(\257B\276\006\017\350=\334\340\247>l\337\021\276Z\232\237>\342\006\031?\365p\227\276P\227\261>)\3165\275\331\"\316=P\343%>Z\365\'>t\321\226\276Hz(\276\225\001\351>f\243 \277\332\320\371\276\372\265\230=\271\344\266\275`\356\222>%\331W\276\337\215\234>m\257\211>\222\254\025=W!\210\275c\022\216\276\335\023\336\276(\3102\276i\301\022\277:qI\275\301.\350>^\255\241>\032N,\276I\022\244\275t\266L\276\336h6\276\tI\350\276\200\037\316>v\307\202>v:\335\276\330M\002\276\234\202\303\275%7!?\247Wm\277\353E\244>\021*\027\275W\324\010\2768\350j>~Y\311>\302\255X>\177_\216>:\023\272>CG\010\276!\024\211\276W\267\216\276A\024\000\276sl\n>\320\363\206<\260\025\301>I\n\204>\235\250\263>\256\244\r>\220\223\274<[D\332\276G.\027?m\202\204>\036\025K\276Ub\235\2754\376\t\274Lk\366=\275\322J\275\275\371d\274&j4\276u/6\276\241\301\360>6\334\376\274\220W\336>3\334\200\274G\353\354\275\376\nC\277\352\224\212=V\002\222\276\3569\017\276\2147\354=\023\341n\276\236\346\026>\210\220\224\276yCb?\177-\024\276\273\200\217\276\021w\210<\240\224\027\277E\251\203\276\3171\"\277+X\037?E(\211<$k\\\276\037B\346\275\256\n\343=\207\227\345\276\220D\253\2757\030\023\277\177\332\334=u\352A\276z\010\325=\"[\276;\234\014\340=3A\007?\3109\037\276\357y\037?\004\246\340>+\242\021\2750\206\216\276\256}\367=\3427\024\276\375\222\001\276\342\036\214\276\233%(?\211\247;\274c\016n=<\270\271\274\'\211\000\276.Dp<\310i\216>\025*\333\274\272\202\250=\364\003\372=s\342\214>@\200\203\276\234\267\352\276\211\340\304>O\345\346>\304\211w\276\024j1\277\300\t\221;\275\211S\277\3414\014?\276=\274\275\207\007\310=\272\214\010\277b\276\010\277!\311\312>\201s\343\276\372\001\347>\236\360\275>\357}\273>\235\201\304\274t\330\030\276\267|\326\276\"_v=\305M\\;^!d>r9q>/y\000?\245\222\274>N\035R=\215\211>\276\332\034\253=\247/\326\275\251w\367>\376D\"\277\307O\352><^\255>Fc\276<\336\313\275=[\356w\276T\265\226\276\341\017\201>oe\026\277\205o\035<\304\371\250\275\006M\031>\271\013Hv\234\013=\355\271\325>\016\300\013?\250\204\310\276\037\374@>\\r\245<\331(\004?m\031\010\276\025\032(\276\023\217\276\276\025N\345>\314\035 \275W\221\255>\252A\023\276Ux\230\276i\351\274\346\332\243>\032\343s>\360\237\324>\254\212M\275<\253\243=?)\337\275\254+\357=\r\323\036\275\362\305\214<\323\317\231>\2713\255=\1772t\276#N\036>t+\200d\333\363\276\240\373\">\347\362\310\274\315c<\276\301\273\202>[\267\257\275e\326a\276\0069\300\275\237G\'>4\224\010>T8\274\276\336P}>+\344B>\206\361z>\367\333\346\2757<\242\276+\212\312\276\033PG=\234\302}\276l`\316>\241R}>\206\325\r>#m\n=\207.\020\275\256\361h=\205\264\211\276-9\335>:\244\003\277o\0270\277\003\314V\276\356I\323\275b\337\031\277\017\300\201>\203\374\302=\272\031\014\277R-\217>Q\205:?p\245o\274}\366\226>\231\003u\276T\320\014\277EF\271\276R\306\264\276J~\230>\304WL>v&\204\275\032\340\304=\365\005\353\276\366L\346=\305\371\264>\025\207\013\276|G\301=\341-B>\361a\370\2766V\t\277H\257/\2471?I\222\314>\353\253x>\253\346\361=U\254I\277\265&\276\276\230A\201\2767\t\031>nv\320\274\234q\346<\373\2737>G\331\023\277~\332-\275\304Z\\\276\231N\357\276\344P+>\0250\313=K\210\005?zK+\277\001O?\277\205\305\353\275+y;>\342z\375\276\271h\251\27502\356\275\265s\022\275`4\344>\376\331\225\277Eg\327\276\235]\204=\240pD\271=\224??\374\265;>I\311\202>\273\213q\276\000C\233=\365\220\010\277\221\216n=\234\375\337\276\204I\t\276\235\006o>n\034\037>\276A\010?#\237\246\276\325S\323\275.\234\034>\274\267\003?\232\322\233\377\n\203>\002\267\366\276lO\217>T\237\227\276\362\311\244>\347\275\235\277\250\204Z\277$\231p\276\235w\344=+\222z=CL4>\224\037g>\221\007\206?)\333\276\276D\027$\276\237x\001\277\235JP\277N5\341\275\241\362\222\276\3378\227>P \254\276as\000\276\207\236&\277\217\226\n\277\037\243\232\2764\272\321;\344!t\276:l\217>%\324\216\276\212S\366\276\200+\365>\021\272\334=y\004\236\275e\032\375>\267\374\237>p\274\005>\003:\244\276\360\215`\276\005p\274\275\207\326\024?\236X\244>\240\340\312=\272`V=f\260\013<\315\260/>\263\026\336>\242v\202>\331eX?\210@4>Dj\244\275M9q\275[\227\221>ShB\276\221\034-?=\333H\276\207\345\335>\3315P>\203F4?M\375\324=\242\2638>\223\216p=\323\016\250=\225\317\366=b\320\356=&\023J?\360\251\326>ge\362<=}\310>\342~\332=\275_\273\274\340.\354\273\020\207\r\276u~\211\276\305\253\236>Qd\240\276\374\202\002>\334,1?\2616\302\275\021R\020>\312\035 >ns\017\277B\200\035?H\031\332\276\252*\206\2765\0354>\303\362\217\276\370!>\276\367\207\260\275C\225\242=Xq\226\275\326Dd>\377Eg?\215\310\215=\377\274\312>C(n>S.\243\276\332\227<>Z\346\322>\320\272\274>\320\227\032>\365\034\200>\326x\213\276W%\006?\\]\360=\202\324\372\275\001\353\252>z\304\244>_\204\221=\356A]\272p!\351>I\313E\276y\353\021\276\0043\266\275\336\355;>\335\270\307>\305M\227\276s\216$\276=\024-?\343F\364\276\001\204!?\267\330\230>d\352\363>\317\247\020\274\305c\375<5\256\217\276X\002\232\276\021\\J\276\302\231\260\276\013\237\256>27\203=\323\317\024\277\301<\327=\0066\252\275A\374\244\276gH\000?2\203b\276\375\332r>}\273\202>\017\340\230>\274\263\'\276q\305A\276\250\033\212\276\254\337\250>\377\016\342=(W\225=&\332}=a\307\360>t\006\314>6\252\205\276G%\202\276\370\223\213\276Z\003&?\364\023\236\276\254\366\300\275\210\303\375<\251?\371>7\365@>F\222Z\277\226\024g=\220\252\006?\227\037u>q\227i\276o\202T>\"\327\345\276y*\007\277\016N\003?g+ >\027i\220\275\327\\\376>)\242\341=\345]\327\276\211U\305\276\323\313p\276\305qh\276\265\324\216>\317\225\023\275\334\014T\276\254\240\345\275Y\344\365:\327H\334\274\330\274\003\2762\306\007?hT\344>\367\350\001\276\254\357\007?P]\372>H(\302\276\203\330\031?\257b\306>\3609+?\030\232\246\276\233\2548?M\036\332=c\237\257>p\001\327\276\250&\006\276\372\177D?\230\324x>X\365\212>\266#\305>\nb\253>\372\215x\277~\030\327\276\312\275\003\276\023\226{<\216\030 \276\315o\313>zv=\276ol2\276N\213\010?(\262\036\277;o\010\2774\033f>8\315\264=\377vS\276\251,\266>\362\034\322>\213\224\035\277\t^\203>\336\205\233\274\252\322\022>&f\257\275\006\030\220\276^Q\315\276\323\347u=\332\374\364>l\332\313>\227p\005?\346$N\276\234\302+>\004\013T>\307\200\365>fIh=-\030\377\275\206$p>\033\034\203>\217?\217\276\241At\276\371TN<\010\227x\2766\344\271=\226M`\276\341{\334\275\363\343%?\006\232S\274rE)>\225A\027\276\206\326\003?7\213\274>\317\331\364\276|&\331=p\366\373\275\253k\323=w\355\203>\345\335\t\275\262%\177>\263\361k\277\311K\265\237\222/\276\027\230&>\356m\231>\346\260\275\276\352\251o>\241@\270\275K\235\227=\375\2742\275\002\224\032\276\202!\323>#\240O>A\205\307>2\025\326>\367\241{\276\257\323\037\277\237\265\355<\366DD>\330\265\004\276-9\027?\001\2171?\026J\356\276o\215O\276~\002\353=\0203\256\276\202\264<>\316\"\326=\266BJ?\377\326\312=-\205\322\276\306\261#<\347 \315>c~\305>\252\003\370>\033\375\266=\3630\'>Z7\277>\237\333\335=\242\332\006>\344\350\201\277\026v\346\276V\231(>\362N\252\276\372\'\376\276e\202\240>\370O =|F\004\276\364\0071\276\004\007\321>s\362\"=\222\"\007?\346\021=\275\037\262\240\276\2504\340>\244\372\'>^\276\371>\245\242\226>5l\236\276\034\010\246\276,\357\304>\t\304\306>\032\245\336\276\244f\270\275\236\2769\277`\345A\276\226V\360=\336\257\354\276\344I\371\276\311Y\271\220\037\330>z\010\250>9F\262\2769\357\236=\322\021\222>\250\370\245>\241\340\265\276\000\\\200>\366\315\202<\035\003[>\327Y\003?\362\255j>\224$\222>\252\365\300>\204sB\276\0072\005\277\376\013\211>\235\362X\276\031q\031=\034\310\232>\245\3037?\245\227\357\275!g>>\234\351\267\276+\265z\274\373a7\276\230]t\276>\262\331\2768\213\226\276\222b\365\276-}\320>\256\034\242\276L\"\003>b+\253>\262\272\273>\273\243\023?<\223\010>\311Z\255>\000FL<\250:\025?\336\030\306\275\370\357\262?~\240`;\247#\264>\364\017B\017\277+;\323\276(f\226\003\277\232\366+\277V_\325\275\261\213\214\275;8\252>\014~k>|\264\306\276\375E3?x\376\276>-T\257\276\234\025\245>\305\316W\273A\177;?\300\037\220>W)\331\273>#\334\274IQI=O]\023\277\344^n=|\ri>\227!\025?\020\344\260>\306\301\351>\374#[\276<\207O\275=\272\'\276\312\2539\277\217C\010?\316\246\230=H\215\203>\323\344\366\273\264\365\341;\336aq\275\357\354\214\276p\333 >\246\205\r?\361\247A\276\340\334\n>53\247>}\177L\277m8\022\275\021\224\232\27684\177>\037h\332>\217\254@<1\271\305\276\321L\r>\"\257\023\276\337\234\315\276\235\177\265\275\255z\014=\2046\272>\263c\017\275k\016\331>\333\335\203\275\037\375\027P\021\276\021\237\247>\254\r\243>\217q\245>\232;\201?\340P\237\274\323\306\322\275\352\337x\275\232m\313>Gu\275\276\331i\273>\254\313\226>\371O\230\275+\303\364\275\3774$\277\200,\337\275(~\031\276v\037\240\276\223@\215?\216 \021\277\024\210\224\276\375\212\362>FI\334\275\0031F\276rM\223>\273,\033>\231#7>\266\233\357\273U\322\354>i\026;?\225\354\223<\r\241\204=\026\177\337\2757\200\305>\243Wf\275\364\212\324\276V\356\247\275\346B\026\276\267\277\257\276\260s8=d\336H\276p\332\n\275\026S\036\276V\372\330=\277CD\276\223\261\367\275F#q=\013\001_>\0320\303=DJ+?\263\026\264>\r\354\311\275\276H-?\257\016\251\274^od>Ow@\276\370%\225\276N\317\242=\\\356\271\276\224\277\201\276\222Y#\275\010l>>\031\201C?\027f\361\276$\300y>\360\223p\274\205<\350\276c\352\304>d?\217\276a\244\204\276\217]G>h\322\235>\0028\033>\264\227\277>\033J$>\000\217\177>\267\341\254\276,s\003\277\214\203\006?\204\207\030>\256X\221>\365\354\014\275\274\341\243\276\306\222\332\276C\357\313>\317\014\021>\005K\030\276\350\221A>?\254\017\276\320w\240\276w.y>\213\204\025>\007\304\320\276\371m\026\276\00044\277o\233O\276#=\020\276c\213/\276\351\033\271\274\336\357/?N\0160\276,\375/=\345\305\306:\016\353\217\274\250\221\231>\213\356.\277t\351\374=\2715K\276k5w\2760\224v\277/9\252\276\355J\264\275l\'\267>i2\r\275\013R\214\276\323\370%?l\253@>\341\2451>R\223\244\276j\374\224\276?\277\304>\342\"J>R\005\010\275U \t\277\324H\030>\005\372\215\275p\024\036\277\"\2334?G.\221\275\300R\372=/p\265\276\314\342\\=\3247\311\275\335k\260>\371\356v=\2651f>\224\246\306>@\212\211>J\341\001>\006\371v\277\337Z\177=\324X=>e\377\241>\253X\237\276\'\321\255\275\213B\221\276\347\367\254<\235I\344\275\253\245\361\2754\027\322\276dP\350\2769i\01396V\306\276\255\263\335>\327\r\t?\036\017\013\275\245\210\t>\254NB>]\317\227\276\334\350\257>\244$\014\276\000\274\002?:B\010?\2213\n?\177\223(\276\241\275\215\276\325\356\252\276{Ao\275E\352\023\277\022@\336\275>\374\326<\273\020\333>X\351^\276\355\277\352\275,*5>\335\t\267>\376\312\237\275G\312\233\276h\212\322=.\246\336\276;\256\010\277\007\236\310=\237^\231=\341\355\331>\317\332=\275\272dp\2761d\346\273\265\300\270>\360\264\375\276\021+i\275\271\201+\276\200M>>M\266j=\310\240\335=\362\347Q\276H\301\020?-V0=L\330\266\276\253@\016\277[\311\300\274r=+\277\327v!>NX\315\276!\306D\276\202\245\001><\256\375=\3553\264\274Vo\275=\315\322\031\276\343\351\231>\022\210h\272\206A\275>\321\321\327>\345>A>(L\357>\260b\302=o*%\277\274\023!\276S\006t\276%\221\202\276\027\035\331\275\367\275\347\274\024\002\242=\006@\000\276]\0272\276\212\3732?\330\232\365\273\021l\255\275H\005e\276\016\323 ?\036rW\276\305\352\240>\3535\347\276\254\026\306=\025\3158\276\347\225N>\321\375)\275\234\303\257\2752u\227>\310\032\260<\261\241`>\320\236J>\017\376,\277\375M\032>Z\322\002?\243\322\303\275gO\000?\036-\350\274#\333\001>3\000\331\276Ibb\276d\363>\274\225\352\255\276_6\020>\330Y\236\276\265FE\273\007zZ\277\001\272\241\276\342\377d>g\0221;Y\030\366>\325u\362=\214\310c)\252\275Ov\233\276\345,I>\026\222\004?\200\232\367\275\242|\262=D\226\254>P\331\332>\240\177g\277\250m%\276\246r\276\276k\265^>\314\204#\275\313\361>>\037\360r>Y\201G=%\274\\>\330\344\217>\260\266\207>(\205\245>\275\233\350=\377\2370?\302Y\247>G\203\226>]\244\010\277\256i%=\017V\370>\370\204\013\277>[U=M\316\215=\234\262\344\275\017\207\n>KU\200>\332\212\r?\305Q\017??\333\245>\364\261\216<\227\301;?*\336\343>\036\273)>\037\3059\277_\260l\276xyB>\002\2230\277Y\316{\276\337\377 ?\213\006\027>\370v\353>Y\302\026?\352\347\215>(kE=^x\331>\201\236\264\276\327L\343\275\010\301\350=[0\305\275\375\313\210<\234\320\032\277\200A\024?X^\244=\000\003\210\275zsz>I\313\274>\303\n\326>%Q\r>h\303\204<\272\346\356\275\332\316\r>\304\336\264>(\370\023?Y\232\305>\273\251\017?}R\374>\311\236Q<\303t\276>\017\335h\276MN\273\275\014\0038=\376\237!>\370#\371\275m\022\014?+7\255\274\236=\334\275Jc\277=\3240N>\302&^>\250\264b;zz\213\273\216\\\226\274\227\013\341>\324\212m\2760\006\002?\331\2010?\257\002\245?\341U\266<\326\312\265\275_\002n>TT\353\275\212\303\273\276\325\277\244>i\217\231>\347r\332\276!Y\264>\350H\301=^\n\023>\021\002\276\276C\270\360\276\343N<=\226\321\r\277vf\365\276\\\004{\276T1\r\277(\0144\276O\227\206>\341\360\232\276\237\312o>\365.\371\275\'B\330=\324\027\336>\326O\220>\010\326\t?\010\341\326=,\244\017\276\215\325\220\276\210;\006\276;\256\036>\310\245:\276\006\230\302>\254\352\010\276w\342\204\276\207\224\265>\033f\274\275\354\330\233\275{\026\346>)\3763\276\316C\226=J\277c\277\321Q\334>\234c\274\274\262\266\r\277\r\222\026?7\314\334\275v@d\275\365H\010=\340\362\274\276\237\260\210\276D<\257x\333\370>Jh\246>\177)\307\276\235\177\030\276G>\315\276\235\177\263=\311\343\317\276\377\315A\276\265\251\242\275\006?:\276B\342\351\275\016\236\024\276\036\266\362,\n\030>\316\311\237\275\304Y\r=\331\330\225\275\340\373\326\275\357\341\314\275\347b7\276\n\344\t?\306\352\001\276\251\035\345\275\302\200\362\276\024\034\207=\004vl\276\312}\'\276\222R\244\327\274~\276\300\232\027?\236\377\t?\251\360\023\276,\215d\276\342\370\235\274\007\3004>\330\206J?\230\036:>\320A\244=)\260A\277g\313\t\276s\377\333\276\257\310\375>d\'H\277%$\"\246\374l?\204\016\310\276.\266\"\276\246\331\205\276`\276\232>\356\333\006\277^\030\033>:\306\017?\300q\260\275\304\021\024\275\214\037 ?\tX\313>(v\016\276\204\245)\277\201Q\333=\363\224\255>\035\273=>\007\374\340\275\355\360S>\004\363\232>\225\366\013?B\372\031?\0165\332\275\250\2521\277\371\247\304>\3512.\277T\321@\277\251I~>/\026\201>\325\200A\276\3578\231>;\342\374=~d\327>\014\253\035?\215\377\020?\232\376\036\275F`#\277\217Sj>\331\205s\276\302\306\361=\005\361*==\322\201>0\025\373>\035\023R\276\\ \376>F\005]=d\023\220\276\313\325\014\275sX\330\276A\344\223?\302W\031\276\241\213\311\276\264W\260>\365\367\'\277\207B\344\276\003\373n>d\0230\276.d\375>`\005o>\372\336O\276\227\325\207\2761\265\213>\252\377\320>J\327B?\234\217F=\206\311Q?{_\307>\321\245\324\265D\005=\201\235\341\276\213\371\222>\222,\347>#\212\033\276\010E9=\223\210B=\010\277\222\276\252:\215>?U\360=\276\207\203>,IR?\310\351\246\275\021x\256\275t\275[>\t\341\372=8\314v\276\350J\271=u@d>\004\t\315>T\211\230>o\263\364>O\224\255\276\3766\017=.\322b\276\3539\323=\r\305=?[\250\037>fK\345\276\377\022\022\276c\037\243>j\322!\273\002\311>?\347 2>\302:\304\274B:\307>\020\337o\276\034\324o\276J.\355>\223\001\036>\206\005\306>\311\000V<\027kw=s\367\004>E\326)>\035>\262\276\256\326\256\276-<\010?\204\267\230=\341\343\260=[\250\366>;M\t\276\315\237\237\275Z\347\356>!P0\277\213f)?\243.|>\376\254d\2763C\302>\365\213\230>\365\277\306>4\007\350>3\366+\276\327\352\'\276\247\311B>\342\225\234\276\352\350\233>Nc\351>\210\220\313>7\023o>2\025\030=De\243\276\177\330?=S\255\220>U\230N\276\216\240{\275l\320\330\274\344~\204>\341\366\306=\273c\277>\177d\371\276\037\264\244>/qM\274\326\322\232:\325\354\216\276\211\022\021>r\275\376<\371\025z>\316t\003>\3317\014\275v\363\223=\236\330#\275t#\024?\206\267\306:$D\334=2+z\276ge\214>w\365\263>\252\177\316\275v\351\010\275\001-\332>\347N\320=\234\007\035\276z\034\r>\240C@>,\351\376>Y-/=8\367K\277l5M?\212\021\323\276`\375\303=P\222\205\275\0318l>N\244\205\276\217\366\245=\004\334\355\276\325\265\031\277u\"\365=\265\304\316>v\226\210\276\370\201\323>\273\376\r\276\310\211\030\276%\250\326\274E\3625>\317\316k=\251\024e>\237\351?\277\365\362\302\276]\237r=z?r\276\350A\311\275\314\034\236>\010\022\030?[\325\227\276\357\"\255=EJ|>(\224\270\276\245pU\276,\310\271\276]v]\275Y\003%\275\336\037?>&\240\270\276\237\0060>\032!U:\025\227\034\275\246\002c\277\323\363\"\277\335\226b\2763\230\213>K\014\372\276f\342@?\204n\3619\035q\023\276\311\341\036?\237\362=>\002\004\033\277\007\367\223\274\315\271i?n\363!?j\337\232\275\346=\032\276\274h]>\263\244\217>z^\244>\270\315X>n\301/?\200\363\351\274c`\257>!\325m?\342<3>5\021\371\2745\242\344\275\'Fx>\204\377\024\276<[\321\276>\352\302=Z@J\275Xq\312\275\023 7>\343)\344\276\270g\341\276\212%\265\276\010bD>\346\273\267\275m\333\255=\365\333\203>\250\345\000\277\300\030\202>$\261M\277V\274\214>\336\\\301\276I\301\304\276\331\373\227>>\"\211>\212\244P\277\232%\343\276\204\266\234\273\300a(?J\020\363>\326%\010>\374\006\325=\263e\267;\316]\\\276\003P\035\277\315k\017\2779\302K\276\263\353#>\375:\352\273R\033\222>\306\224\251<\007Y\210=\225\r\332\275C7@>\2663\261<1\0206?\016^]\274\234\374\232\276\243\267A\276\032T\010>\324\010\336\276\371\225C\274b\227\243;\345\3473=\246\357\246\275\"\210M?_\376\212\276\025?\334\276o\003\214\275\354\020\340>N\357\017?lH\250\276\341C\275\276\202\376\023>\001\363\355=Sy\001\277\323_$>\321\201g\277\247\300\255\275F\206o>1$A\277f\317\362\2768\256Z\276\307pq\276}x^>\3634<\276a\'\022\277\236\037\206>\374o\246\275\330J\226<\334\016\346=A\006@\276\267\"N>\240a\n\276\356(\030\277\203+\030\277y\332\007\277&\327K\276\271\356\220>\027\254\276\276\330\234\031?\200T\377=\354g\202=\203sO\276^M&\277,\317\267\276\303\324\214>;\263\241>\341\252 \276\312%4\276\034\204\330>\205\373\266\275\010}\211\276\367\026\341\276\000\374$\276D\263%?I\035\014\277\252\325\303>0\336\217=_\335!>\344\031y\275-h\354>J\255\212>]]\302>\2366\274\276?\225E?^A7=\021\376\306\275M_k\276\271\002\016\276h\332\013\276\250\211\315\276?\330u>\237\322\255>\374\200^\276\\\317\341\276?\253Y>P\002\\=\005=\240\276\270\232/\2765\204\326\276K\n\234\277\337\3223\277W5i\276\353\322A?MV\220\276J*\352>\215F[\277\r(\200\275\252!\021\277\260\203\202<\254g\351=\301\3562?\2430S\275:\214\372\276\031\177\252>#S8\276\327LE?\232\351\360>\000\\(?gn1=\304+2>F\365\201\276\366\315h>\304\313)\276\177\017\246>i83\275m\224\247\276L+\335=o\337\357>\250a+\277\357\242(\2775!\330\276a\326\245\276\0006\335\276v\217P>\200\250\204\276\t\350U\275\000\231\263>\006\333P\277)\334X\276\000,\264>Jy>>,\300\265\274\007\242\261\276\276j\013\277\377\231o>HAx>\250\227\206>\206\006\210>\307[\231\275\n\276\245<\236O\322>\302=\351\276o\030\237=w\267\306<\t\276U\276\036\333\206>_Mh>\021\\\233\275f\256\220>I$=>[\'g\276\014\241\300=\331zes\324\352=V/.\276&9\205=\265&\226<\377 \246>\302\356\336>nI\355\276\377m\201>t\310\233>a\264U\276\256\266\323>\'\300\347>nqN\277\311oa\275t\363F=\222\331\216\276\361\003\205\275I\362$?\014\226\"\276H\002\232\276\335\212\024\277\275\031\261>t)\241\276n\202\016\277f\375G\275\"\354\n=\221U\333\275p\223A\277\242\254)\277n\014\032>\304V\230\276\335`X\277x=\206>U\250\002>\\g\371\275\250\334\261>\327\033\274\276\332$\222\275!\307A\275Nk\347\276h\277\346>\237\202\026?C\024\215\276p\001+\276\014\017\013\277\003\265\334\275\350\347{>\246(\263>f,K>\324N\271\274#\202\262=\361@H\276\354K\331>M\203\265\276r\222\300\275]\251\027\275\344d5\277\253\301\321=\266p\264;a>\216\276Uh\023=\253^\206\276PV\232\277MbL\276\277v?\275K\025\233>\210\335\354\275T18\277\271\031\210>\314\034\337\2769\3003\277\'Z\334>\026\211\317\276a\220\017\276\246c\001\276\225\262\376<>\322&=\342J\274=a\327\315\275\246\212\316\275\230f\230>SW|=O\256\242>&\225\010\277\245\333B\276%M\202=\266\206-\2512\201\276u\344+>\314\303\217\275\271\324\227\276\270N\375;jVF\277_\320\036?[\345\241=h\233\341\276\364\230\345\276:\002C?^|\314=\243\270\371\274\312\'\235<\022\257\231\276\215\310$\276=\317\211=r\256\357\275\217\220\207>\031*\013;\220\312\'\277\344\036\232=\006~\304\275\022\237\276=\024\'\227\276Sa\200\276\344\262#\277\305\362B\275\362\316l>\311%\315<\254X\212\276j\225\007?\n\300\017>\245\017*\277Z\364\276\275{\225\366\275q#\326\276%\264\036?`\375\210>w\337\376=\326*\013>\302\303\200\275\310\034\224?\370?\204\276\375\226g>\340#A>\273\026\303\276\246\372*\274\342\330\234\277\233`\260=\313\r&\276\002\014\246\276\260\344E?\213\235\311\276[h\303>\340\322\002>\361G\027\276\265\264\231\276$i\'<:PG?\376\321\221\276\017T\200\276\230_\277>\357\333\321>\301p\214\276\201_\355=\000j\032>\362.\264>\227\010]\276\322\022j\276\216I\326\276\246\006\013>\267\005\211>\261\327\022=\233\013\334\275j\251\277>\232(G\276:UF\276\311\023\321\277@\347R\275RzG>\337\327\343>A>^>\025J\036\276\353\'\001>\340\r\314=b\024\204\276\300T\352>h\224\275\275c\215\222\277q\343\021\276GK\216\276\216Sm?\341k\267\276i\303[=S\361\361>5\013\232>\240\316@\277I7\205\275,\327V>F\343\225\276\213p\007?\215\034\270>\201\261 \277\327.\305>\255\310;>1$^>\337:\351\276\341\371\212\277\032[\326>\333\204l\277\226\212\311=\354\263/?\030\276\223r\017\276Xo\256=v\223\016\277\263\266\320\276o\020}>\007\364*>\023\251s>\351\016(\276`S\023>d\262\340\274G\367s>\247A\265\276\305=c\275\252Fc\276\346\005\350\275v\233Z\276x\253\356>5\226\227\275%\266\241\275\210\362\203\274\230~\254<\337\261\251>l^\345\276\034\244\t\276<\256\202>\363x\333\276\036\346\266\276\234\356\274\2756\031\350<\"W\204>\002\036\377\276\306s\277\276<\2552\276-\002\006>5\r\007\277\006\r\275\276}=\355\275\001\212\030?L;\276=1\267{\275\374\262\235>\005\2067\276\230&e>Gh\302\275v\017\n\276\227\t\311>\256\363\225\276\177\303\274\274\022\337\202\273\315Y\001>\276\013\354\2766s\225=<\016]\276\365C\"?\0223\020\275\267\346\376\274\353\246\007\276\006\342E>\265b\006\275?r%>T\272\213\276\360Q8\276\001\026\230\276(\353\311\273\357+\256>\364\372\322=,z\033>7\003\374>\252\245k=\00681>\262(\376\276l+\236\221\362y\276u\356.\275\234\234\274>\311;(=\332\272\211=]\236M>\2629\301>E\327\202=\013\263\257>\001\263\030>mb\341>!J\211\276\036I\036=\244\035$?\031\025n\275\230\007I\277\336\333\236\276\243\310!>v\344{>e$\030\276N\261\313\264\233\246\276\273C\332=\210\375$\277\215\270\t\277\372Au\277\312\273\203\276W\227\320\276\252\000\233\276\355\016\005\276\366;%\276\342\037l?o\347\207=\234\332\201<\226H%\277\363\353*\276\233+r=l{\024?G\305\010?:d\023\275F\371\332\275\027\035\261\276\207G\177?\201!\331>\021<\271\276\271P\024\276\343 \316\275w\036\241\276a\303\244>\322\214=?8\002\220=\0330\270\276\3656\034\276Pk2>\022:\013?\224B\"\276\362\177*\277\t\267\234>LB\360<\353D!\277v\266b?\2244X\276}C\213\275M\214Q>\237\226\243\275P\214\323\274\200\332\345=\203\313\277\276\003\007\023?\221\223\242=\230<0>\275^\272\274\005\312R=q%\215=ZUG\275\211\033\262>\241\205\317>@\332{?*\331-\276\330\211\361>{f]>v\"!=\275\262&?\304}z>s\303\336;\001\304\370>J\247\r\277\037\240\376>Y\r\177>O3\335>\'\031\357\275R>o\277\2271\013\277\263\304\233=Uw\223\276U\204\246=\205\003\300=*\362\036\276\302(\257>[\tD>\374\340\226?\027\271\220\276\370\236\255>\225,\037\276\366\\o\276\006T{\277\342q\210\275\375\013\336\276\303\017{\276\2167\220=\377\322\036?-\226\252=\263\362\006?m|\230=\330j\222:\254\246\022?\032>\037=\340\372a>\341\266r\274\245\033\320>\036\013d\276w9\234\276\245Np=\177M\202>\034\233\370\275\014\240l>\217\276\033\275\021/w>\000\265\207\276F\252F=\363\312\256>\325\020{>\031\031\250>\2220S>\246\307\264=\217h\253\276\232!Y=\327\217\300\275@\006\355>\237\331\200<\250\327\025?+\312*=\302\000\204=Yy\007?\342tN>\373\365\222>\323\365M>\016\306\210<\227\236\360>|\342D\274x\030+?\037\316\364>\231O\247>\270\266\312>N9\247\276\034E\240\274\350w\326\275[\326<>\3529\276>\252O&\276w\301@\2777\204V?\346KX\276a~\021\277|\007\004?\241U\221>\020\200\377=a\211}>\264|\003?d\263\274=E\030\032?y#I=R\003\223>ql\301\275\221\352W\276\203\304P?\227\331\352>/\003\330=\"\373\025?\0226\022\274Q\220\251\275\236\222\257\275\265\344\026>\2555\032\276\023)\306>\206\226Q\276\323\334F=\r\242\314=\214V\355<|\025\302<\207\325)\304\360W\275\306\260)?\221)\021?M\200\234\276\353\377R\276\335\004\330\276\301\345s>\221\263M\277\340\247#\277\2343\336\276\004<\373\221h\300>S\274\030>%\210\327\275\006\2476=p\010\234\006|\215\276\305\346\266\276\211D\220=X\005\206;\346\037\260>k8\360>\312\026\216\276\'^\374\276\201\360.>\010\246\265>\370\347j>\367\324\233>x\361\003\277\212\320\221>\001\336f\277m\'\016?\323l\"=\222\351\210\2767>\200\2763\036\242>\330\313\256\276\200\205\177\276\353-\236\276\252\005\257>gO\317\275\210{\236\276\220F\240<\273\374\201\275\246\261\200>0\224\264\276\331\255T>\274\231N>\275xG\275\264\017\177>>\241\217>\357\213r>s\376:\276\325[\370=J\342E>\340\002f\276\211z\013\276\340lD>09]\277-\222\021\276\322\306\013\277:\275L>\237\013\224\276\277\025\331>\004\001\261>C\312\032\277%\3746\276l\017\361\276\262\000\004\276\233h\241>\003N\177\275\212Z3\276F\006u\276\360\217q\275\253\213\004\274:\230\303\275\251\240\362=1f\230>1\024\263\276\3642&>\362\220)=r\3363\276z\373j>\003\003\227\275\201S\314\276\225\007\275\276KN$>nW\037\276[\345\353\276\337t=\277\203\366\344\276^\220\301>\037eL>\267\320\001?\356Y\247\2764}.\275\207\277\007\277e\272T\277\0027\034\277\327\361\010\276\306\263\034\277\226W\224\275\303\357*?F\262\263>\272\266\"?\37204>{yM>\267e\204\275\036\322\036\276=\245\022>\0260\374\274\003\036\026\277O\214m>\317\034\254\275~\214o=\350\210y\276iL\273\275\357\322\271>/F(\2762d\222\277\010\000\324>\336el\276\377T\365\275\377\273x>\315k\"\275\226\"\034?=\020\251;\352\307\306\275\317d\342=\r\365s= \375&\275\232\\\222>h\252\027=,w\370=\354t\300\215\321\177>\344\334X\275\351\337\260=\352K\006?\244\017\260>#\223\002?W\3259\275\266W*\276\334{\213>!\342u\276<.\276;\221\340\260>\240Nd\276\200\350\301\276\213p\345=\233\0137=\375\237\374\276\342F\006?\273\234a\276\221\202\233=.\345\221>C\032\005?|\007\237\274\t\220<\275\000\227\333;\351\314\220?@\035\276=\004&\325\276\335:O\276\360z\327>1L\240>\026\320\032<\366\267\200>\260_\316\275\030\222K\276\366\255\201\276 \025\335\276\241\306\203\276\361\353X\276\314v4\276Q\354\256=R\202\240\274=\344\026\276\323i\203\276\037\241\226\276e9\215\276\267Ps\276\260@\327;XQ\006>\213\262L=x\253b\276\023\214m\276$|0>R\310\330<\311E:>\251\244/\276]\263\006>W\3000>\273T\347\273\212\272\353>\320}\231>\254XW\276\251\232\253\276\251\342M=x\025\326\276C\363\242\304M\337\276\250\213\257>E\375E\276\000S\020>*\370\225\276\010i\312\275\322F\034?\205\034\272\275\201[\353>\006I\'\276w\342\311=\352\326\034\346=\014>\213\301\246>\247\202A?\200\251`\276\303h1\277k\240!?\204\360R\276N\202\316>\316\302\304\276&\251C>Z\314\026\277\221dl=\324&\203>\242\346D\276\247c`\276\217g\351>\031\242D>\036\252S>\t\3044>s\277\004\275>\340\306=\207\010\021\2763]\363\275\"\331\007?Z]/>09\016\275\347\276\272\276\267m\002?h\263\005>\241U\324>\2668\002?\020\237W:\331\264\313\275\227#-=\030\376!\277UF\201>X\373#\276\346\355w\275\307\326\035\276\232\224\307<\324\214\202>;\261\236>G\355\270\275\357\311\035?\246\307+>\244\252\222\275\201\350y>\302\236\217>\265\266\250=z\230\214\275\377\\\343>\036\t\234=\32262\277\024G\203\275\234\254%\276,\261\010?#\347\007>v\316\265=v{\357>\036\310\271>\031IN\277)\371\200\276\207\366I\276*+\267\276\227\272(\276` |=\253\250\027>z\321\273>O\010\273>\224\267\036\276\234;#>\240\005\301>\320O\005>\250\272\356=;\372e>\341\274\273>\217\367\030=\2045\020>\237.y>=\254h\276\333\322\223>N1\033>>Y\343<\\q\032>\345\217n>M\336N>=\352\213\275HM\036?\214\357\347>\334\023\232>\2401r?v\2067=\277\010\300>%\354\326=\301\251&>\331W8>~\200\346\275\336\304@\276\276|\260>1M\224>\310\205f>SX\355=4S\226>\257Q\262=X\363\333=\206\233\342>\017L\200=\270\023\217>`\004\203=\273\276\303=\326i5>L\0050>\337|N\274\241\227*\276\377U\025\276\\\304\001?\220\221\311\275;\354\242\276\221I\004\277SN\n?6\340\217=+A\212\276)\260O\276\203\377g>\356\\b>\247Uk>\251\261\201\275\223\235\221>A\037#>\177\341\224>\240S\263>l\334M\275\267cb\276\355Z\004\275q\2746?)B\256\276\246W\214>\005\204P=\331o\231\274\027\326(\276m\320\274>\345\351\211\2762N\302\276\0031\017>\301\030\326=FC\261\276\277<\\\277h\210\340>H\252\366\275\033\307\201=\335\023S\276\035\215\373>\335\214\253>\323|\201=\364j\364=\317\301%\276\326\013\002\277\204Q>\276\234\202M\274\017\277\333>\374\013\212\275\276\275\351\276\246hC?d\353\214\275P\202\001\277\205\265\020?\256C\250\276\220\035\003?\347\356\010\276\262\247K=\205\"\320\276O\215\335>G\002%>\033\250\263\274\003\027\206>\242\"\\=\005\332\255>\215\325\203?\303\211\351\276\344\204\353\276\322\337\222gJ\222\276\342\351z>r1\003?6w\005?\001]K>\364w\254>\235\232\312=\'%]=!\2615\275\2166\007?\276G.\276\214\002\200>e!\251=E\362\370>\302\237\265\275\275\313\013\275\374}\206>!\343k\275\251\356#=Tt~\276<\225V>\315:\277>\345!\244=\257\226<\277B\347k>\005F\036>\243?\001?\225V\216\276\003\030\006\274\273\332\217=\366\271D\277=U\226\275\363\344\321>\242\035\010\277\303\240\000>\300vz>\021=\221\276\324]\'\277\337\360\030\276ap0\277\217PP\277\005F\251\274\322g\010\2775\223\245\276\257\274O?m\205o=\265\257&>_\366\323=\316\234/?C<\t>\301M\376\276s\337\224>\372\021\200?\031,\211\276]dE?_\373(\277\037k\202>\216-\334=~\253\n\276s\362\373>\233/\340>\371\332\254\276\353\337\241\274r_c\275\266g\233\276\240\351\357>\250\327\332\276\td8\277\344\373\231\276\223<@\276\014V\006>\026\2627\276\277\340\222>T*\233\276\306\244\306\274\254\221\331\276d\325\016\276\332m\347\276\221a\306\276\317\234\026=bjx\2766\332\213\275\216\334\010\277^F\035\277\254\252\345\276ak\221\276`\306\305<\244!\230\276\004L\321>r\250\371\274`\0143>\244\371/?A\320/\277\211J\337\276\274S8\276l\245J>\016\2072?\236\340\371=\345\240\036\275\256\"=>.\361\326\276\3406\365\275dw6>Wsc\275\364\263\335=)1C\276\351\016\211>Q\013\252\207s\307\275\357#\367\274f)\376\275\005\027:>+6j>\265\030\223\276)j \276\273\336n\275\2352\352>!\310\366=\270N1=`\316\000?\326\305H:\030\243\255>-V\306\276Q\025\201\275\250\362?=u\225\006?+\003i\276\352\224$\276\245\352\002?\2446\260>\322K\002>\251\330S>I\355$\276\206\201\200\276\206[\234>u\225\341\276\265@&\276\227o\302\274\243\305\025?\223>^\2761m\210>\246D\204>/\335\277>O\261\202\276\336.\233\276\252\247q\276\234\307\250\276\376\261\\\274\255\035\001?o\201 \276\272\213\016\277\210\020M\276\177\303\327>\342\254H>\001\000=\276R\347\036\275\014\217\355\276\353c\347\276\364\274\300\276\321\273x>\246<^>\203l\354\276\336\262\225\276~\037\n\276\031\010\r>\211/\303\274\234\270s\276\007\265\377\275\325\024\210\275\300\225+\237\335\276\252\354\237\276\020z\033?\223\213\355=\254O\374>h\245\002>\212\333s\276\241\354\265>h\255\001\277\347\240\016\277\202t\022?\260>-\276\361\007\343>\021&c>\343j\315>\002\020\200\274\030\213\264\276\017\005\014\277\240[\025?\310o/>\357r\034?\005\300\236\276cs\205>\032<\036>r\233\016?WH\376\276\026Zw\2760\226(>\3779#<\344\311\227\275\304\230\2239$\374\246=.n\257\276!\263w\276|\253\020\277,\264\252\275}\323\\=\377^\232\276\222^\372=:9\020\276\007D&\277\234\273\226\273`\247\234>\333w\'\277\202\007b\2733\312N>\351D\t>\252dD\275\225\230\035\277(rm\275\311U\374>}\250\220\276\202)\016>\377\001\227;\321X\023\276E\345\305\276%\005\343=\262\266\027?\273c\226>\325CY\276\006\255\302=]S\r?\374yq\276\274\226\031<\226=)>\357a??w\"\326\275\177\366Q>\3616\251\276 RT?\371s)\277\375s\213<\315\026\236>\021RZ\277\016tt\276\322mQ=w\270j>\372\322\027>Xe\301\274@\244\260\276A^E>\336(\232>\217\271\254\275\325\361\274\275\253C\223>\220D\334>\226\325\364\275\225W\235\275\2157\016?\340\242\373\2744\255\234\275\371j\342>O\225l>j\301&\276T$C>\302]\216\275\322\003\356\276\362\227<\275\273H\300;\350\343\241=\312\r\215=\371\326c>\313f\014\277\r\374\013?\316\364\001\277z\306\337\276\031\234\361=\234\201\037\275\241rz>\341\232\305\275\224!\213\276Jn\257>\213\352\262\276p\260\225\276\020\344\r?\345\363\236\275\246\211\035?\267>\340>\201\364\223\275[\350\033?f]\346\276f\243D\276n\366\300>Gk\204>PJ\021>G\323+=\314\250\214>\370\346\200\276U~9?U2e\276g}\277\275\326\022\224\276\227Q\256>\222\302\237\276WM\342\275\250Q\361\276\026\261\222\275O\021\003\277\362\357\302\2766\327\016\275,<\250>\353\262\033\2775q\014>\204\274\004\274\020\374\204\273\347\215)\277w\235\252\276\255Q[\276\201+\010>\370\367\016\277\002\275\262\276c\2308=t\346\302\274\035\213\213=Mn\010?\355\260B\277%o\205>\352\374=\275\346\023\366\276\341?~\275B\343t\273%C\311\276\321\313\345>[;4>\251\234\252\276W\277\251\276\025o^>\213\354\366\275\033z\327\2758\3304<\325\200\260\276\332\311j>i\302\267\275d\273\261=D\233{\274}7\240\274\006\332\340=\r\217\225>-\032\003\276\234\206\240\273\363\353\263\276\251\371\312>\235!\026>\031\007\352>E\211<\274\330\273\215\276\307 \236\276U\2760>GA6>\302\355\314\276I\322o\276@G%\277\360v\025\277v6<\002\013\202\276|\251\013>\210\004E\276\330\214&\276\246\\\346<{\363q\276\213T\336\276be%\274zp\213\276\351$\314\276\266].=SG\017\277\265\373C>\001\354\022\274\240\315\025\277i\371 \277\240\267$\276i\345\213>$C\331\2760\237\212=\270A@\276\345\253\277>\306\230\274>\376U\334\275\034\317\030\275.\341T<\221?\t\277\250}p\276)\233+>\247\302\021\276KoD>\026\005*>\302\246g\276\254jC\277\370\221<\277r\210\335\276\362\0073=t\312`>\243g\214<\334Xu\275(\235Q\276\336\026\335\275\315\267a>\246\276\016\277|i\233=q\347B\275\240\030\246\276\337\246\266\276\2451\214\275\270\270\020\276B\340\365\276\3250\231=`\215\251>\025\244\030=\341\211\217\276@NY\277\232SZ\277\213\273\006\27772\274>u@\305\276\221\320\313>4\233$\277N\374\277>\336\025\250\275\217p\372\276+p\004?\305\010M\275\301\210\233\274\301e\263\274;\225b\276\031jm\2754\357d=\263\310\203\276\230}\013\277N\210\211\276\010\310K>\310\263\203\277p\232\032\276H\353Y>\202\274\354\275<)\232=\366\"\243\275\371x)\277\242\005\201\273\317,\371\2757r\246\274\224\226\316=\376\246\322>_\324t>\3558\252=\242\014&\276\230\325\202>\240\263d\277W\212\006?u\230\246\276\212\237\232=C]\220\276g\326S\274\313g\255\275\225>\334\275u\026\032?\333\224\024\277\327\363\243>]\227\356\276B:K\277e\245\031\276\214\217\244>\213\226\216>\340\330\033\275\260\031\240>\020\234D\276\315\266\\\276\233\021\215\276\013;\224\276\177\022\334<\230\250\236\276\200\254l\276\"e\352>\031\005\241\275wE(>\212\325\370\275\375\236\344\275\027\317\257\276i\307\000\276K\026\023\276\332\373\205>\364\2432\277\222\357\236\276\321\245\372\276\013\206\211\276\242\305\317\276\246\020\\\275\247\214\215\276\215\234\210\274\242eF\277\304\224\235>U\306\311>t\252,\277\320\221\375\276\3601\243>\370\223:?\214\020\365\275\027\211\325\275\302C\006\277\n\003\342=\034#\212\274\335\346\026\277W\236M?j\337E=\262)\232\274\351\361\354\276\261,^\275\314\347\013\277_\204\254=\224\323>>R1\022?\227\342f\276\336J\205=*z\227=\345G\326>:\242\237\274rLW\276\030zD\276\316a\230\276\212\004\200=\233\201\357>\302\274\030?F\376\273\275i\274\210\275\261L\304<\271.e\276gg\237=\010\037\236>\003\007\225\007GW\275\030s)?\200\207A\277\365\001.\276\0333\245>R\222\377>\n=\265>w\273\225\276\273RD\276\n\207\241\276N\277\332\276[\300\353\27621?\275t4\231>\365\0009>\313\335\371\276v\342\033\277\373F\225>@\224\204>u\345D?\346\317\266>\006D\014?;T%\276\024\020\213\277\247\230N=F\3712>\362\014n\275\017\250\037\276\202\266\235>B\253)?\033<\037\277\250\325\365>i\213\n\276\212l\305\276\'&\355>Z\335*>\223[L>Mb#\277}\022`\275\365a\010?\023\n\216\276\253\014\212\276\340-u\276+\324\001\276\222A\002\275\374\001=;\013\204=\276\210*\333<9\215\355\275c\347\273;\2169\377\276v%~\276m\326S\276h\027\010>\301r\336=\223\345\\\276\0026\206\276\305Q)==\357\010\276j<\202=\347|\033\275\256\371.\275=I\246\2759\202\315\275\252j\025\276)\272(?\026J\000?\217\272\203>\"H\223\275\307\317\207><\252\267\276Q\325\235\276{N\273>\245\207\265\276\335\261\026?\230\203\211>\337&\226>.\265\257\276)\024f<{y&=7;\273\273\355\253{>\344k+?F\025\266=\363\340\212\276\200\221\255>\244\260\020\276\004\177l>ju\n\274q\256\021\276@\237(\2760\016\350<\375\255\014\275\250:\276\276v\003\013\276\004S\224=\035\216|\276\254\035u=\002\2047\277K\333\001\275e2\014>\rZ\254=\250Y\021\275C\3731>\241O\332=CJ\207>\033\260\216=3\014\256:2w\351\276\'1\020?i\302\252\276\323\205\373\274+*)\277k\002\347>*6\236<\377\202\002>\240q\362=Q#\341\276\320\360\322\275\211\352`\275v\252_\276A\234?>\270 \355\275V\225\226>\252\371O\276I\010\271>\223k$>\350\2260>)|b\275\352\020\037\277\260\273\000\276$\354\025\2763p\177\276\227\\X?\301C\377>g\333^\275o\331.?\203\316\001>Bnn=\361\324\315>\361\2424>K1\354<\222\000\035\277\217\020,\274Z\033\333\276,\323H\276x0\025?\204\271A\274\312`\260\276\022\337\t\275\3770\002\276\360&\273\274\371\000\013\277\0162\332\276\257\374\027<\250\367\006?wm\001\276b8\213\276w\017\024>\r\214\035\277\335+6\277\037\274B?\226\224\240=^\364\"\276\264U\003?P\213\202>\317\236#\276;\'l=\247R\220\275t\374\240>J\346\366>\261=+>\213A\021\2755\314\207>\226\r\226>\230v\366\275RLR=\254j\024=-\000\205\276\031O(\276\253\361\226>c}\023>\004\347\245\276\000s\234\275\266\275\027\276B\262:\276c\212\013>\320\304\265\276\206T\352\276\030fi\273V7\001\276\203\033\371<(4F<\275(\316\274\330\347\271\276\253@\330\276,\237%\277\021\0046?5\211\021>e/\367\275\251n\377>\345z$=X_\013\277\353@\217=Q\246->\311\376 =\276t\362\276\360\346\215=\362\263\233\276\227\354\215>\260\272\235\276\005\373\037\275 RM\277\326g*\276\257I\352>\031\027\231\276*V\372\275\276p\013\277\271([>\036\234\362\276X\321v\2764\304\246\276\024\257q>\354=\242\276NU\376\276\2750\r?`\373\227\276\261V\004\277\005\360\265\276\342?\004\276\301\341c>\004\236\212\276\356Q\304\276\204\245T\276\305\030\203\274/5\357\276\243\345\002\277h\366\327\275\021\233\035\277:\240/\2766\0305\276\321\034\001?\010\326\273>t\231\364v)\200\276V:\270\276H\365\035=\3227\344>\014\214\210<\362\244\311\274\264\276\227>id\210>\222\345\202=D\231h>\321\334\214=\217:,>\177\024\251\275\362\t\245\276\260i\036>\317\010\253\276&7\304>\242\215g>Y+\000\277\013\256\315\276~S\207>\243\354\255=l\335\200\276mJ\336=T\324}\277/\350\203=\310\023\311\276&\335\214\277\261\352\317\276>\350\230=\352\226\343=\315\271M\276\274X.\267\031\032\276\260u\r\277\025\235\372\275^ \336\276\2348\231\276\233\344\201\276L\013y=\322a\026=\r]2?*\277.>A\031M\275\335WH>\316\037!\277\020O\345=\207\224]>s\255\214\276\305\024\310\276\347\2646\274\215\215\264=\356\326\342\276d\020}\275\313\023\217\276\251\223\371=\326A\007<\234,\223=\034KU\276c\243L\277,\276\374\276\214\251\222\276\203\255J\276\330\330I>N\342\324\276\230\3552\276\t\306o>6\367V\276t\226\213\276\236?\005\277\010\246N>\314cC>x[l\275\0130\025?5\254l\276C\310\033\2763\302\002=A!\341;5\210\206>\320v\335\276\0131\356>\320\3552\273\007\325\374\275\001\270\315\275\375g\2039\360Q\270\276\356\343=\276\3674\270\276\002v>\2772}{>v\266\354\276\307?\357\276I{_>i\001\246>\357h\006\276\214\215\254\274\325\264\321\276SD^>\261Q\222\276\247(Y\2719\201\271\275I\362\335\276\241\351\250\276 \275\021\274r\375\004\277q\001\307>g\224\217<~*\013=k3H>\242\'\024\276\254\233\212\276\331\302\313\275\320\200\243\276\304p\231>\3701r=\260\263\215>Sw3>U\333\346\276\345\375\033\277\202\220\235\275M\342\'?\366\360\200\276\230O\335\276\031\003\206>#\3344\277 hg\276\0240\271;\340\266\r?!K\214>b9\320\275\3478\250>\302\274\rq*\216>\274\240\236\276\370LX?\361@\014>\2021\230\276>+Y\275\230\351\377>\230\'\347>8l\323\275?\033$>\263\311\340\276\030\231\214>\216\246\271>so\232\276\207\371\223\276\026,`>I\316:=\361E\307\275y\347C>\333<\266\276$r\242>Q?\330>\032\312\326>e\034Y>\237\226\031?\006s\371\275+`\275\276F2}>O*\217>I\234\017\277\235\213\206>\301\246\357>\260\354R?\356\223\235\275\304\310\314;\273\376\317>8T\336>=R$>q\034\337\276s\251\245>80*\275\304\302\351>\274a\332>\021\360m=\250\226r>\324\254\217\2761$S?\264\351{>\326\374\375=!d\230\276\322\310\240\275wnC>Q\302\337>PR\311\276\001\264\213=\362h;\277u\322\003\276;5\026>\030\337\247\276\017\311\265\275<>\322=!\036O\274\363\345V\276*S~>\236Q\210\276}\364\333<\216\252\211?\300\253\002?:\203\337>\230,\204\276v\355\366\275\357p\274\276\336Vm>Ab >\027%\036>\231-\007?>\214\342>\364\354[\276\213\216\002?B\"\316\276\025b\004\277dge>!\3558=?\333\261\276S\035\246>^t\260>\245\3373>\037\243\264=([\220>\326\003j\275\207-D\276\202\033%?\322\233\334\274!\352\021\277\331\263\360>\177[\017>\032v\231>\314%t\276\372\263\271>\263\372\036\277\003:#>\226K:>\330\242`>\206\301\351\276\324?\223\276\275\253\230\276j\273\315;\321\213\271\275\376\227\317\276\217$Z>\241R\246\276\3444\206\276M/\006<\225i\225==\270\271\275\206\347\211\276\300oA?\353\321\216>\034\263\232\276\033\260\252<\345\2228\276\2254\215\276\253\007\374>Lw\211>tX?\276\342p\376\274\241\342,\276\032\'\362\276\356\272*>\004\335\302=e\2302?\025\023A>h9D\275sg\203\276v\037e>\006\336`\27620\327>\314\316z>\360\233\300=G\216\330>\203\223\270=\314!F=\263\343\005?\027\351\032?\312(\r\277\341\220\244\276\022o\375\275\017\347%>\204\000\220\275\356\277\016\274\306\"\311\274\223\027\201=$&H>(\177d>J\267\326=u\230y>\370\2362>o\250\202=\275\034\257>\331f\361\273\017\255\335=\232\217Q\276\270\035<>\"&\002=\373\017\236>=\035\277\275\001f\342=B5P=F\347\236\275\0078\211\275\313\321V>0\277\257\274\220\226\034\277XJw\275\314\370\265>X\364S\276\007\340y\276\240G\302\276x\361\366\276%\203\220\276\270G\337\275\363\356(>Z\000\230;\350\237\025\277\312\260\321\275U\365,\276\222I\r\277!\021<>\217.\347\276\301\220\366<\357\224g\276\366\312v\276\"m-\277\244\265\255\276\207+\'\276i\021}>\350\213X\276\007K\007?_7\247\276Q\373\275\276\222\017\272>w\001\211\276\t\376\370\276\033\247p\276\210\237\235>5\t\376\275\230\251\r?\014N$?\336Mn=78\240\276\315B\026\276\262\265\342=O!\333>\254\303\251\276\334\363\273>f\037O\275q/\305=\256\252\221>\242\225\310\276\331\032\225\276\031)\234>\265&\n\277p\301t\276\246\023\267=\233\205\002=\375\301\220=\342\r\330\276\017\3671>\346\212\205>\036\230\222\277\244\005 \277[{\345\276\355z5>]\261\371\2768\375\336>d\322\266\276\273\312\305\275\310?\233\275\344\347\226>\253K\237\276\233\354\327\275\360>\034\276\321\026\215\275d[\221>\205x\203\276@\366\255>\014\313\301>\230\337 \276\30085=*\237\000?:\325Q>\021\026\240>\244\344\001\277\332\233<\275\021F\210>\335\215\210>\347,\311\276\234\340H>\370P\333=xb\\>+\347\364\276\302\207$\276;\275C\277\256(\037\276{\241\177\276\322\216\177>\032\014\252\275\343\217\377\276\346\277\246>r8\027\276m,\263\275\\H\371\276\030\323\261\276\"\367%\276%\2037\276\330\255\272>\037vD>[_\201\276\305\035\210\276\272\217\010>\217\225\213>\301\027\370\274j\312!\276up\224>0\'\325\2766h\277\275x\315\205<\252\263;\277\325\037\037/\276gN\r\276\237\315\\?M:6\276\317\242\214\275\005\033\341\274\306\370\366\276\303\247\255\276\204f\271\276W\342\374=\363U$>l\010\307>n\240#\276M;\236=\007\270\353>i\376\\\275\272\030\314\276\207MQ>\021k\036\276\206=t\274\016@\360\275\370<\354>C\022\007\276\2371\220<\030\007\222\275\217\373U>\317\2062\277&e\361\276\032\300\320\276\234\263\234\276\343|A>\024\251Z>\026H\220>\254\364\204\277\232j@\275\373\351\323\275I\347\"?\r\334\265\276\274hj\276\207p\002>\2238\255\276S`\244\276\007\210\032\276\327)1>\'\215o\276\374\234\252\276XI\007?\234+\274\276\325\337\230\276\343\365\237=\200\343H>\327\351\026\277\250\3643>;t\315>\266\246\323\276\024mv>\307*\266\275-\025\241>\226IB>\337H\257\276\'\361_\276\3308r>\242\235\351\276\237\227\376\275\354G\244=\\\364\320\2759\262P\276q\034\355<\005;\310;\363\335,\277\326\334\021\277\317\017s>W\033\036?\250\231\245>\274\344\247\276\327!\211=\203\325\n\277\237E\032\276B\020$?:\274w>\002%\264\2761\\\211>#I2>4\340U\277\365L\212\276\023\236\324\276\225I\017?\221\002R;,+J\275\031\262\200\276\177Q>\276\300\220\353\276s\260\226<\0074\213>\341\254\006>\264\216\223>\322+\230<\302Y\312=$\221$\275\352\220F\276O\253\222\275\314\255\216>BqN=\232\375\032\277Q\350\205>0\006l>Bj\217\275\254|\340\276\374\324\340\276^\252\204>\017\365\232\276{\005\304=h\021?\277\252$f>\232\231\211\275\234\306\273\276\250d\020\277\275\034\354\275\316\262\363\276\336\200<>\316~q\274\203\001~>\362g\344\276\274-L\276\330S\210>\034\221\037\276\027\214\017\275\204F\003\277\201\276\336>q=\244\273 \256\367\275\003\271\'\275F}\354=\007\377[\276\206\254\251\276\306\277\204\276\371\200\275\276L\270\004\277o\357Y\276FW\202\275Y\256\020>\326\354\303>\257\236\340>z\177\373=\242\354\204\276+\302a>\325\322\232\2763\231\027\277\024\266\324\276\274\262)?\000i\301\276I\214c\276\320\264\272>^\210f>:m\234>E\023\030\277~\n\027\277i\231#>?O\206?\273\032\256>s\365}>&\243\227>:\345\"\277\032\373\267=S\366\034\276\236$^>\253\207L\275\270\231d\271\2748\277\234A\253>p\225\364>\364\345==\3108\372>\0258J\276\234b\\\276g`\002?#\2124>\313\304\034>Y\221\252>\364\217F?$oX\275Yd%>b\'\334>\217\235\256\274<\365C>\231\203\037?\020w_? \314\224\276\357\223\201>6B\216>\016l=>\002\005f\276\246\010\304\275V\372\277\276\221\376|>\254\310\212\276s\2506\275\206\256\033?D\026X\276\243-K=N\362\253>\272\342\316;>\345\207>\311\030H\276\232\217\352\275/\234\201>\376I\225\276\027IH><\206\000=\002l\312>\317/\003?\203\242\205\276\347b\004=\322|\264>\260>\354\274\211\032\276\274\017\254\336\274B\031w>\007\333\346=\2511\223\276\014\324\303>\253\363!\277\266\265\220>|z3\276\026b@\277l\225\367>D\220f\275\203hp\276\300z\200\275\024a\325\275\274?\321>\206P\254=\300s\307\276\343\243\031\276r\362\377>^\326\203\275\177\\\373\276\321`\374=\3169\002\277\336\272\214\276\355\360*>\342<+\276#\373\013=\235v\010>\374\010\010>\006\023\336>\336(X\276N\350\000\277q6B>0\266\274\276\344\307/,\021F>K\303\2659\312\310=iN\026\277\t\r\314\273\232\000P=W\004y>\211\315\210>#\372\223>a\266\"?\247(\355=9T\026\277\274\226\225>\233\232\014>~`u>\324\251\355>P\177\335\276|!$?m``>Cs\024\275N\363\360>A\251\333<\335\342\255>|\204\312\276j\221\313>Y\367a?3%e>\246G3?\034\360h>UL\206>\226\353\023\275\256\232e\276\371~T\276\32181?\202Jx\276\250\333\337>(\342\215=J\345V\276\373\225\026\277\277\005\204\2765\322\t?\371\231p>x:\364>\037\222\313=&\\\276>\250\251\021?\340\332\200?v\225\340>\2725\357\275\222i\323\276\337\3562?\277\257\271\276\246\343\316>\013\241\370>\2261\271>F_\020=\306T\242>\030\362c>\301\361\222=\213\016\355>\350\256#\275_\274s\276MM\244\275\031YF\277\030\222F?\021F\310>\241\016\t\277n8\250>\365\372,?%\303\017?\353{\216>N\007\376>\214\243\r?\033j\227=\227\221/?_\220\225\276\177N\203\276d)\220=k\340\032\276\202B\014?\241\203\206>\315\026\267>\376\003\204>9\036h>$w\204\275b\243\207\276\323ff\276\006o\367=>\267\021>f\253l>\007<=?\341b9?u\225\245\276\347}\343>\252D\034\277\227\376Q\275\314{z\276_\334\301\276#\352\301<\r\224\275=Jhh\276\246\343\220>\005\3102\272\321@%\2759\201\362\275 !\026\276k\264\034>\373\022\375\276\\\350\021\275\325\221\253=,&\212>\0030\021>\0078I>\016\370^\277\256\341\236\276\201>\256=)*j=H\302\304\274E\2534>\351\031t\276\237\261=\276hz\205\276\016x\217\277\354_\330\276U1\214=\242U\374>\304m\241\276\354\001B\276\302u\234>[,\343=\306R\320=\307\323\322=\r\300\327\275\336G\020?J\314@\277N\246{\274\236\371\330\276\265W<\276\325G@>.\031s\276\337\327Y>J\215[\276@\277\261\276tA\253=A\306z\276\257\027R\2768[\245>\313Q\000\276\221\252\213>|@\275\275\246\037j<\276\310\243>\352\263}\276\343\343\\>\373\347Z\275\303\236\346>\230\216f\276E\002\275\275\327v >\024N\203>\371\211\016>mwb\275\375w`\276\227\016\022\277\024\266\370\276\224?d\274K\370R=N\373\335>\3559\241>\253\346\022\277\336E,\276m7\237=*\3446\276\321%?\276`\025\336\276x\234W\276l\307\246\275\353q{\276\221\263\222\276\204\350&?\001\356\201\276E\020\370>\362SD\275\021\344\301\276}G\001\277\215\nU\276\230\214\345<\331\"\245>F.\271\276\036\301\274>\3107\357=\n\275\004=~SO\276\016q\'=\253W.\326\367\266\276kr\004?\032J&\277N\241\313=B\017&?3\214\363\275\204nY=\370\255{>ZS\305<\016\021\217=\0008\264\274\374Ra;\016?\325>\356\213\262\276\034\336\315>\365\317\215\275\220M\013>)\013\t?\013\010\245\276\332\255\267>N\277\035?*d\031?\264k\271>\247\347\222\276\202\022\203\276\030^\023>\202|\361\276}\252=>\323\006\235>\340w<=,*\274>@\250\013>gy\323=\360\376f\276)\220\266=|\230\303<\362d\215>\245\337\361>\332\200M<\\L\t\275\251\010\315\276R\033\332>\003c\033?_\221\300>s\004\264\276\207&\361;,\016\023\277\rI\364\276\030\240\340\275\322L\036\273Vz\242\276\004\313\374=\320z\230>\347\232\220\276\030o$>hq\326>\344\357K>\177\257\327\276\027\370\241\276?\347G\276E\231\020>!-D\2765\377\003\276V\217a\276i\210\265>\017\022\215\275\325\272\317=\n{.\276\237a\314=\001;\037?\210\377\177\275\037\246\243\276\000\315\017\277=\350#?{\322\363>}x]\276\025%S>\370\356\223?\327y5\277\024\310\214\254\016R?\312\225\327>G\247|\276Hi\320>\374w\034>)x\033\277\314\202,?!!f<\031\2413>\316\377\316\274\374\277\247>\316[-\277\026\262\213>\334j\001\277i(\261;\265\363\247=\277\001\302\275\245\0312? ,\210\2757C\205\275Ne\333\261\377\006\276\352\030\030?\242H\341\276\257\020c\275\246\207@?\004\232\\\275\270\225/\276h\257\247\275I8\305\276\3752S?\264\016G\2752\377|?\246\005\313<\375\306\270\276\311J\014\277}\005\034\276!D\004?\335\363V\276K\312\021=x\n\001?\377\004\321\276O\034>\277G\036V?v\251$\277\217\r\267<\222\356\303=\243\250\371>\022\215\031>\034\353\252\276\354P\303=]F0>\304\343\246>R\370\305\276\361\371z\276\336\311\202>\213\333Q?,\255m>w\037\016\276\361\303\200\2768\223\221>\001\027B?\254\376\266>\272\005\234\276+\322\222\276\257?\245\275\024\314\244\276\034\227\221=\253$Q>\322\272\027\276|\272\336=.v\342\273I^\260>!\371`\276U3\245\276\023c\327\276\355\017\005>\312\207\003\274\360\227\225=}\177\027\277\016A,>E\326\024?\300\247\334\276\n\003\330=\242\305\231\276f\252P>::\221=S\237,><\013\233\276\021\225\300<\014f\360=\212y\271>\373\316L\275\313w\277=\230\265\321\276+c\326\276\021\007\270\275\217H\036\276\230m\223>a\211v>\265\t\235=!WT>\002\365\370=9\242=>\257\310L=\274\232\324\276\203\332\214>\200J\370>\243\344\026>\230\0044?5\354j\277\031\213|?\237i\301>\213\227\002\277\205\350\005<\212c\003\277\026\234\202\276\363\343^\276\363\3265\277\303\306=>\335\236\036=^g\327\276\321\311\014<\013\020\277\275\334(T>\341@\277\276\331~\217;\241\375\221\276t\336\226>\242w)>\r\350d\276\334Z\004?l\236S>\001w\334<\021\212P?np:\276\007\207c\275\361\335\332>\271\355\005\277\310\304j\277\221\240.>\006\302\220\274\361\206\345\276\337\023l\274\311\325\336>]/:\276\223ed>\0258\224>\343\010\\\276^UY\277\216\257F\277\241\n\234\275:\260\014>Z\304\343\276\350\323\026\276gK\313\276\r\352\242>\025\"\231\275\235\262Y\275\3434\351\275zn\230\275\026\300\004>6D\224\276q\343\031\276P\"\003\272\014R\344\276\332\346\343>\314\363:>\355\032\214\275!Zz\275\003n\256\275k\307V>`\016\372>\3511B?\031G\305>\347\274\213\276A\235\213>\025\232\362>I\272\312>\217\324\031\277\314\037\373\276\340\365\222\276\225\243\300>\201L\006>Y\325\206\276\'\027\324=\365\214\217\274}\2066\277=\"<\274\241\326\254>\024\016#\276M:@?|\204->\177\252\">@\225L\276$\001\221>\263[\256>\234\234\347\275\341o\205=p\212\304\275\177uI>\360:\271=\260\351*\277\336.\032>]\243\337>\210\2647>\351z\025\276\203\233\344>\324\261\224\276\214\276\006\277MS\233\275\007\340\035?+\257\231=\211\211\242<\320p\236>\360\267\023\276s\253\337=\357;\n?\311\313\253>\341e\'?\372\232\323\276*\240\277\274z\331\000\275\366\200\005>\005\241\214>\'\317<\276\013XH\276\313\245\262>m\364\214\275\200\213{\276Q\310\342>h2[\275Kp\307>\261E\225>\275{\203\275T\311\006?B\314\207\276]\343\222>u\243\264=\334\000\016>R\204\265;`\004:>I\256\261>\034\350\310=YN(\277&y\263\276\205\005\256\275\345\277\305=\014\275\204>=\250\262\276\211&\002?\002\272\324>`K\003=\332\024\315=\316\322\201\276\221\306y>\264\2035\276J4A\276I\222\"\276<\371\221\276v\302\250>\tS\022\277\020\t8\276*N\005?\301\371\316=\2651q\276\361\353\177\275\240\300\027>\n\275\226\275@\367\240>\254\325\325\276\234\353\222\276\376\022\317>\327\243\302>\006\244\203\276\nYa\2766\262F\276\316\274?\275f2n\276\0052\375>\312\372\223\276\257@\322=\020\2050?)6`>\257\206\255\274 J\234\276pK\031?\226M\314\275\346K\215>\030\210_>\276\020\242\276\375\311#?\210\360\270>ap\262=\332\027\007?y\224j\277\367\000\343\275\330\343\333\276\361\266v?\333\375\334\276)\262\343\275\205M\237\276\354\263-\277#\261\206\276g\275\"?\324#\217\276\007k\234>v\r5\277Mt\217>(J4?\023\270\252\276\247\376n=w\0370\2778\216\264=\270^\326=\034\000\304\274\313\300\010\2767\030$\277f\373\301\276\214\250\307\276\235\201\266<\351\3704\274\275\310\374>\261n\231>Qf(>-\346\331\276\234\227\n\276E\310h>\\\251\303>\340mC\277j\034\213>:;\003>\341\313\227>\377\207\327\276\202\3008\276\311\331\252\276\014\001p\276\276*\355=o+\003\277\010\227\030\271.\204\200\276\271;A\277\332\232\355\276\224\370\252<\240\003\324=\233\374\341\276|\371Y>F:\214\277\240\270\341vM\274\206\336\037?\361\323\211\276\353\303\375\275nQY>\027\343k=`\343\202\277\221(\006?*>\254\275\370\363\366\276\3108\273?5\036\002?\2202u\277\027\025\303=\330\253\366\2762\177\313=^\371E\275\225\202\t\277\226\253R\277\252\241\332\276\363\346\301>\362\204x>\245\020k\277\\\247\216?\323U\005?!\013\363=\243\363\277\275[\265\021\277\177+\231<\343\300G\275d\327\211=\205\320#>r\320\201=\t\207\302\274\035s\"\275M\025\201>\032\263k>\"\265\212>k\035^\2763\207E?\023\365\226\276J>\035?C\260&>\0361@?\rG\221\275\233\223[\276\255\272_>5#\021\276\001\037\032>kn\364\276j\030\356=q\2611>\334\226u\277\201\200\033\276w+\253\276\236,\265\275\315\361\227=\365,-\276>\030(>\014E\272=\265\214\007\274o\235\264\273\0050\277\276\036\025\322\275\317\247\267\276\276\261\033>|D\271\272?l\257\275\310\304\263>w\024\210>\201\0215\276\266\231\205\274>\306J\277\340\302R>W\313`>s\241\017?\034\357\335\275s\026n>5\352r>=\356\327=L\216\371\276\377O\333\276\262\013\274\275\037\232/\275z\342\200>\267e\304\276\222\027\365\276\272\352\303\276\267l\003\275\373H\'=L\256\251\276\006\025$\276?1\005\276\3175\021\275\265\357\200=p\021\367>E;\304>\310\337\372\275S\316Z>>p&\276]\346O>P\353\352>$\314P\277h\361\213>q{\242>\246\353\213>\3507O<\220.\312\276\"\\\n\277\035\007g>\352N\277\276\335\225\222>\306\303\215\276\002\021\">([\200\276\341 \016?\365hI=,I\222>\322\334\221\275/AX\276PP\220=\r\306_\276\313@6\277\274\235\276;x\222\344>79G>\\\223\235\274ai\216=~\321<\276\020w\203\275\004&\375\276\260E\205\274c\264B\276\037\0148\277\366@\016?\225{\372>\021O0\277\"\210\313;_\327\032?\217\310\021\276#\264\225>\276\225u\275u\022\340\275\236\350\022?1x\304>\253`o\276\231\216,=\016\315\313\275F/\"\2760_\006\275\255\r<\276\236%X>\004\036;?\374g\024\276\361\211\020?\037^\341\275\373c\361\276\250\210\274>g\020\261\275\230\252\017\275\270b6>\225+\305\276\351\377\027=Z\257\237\276\251\274\273\275\250\372\n\276;\343(=\243/\032\277\2232\202Q\001\211>\014O\213\276\331\304\367><\227v>P\302\267\276\340v\341:\313\376\200>KeM\275H\375\235\275\221\3121\275C\312h>KN\344\276\333Fv>\177\344I<\232\205]>`E\206\274\247Q6?\225\224\200\275\251\250n\276\312\271\207>\275\260Z>\267\242#?\000\256\256>\252\372\370\274\374\354\267\275f\267Y>\217M\005>\332\343\311;\0341@<\007` \276#\370N=\222k\023?\330^\243\276\217\301q\276T\337\033\276\354]\232\276F\310|>\322\241\366\276\342qq\276\010j\004\277\t\247\226=f\327\\\275\340\221\355>z\235^\276\034\225\200?\347r#>V\006\"\276\316\257\367<.\037\023\277n\375\024\276q\231\320\274\ri\320>^E/\277eLx>UF_\276\264A\240>\320\000\336=\033n\272f\360\004>\305\276\220=Y\270\306>l\202\336\275\3062\213I\027\200>ne4>\372\022\264\273\304\226t>\343\260-\276\271z\222=\320OT>\203o\022?PF\247\276\220\tl>K\246\016\275Y_\264\276\224\212\020?;=\304\275\323\023g>G/\366\276\332\365\372=\023Hu\276\004q\344\276-05>\266\304\206>F\315\342>>Eh\277\013\026\255=k\323\273\275S7\225>\032\333\367=\000\032\255>=\216j>c\377\203\274\273\245\266\276k\035\232\275\315b\347\275\342\234\021\276\311\037\247\276\205f%>\r\371\256\276\rde\276Q|Q\276\030>$>\310\035\336>6\327\031>\354\311\237\276\370\024\000?\353\340\247>\001?\r?}a\026>~K\256\276\320\312m\276\250\351\031\276\360@\314\276\375S\217>Kph\276C\365\005?\026\3419=\3341\017\276 \034\">\n\370\340\276Q\321\302\276#\351\234\276|\306\222>I\354\\=\376\301\223>0\026\014>n~5>\260\331\226\275\232E\346=1\270b=ju\346\274\325\377G>\222\003/\277\231\031\270\276C\213\004\275\002\264\351>7\262s=\343_\265\273\307\344\323>\212\254\177;\254\202T\276\376\325\002\276\231Md\276\324R\341<\217\371\212\277q\241\037\277\363\252.>\026\253\033>\213\217+=QG\266\275\237\274\332=\210\266\302>\314\312\350>w\305\013?\352 \"\275\353tE\276\333\035\246>.\001\304\276G\2563\275\030\013.>\234Ew\277\031\256\221\275\246\037\261\276i\206\203\276\306\231 ?9\207\205=\217\312+\276\'<4\277\177\221\234\276\334\204Z>\311F\267>\377\257C\277\262\333\024\2777\032\306\276\333\322\336=UJ\036>\357[\255\275\022\335v>\321\027\250<\223\002\224\274\341\311\373\276/\312\223>5\224\2422\342\205\275\227\327\336\275\033e\234>\350RT\275\001\204\023\277\374\037J\276B\333\357\274\201\376\023\277i\241_\276{\024J>m\253\226\277-\033\002\277\324`\274\276\275\254\247>d\016\021\277v4\324\274\000\240 \277@53>\240\240G\276\342\022(\277,c\004\277\243\027\271=\222\216?\276\200yL\2760\'\214\275\307_W\277kO\323>r\036\274=\340\234&?\327*\202>\376\201&\277\244I)\276gn\366\276\271\211\343\276\350\004\025\276\377!R>\360\350\321=\256\\\220\276~\367*\276\263\362:>\010\225\024\277\260\315\260>\216yo>(\255Y?\363\242\375>\253k\242=N\366r>\375f\220\275\250\206->\006[\210\276s.\000\276\004\224\024>\034zn>\345\377\225>\236\323%\277\327\253\034\276\347\032\325\276oF\245=\346\345`\276\272T\314=\377\342X\276\037\220\310>\332\262v\275\006\377\313>\003G\260=\203\246T\204>\215\274\232\301\217\276],\274>k~\014\277\340\n\033\277\026H\307\275\313\371\240\276\261\232\"\275\230\253\300\276\033B\327>oz2\276\315\254\"\274\253\243\250\275F\275=\276\034\001\n\2779\t\317\275\264|\277>j:V\277\345\336\346\276\241\022\017?A5\221>\030w\273\275fJ\203\275\003\347:\277}\212\020?\226\243x\276\333P\370>Y\375\267\276\021P\312\276\373\035\250>P\266\330\276\355\317\205\276\027WA\000>\225^+?\010\206\266>\253^E>\020\244\344\275|\271\303\276Iu\017\277\\\233\303\274n_\212\275#\327\337\275\364P\210\276\252\014&?\374\312\346>g\307\325=I\250\367\276\005\373\232\276\364\000\013\277R\300\031\276-?\305>\024\244\200\276\366<\337\275\332M\222\275\367\330\017>\353\0322\276\303y~\276Sr\336\276C\373\033=\367\366\263\276\266\302\021\276\347\376\305>\224Z\032?\312\332\252>\236\351\350=\374\266\202>\243w\013\2771U\002\277<\325*\2764\341\035?=4\210\276\t=\220\276\354q\010\276\020\311\252>\376!\202=\232S\200>\251\360\377\276\274\256(\276:X\257\276\241\344f\276oL\020?b\214\010=b\373\265\276\315~\027\276\'\024o>w\351]\277\373i\237>\'\331k>Fe\303\276)\341\\>\341\374\356>\301|\367=P,\'>\317}]>\357~\376;\254\311\025\277v\340\316=\223\237 \277\223\204\036>{\261A>\256\214\240>\nH4?\033\254\333=\363#\236>n\036\335=&\021\004>\313\'\021?\031\257\016>\260\367\303>\334\034\264=\255H\310>\0033\004=LZ\245\275\231\313M=r\022\207>B\2016>~\277\241>\n\227\003\277\366\224\224\276\031\013v?\201b\225>p\030k\276\333s9\276\302\360\004>.!\350\276\261\237O\276\202\2544\276\233#\205>\3607\213>J\316\343\275/\331\002=\265m)>\013C\276>\203Bp\275C\314J\276\263\257\013\277M\232m?O\200d\275\222\220\025\277{\032Q\276\n\353\254?\233\256\204?BES<\3412S\276\311{7>(\016(=2\235b\275\030\331\350=)\314\260\276$\310\311>\325p#?\3469\005?\206s\033\276\375QG>\233x\320\276^\223\325\275\036I\032>5\364\263=\360\366\220>,\336H>B\334\267>)Q\246=\021\254\316>\226y\014\275R\230\235>\213\030F>\232\026\366>K\367\370\276<\031\270=b\367\306\276\321l\003?\276\006L\274\342\334\321\276\303-\310\276\220X\315>CM\n=\273\001\210=\242&v>/%\235\276S\243$>-F\256\276\306\334\243>\002\350\306\276Q\244C=RQ@>\257\241\354>\357\243@?%\325\013?\360\030r=k\201\027>T\256n>\003;\321\274\301\342\370\275\341J1=\300*\362\273{\340\206>09|\274D\303\342>\332\014\0024J|==\373F<\237e^\276>\340\233=1\t\264\276[:\t\277\355\207\004\277\027G\367\275\304+\370=M6\360=\256\253\372\274\211\244\234>s\337\315\276]\013^\275\231\335\005\275V\003\201\276D?\306=\247=\305\276\0300\313\274>\037\237>\261\256\023?\273\t\200\276\235F\240\276e\332\345>a\211p>m\247\247\274H\225\002?\361\274\300\276\232P\257>^\247\346\276q\253{\276\315\033Z>\312_\027\276 \337\210>\031`\003<\242g\225>\356<\035=\236\343\r\2754U\021\276\213\335c>\353O\017\277\364\243\345\275l\224\217>e\020\034\2765\006\031>m\2263\276p\223\361\275\272\335\274\276H>J\276\372N\002>\306gl>\201\3452>\272\\\211\275;O\003>\250\255\274>\302>2>\030b\233=i\2668>\362\024\375\276\240\241\234>9L4\276M7\230=\3459\275\276;zw>\007s\021\276O;2\276D\260v\275\370S\263>\313\034 \276(\007\025\276d4\005>\001\242e;\347\304\234=\263,L>\224\215\026?\270~\355<\2610\035\276\341R\"\276V\360\272\276o\335m\275R\007A\276\342\222\323\276J\351\202>&\352\006=\251(\000>\321\271v>5\200\243>\317\300\241\276\232x\213\204\023\000\276jo\217=\032\374Z\276\016\350:\274\270Fw\367>\352s\t?fK\233\276\010>Y\276d,\337>a\370K>i\350\023\276\213b\000\277\232\227\254\275K\237a>\314\221+>\255I\201\277m\260\335\276\010\357p\276\347-!>\302\\U=\250\240 ?\002\276k=\2506\300>\017\313\006\277\342\376\003\277\226\020\231\275&\304X\275=\302\032\276 \341\256\2766\234\214?\226L\032\276\323\257\305\276H\306\316\276\255\344\333\276f\n\002\277)\344Y\277@\361\257\275\342#\240\2767\344\257=\206\235\364=\265c\005\277\334\347A\276j\216\201>\t\352\264\276={\253\276\203\331{\276\021\266{\276f\341M\277:\323\262\276\332\034\271\276\376\231\316\275UR\\\276\216\277\253\2760M\221\276\253A\016\276\270\233\254\276\201\352\243\276\365\372\273\274\361\346\214>\221\202\261>\213\317V\275\270\2253>\335~}\276E\316\245=\374\032\245<\027\034\027\277\366\325\t\276\350X\346>\215D<>\013\222\022\276W\272g>\343\206\351\276\365r\221\276\177e\016\276\014\025d\276\314\217B\276\255h\023?\363Q\004\276$\211=\277\2433L\277}\366\332=\335\024t\276\354\037\267\276\323\311\242=\343\337\360>\213\351X\276\356\274:>\206\242\307\275\036\205\370\276ig\207\275\223\311\264=\201\000\374\276\255WB\276O\021u>\031\335$>b@\277\276\267_\303\275}4\252>H\323\315\275z\264K\2765*\327\275\245N\351;T\261\306\275\242I\034\276\202\300T?\004\n\002\277\364\227J\277f\031/\276\270\213\207\277;\334a>\347\247 =\334\372\037?Db\342\276\214_\304\276\035\315\005\274\017\007\312=\334\232\313\276-\345M=\352\344\005\276\365U\004\277\276[\202=^2W\277\202\332\235\275??\320>a\310\363=JT\245\274\374\324u\276\353\"`\276C\345^\276\350`\361=d\326\326\276\3119\376=\340\332%\277D\360\314\276A\226\277\275\334\013=\276\327\035\212\275\261\033!\275m@\277\276\336\243\322>`\323\360\276\341\344\263>\272,\256\276\216v\354>\334\301\260<\213[\237\275\234\\:\276\215\363V\276\276~\320\274\357\226\r\276%\357s>\021,/>\3078\237=\036\202g:\255\340\t\276\326\020\324>5\223\357>,\340n\274)\366\230\276\267\230\325\276\303\307\233\276\236<\n>S\217,\276\227\253\030>\327\261\016\2768\274Q\276\022\324\212=\331&\364\276\307;\007?\025k\200>IKg>\212\371\n;\331\204\366\276\305d\026?\251\242\351\274X\204\367\031\244\276>\014P\010>\232Y\274\276\030%`\276\366O\342\275\335(\216\274\023Q\242\276u\236\356\274S\n3?\322\354\002\277\256\343z\27657\">\031G\235>:\n\013\277\344?K\275p\027\272>\267\331_>\244\276\301\214\034\277\244\335\233\276\357%\351\276\341\265n\276OW\204\276\3277[>J\024\264\276Ei\202\277P\n\311\275\307\341\265=\363\272:=\347h\025\276\376\223/>(6\216\276\017\200%=\202\326\367\276\337\2435>\203\3304=\212\375\031?rN\232=%\343\253<\016\220\207>a\361\247\276\311\204\307\276\311\000\032\277+\323,\276\357\007\334=\t!\331>\330~\203\275\r\376r>\027y\206=\261AP\276\014\t\213\276\312{t\276\250\374H=\220l7\2771\200\247\276wxL\276\310\217\373>\000\256d\277\355\376\366\271G@\330\276\351\207\023\277\204\035h\276O\n\213\276\002\300*\277\220}\327=ov*=\204\302\221\276\362\010\312\275\325 \022>J*W\277X\244\315>\365\023\333\275\004k\036?\211\373\353\276\316x\000?:\372\031\276R\367\032>\034\314\204>\\\r\304=\260\333\261=\002\227\245\276\223\244\326=\347\206\000\276#]1\276v3\013\277\024p\267\275U\276-\276\020p\240>\353Z2\276\321!\027?aV\t?:\350\377\275Y\246\016>\337\271Z\276\2167\373\276\351\222 \275v\367\016\275\037fF>\226\335\200\275d\362\r?\263w\250>4K\204\276\346\'\264\275T\342\014\277\3051\227\277Q\205\204\276\317/\006\277\204-\323\275\235\363l>9\264\r?\316D\207=!\004\023\276\277\2459\275\246\346o=?k\245\276P\"\177>\360\030\216>_\316;\277\232\3576\277\317\327b>=%\227\2754o\005s4\203\276Xp\346=\227\002\267\275\207N\207\277\n\226E>\247@f\275\222\250G?\274\023\205>\324\304\367\2760%\377=(\252\354\276\230[r>\213Y>\276\246P\030\276y\035\365>\020\001\234=\0011\224\275\2053\225>\2641\210>b\241\022\276\376\035\222\276\001*\217>9zT\277s\266x>7\236\007\277\332\351\344\274l\261\236>z]\253\275HP\361\275\177\277\200=\010xU>\235\211\256\276A\366Y=\210Q\371>\220<,=_\036\303\274>=\236>\356\312\200\275\314\232\013>\317\236\262>\005\347\322\275\035\033\354\276\235g\270\276}\035\235>\003u\261\276\276F\345\276\221,\004?2\233\236\274\377\\\302=c\206I\273\311\351\351\275\340\300\322\276\345\324\242\276\242\341\035=\206\212\211=Ry\270>FI\213\2756\026\255>e\224\335>\023\312\367\274\217\327G\276\305\031 >\273\237\310>|_\223=\357@\032\2744=\017\275\030\237\266\276M\372\277>\037\0267\277\255,M\276N\021\006\277#,\017\276*7p>\221\224\320<\264~\033\277\364e\203\276}5\302=&c\341>\034\022\"?\010\006\224\276\214H\217>\303\3149\276k\271\322\2760\311\037=\332D\324>l0)?\303\323o?RQ\027\276\232\3126?\351,\n=\265n\016\277@[l\276n\025\346=b%z\276\267\265\267>y8\276=\352\264\366=\277\255\343\276\357\227\226\275q\001^?[5\006?\273d\256<\245\004\363\276a\366\376=N`\237>^\017\332=\246\347\260\276\325\375;\277gA\017?5`\301\276\317I\264\276\266\213\270>\370b\007>w\235\342\276\375\363y>]\244\t?*\270\307>\214>r=N\232\020>\324k\005\277\233\001\275=\310\215\253>\274\351/\277N\235\231\276\271\373\367\275\t\3709\277Zq6?\253\311c>\231\3602>q\235S?\300\"\202\273\001oj>\032k\256;\214\005%=_\207\263\276\213\025\334>\332\033\026>\014y\010\277\214i\270;\310\212\026\275|2\300>\'\353Y=\020\312\022\276\\R\333>;`6\276\302\201\346\276\306Z\267;-\243C?\204\216\264>\271\277\243\276\024\250\261>K\004:\275\312\213\234\276\337\324\230\276V\331\211\276}\215a\276\272\200\007\277{+S\277\375\203\366<\2059\212=\006F\207<\352H\337>uM\004\276Ec\266\276G\325\274>\3401\240\276H\002Y>\014\302\364\200\200>\037D\217>\303\031\313\274}U\324>\262X\256\274e\260\225=\235+K?:8v\276\020w\216\276\310\001\203\274}w\355>\231\225\267\276\316b$?\326\303\376\275\373\363\273\276\016*\000\276i~\365\276\313\2527?\214\242G>\245\256\022>\257\223=?\243\330\313>\216\224\227>,\211\032\276\367\014\246>\266\335\331\276%|\005\276\310|\222>\304Ax\276\"\030\306<\004%\373>\371\245\222\274ss\005\276\374G\216\274 \t\227=\272\373`>\206\0334>B\376\013\276\004\216\211>H}\272>,D\217\276\335\217\231>\357\340\370>~M\257\273\246j\231>\275\026~\275W%\203\274RA\372\276]H\036?\373\344\267>\"C\324=\255\006\003=\212\242\325\275\333\272\265=Z#\257\276\366Q\034<\301\233\232>\206\225\223\276i}\246\225EL\277\\\203\207\275\364\330\204>\311\035\004\2766S)\277%\257\023\2774\276\233=}\236\363\276o\347\004>\010\375\243:e9\340\274\230\003\000\276\345K\227?\261\025\346\275U\261\343\276\367\360\230\2761\217r\276(\226\336\275\212\224\234\275\005\263\013\277\206\320\261>p\245}<\313[\032\277\353\362Y\276H\321\020\277\246\224\373\276Lu3\277\036\304\354<\267$\245=\331$\354>\013\257!>Ql\312=\031\320\232\276\272{\010?\021i\013=#|\207\276\020I\266\275\212\266\356\276\217o-<\216\336\303>_u\304=\205\006\234\276-\276B\276\361X\221>\251P\316\276\371\321\250<\366\363C\277r\213\005\276Z\277\362\273/B/?W\214\361=\247P\254=\207)\254\276\364\344\252\276\274mC>i\327\204<\214L\376\275\267\306\361\230\341\360<\000\246\003>\235Qt=\002\030\305\2765\233\033\277\r{r<:\337D\274%\3026\275\273\032z\276\177\326E>\3523\251\276\315qm>U\376<\276\327p\024\276\370\221\310\276v\306\227\276&\t\025\277-\t\302>\2139{\276\262b\272=IX6?\312$!\275\217\251\030>qY\230\276\361p<\277\030\365\375=#\000\304\274\036]\036>\2624x>\335\200\335\276\314X\216>E\360:\275L\335\023\277e\373\201=.\276\225=\304\036\233\276\223L3>\202\326\210\276\034\205Z\276\316\374~>h:q\276\007\222\357=\354\371t>\226m\305>\240\341t\276\262l[\2768\347\216\276~\345\373\275.\016K\277\374\207)<~\224\367=\206^\t\277c\377k\275JR\202\276\277\354~\276/\030l\277x\360\262\276<\307\372\276\364\024\314\276\323\002\252<\376%h\277TL\301>\006D\022>\342\001\001>P\034\030\277\026\330\214>\246\240\230\276\014w\230>XL\023\277\304H5\277\307\006\203\277%\267\206=\220i\'\276\242G\017=\031\354U>\'\372\377\275V\000\225=8M\304\276\261\224\"=\200\315\355\275X{K\275\270\024\316\276\312A~=\211\311[\276\036X\376=\2022\333;\307\006h\276\037J\022\276\270\231\206>\267LF\277\010\362\034\275\330\230\224\276\315\025\255=\210\311\233\276O\036\362\275}\277->$\020\355>\210\317\322\276\365\232\375\2764\200\006<\036(\223\276\0350\321=\361\026\\\275\373>l>\274O\014\277\220\232\307\276K~\245>\037\274\305\275@-p\276\264\220\321\275\3657\273>\266\267\234>s<\013\276B\247\307=;\212\n\2774@\220\275\226(\022=\325\330\231\276?\r\027>Y%\303>\231N\340>d\036\336\276\375\t\'>=U\226>\256\027f\275\204vn\276\247\270Y\276\242\250\347\274\342 }\275a\362\327:\342\252\250\274o\001\236>\030\322\034\276v\032?>>\373\240\276\243\3015=\006\0305\275U+\210\276\355\253\310=\353>\216>7\316\270b\341\305=\002\261*>\345\256o\276A\315\r?\323\201\033?\312\017\003?\0131\204\276\230<\034\276\240`\005\277\0141\374>\\\335\255=\334\362s>m\332\202?`\233\201>\367 \260>6Q\"?\377\242\341\274\375p\205\274\205\362\221>\n\310\304\275)\265\035\276S\265\240\275\246\261\236>\273\010\244>\017kh\277\250\334\037=\t\251\r\277U\354I=!\232\306=\272\013N\276\263p\\>*c\020\276)>7aoh\276cW\254>\213\352\t?\302\267\356\276\252\327\252=\332L\344>\347`\215\276a\270\337>8\025\014\277\204\235\216\276/\367\375>g\310\377\2761\244\020\277\234g\224\275\0260\006\277\213\234\264\276\\\327\021?\001\271/\276J\266\316\276H^\024\275\251\213\037\276[\276\252\276]\242Z>6\217\273\276p\016\261>\334\034\233\276\224.]\277F\310\222\274\341Ld>\357w\334\275t\375\362\2757\370\004\277\373\002\261\276!\366\271\276\222\265\252\276\013\275\253\276\234J\261\276\325\233}>{\274\r\277\234\243\233\276\351\265\033\276[c[>\252\322\010\277-_\254\2758\371\310>\306\346\342>\261\236\326=5\341\211>\330N\n\276\332*>\276v\346\230\276Fm#\316\262\226>\347\\\022?\tZ\375<\350\177\325=\363\207\327\276~\027q\275\322m\007\276\004\366\016\275r\017\021\277\022hB=*\331\247\276S\207\266\276\327\362\014\277\242-\007?U\372\t\277;\036h\276KA\032\277\342mQ=SZn>\224B\245>)|W=,\223\335\273\031\251\210\277\246F\273\274\316lC\276\021\301O<6\007\240\276\016\256\301>\361\255`\2756i\277\275\241\261\337=YZ\'=\t\236\322>\360\373\203\275gc#\277?\324\021\277&\374\352\276\002\376*\277Iw\227\276\246\004\005?}\347\330\275\260?\345\274W\316\231\275\t\2657>\355k\215\274\326g\177\276\266U\366\275\245\337\325;\034\267\373= \255\201=L\010\020\276\207\300\373<\022f\222=\367\207\310\276\036+\251\276|J\330>\253\t0\275\033\014\240\276\202A9>\020e\t?\000\222\227>\301$\301\275kp$\276\261\247\267>Y\212\316\253\014G<\000\004\256>k#\336>\002\261\366\334x\346\274\314\3522\275\362\3762>\236\006\030\276E5\353>\224\2509=\032\025\016?eQ\211\276r\023W\2765n-\276\267\356\201>oi\304\274\257\334\230\275\323<%>\205\"\016\277\037\362\034>\3276>>nI\001?\345\376 \276r\021\315=O\'];(\314\213\276$\216\325\276\377\263\244>\350\331\342\273F\366\374>\277O2>+\346d>\013\021\031\275(\336\t\275\261T\364\275\2025\235<\341;\000?O\303f\276yY\001\276z8:\276\235\320\212=,_\250\276\311\377 ?\272?9\276\201\365\227=\342[\177\276\"\344\366\217\341=\224t\003\277\017\333\257>\230\234.\276\314\003y>\335\317\362\276\236\342$\277\213\356\217\276~\025\246\276q\t\323\276V!\272>\205\225\274\275\312\310|>\226\214\247\275\361\335\031?\335\021\323\276\177v\334=\2524u=\274\247d\276\2271A\276\362\271%?\3320m>,U\022\277&\340\261>\225n\024?\347\2454?\355\371\234\276C\036&?i\3219\274\354\017\202>\'\371\344\275T\2105<\037\003C>nJp\276F\216I>\016#\374\275\035\304\202=\016\256N?\345{\354>\377\226\007\277\267\324\202>E\335,\277\177\311~>\215\260\'\277\311\244>?\217\026\025\2771\023\343\276#\370\032=\032\351p?|2E>\345\361\242\275\013\251\210\276d\237~>+\023\023?t\343K=\317\272:>\025^\364\276\301s\366\273\270\3218\277\231\'5\276\224K\276>\027\327\r?\237}\355\275L\321L>\360\0363\276)\355@\276A\237\200?\210)\005?n\335\n?\225\374\004>\216P\220>\013\363#=KwG\274J\002\270=\314\332\366\275\204\007Q>E\343\">\361\217\220\276\261\217\234\276\034\345\272\275mE\232\276\013\023`>\263\275\226?\330VS\275}\371\303=\213\251\342;\030\032\340>\377\361\245>\323}\202\275\013\365\r\276\314Zp\276\275\333K\276\254\003\014\275\347 \"?}\202\250=\336Y\206\274\034\222M?!\321\210\276\373u\314=\237\022\022\276\020\354Z\276\277.\004?\343\355\245>+aj>F\031\"\276\262[(>\371X\217>\033\320\005?\322Y6\276\270\271(=\030\261\375\276\033\367[>\"\333\311:g^`\276wvK\275-\316\306=Bq=<\205iU>\377\3653>\357\005\242=\223%+\276\307s\313=\312\2603>\035c\033\276{D/\276\334]\033\276\273\001f\275\372}\014;\301aw>|\316U\276\274\365\257>Ct\370>\272\344\227\276V7\026\277X\272<\275\242\207\343>\035@\324\275\343\276\227=!\203B\276\372]d\276\216\273\233\276\006:\232>\3642\275=G\325\227\2763\350\001?\n\307\017>\275RF<\032e\321\275\253\366\225\276({\362<\nU\3464\025Y>\205\000\030=\213\217\022=\206\306\017?J\237\031=H\022\r\277\310\342\240\275\205@\224\276\3524\244\276gw\364\276\223[!?K4\024=h\007\341>m[\251>\320\215+>\006\253\357\276\212\322\233\276K\200\005>m\336\r>{\242\243>Y\021\213>b\327x\2767<\354\275\004\331\322\276;\320?= ,\361\274\356d\027?w\035\330>\313\224V\277#Q\345\276s3\257\277\263\240\001G\350\257\276\032\014\312\276i\311\212\276\316\0212\273\341\220\020\277k\300\355\275)9h>J\360\201\277PD&\276\304\313\371>\340\277\000\277\255\240\366=\230\006\217>\3675\376\275\032\026t\276\344\213\235\276d>\241\276G3\247\276o\221q\276}\275\332\276\361\264\315\276w\010\034\276L\305\315[\340\032\276n\254<>\326\351T\277\214\202\\\277n\202\315\276\256\rt\276i!)\277D\267\276>c\246\312\275\305\255\234>\371\243\003?\221\364\211\277g\'\322>\314g\216>\205\221\204\276\2257\231>\303\301-\277Y\027\246\276\302QW\276\376X\200>w\325\261>\333\361\n?\331\303\017\277\247H\240>\346\365\036\277\211x\230\276~\273a\276\237\035\037\277\344\361\205=\266\373\031\265\230>h6\r>7\271\323\276\252\366\237\277\335\023\211\275)\360\217\277\241\225\322>\371~\251\276a\005\255\276\246\273\311\276\214\261\247=t\347!\277\201\300\037\277\333\251\262\275\307mC;T\230\326\276og+\2742Y\205\275:\274\317\276)G\365>\322\032\350=\304\345\'>\242\033\232\275\316\034\013>O\311\020\277\350\201\314\276\330\260\\=X\337\376>H\213\r?\272\245j\276\210p\234>\000\332O\276\330\034\305=\320\177\324<(c\003=\\a\223\276\n\206\211\276UaW\276\273\314\261=\313\300\037=\'j/\276\242\223\n?\221G+\276MMP>P\2318\273u\354\204>\210\177\022?\331\034D\276\002\214p>6\365\270;\313v\334\272\032\010\006\276(\322\301<\352\325\006\277\255\331\024?\201\017\303\276%Y\310>h\037\242>\n\266\326\276\026\353\025\276\0275:\276V\021\304<\223p\233=d\314\214=\001+t> \273j>\241o\271>t\222\326<\033\rD>\t\354h<\333B\203\275\212\254\351\275\224>?>R\217\357\276\325\326!\275\003_\372\276Z\317\351\276\273d\213=\262\226\203>C\227\026?\335\335K\275/x\252=C\246E>\275mB\276\222N\253\276\242\217\257>i\307\275\276\345c\022\274o\340.\275O\320\317<-\003&?\262\261s>r\177z\276\271*\375\274R\367\250\276\220\273\260\276m-\304>~=\203><\361\241\276\300N\332>`;\203\276\362\227\316\276\307C\216>ZXc>\005>\237\276S*O>|0\337=\306\342n\276b\325\270>w\243#\276!\016\277\276\020\203=>4\024b\277\024}\336\276\203F\340=\266(\357\276+Uq\276l8\214<\034\341\001>\013}\022>ef:\277\027\264\003\276\n\342\261=\271\232s\276\177\351W\277\246\214\244=\206?\003\277E\326\221=\205M\'\275\244s\213\276\251H\026\275\357\267R>\234\252\274>Y\205T\275\372\t\350>\\n4\276\240W\326>]\tD?.~\243\276\326\321\t\277\212]\320>\215\343\316>\233\336\354\275\200l\251>\305{\335\275\206]\027;\273\034\346\275i*P\276#\255I=\0139\303\276$\004\341\276R\376F=\217\271U\276\305\223\206>\303\307\021>E\243\020??\2319\276\307f\036=sC\327\275\375\374\027\277\233nG\277\375?\016=C\2376=\366\311\243\276\271b:?\266\252\263\275k\247\324\276\332\341\342\276K\201\302\276\302\303\202\276\344$g=\246FB\275\005\370\356\276\370#\201?\003\313x\276\235J@>V\264\354\274%\254\003\277\033\225\222\275\304+T<\342\344\010\276\367\rA\277\262\342\340\276\227\202\334\276\002\032\246\274>\224\304=\005\211\234\275\210F\035\276h4-;\220\3059=\323\277\330>F\325O=%z\304\276$\202 \275\354~p=\345\311\331=\343\303\222\276\345k\353>\200L\315\275He[\277\237\216\210\277\243Y\205>w[\337=\347\262\254\274{\231\n\276\276\006\327\276\356C\227\276\353?!\277\304\236\214=\224\237$<\207\374@\276\344\030\301\276\035\360Q\276\331\363\251\275\250\260R>\001\266y;\'\256\303>)\024\223\276@\237\274;\0215\205=\t\203q\276\264B,\277\366\230(\277\321!\343\276G\233\207=\251\323\004\277\376\252\375=\327Y\234\276.1\335\276\353\236\303=\222b)>\210\375\255\275\207\304\027\2759\337g<\313\362\271=\365p \277\001mw\276\277\236\006\276pd\252\274\323\247C=?2\251\275P8\373\275R^8>\346\370\266>(s\250>\032I,\276\031\312\315\276\320\217\360>\001\371\262=\377\375\033>\330\320\204\276\022>\211\276\225\326d\274#\225F<\220\233\227\276\267$\275\275\335\227_\276\3002\005\276\225wv\276\265^\230>\234+\376>$mb>\226H\035>j\003\244\275\373\010\317\276\252Y\327>\031\'\242=2\325\213\274\204+\032\276\232\370\\>\002A\361\276\276\305\375=N\264B=;%\200>\244Az\276m6$=\222:\014=\224\313\227>E-U>a\346\356=\023\373*\277^\260\230>^\267\246\275\356\340t>\037\374\373=\202I\022?[\274\273\276 \020\340\276\334,\276=\345\n\025<\345T\233\276K\026c\276-X\311\276\253\374\312\276\332z\037\276\350\342\203\272\370\3649\276\217\013!>Ik\216>\223+\334\274\367$\313\276\343& \276\315\214\200\276\270+\373\276\260\251\375\2768A\037\277\3045\304>\005\345\024\275bCM>\321z\007\277\206Jy\276\376;\233?\202I\200\2769\362\373\276o\206+\277\322/\273\276 r\334\276\346\256\304=\312\277\263\276\"\335$>d\266\016\276\3056\245\276b\214\214\276\342\374`\2762\214o>\237\375#>\355\0302\2773\264\222\276\360\372G\276\241l\374\275\373\304;\273\356\346\034\276kz\210\276\304\026\002?\303\212\034\276\367p\220\276\352X\307=\206[\220\276|X\022>\235P\256\276\203\347\261\276`\271U>\007g\026>T\270\346=\274}\327>S\360\343>D\354\355\276\002\335Q>7\327*\277\226\323\363\275\177\243F\276^Y\341\276\202\256\203\276*\267\246\276\034[l\276\342$\363>\364\222\257\276\257\n\251\276\237\026R>-X\343\275\r$<\277$]\231>\326J\276\276\0201\014=6\300\212\277+\351X>i{\214\276j\212\005>\r\377,\277-,\266>_\026\200\276\270&8?J\032@\276\013\3701\276\347\025\303=m\002Q>R\313\004\277L\003\207\275\267yP\277\213\202W\276F\032F\2777P\236\276\370\326??<[\260\275tP\005?\014\237[\276\365\004\302\276\362\261z\277I\2303\277\000\224&\277)\311\212\2765\202\035>6\352w\275\274\311\262\275QX\376>\3414p=]\230\014?\225t\020\276\030\321\215\276`<\312\275\213Lh\276/\255\267=\031\247t>\274z\003?\001\3325?_\2729\276LHZ\275\303\345\217\276Q]`>\023\303\001>Q\307\">\213\303\332=\306,\022\277\311T\244>\031\3210>o\030\364=\353\241\333\275\246\366[\277\274x\016?\325\362\007\275\311}\332>\356\257\027?\016\375\317\273B\231\221={\245\202<\354q\306\276\321\3221\276\334\001\226>Wu\273=\033\226\n>\233\261\221>\014\037Y\275\302!\242=\0045\030=x\337t>\234J\315>g\244\247\276T\017Avg\237>e\257\217>\260\242E?\222AT\276$2\026=\214\317\204><\360\376\275\265\204[>89\212>\006\212\353\275z\275f\275G\006m\276\261u\003\276F\213\\=\2740>>\250\357\310\276\216\307\014\277C\236\371\275\213\356\343\275\014\260\321>\213#\316\276sIv\275\245\212\205>\2454\336=\375\366\\\273\230>\222\274\037\341/>U\217\014\277\017\271~\276\307\326I>\022m\337\276\340-\371\274\217A\206=\370\300\221\275v`\306\276\3648\255\276W\250\036\276.\355\252\275M\257i\2757\r\340=:#[\275\200\270X\276\205\nn\274+\244p=\223av\276\220*S\276i\373\340>\373\341\266\275\377\363\364\275RP\355\276!\221.?z\371\212\2745\260\025\276\214\246r\2754\213N\277\265\322\021\276\325\240E\276\254v\250\276H\263\240\276\330q\243<>\014\240=Y\214D\275\355P\026\275`\025\201?\274\001\311\276\270M\221>\r\217i\277\236 \363=\264g%\276\220\304\240>5P\211\276&\215\024\277\225\232\341\276\301\277!\276\017\246\367\276ax\303>3M\347\276q\357;\276\253\0070\277|\353?\276_\343\311>,xW>\006] \276\037\016s\276=\253\n=\262\'~\277#lZ\276\375\371\\=j\004R=\024\227\221\276o\205\014\277|\002\271\276\243\367\313\276@\363\273<\260fG>,\225\246>\255Q\200=\007\214\027\277v\266\333\276\212\"\022>O\253T\277^N\020>\220\237\314\273\214\323\372\275*\323\263<~\273\230=\027\0328>wLB\276$\036\274\276\364\365\013>\254u^\276\235N\306>\335O\006\277N)\013?\275\220\205\275\177_\256\275\304/\250\276d^\231>\266A\017?%R\233\275\2611\013\275\t\t\355>\276c\r>\037\303\006\274|\347\266>}\221\312=H\232\026\276\323\345\210\277\2140\007\277f\301\212>\246l\215>\030\024\026=\374o\367\276\302\261%\275lj\n\277\330\353\010\277\333\025\357=9@\006?\024\316b\276\371g\021\277\005\223\023:#\322\315\276m\243;?\355\223\031\277%!\227\276\226\322M>A*o>/d\025>x\020\203\273\213\210\237\276\2515a\276\\\270i>\222\321\'\276\2211\235>\224\322\226\276\272\364\026\276\342\312\017?Xl\340\276\232\206S?WZ\233>u\230\225=\264I*>\305\014V?\205\341\330>\017\223\314=\300\224\337\276M\371\326\276>&4>\207^\361\275\317\200\007\276A\337\251\274rR\003=\034\375\363\276\'\030\271=VuA\275F\366\327>\'#\267>\235\013~=\3678\234\276[\023\312=,R\205=`p\035>\270\230\016>*8\350\276\322\372\234\276%\016\"\277m-]>\322\344\026\276\023\013\212\276\2029O\275.\225\207=\025\022\235>\353F\200\276c\202\025?\366 \372>\256\214\324=\2734[\276\202\207\314>\320\323\301=\356\036X\277TI\276\275\202\022\301>\273$r\276z\335l>\007\313\360>\036\337\304\276U\375f\276\372W\243\275^\025\232\276\215\034 \276\367\210\271\276\367\275\261\276\366\335\235>\326\235\260\274\375\213\216>\331o\365>\334\n\204\2765DV\2753Kc>\244\341\365\275\306\215\007\277\204\035b\276`\334\004?&\306\256>\251*L<\266=\032\277N\376\014>r\256\032=L\232\232\276\220\223\306=>\251\245:\r\245m>M\352P\276\233\006\203>f\327c=`3\343>Eh\224\276$\326>\276\267!\337\275 IW\276\r),\276AM\321>\207\016\234\276\212\032\211\276\223Q\241>\262|2<\275B_?\303\010\035\277\305\237v>?v\303=N\351\365=\027\022\324=|E\001\277\260\325\272\275\253\271Y\276\257\366j\277u\231\033>\377V\237\276`\177\033?Y\001\312\276&\231\257\274\374\224\001>+\364\007?\035\366\340\365\007\"\275\345\3221\277B\277l>\224\367\014?\273-[>5(\263\276\213\351\005=\246\032\023?t\357\351\276}\333\303\275[\252F\276_1\275\275.\020\027\277*\220\212\275\234\3356>\032\267\306>Lh\273=N\274\344=\004\033\244\276^\342\354=\305\tQ\276\247\350\224\276\342A\260\276\035\253u=\353\226\200=\002\240\035>\201#]\274\301\345\337\275\316\306\014\276N\340\276=5\261\205\276\231\211\010\277f\220\254\276\315#\033\277\345\267u=\030-\022\277\363\034L\277\212d\256=PW\341\276\324\347\345=w\025\245>\307\231\250\276\331\016\017?M\356\240\274F\352\023>\250V\021\274\210\266\342\275\225\201x\276\235X\240\276l_D<\347?\332>9w\000?:sY\276I\034\215\276aI\263\275\177\376o\276\373\244\273\276\216\014\327=>\373\026\276\213\347W\276\357\031\222\276\336\\\355>]\340\264>l\360d>2\367\177=\371\276>\276,\032\032\276\023\262/\276\350\200\265>g\t\037\276\212U6>\214\210\034>\361T\020\277\306\204\034?\333\316\213\275\210A\025\277(\n\227>t+\300=EC\213>\230\200\002=\372o\250\276\337^\013=\274\274\000>\221]\263>\367K\254\276\371\322\2729r;~\277\026g*>e\265\250\276\222OS\275D\020\032>\274o\317\276\325UN\276\266bC>\225L\351\276RZ\004\276!\001\036\276G\2232\276\307Y\247\275\033\376\277\276\237B\025>!\370a>\r\037\025\275\014CH>p\017<\276$\037:>\007\216\232>#\242\235\276y\300H=d\363\302>\342\022\354=\025D\'?\275\275\023\276!oG>\003\207$\277V\326\341\275\252;)<\333<\247>\274\334\211>G@\260\276\t\021P\276\271\020\031?\345N)>SK\342\276b\\%\275/\207V>\237\273\224=^y\240>6\235\207<\267z\354\275\203\376\006?\021\366\257\276Y\247\204;\033U(\276/\002o\277Y\221v\276\372I\362>J\224\223mD\034\276\347pT\276\037\032\366\276n@p\276`,\224=\221\272+>\376[\214\275Y\205\223\276r2\n?\360\312\'\277\037@\330\274\213\361\310=\273gB>\306\3304<\033D3\276\2063.\276\251\177\231>|\254H>L5*\276\312\\\032?\021N\311=\\\302\272:\034V\323>^\373\\\275\323\031\352\276\231\275\025\277\344\030\024\275C\017\252\276\247ia\276\351\363\366\274\'\3237>\374\237\326=\032\272\253\275\'\377E?O3K>\223\211\336\276\232\343$\276k\260\313=\261\024\202>\016M*\277\032\036\371\276\227q\337\276}\232\215\276\325\207\024\277f\332\030\277!\222\235\276\314\"\025?\350\007`\276\030r\316=\361\375E\277P\363\017\277\262IG>\016t\236>U4\336\276R@{\2768\313\026>\352*\315\276\202^\307\2763\351\247>\253\277\020\277E\203\022>\'\204\025\276\276:6>)\257\001\277\261\337\205\276e\353\333\275\'\332\'\277\250\201D\277O\035[\276\036Z\236\276x\016\357\275\263\276\214\276Si-\276e\204\347\276\316\005\205=\"\004\370<[\322\204\275w\017\251\276\271\355\"=\333\177\375\276\316\211\006?-X$?\242>H=\302\354h>\0219I?~6\372>\'p\037>\322\004\236>\263\214\314\275\3560\317>\177\340\275\275M\022\371=\230\362\231\276\306\365V=1\351W\277\3238$?\037\306p>\333\255\217\276BZ \277\235_\210\276y\270/\277\265r~>\320\3456>\243\360\276\276o&\252\2761\027\356=\375M\361\276\240\035\351<\242\356\344>\343\211\245\276\021\342->\241x\202\276\255[\312<\2167\221\275\334*>>\r\273\022\276\340-s\276=\016\231\276\215\340\037\325\025\253>9\204\331\276}\000\213\274\346\353\200\276\236K\216\277\024K\030>\326\034J>9\253;\276\310D\037\276\177\365H\276\313\300\001?\272\234n\275\206\342\303\276m\224\343\300\025\037=\267\370\207>\215\025\243\275\ng\331\276\262\206\234\276\032\217\224\276\241\357e<7\224\376<\370\277^\276\347\355\035\276\302\202I\277q\036R>\376\205\226\276#\227X\276`To\275>u6\2770]b>e\001Z\276\375\225\266>~\342\000\277)c\003\277yz\002>GR\256\010\203>\025\352\265\275\314M\305>\177\032\016\277rY\363=\316\325\323\276\357\215\343\275\202\275y>\371(\264=\346E\020\276F\013\274\276\374\303\313\276m\375N=\243\232\227\276(g\200<\013\001\026\277\r\270\231=\266_\303>\211\223H=\373b\371\276f\354.\277\0160\365\273\006\242\332\276\'\305\220\275a:U\276e\031G>\361r\216\276\033\0310\277B\016v=(\344\032\276]\327\343\275\353+\021\276B\262\243\276pJ\230\275\303\323A\275F\2102=\233g`>3?}>\r\331\246=\350>\202>\240\332\336\276U,\331>)\324\334=\007s\274\276\304\2146>\360*\334\276L\336M>\241\223\237\273\360 \325>\343\034N>\031\323<\276\n\372\000\277\215\262\247\276G\354q?\177\320\022?\005s\030=*\301 >\316\336\332>\343\2064=\330\273\027\275L%\364\275\206\214S>\277\371\034?\247\251\212>\177\036\215\276n\001\244\274\021\373\245\"a\377>\276a\003\277\\GG?\350\266\217?\177\337\373\275\245Sh\276\214\376\360\306\365>\016\035\376>\006\"I?:\367\356>\224A\275=\340&q=K\322\312\275\335] ?\265~\272>\362N\006\277.lH\275\341\313\240>x\322\215\276\321\002\360\276A\264L<\226~\210>x)\027?<\316\330>\3031:\277\035\370\331>\370\006O\277\360\275\002\277_%\201>\'\222\016?]\320\">N_f?\333\013\254>Z\2151\276\004]\225>2\001\206>?Xo>\354\210\244=\272J\017?;e\376\276\013..?%<\211\276\202\210\357>w~7>\274\245n>\303\002\n\277:\363\300=\215\331R>\305\234\223>\262\022\330>\203E9\276\376\212\240\275\265\230\033?\216\303\005?3f\226>\317\306E:M\254\325\276\260\264\016>\306\345\315=h5\255\276\307P\007\313\013\021>jx\010\2760v\323\274\254\350\262\274\320\231/\277>\326\215\276#\000t>%u\211>t\3472\276\204\317\254=\241\232\242>=\371\212=\034\237\216\276\365\027\307>wL\204\275M\246U\276\372r\355=\265$\022>\373\034\200\277\231_J?\'V\033?\243\321-\277G\030U?M?(\276\361\035\264\276\013\204\344>\241\0134\276mS\266>\352\003\221\275\201\321\253\275|)D>T\203\273\275\364\326\002>\3157\274\276\260\365v>\333\314$?\247M\033?\236\205\r\276\177\374\256=\r\010q\276\033\334\255>\311\363\346>\025~\252>\317\010\306\276\276@\356\276\331c\022=\302\306\027<,e\360\275\365\271d>;[\017?\023\223\007\276\352\321\313\275\324U\006>\215\311\364>~\267\202\276sP\t>\211X\033>\037\302\035>\013|t>x\270\351\2757\221\335>V\304\317\275\334\007\222\27549T\276\245q+=q(\365\274M\205\203=\376\264\330\276;\251\200:\026Bv>) \273>\366\n\232=\211\265\"?,\276/\2773Qk\274k2\036\273\024\366<\2761d\037\276\241\335(\276\030\374\014\2777\3653>\307=\261;\275\211\310<\312!!?rR\332-/\221>h\221\251\276\365\373P;|[I\276\226\232\275\273\352\237\301\275\257\275Q\276\222\037\307\273\346\203Z\277\275\232\037\277\217e\347>E\3419\276\275\251+=\354&\217\275\341\270\237\276No\212>\265\356\020>\037\343\002\277E\032\004\277\252\035u\277\242\322x\276\274XQ\277o>\334\276\367\270\022\277\263D\374\273\0223\244\276\231\214\021\275\"Vr\277i\002\360\275\352\311|\277m\251E\277\031:\225\276\353F\004?\257V\275=\303\304\246\276k\2268>_\007\000\277`*\324=\256\013k\276\217\032\263>D1\276\275\370\200\272<\225\311\205\277\300\323C=Q\2268\277\367\017\220\276\343\025{\276\347\013K\276\210X\202\276\261<\025\276\271t8\277^@\211\277F\225\031\276@5~\276#\205\324\276\273\236\366\274\220\276U\277|\247\353\276g\003\010?\200n\363>>\324\231\276.\304\313\276\322i\017<\274C\004\277\327\030\222\276c0\351\276n\322Y\276\275\344l\276\031\006\255\275\223\324=\277\341\260c\277\230Y\255\276\340\205u\276\376P0\276\265:\257\275(Q-\276\275[\"\277\270\241\210>f\022\236\275\356^^=\240\201\001\277?)\303\276\253\305h\276\260\025\347\276\226\037\010>\256\332\350\276`\217l=\227\204/\276nh\025>!Z\223\276Y\360C\275!\251\331\276\317q\r=Z\205\325\273u\r\345\276~\036*>wU\200>C\254\330\276#\231j\276c\326~P\267\220\276\333\2200\276\277k\214=\027\242\201\275\033[\376\276\346\204\250>\205\246\232>\324;\233\276\367\346\206\276\231\241\202\276\211,N>M7$\276hh#\277\021H\205\276]\036\037?\251\330[\275\202\276\255\276?U\014\277\212\257\037\277\304\353\223\274\273?\263:\345\003.\276-\361d\277 \256N=L\006\211\276\373?R>\200\306G>\005\')\277X$\347>q\257\352\275\036|\252\276\352\030 ?L\007\343=\205\317l\276\367s\241\277\265\000H\275\362\037\271\275\034\305\022\277=/\332\276\310m\350\2751\025\007\276W,\276=\207\227\263\276\002\342\010=0OX\276\314\326\326\276\237+i\276\202\333\024\277\342o\006=\365#\343=\276+\201==\314\314\276\237t\360\275i\203c\276;\330\217>F\373\035\277\317v\010\276\025\251I\276r\360\367\276<\373\034\277S\023\345=Ri\273>\240\330\261>\316\240\227<\216\337\212\276&\305c\2777P\035>5>\336\275D\365w\276\351@\264=W\360\'?\322n\232\276<\200\366\274\331\211N\276\2551\322\276\302\374A\277\377q\200=\374\233\345\276:\003\263\275\372!+\275\327\332q\276E\002\223\276|]\261\276\251e\345\275\020c\333;_7\264\276D\363\323<\356\275\362\276\267\273\211\2762H\223\276Z(\216> \202\210\276i4\177;\240\250\275<\373\302\255\276\216#\200=c\351\037\276\326*`\277lf8?\024\211D>\360\244P\277\355\330\347>\326\200G>;xO=<\332\213\276\345v\216\275\222F!\277\n\356S\276bA\253\276\255\360c\277\310lp\277\342\340\363\276\257\332r\275\034\226F>\243Dv\277\223\016\360>\346\223\306\276\301\251\317\276w\265\t\277n\3276\277b\241{>\nh\221\276\305q\361\275\312\034\025\276*\366\213\275\236r\212\276\341\336#?\225\177\204<\246+\253\276\025\344\246\275\216\245\205>:\203 \277E\213\002?\322\337\322>o5\224?\036~\022\276\236\022\356\276N|\373\275\"\'\236\276\225\217%>\214\017!\277\307\206\363:3n{>v\376\030\277\022\231g>\273\t*\277\024\343\355>\026\341\034?\244\361\016\277\023d\262\274\222\026\227=]c\324=\2675\244\276\345\376)\277\263\260\222\276\300s\267>\036\312\232\276\226\201\207>\023J\034\277\266j\216\275P\321b>\3315\317=\327\"\376\276\021\n\313=X\303p>\324\336 \276\242\253t>D\244q\274\323\370\214=\211Iv>`\271\323>\304\363\326>\231\300K>\343R\207>\252\201\030\277\360\364\305\276\250\216\274\276\332\021\021;k?\241=\260\255/\276\r\342\255\276\363\363\003\276U^\351=\263j\217\276&]\324>\020\246\256\275K\001\216>z \336>\370\354\230\276\357\031y\276\002\2657\273\030\031\177\276\r\266\014\276\004\333\223\2760\270\026>o\210(\276d*\252>r\243\t>\272\360t\276\276\002\214>\351u\362\276\227\366\346\275\253\207\311\276F\254J\276W\"\312\276\245\371\275\276\257%\214>\271\026/\276`\361)\276\020\275\017?\260\0246\277\rD(>\346Al>\331\245\312\276\t]\016?C\254\324>[\326<\276^\031\252=,\245B\2767\036I\277\350\004?>\265\2361\277\"w\220>\260\n\364=>%\256>\347wt>>M9>\3162<\275\336\0172\276\027\032\247>G\'\342\275\264\\\305=r\312$=uH@\276\275:\324>$\241y\276\236\220f\276\240\031\244>\202\355:\277\020\324\323\276\3134\223>\226\247\272>\347\005\035>\213/\245\274\233\327j\277S\000\\=^\373\200\275\374>\213\276\017oO?\306_8\276\001@\212\276Z\256!>_\n\262\276\256\363\252\276\3764\222>\023\004z\275\016D\212>\361\312\211\276GgP>\306t\203>\353\305\004?\306\206\013\276>z0\275\216\n\021>F-\244\276^\016\025\277\020XS>\230\347\'\276\276\006\026\275>\364M\277Ej\275>\346\007s\275Su^>\340u\246\276\020\356\202>\323\264.\277\265#\321>4\230\325<\364\017y\275\353\245\225=TT9>FH\"\276\231a\204=\263Ld:\304\330\346\275\025jw\276\373\273\004\27727\007>\206\r\270>\272\276\220\276q: ?i\311\255=\023K\270\274A\177\254>1\201\r=\363\225!?[\226\034?\323\0030\277\324\025\354>\201\302N>q\325->!U\326\276u\241\215=\317\324B?\257W\002>#\017\310>\302\355@\276*\274\024?Bn.>\250\323\"\276\213Y\025>\341@\335>\205\342\221>1}W\275_f\004?LDd>_~\254;\262/>>\362Q\364\276Xw\337>\240D{9\314b4>\237\304\217>\3139\256=tm\034??)\355>\010\244,>\261g\277>\333e<\277W\231\235\276\240h\r=\345\217\016?\3678\202>U\316\266>S:2=\247\"\251=\211\343\016>\371\260\374=\001\200\266=\345\305:>\300\372\237>\310_\031\276\212\277U\276\313\215\373\273[8\367>d\022=>m\355R?\25404>\356\243\213\272]\320\236>\266\t\243\27626\250<\216\027\231\276R\n\316>\214T@=\371h\271>\350\245\230>\336\177\005?\310Lb?@\230o\276\346\367\274>\220\215\303>/\327^?}\271\000?\225\224\025>\366\031s\275\322\272\217>\270\214\254>\361\227\202\275]f->\340\324\006\275`l\354\2768\324\346\275\300\363T=\344\257\036\277\245\355Y?p\324\336>\226a\003?\306&\211?\265> \277\210\037\252>\016\202\316>pc\327=T\363\n>\360\'\027?\261K\244>gI\005?\301\221^\276\'\016\226>\356\030\357=QBB\276W y\276Wt\314=\3754Q\276\353\022H\277\020\236\233>\323\310\361>\365\005\200>\372\204\250=#\263\354\276i\371\223\276\246\337\031>\023\202\223\276^Z\352;\276\342\'\277\250?\030\2765\315\231;\352\250\364\276sv\224>\324\227\315\276*&\027>\203{\227=vT\356=,\0218\273\000\003\261\275\227\271\215>]#\211>=\213\357\275\353\230\311\276\203m\364\276\177\2047>\"\003{>i\033\220>\365\323\343\276\312\r\'\276\331\361\216\275=\"\006\275\337q\335\275\215H\263>\265\276\023\276\220u\233>(\350\002?\267l\004>E8\'>A\254\354=\363^f\275R\242\346=\"\220\017\276\021\217\215<\264\035\030\276\332\006\347=:\203\317\276p\377O\276\327\370x>\277\016v\276|\0340\277\223L\237>KD\026?\355\252Z\276\352R\320\276=\265\212=\3770\226\276GG\366=\242M\177\275\316\257J>\347NC\274\'~\313>\260\210(\275\271V\323\274\343\263\003\275\333\217\271\276\344\336l>l\333N>%\276\373=\214`\3778<`\333\276\'\023\365>\001y\236\276\341\214E\276b9\263\276+\251\351>=\'g>^e\273>\007v\211>a\276\023?zAp\275\354\023\031\277o\"\221\276H\021\240\276\311\3013\277\034\261\373\275\372EB\276\002\205e\276\024\223\265\275\211\237\210\276\026\023|\355\3468=g7D=\033\031\021\274\013t\026?\351\017\003\277\273\267\265>\372\025\001\276\203s\275>\350\227\324=\355w\304=\005\355\'>1\256\364=\214\221b\275O\343\033=\n\nU\276.\303\274>\277\357\t=7\246Q\276=\215\'\274\025>\201\275\252\353#>>\243`\276%\324\032?\016t|>\315[\212\275\3479\335=\267\207\233\275(\351z>\203\251_>\350\273:=\270zt\276\000\004\364>w\236\007?>\203e>\306K,\276\007D\271\276\371\204K:\321I\220\276\225\226t;0>\232>N[\333=\251\365Q<\'\240\375>\335g\t\276\341:O\277\260_\004?\022tH\276\363\215\302\276R\242\231\276\320\275\207>\350\316\205>\311f\276=*):<\333\345\007\277X\367\333>R\177\313=\271\271\200\276\262q\031\277\342\r\321\276\351\036\310>\27682>\262\032\343=&\336\025>\346O\204\276?\265\275\276}\004B?\211\017\371=\270\017\330>\310:*\276\352\266Q\276\321X|\276\033\266C<\022\031\020\277\266\006t>&\317\276\2760\321\355=\275E\200\276\331\202\210\276\227\254\023\2763q@\277\362\177\222>>!\203>(\"\313=\361\263\322\276\261N\t\275\342\345\246\276\377\344\023\277S\032d\275\n\221y\276\220\373\331=s\304\021?\363\366C><\235\n>\341\202\346=\306\354\211=\331\325\327=s\230\251>\304\016\035>@\351\311>\032\010\023>\3661f>\205\277\257>\340x\t?\213j\352>F.9?\027\"\222=\371\306\376\274A\364\243\2760\256.\275\3375\342;hc/=\376\316\236>&\257\253>(\366\t?\275q\260\275{g\337\275\302G\n?\307\236Y=1\346\357>b]0>/\265\215>\224\311\000?1\350\010=Hk\037>\247\323\206\276\270FU>\211NL\276\210+K>\020\013\232=\357\223\\\276\342\256d?mu\013\275Y\214\364>5D\205>\211\007\244\276\352,`=\ny\357=o\310#\276g\2769?Ax\025=\234\316z\276Z\001\245=\316\373X>\200\331u\275\004x\230>\320\312\250>n\315\r=\207N\236\275\344\236\007>%a9\276\327kk=tT\331=;:\017?\2311\007\277\\@:\276\356\335\245<\215)\322\276~8\302=\3325\336\274\037r\273=\2062\247\276J\324\267=_\263r\276Qq\277\276\026BG>\270\227\265\275\275\3423?\316\224\201\275g\310>\276\265\360w\276\r\017;\276%\245\364\275>\260w\276\214\374m\276\236%v>C\375\247>l\032\247=\226\317\245\274M\364s>KY\237=\334\330\354\276\251\353k>\267\007\347\275\236\030\331\276\t\325j\276\3255\224>\373\312\227=\345D\230\276-{e>*\204 \276\321\024\247\276\177c\233\276\334\021q\277S\3715\276\177b\035\275\005\003:>`e\232\276<\263\245\276\314V\270\276\215T \277;\351S\276q\250]?g$\347>nTU\275<\2276>c\212%\277\2152\n=\235\263\022\277\316\275\013\276g{\036\276\300\227\361\276p\nx\276)\276\214\277\246DL\276\316\372\000\277y7\354>P \252\276\023\220\013=\362rw\277\362\233\322\276\237\225\207\276`\227\031\277\270\342\237\276\n\335\001?\020\331\241\2761<\243\276\3506\337<\313\365\336\276;\005\232>\355I\215\276g\304\r\277\026\255\210>g\313$\276\332E\324\276\274x\251>\r9\315\273\r\2322\276\231\332\022\276\020\216\341\276\216\362\353\276\315H\030\277\372h{\276\036\305\261\276\340\027\356\276\276<\177\276|_\314>\274CR\276ps\000\277\272\373\234\276Y\251S\276\252]?\277{\311\252=\t\316D\277\217\3130\274\006\373\215\276\237/\247=\374\274\321\276\342[L?Q\304,\277Z\321\'\277\034z=\277t\251\371=\237u\022\276\343(\232\275\223\257u\276a\351\270\276w\005-\276\361\355\372\276\230\230\376\276*\007\342\276\237ih\276\313\330k\277gS\217>\202\261\027\276@\224\226>\003\211\212\275 \306&=\0213\204\277{\231\367\276uVZ\277\357\235\236=\341\303\r\277\020J\313>\037u\223>I\210\375>b\260\260\276\014\334\354>\014\217\305\276\370\300\277>\235\034h\276\367(\240>\222\343\276>\331N7>q4\274>\354\334G\276\212\310.\277\245Ud\276\225\210\237\2756d;>w\207\002\2759\232\">s\346\304\275\217\243\256\276O\375C\275=\351\250\276\210\305\032=JR\301\276v8\351={f\001\276\354=\356<\356,m\276\021a\003>\303\333W=E\263C>\024\034\202>\023\316y\276\271\255(\277\204+\300\276\270P\233\276\0261\021\276\354\372\214\276:H\014\276Y\022\251\276\305\203\321\276-^0>V\305\373\276\251.\007>\024?!\276B;\037\277\tl\344>3Wh\273\301\260\276\275\007/\240\275\354A\241\276\024x\030\277\344\327\266>\260\374\002\277R`C\276fXy\2762\177\376=\251i\225\276U\302\002\277\306\223-\276|>f>\037\021\003>\002\304\234>\224\t\263\276\\*\303;\003\302\234\276\177\252\325\276\236(\'<\020r\026>T\025\224\276,\025\275\276\036^\013\277h\342\300\275;1V\277\274J\002\277$F\332\275\325\217\336\275Fn:<\"\207\223>\312\261\210\275\177L\306\275\230\345\277\276\025\300\231\275T\036?\277\273\334Q>+9\366\276\207\356`>\341h\026<(^\241=tL->zf/\276\345\255\361\276A\366>\277\241u\221\275=\216~=>^N\277\235#-?Ps\\>\025\273\350>\263\352\304\276Z\005A\276\376\010F?|\r2>\317\025\314\275p0J?oS\244>\277X\320>id\200=!\370%?\277k\341<\030\032\030=In\240\276\242J\000\275\317\312\235\276\345\356\345>\211\030(:H7\236\276\224\204\213?\023\330\330\276\316m\320\275\336\267\311>\0375D\276b\267\002\276s ?\276\'\344\031>(\264E?j\020\246\276r\'.\275\016\324\037>\316A\r?0&\337=\345)E\276\245\253V\277Q\016\272\274\'+\032>\310\353a\276\th8>\330\312\335\276\253,\333>\217\2523?\212\225U=\275\335\274>N\211\300>\246!`>9I\202\277o\364\343\274\234P0\276\353R\217\276Q\236O>J\"D\276;h\232>\016\232\275\276\207\2103?\372\325o>!\025y\277\365\034\377\275h\354 >\32690?b>\032?vo\212?\342\300l\277\035pu>D\250*\277\0271\220\276\260J\035?vZ\022>\365(\025?\333s\242>:_!\276\240&j\276i\337\217>\223w\\\275Z\321\335\275\237\n\005?\2410\204=\223<\257>[\342%>\242\323\013>06\237>\336\t\205\276\337\256/>\242\357\365\273-\014%>\026j\025\2771\271\337\275<\262\231\276\3672o>\001D\030=\214\372b=\014Y\321\276\020\316\317=k\250\202\275v\325#?{\242\255=E\304\251=\003\347J\205N>\325\315\235\276\376\231\016=<\256{>7\265\257>K\006A?\212\272\256>8\271\202\276\326\243\215\276-\001u=\355\270\203\276\275kY>\202\335\313=s\315\037>\327\226\275=P=\r\277\274s\221=\226k\306=\221o$\276\t\2639\276\230\314F\276^\212;\275\241F\346;\t\262U\277\350\020\240>\366K\237=[r\234\275\351\220\253\276G\tG\276@\245\243\274\006\202\316\276\210\323\203\276\315\2552\277\271VK\276)\334\016>\241\t\261>\220.>?\356K\226>#\253\332>\370 \223>0\344\253\275\244Bo=\256\224\014\277\223\006\336\276N\356\320>mtl>\235\317\302\276E{o>u\017\213\274\252\347\254>\333\177[>n=\241\276\377@\003?(\201u?Z)\004=s\214\224\276\301\376<\2766\217\237\276GJ\021?\320\231\220>pNf\276Y\205\363>\324h\270=g8 >\215\ns>\371\007\270=B\2656\276\202=\221\275U\340\316<\363\252\321\276\177\253\213\276\357n\205>(E9\275W\251\361\275\035wl=\335\271\247>\343\177\361:q\247\340\274=\267:\276\023WK>7\215[>^\247\251>\222\242B5\347/\276L6\002?\032\010\325>\361T\232\275\205\\\344=ow\205\276D\221r>\224!\357\275\303%\326\275\326\003\264>\237c\003>\232\242\331>\034\270!?\352\215H\274\\v\271>\313<\274> \007\223>\323\013\201=7t\237>\250\214\004\276\244\254#\275_\246\201>\231\214\233\275\250\254\334>E\013\377>\313v\256=-\327_?\337\217\273=\342I\356\275E\312\\>\014\220\302>e\275\371>\2455\004?,;\316>\2407\025?\3402\005?\371\372)\277\013\337u>RHS\277-\213\303>D\234\313\275g\255\253>o\356]>\356\234H>\260V\367>h\035\300>\234\313\205\276\327\007\256>\"}*>4\030\322\275n\315\327>H\013\030\277\362\013\364>MC\343=\030f\252\275\340\017_\276\362\210\t?\350!\021>\003\332\212\274\364Qq>n\205\323>\212S\240=\250&,?\321%\252>m\271\225=\033\'6\276\020UR>\226\234m>-\242\362\275#\330\t?X4\204\276\216\021\275;\353\277\302>r\020;?\030\217q>?\277\\>\210A\347=\373\332\334=\357I{>\200\000\027>\006\242\367\273\177\200\202\276\217\006@\276\260\362\235\275\177,\227>\213y1>\007)\304>\244\177\025\277\275:\262\275\264\351\223>G-\005?[\025\222>_\326\204>@\322\332>\217\357\341=z\341\363>\327\354\025?\016P\033=\203\231\304\275\325JD?^\220\253\276\226\377\000?xZ\362\275\231\2749?\252\023\203\276\260\352\010\276\022\276\373\273\262\t\r>&\005B>$H\367>\332R;>\233\374I?\376\320\037\276!*\027\277\315\007\350>\257\366\217>\335\371\201>\0263\325\276n\250\332=\001\355\225>\267\266\204\276\343d\336\27585\312>~\310x\275!b\014>|\355T\276\240\374&>\213A\001\276}\260\303=\000\245\362\275z\307\274\276I\034+\276\373i\024\277\241\241\010<\270\277\007\275v\357\270>\361Eq\276,q\026\276\272\307T<\3304\221;\204\373\217>\377\253\020>}\367\032\275\032\031\236\276,-`\276oU\216=\330\262\272\276\261xS\275\030\216\312>\023=\314>)\022\311\276:>!\277\221z~>\354\344\253\275\367\3240\276\362\335\">xt<\277\333R\"?\270\254\337>2\367\200\276\273^\364>\334\307\354>\"\227\235\276GR\006\277V\370\225\276\2062\023>\003A\330\276\272k\233>]\034&>\213X\211\276\216|\217\276\246\352\301\275\300e\225\276\'q\301>\360S\037\276\367#T=C\272\006?;p.>\332\375&=\321\216S\275nl1\276\375w\354=I\223\021?jo\n?\273\031\271\276o\034\245\276<\240}\276T\340\200\275\230\216T\276\177*\026?\\\353=?\253O\242>\220\241\002\276\273\347\265>\266\202\352\275S.\026\277\342EO\277A\007>\277e\036H\276\263E\037=\325\377\353>\000\311\036=\254\244\202\274,H\340>U4\211C\0313\276\311\230\255\275\244\031\376\276\356\020\024\275\372=g\276\340\'\224\274\033_\205:\373\313\245\276\007\371g\276+\315\371\276sE\250>\242F\375\273\315\322\311\276\334\236\221>\243\355\320=~\336\">\254yL?\265$\004\277mU\000\277-\356\303>A\205\n?\334\034\026\277\304\'\267\272\271\214V>=\377\343\276,\014\364>\237\371H>\014u\365\276\203\306\374>#\217\365\275\376E]\276223\275\332\340\037\277\272x\314\275\221*\212=\212\221\036>\254\3223=\311\246E\277\177\263\235\276\351\345\330\276W\027\216\274\216\030\360\276\024\311\"\276\303\373\364\276\217_\013>\274\005\274\276\354K\246=\355\033\277\275\004M\003>\316\030\311>:\377^<\325B.=H\020s>\270\233\236>\0341\"?[\263\331<\322\243R<\345\246\027\2756\246\r?\216\3234> {\307>Jo\362>{\244\036\277LA\302><\265@\275d\326\006\277pN\202\276\251\021\177\2762\312\201\276I\277r\277A\326f\276\214\245\343\275\207\r@\277=\007\377\276\000\225\241\276\232\010\250\274\364\2744\277V\001\267\27561\241>:\004\337\276K\373\276;\367\376]\274\371d\246\276\326)?\276\205\352$\2777\000\270\276\364)8\277\274\241O=f\006\205\275bJ\030\277\277A\302>\376\214\256\274`$\237\276\253a\310\275\032\250;>\275o\262>\232\250K\277<3(=\322\200\264>\257\256\214\277\267\002\'>\207\334\242=_\274\017\276~\033\277>\265G=\277\236\337\034>\361q\203\2764\334e\277\252~>\274\007\306[>MQ\320\276j\343\275\275X\277\236>\001\207/=\211\267\265\276\300\275\005\2751)\277\275*)\322>@\037\271>C+@\276\305s\216\275\200\'\253\276\302\373n>Z\n\031\277k7e\276\231h\010>\330\032\212\277SW\342\276\376\224@>\034\372\302>4\"{\275\243w\256\275{\263\311\276_\330}>\311\302z\276R*\362\275\263\320\030\277\220\234\000\276\r\325\210\276!\236Z\276c\225\201\276\207\213\322\2764\314\032\276\242kX>\356{M>\364&\360>\370\370\370\275\2779\262\276\020\341S\276\347\010\300>\366\265\217\275\264]9\276N>\340>\025E\202=\231\235~\276F\000J=\226w\236\276\000\214\353>\\$\273>\035&\216\277\220\375\347=E\213\201>\0054\221>\203S\224>S\240\223\276)c\016\277c\024\033\277\323JC>\272\371\276=\255\276\217\276Q\245t>n\312\374\276\037{\204>\220\266\026?\013\r\247>bh\'>\357E\366>\223w\233\351\305\000\277V\034,\275\316\000\026\275\276\330\355\275\236\'\037\2760\360%\276\250\004\264>\010\271\272\275\3410\177>o\351a\276)_)\276M\351\033?\265\212>\277M\002/>\233\226)>aS\177>\030%\336\276\002,\344>\352\232\370\275\362\311\326>\210\375\246=j\271\374\275\314\221\215\276\277\366D\276ni\245\276\311kN=/\3017>v,\257\274\217xQ\276\350\260\232\276\252\023\217=S\032A\275\214\353\221>\031_\341\276\212\200\221\276\337|\031>\214=\255\276\031\1779>~ZB\273\'\347\017?\"\327\266\275\253o\241=PR?>\346\325\220>\236i\375=\342\241\"\277\210g\341\2762\345=>r\177*\277\017\336f;\017\376\215?\375\240\253\276\325Z\301=\367&\215<\330\321\321>xK%\276\014\313\277\276\366\267O\277Z\031\354>\312Q\303=\2060\271\276#Q*>\212\236\037>&\313\253>\332\240J\277)\300\335>\274\370J>5a\230>\307\354\211\276\243\024\200\276\037\363d\276\352\377\307<\022\223\017\276jm\250=\271[\257\275\336\\}\276.\305\374>\246\324\375<\240P\363>\337\\2>W\t\315\275\214\356\205>\235\347?\276J7\356\276Y\004\206\2751\255\242>\246\003\326=V\026\247\275\352\240\351=US\221\277<\3674>\203\244\032\277_\3105<\007\360\375=\213\003\277\275\322\255G\276S\026Z>\251\247\334\275\004\177\265\276\355\300\216\272\3343\237\275K#\231>\375\253n\274&\032\220\273\243\373\344\276\341hi\277LC\216>\244\375\367>#b\312\276\346\350\370\337\351>\020E\016\277~v\230\276\306\375\316>\310AT\276C\244\355=7\027\035\277\315Z\204>ox\222\274*,\032>(~\326>\233\266]>axp>\236\377G>2\\\232\276\343\2203\276\216O\234\276&5\320\276\2531\340T\317\024\277\250\267\304>l\246\373:\355\364\223\2751\216\327=\215\237j\276\3451\021>\302t5>f\002\207=\n\202:>\300Uv\276\030\355x>\217\0070\276\265\326\271>#\344\237=:\0337?c\276\270\275\217\360\325\276Tr\200\276l\212\205>\334g\003\276|\246c=\326\227\225>(\357\244\276\214m\254>\227\0133>\256\007`:\035\240|>\2364\345\275\352B\">\374\005-=\354\314)\275\033E\243=\342[\231=\031ck\276&\261\335>\0268\234\275\372C\327\275k\350G\277yYp\276\t\334\261\274\220\2569>\376\312\213=6\337/>\262\023\373>B\217\236>\006$\'\276\010k\214>\321a\245\276\341\353\253>L\347\020\276\360\246\004\276\002\3653>S\351V>n\034\200\276\232[\265>\016W\323>T\210\214\275\226*\330\275\233\225\024\277f\'\231\276\360\303\020\274\345\257\035\274\027Y\201>\"\262\350\276)st=ihX>\177\253\252\276b\222(>\335R\325\275\017p\255>\371\337\327<\370\306\307\276\212\252;\276\356\374\245><\236\n?\r\016)\277H7\253\276p%_?\365\227\317\275\256b\017\275\345r\236\276)\r\031=\004\345\377\275?\366+>\271oo>\317\270\331\276\323i\234=y\317U\276V \010?\271E\212>\266\252\226\276\'.\301=\021q.?\232t\017?\360\241Y\277/\022g\276\254\010\331>n\313\242\276\303\036\273\274i\275-\276\334]\254>\t\220\212>}Z\310\276\275\371\017\277\335\300G?\"\rD= _\034\277\02260>\273\267\265\275;}\315=/\002\217\276\303\2434>\363%\221>]\023\035\276i`\304\276@y\211>\234Z\350;\251\342:=8MY?\3217s=\277\020P\276\017\211=>\240s\\<\242\026\024=}s\030\277Q\365\275>\262\023W\276\023\3607\276\253\330j?\311\244\035>\244\247\207>z\343y\275\261\026\014?:\t\205>\375\212\351\275d\307\263\276\326\t\200\276\005R\201=\014\276\300>3\217.?E\347^=p[6\277gQ\263>\3726m=\033\301\327\275\200\"W;8\010\234;sXQ\275y\346v\274\367u`>\377\346\004\275|\rB\277Wp\025\276\207\001F>\240\330\017>M\037\303\275\341 \217\276^\300\310>\334\376\230>^C\001?c\353\227>\347\236\205=\3106<> \323\374\276>\240\331\275{\276\030\275D\001\360>\347\263\301\275\'7\035>\2240A>\030\347\331=\\@\231\276\224\004\020?\326\020\312\2755\257\321\276\251\004\334>.\335\246>._\023?o\360\263\276\311\276\231\274,\331\223>\213y\013?\305\322f\275B\306D>\205\002\337>\223\307\222\273\260\250\021?\275\357\025>\347\335\255>|\024\262>\277\220\231\276\270?\325;\013\333Y\276\261*\200\276\177\010\230>\265\177\252\2768H\352>\032`\014=\026^\t\277\343\367\263>\373\216~\276\361\247\215>\007CT>\201\210\374\274\230`T>\255Q\004\277\237\366Q=M\217\247\276T\225\271\275\010\027\005>g\266\310;\307\'k\276m\036\035>\344\234\362\275Y\r^\2764Z\344\276\255H\227\276\377T\\=\224\241K?\312P\263\275B\356E\277\022\372\004?\343\376\230\273\273\213\312=O\331`>\356k\013>w\257\265\274q(\215>x6\343\275m\037\033\276\334\036Q>\\\006\226\276\264\316\271=\363\332\026>\"\342\017\277h\334\251>\347\234\265\273\227%r>c[{>\354\343T\2761o\241>\010\271\224>\227\333\351=\256\351\204\275He\203<\355#H>\372\335><\362Eh>\367D\\>\355\244\026\275\367\3019\275OR6?g\375\271\276\335$\253>\301G\311\276\033\005\007\276r\305H?\224\227l?\326\246\253\276H\004\026\276z\370\201>\242\253s>\356I\024>\030\364\357>\202\3540?RS\261<\264\366\344>\022\231\237?rn\304=\346\216\325\276\314\035\301>\222\221\t>\3078\367=\r\355\341\276\376;\353>\337\027\263\276\266=\233>^g\216\277\277`\207>8b\335>\272\027\247\276g(\023\277\244\357x>?f\356\276T\037\020\276y\233\371\276\037\215\022>u\372\337\276\3645\036?\331\210G>E\341f\275\272a$\276\004\365\336\275i\344\223>m\230H\276g\224\237>\016\314&?2gB>\014\2357\277K>\002>cY\352>P\016G\276\331\0029=\013\2075\274\325p\330>\230\264X=\376\203\374\2751\314\351\275l\325\216\276\314\"\345\274\373\037\243>$\214e\276vnf\275u\267\355\276\235\nX\276]IU>\"\270\004\276=\263!=\032\276\017>%!\200=\245\035D?\027jk>\013<\304\274\242l$\276\003\006\371\276\306\304\016\276m\361g>P\245\260\275\024\002\331\276y\350\371\275M\246\344\276\003\305\210=\3051\'=T\355\270=Q\333\r>\021\301\007?\010B\330>\002\323\034\276\352U\r\277\010a\366\275T\265\255\275Pg\231\276M-\306>\320\360e?\260iO?a\032\326\276e\306\301\276\376\365\022>Ct\311>\026D\364\276\242<\312>/@0?\036N6?,\332\320\275O.\321<\352\017\240>\2656%\276\276\003\002\277G\354\215\276t\321&>y\020\365\275\321j\342>\323\2434>\233\250\004\276\273\357)=\037\327\355\275\343G\245>\210}j>\255\036\230\274)6\200\274/)\027?\013\322\027\275\"\313\024?\305\350\000\276p[\243\276\356\305\213\275\267zR?hV\263\276Y\354\217>\325/B\276\343C\304\276\343\002\326>\321\010\323\276H\215\253\275\323$\351>*\265\264\276e\201h>\004\311\007\277\035\373\023;#\221u>\355\003\226\276%\024\233\275\271\007F=\212\276~;\314x-\276\230\263\014\277\032\273Q>N\264\265<1\000e>\340\273?\277\235\274*?\214\316W>\014\214\256>\200g\237>R\276\220=2k\376=v\0269?\301A==\262\362!\276\3408\306>O\316\275\276\2152j\275\000i\323\276\365\215\013=\275Q\016?\273\313\003?\370i,\276^\003F>r\321\341=\236\r\034?\376/\021\275p0\222=\330\344\311\275\342/\030\277l\271\244=\214\251\216\276\0216\357\276t\250[\276\246T\023>\013\315\332>\210\266\006?\316>}>\007\276\247\275\332\034\271\275\272<\036>\216\242U\276o\304a>\255]\214\276]v\"\277\003i\343>\004dv>B\233\210\276D\372\017\276\256#L\275\313^j\276`G*\277\005\273\254\275m\302\264\276\237\255)=\206\3466\276\253\032><\241\365\322=\177\202\315\276u\303\333\276\027\001\024\276k\346\201\274\335\246b\276\345\2105\276\361\231\343>\276\356\024\277\370x\266\276u3\230\277>6\303\276\010\331\224\276X4\202=Fm\324\275X\036\314\276\357f;?A\206\001\277\013\240(\277\342\355\300>\002\225\307>\233\213\204\276O\345\306\275v\217\213\276:\016*:<\215}\275\240\032]=\265n\267\276\031\336\372=\315x0\276W5\202=\21358\276\265n\274>\372i\332=f\030\205\276\234\\\365\276=b<\276\251\224\324 #\035\334\2769E\342;\002\252\235\275\363\031\326\275\237\241\013\275\355\307d\275BA:\277\216\337\030\276y\354\004?\276>\222>\372,\270>\036;y\277\314\"\223\276\035\354\022\276\276\001\324>!\004_\276\342\213\241\276\360\302k\277\243\354\036>vq/?g\321\336\275\226c\317>\231\302\037\276qXQ\277\217\272\"\277\364\355\260>\t\333\214\276\245P\224\276@\325\231>i\241!>\265l\252>h\r\323\275\021\307Q\276lk\034=\034\037\024=,*\027=\327jC\277\236\360\001?\332\263\356=\323\304\365\276\354V\"\276|\030\216>~to\276\013\'N\277-P\352\276W\023\276<\223+5\276\273\t\340=\320r\226\276\006D\017\277\272\214\333=\210L\245>\211\351\306>\352Y\242=S\000\375>\312\031w=\360Q><\334#$?\221\307\000=C\'\'?/:\034>P\355Z\277\373a\365>\357\023\013=\206\377\311>\347\262\204<\000nV\276\371\363\352\276\344\025\"?%-J\277\362\355\260>\253\300\325\275\321!\021\275\253\206\210=\324\335\032\277\004\333i>\367\340\310>\216X\346\276\374\221\333\274S.\255\276\250\266\320\276\332\317\277>\005Ud\276\250\022\207\276M\027\353=\355\377{>\302\313\201\2741F\000\277\002\031%\276@\361\256\275rd8=\355p\241\276C\241>=\006\177\306\276U\266\263>\214\'7>c\352\021>\235]\263>\354V\272=\332\274\336\276U9\253\276@\022\326\276\345\376\353\274W)\003=\206\214\273\2761v2\274\327x\004>\240\024\276\273\023\013\203\276mh#>\351x2?\242\214\341>\002\311o\275\234\245\177>\310\324\246>\351\200\002\276\024\233R\276\022,L\274\240\316\303\275\022*\303=\236\343\023\277Fh \276P\243\275>\263\357\236=\310\014\361>\016\022b\276\270\221k\276*\374\265\276\373iH\276\3143~=C\003#>Ag\336\276\326\262\'\277^\223\017?\003\236\007>nJ.\276\274@\205;BO\300>$\300\215\277\236\255\316\276u\305\005>8\271\253>H\005(=\261\304w\276\213#>?<\037\224\276Vq\003=yX\240>\222\243\325=JW\345>\372z\240\276\201\254\377>\021\2442\2768\224\276\275W\031\314\212\351\024>yl\350\276\323#\010\275l\3003?BlL>\363\237\270=\370\223\231><\242l=\2409\306=$\230\305\275\021Wf?\361\214\311=\371U\336\275K\3374?Zs\200\276=/\036\276\341m\225?\255\236\230\244F\004>\206\321@\276\323$c\277%U\004>\027=\260\275\3313\256=\313\242\250=\303\242\203=\',d\276p\250\017\276+0\002\277\377\316\027\276\022|\013=\251c\261\276\3025\253\274\352\005\265\275:\241\302>El\001\275\323\036\026>(\033\331\276\255\306(>j]\241>f\031\236>\014mW=N#\007>\231\313^<\034M\010\277\022\3527\276|@\234>\253d\334>\014\2553?\026\212\020?6\000\211\272\311d^>U\206\224>\301`\313>=\211\002\276\240\300\332\r\177C\275\354xi\273\201\337\325\276`\307\234<\304 /\272\t\302\030?P\320\321>\340\344\251>l\237w>\204kW?\027K\260<\322\t\346<\342\326B\275\336\014Y=\232\316\004>\241\271\317\275!\277\025?\314\250N>VC\004>\006\246?>O\020\026\275\345\016\t\277\351\363\357\275\301\205\226>qP\003>{\001\254;\375q~\276\360/\373\276%ye=]\325\203\276T\230>\276\255C\240>K\203\262=\346c\243\276:\010A\276z\202X=\276\237\014>\233zC>\316\361\226nc)=-y\227>\221\262\221>\021=\374\275M)y>%%J\276.\376\2759g\227v>\225x\203>\016(\371=S\365\242\275\276\241-?\225\304\255>aM\327\276m0\204=\325r\223>\366\234Y=\177lq>\3052\023\277Nu=\277\374EK\276\320\371\210>\303\336\247\275\030\002=>\235J\225\276Q\221G\276\3473\223>\316;\210>\225\032\324\274\367a\263>\255H:\272\375\2576=\037\265\370=D\331\265>\211m\250\276\347|\343\276\352\t!\276\025\\\377=z\002\320>\376\021\224\276\377\243;>Z\303k\276BI\222<\017^J?0C\031=\007X\014?\247\250\261>SI\005>\375A\006?\3742\245=:\006\203=\341\367\242\275\275\256\226>\324\255#\275\311(V>\307\300\024\276L\227^\276t\201w>\247O\310\275\342\273\234>\240<\002>\345\321w>\262\350\217>\025\323\235>\260\242\337\276\275\243\010>\202\342R>\221\255\302\276h\025\277>\215K@\276\232\333\327>>?\020\276\226U\226>\035\2254=\205\302\264\275\030o\206>\320\037\354\276\312\230i\276U\030\"\277\030\242\342\276\241O\336=\243\373[\276Q\232\023>\226\331\252=%\236\321=\317\037\362=\314\006G>)N}\276\216\257\370>\2776/\276\263\036\236\275\272\253]\276u\317.>\013Q\217\275\254NM\277J\271E=,=M\276\207\341f\276/FY\276\332\275\003>\220\' \276\033\022\324\276\273\\P\276B\007\353>\026\210\371=o\037\325>d\334\241>St$?m\036\001\277\327F\230>\210\236\212\276\306\300\256\276\320\204\024>\300\337\344\276~%\243\2759\241\307>m\tt\276A\325\326\276F\251\212\275X9\247\274X\375^\277\374(U\276\267h\030\275-\354\275=2\227\223>\257&\237\276\336\243\t=\324\365\370>x\307\227;\237\336/\277\246J\367\2755S\320\276\364YH?\216\032\216\276\306\370\326<\003\350\234>q\330\235\276\tt\241>\300\243\245\276\024HB\276i\243\r\275\265^f\2767\231\265>cF\253>j\024\221\275\014f\276>\3769\351\276u\351\310>}\244\245\276*\314f\276\212\260\361\276h\t\247\276\220\n\306>q\347\244\275\356\217\220>=\235\265\275\373\210\024\277\022\0257\275\307\352\001>\004\364\226\276\227\331I\276\217\351\321\276;L]>T4\004\277\273\301\001?\371\000\221\275\276G\207=C\350\215\276(\301\342>\251\n+\276AO\241\276\331\340\267\275f\210\373>\325-\245>\033\244\312>!\311}=T\277\356\276\312\256e\276\024\233\023?\253\206b\274\312p%\276\225\220.>\032\027\212\276H\215\267=\001\260\215\276\322\207\233=\262\227\002\277D=\"\276\223K\240\276c\275r>\030\300\022\277\277\020>>\230+O\276f\273n\276\317f\n\277K#\\\2770\265\232\276\2449\026\276~\355\356\276\250/\245=7\246\335\275{v\006\277\264\355\307>\321q\214\276\340\311_\275\221\377#>\352\224\355<\2007c\276*h\n\277\373\356\r?Y\r\363>\022\256\217>\252\202S>\366O\215\276\233%\220\276U\215\211\275H\002\364\275\006\375\233>a\374\003\277\010\244\310=,\365\233\276\311\315\206=\010\026\273\275TM\365>0,\253=m%e\276H\r\201\276\036>\000?4\317\031\275\226\360%\275\345n\001\276\\\220t=^\301\025\277\243\010\225?\177\226\375\275\277\3642\275\205\220\351\275@\272\312={\031\235:\322\347\020?L\033\020\277G\222\266\276\253\266\335\276w5?>\221\253\263>\016\024^>1\r\344>\355\237\242=\326y\271>\216\352P=\275\355\300>\336\224`\276\004\260\263>\265\\\222\276jD4\276!\375\006>\2431\301\2759\020T>\317\202\311\276Z\2560\277\277\005Q>r\321\255\276\022\345\t?N\353\366\276\'\222\372>\372\212\265>p]\003\276\334n\203=\224\347\007>\360\016*=\303A\226=\254\014\026?:l5=r0\220=\025\250\"\277)/!\276\363\301>\276\006\374\026>\003\030\211>e:\255\276\217\241\212\276\200m\371>T\374\\\276R\375q\274\365\002\030?\3031d<(\370\207\276\216s\317\276pj$\276~\223\006\277\346\014\022\276\247\322*;\333e.?\326\376\303=P\200\035\2761y\345\276.\016\220>x\234\266\275\215\260\237\276\310Ql>,\372\217>zm\001?8N\224>\273&y?\001\325A?\304\225\220\276\013\365\036?(\321\355\275w\200/>\360\0045?\257\217W\277S\312I\276O.i\274\330\244\331>W\2160>\t\324\331=\244c\364\275\244R-\277\320\276\270\275\266\232u\276\032%\235\275w.\251\276\205\0047\275\245!\034\274\314\365\212\276\2503G>\352\207\372=\360O_>Y\247\006\276\341\364\337>\236\223\302\275\211\226E\275UZ\240=7^\327\274$G\240\275\253\003\222\346\376R<\n\343\036\276\2167\033\2753\322(>\302\323\300>s\343\277\276\345\264\257\276\304<\323\276\345\361\203\276J\340z> \374\255>\357\361x\276|\373->\356o\036>\322\307\350\276}*\236=P\337_\275D\307\206\276OP\234\276\241Jp\276\304\351\205>\365\025\224=\270\305\313>r\240s\276+-\254>4\2427\275<\266\226>:\301\204\275\254h\367=X\274i\276\032\316\013\277\374N\033\276\003\324\255>\215\332\356=\010}\275>7:F\276\246mu>\215\353{>\322\272\215\276I\227O>\347\307,\275IK\373>\331a)\276\336\010\300<\213\351\">\"\014W\277\363\217\270>\024\n\327>\241\331;?\200\200*?\333~\222>so\230>\214\307S>{1\024?\010\310\206>\235\346\327\275\242F\325>\307\020\245\275\013\204\206=\034\0233>\232\372G\276\301u\005\277`\272\203\275u\030\030\277Z2\027?33&>\030%\323=\263\214\325>t\330\247>\352\232\214>b\217\336\276ZB\217\233>\250!\035?\241\360\t\276\027~\007?\3126%>\214\302P\275\037\353e>\0278\320\276h\341I\275\310\001s<\364\300\314>\"}\252>\262LT>\343\255>>6\364\272\276\312\342u>\332\037\n=R!\244>\013\252\343>\303\201\245<~\220\177\2761<\023?5\3740=\032\3575=\252\356\203\227\025\025\276\221\032\003>r\366\234\276~\304\354>\261g2\276\326\250\340\276\234b\356=\007\376\201\276\277|\263=\230~)\276kF\016\277\270\303o\276\376Zw>U\2134\276\017\224\211\276\376U.\2763\251V\274@*\232\2760\253\035>,\305\310\276\314$\273\276v\034<\274\202\236\276\276\367x\037\2762\215\221\277\302?\006? \323\r\276\016>\027\276N\246o\275\260\332\375\276}\200_\277\021\221m>\356\302\223>\r\202\211\276j[\273\276\3765\224\276\264\225\234\276q\025\355\276\021=\201\275\0068\307>mR9\2770p>\276,\016g\276\3731\201>\312y\241\276\332\375\312=\353\201\001\277\364\341+\276\316\330)\2777\353\250\276-\361r>\325\342\'\277\325Y\222\276\013E\207=\344\2174=v$\311=R\221\362\2745g6>iH\370\276\256i\005\277\263\361^>k}\263\273J\237\326\276\233\365\027\277\301\001\206\276\365@D>Q\n@;\265\336*>`\274l\2770\216\213\276\374\352\234\274\207&\242\276\226{\005\277\202\222\330\276\336s\201\277BLR\277+\310\274\276:Z\t\277)\354\201\274/\242->\230\307\221\276P\341\000\277\244\003\354\276\216g4\275\2761G?\261\tF\277fbr>\213\000H\277\034\307N\276\017\027\221=/\236P\277{\323\'\275\315\022\340=w\353\270\274\345\330\376\276I6\204\274:\334w>\303\316w\276N\265\r>Tk\341\274\311\364\261\275\003\340A\276vST=p\334\242=\274\343\224\276\236\356\225>\203\334\211<\014\265\314\276\257\267 >\361\027I>\314\021\374;\234T\203\276\364d\257\276\314k3>W<&>\206(O>\267\026&\275\250\344z\2765\350`\276Bp\034?\213M{\276W\254\030?\340\314\235>\273\236\001>\256.\375\275mG\231\276\373\276\251<8\3467=\037\306\237\276\352\256\226\276\016\253\260\275\337\203\215=\210\002\202\276\376%\006\277\0014N\275\233\322\010?dy\354=\345\023\006?\001Xs\276\300\211\t\276\006D\205=\303\315\206\276\355.H>*\214m>\203W\004\2751\034\364\274c\214\255>\343S;>\245\223\374\275;f\240=\322\202\274\276\371\\\271\276\353\341\313\276v\272\255=\3744{\2760\034\232\276~\200\025>\027\210\350=e\242\221>\307g\354=D\370\365=\3133b>\255\201n=L\232\021?\200\221P\276\'\3644\274=\240A>(\305\263\276\032\242\025>\260\326*\276\352ke\276\325:\032?\016H\316<\336\350\314>\243\377~=+\305J\275\307>\255\275/)\336\275\213\211\002\277L\3104\275\037\211\212\276\376\265#>w\256\005?\313\216\232\276\255\275\351\275uG\326\274W\232\242\274K\310\266\276\270/\277>M\322$\277\302\036G\276=j\035>7\240\022?hf\201\276s/\376\274\250\3453=U\305\236\274\034\376\007\275\207\200&>^\232\022>\206m\317>\307\232\320\276&\366@\277\002\346\343\276\343\232\010>/\313\217=\366\212\344>\217\027\266>H\227\233>\305\007\002\277\217\030\"\277U\013\030=\271\326\006?\221\3274\276p\313\211>2I4=+fy\276Yir=\212\214\023>\227\262\366=\323\222\371\275\230\274\014\276\t\232\276=\014\303\265>~V6\277L\247]\273k7\232\275^\032N\276\217o\345>\'\222\002>\243\'\357\275A\272G>\235\304&\276\t\242\031?d%\216\274\322wM>tj\025\276\263\276\274\2750\270:\276\340\214\376>\204_.=\342\342\212\276,z\222\276nl\037\276\312`\310\274\004F\200\276c\020\275\276I\224\206=&\213\003??\227\243\276\373w\034\277\037\265#\277\366l\005\277+\321#\276\356\276\314\2766\004\367<\200p\022>?>(?\310\312\376>\3330n>\370\200\314>\257\213|>\207-\275>rRg\276\371nF>v\021\031\276\007T$\277\222\022\265>\026>\211>e\204\242>\002\323\325>V\236R\276}\245\316\276\263\007k=\277\260B>\177[\255\276\255\222\372\245sT>\212\251!\277\366\232\361=}z\014\275\210W\344\275\254\221z\2769D/\276\221\213K\275\313\227[\276\021\014\261\276\013\324\320\276]\330\215>\000D{>\354\212X>\254\2060>\306\243`\277\n{\207=bW\203\277\360\326\374\274\204\265\214\276-\251\347\276sA8\275\201\305@?m\342\034>\034\207\220>\003v\216>\375g\317\276\021\301\t\277\375!\226=\2657\334>W\020\014\276\336\312\t\277:\020g\276x\370\203>3\347\335<\376\357\001\276\334F\017?3c\260>+J\277>i*\276\276\r~m=Z\221\031\276\'\254\320\274\201J=\276Y4n>\265\r\322<\254$\337\275\223Y?\276S\361&=?d\266<\205N\254=\315/\276\276>[r\276\352\231\n?\302\205p\275U\036\367\276\243i\352=\027\277\037\274E\224@>\266\245\004>\357i\363=\2209\242>\332\214\307\274\332&\370>\305\323\351=\324\004\303\276@\246*>\223\244\274\275i\334\363>^2@?\322\343\357>\305s\177=\250:\354<\241\201\316\276\n\256\276\276\033i\324>\256\331\002?\273GR>\375\354\037>\010\244+>c\251\364\275\rqd>)X\004\275\3748\271\275\"\237{\276\030\326\200>P\324I\276%h\220=\222)\201=\330\035\325\276\315n\357\276\371\030_\276As\324>[(\260=\354U\002?\374\235I>/\004\032?\270\357\255\276fE\344\275\310?\313>m#h>t4\016?C&\202>\264\242\370>#\237\t?\022+\274=e\334\217\276\205VJ>\'\020\376\274\363\321\330\276\263YA\276\262\362v=_\232\230\276\305\024;>4S.?\270\301\207\276@\271\300\276%\356\232\276\026UC?g\243#?\034\"\030?N\374\'\276m$l>|\376\021>v\254\332\274\300\236<>5t\204>\277j\227>@\221Q?\212}\233=\016*\362>/\266\361\276p\001\206=mz\225=[\314E?\010\'\n\2764\240\206>4c\221\275+\304\026>\363\215\300\276\230\016$\275*\272\330>\257v+\274b.\326\276~\264`<\001\230\361\276d\331\233>C\322\307=K\372\214\274\326\334\234=\232\234\360\275\375P\221>_!~\276Z\227\220=\234B\351=~&2\276\201hx\276\221-\211>\330\273(?\335\326\317\275\275\373\212\276l\342\240>\007B~?90E?\363\223\362\276\241\t\262=\256\016v\276\002\007\234\276@\253\375=G\336\335\274\306\246\032\276\360i\237\275t>\001\276\240x\215>c\367\356>f\203p=\016.\306\276vz\352=\005\002\216>\244\215\206\274\255\366K?\231\202\351=\373\306\303;I\000r\276\004\004\266=\372Y\344<\243=\254\276\014\177\373\276\341>7\273\016x\026?\331\364\177\274U\332\206=\344 @\276\r\306\212>\356\032\037\276\265W\033\277Wr\267\276\231%(>$\036\204\276)cG=\316(\361=\346\330H?\241V\256\266\276<\0328\367>\3703I=\231\'\303>\213\303\215=\037\340x>\013 r>-;\020>\370\234};d\007\340=\360\345\037\276@\003\211>\274\374\254>\346~\275\275\357\265I\274q\207U\2750\344%\277\023\005&?$;\010?.7\211\275@\352\250>U\270\232\276\034H}\275\271i\361>\315\344\214>\035\024\217:\005\034\322\276?ec\276\336J\354\275\227\271\306>\335m\353\2757\347t>QZ\r?\237\007\030\277n\302a\2741\340\310\276\021g.>\000\340\031?\337\177+>\276-\334\274\245n\272;!\330\341>\255|\337>\224\215\003>-$\252=\305y=\276\036U\233>t@\215>\203\264??\353\021\233\274P\361\377>\272\022\323>\332I\235>\251\377\253=g\346e>\361\032\330=\t\222\237\275U\343:>\310\302\310\275\240\303Y>&(\343\274\244\032D?\007\305&\277\276\214\330>G~?\275\233\351c>4\323\364=,\226\033>\303\255<>\262\236>\276\021C>?M\326p\276\272\010\211>\\\352\023\276@\244-?\204\327\001?\034\315\255>`\317p\275\270\321\375>\257\177\216=\372q*?\371\252\206\275\276\341\340=^\251\325;0%\034\277)\250\003?<\033z\276\211=m>\317%&\277\217\323L>\204\200\345<%Ur>\334\027\222\273_\250\265\276d\202\373\275t\350M\275\245\343\343\275\356K\027\276\232\276\n\277b\363%\276\30158?l\205\266>\026\346\227\276\215\r\221\276\017a\315\275\374\037.>8\227\214\273\217[\030>\372\340\340>*\226\312\274\335\2664\277\260G\246\276\262$v;\212)\037:(\243\214\275\'\256M>)/\361\275\304\307\031?\324#~\276\302\273X<\366\007\307=J\223{\276\247\276K\277}P\265\276(\252\366=\263\3712\277\\\216\t\276\014\340+>1\346\345\274\0319\t?Z\322~=V\031.?\316m\374>\253\260\032?N\000\235?g\017?q\305\311>\370%;?\232\014r>\252\365\242\276\330?M>\351\251\354\276N\342S=\345E?=!\307\224\276\206\024\r\277\036\276~\276=\022\266\274\230\266\007>>^\223>\224>\025?\t\017?>5\036\244=\013\311\210\275\305\370\374{K#\276\353 \315\274\014\265\375>*M\274=D\330n\276\367B[\276\301\333\222=\355\277\352=\274\316\311\275\301\0277\277\301\343\177=\354.\227>\033(\005\276:\344\010=B\007\244>\222\3476?\340\351?\277\2579\236\275\244\351v?\371\000\375=\372\345\035>\304\177w>\365@$?\035a\202=\r9\211\276\250\356\267>\023\242\332=\340\373\355\275joi=\242^\323>M\306#?aH\014>\030\2326<4\202\020\277ftE\276n\200/<\013`\247\276s\307K>\022\214\336=\244n!>\231\326\326>`\026\275>\226\301o\275\230\262\351>\027\212[\276\214\260\217=\261\321\002?\251\246z>\371\213\000>\022\340@>2\025F\276|\254\210>\355\222W\276\n\\i?\216\201\257>\234\014}\275\317\311v\276\202\0027=\231\325Y>8\210l>,\366\336>\266\376\340>i|-\276+\014r>\272}.=\tf\367<#\272E=\372\365\r?\210^\027?t\203;\276\\\010\335\275i\010,\276\253\250\n>\313r!\2767O\340>D\373r\276\321\227\203=\247\253\003>\237S\200\2764\016\244>a^5\276SY3>\004\232\251\2768\260\235\275z\363\373\273`\210\017\277~}#>?\324\201\276\023OA>\364\217\346=\225\261r>\375\242\n>\304&6\276a\344\350>\204\3562?\tv\252>\342}\305\2769T\215>\234\277/\276)\313\261=\341S>\275\217d\361<9R)=\333\247\300\274*\216\010=\343\263\325> /\232\276\034a\236=\343fp>\265\211d\275\210:`\277\013\020/\276\022\236\243=\372\r\035?\336\241\251\275q\364\272>\313\232\033?\252\214\323\275F\376\217=\341\216\016?\022;f\276\214\017\311\276Y\361\221\276\212*=>?\343x=\331\343\025>\266\366}?HH\346\275\226\306\n\276\244?\250>\323\t\013\276\026\t\016?\3042\245\276ua\202\275Pd\352\276\275\305\013\277\010\305\024?^u\244>[\023\352=E5\341\276P\237\025?34U\2767\004\322=\337\2309>C\315\225=\347\025\332\276\254\227\204>\244\215\017>3\342R\276\312\010\263\2769h*\276\254\3269?\307\005g>\350T\350=\3344{\276J\363\323\275U+`\275\323f\257=.k\340\276\223p\351\274\220T\002\276\226w\003?a\355{\276|B\375>\240\217\213\276\330 d\275\377\241\254\275\265m\002\2767<#?n\217\310>t\\\337=e\000\361<\203$\244\27550\362>\251K\327\276Y\035\346\276\365\362\n\276I\221\364>MU\035=\267\301\361\276x\262\232>\036S>>\001\227\350>;\340I>,\372\370>E\214}\277\274R\037=p\274\244>\245\332\357>\332\001\226>\007\202\003=/\316\327>\260\235\245\276\033$H?z\0226>\'\311\373=QH\001\277AVD\275=\344\312\276\267\'\352\275\326\362\234=\331]\216=w\342\325\275]\243=\276\337\312\202>\006\020\266\275\020\212x\276J\203\242\276N0\240\276\256q\263\275O\325L?\343\237\224>\362\244k\276w\274\203\276A\030\210\276t\352v\276~\262\033\277\321\177\027=3>\201\277D\357.?\337\207\277\275\333\346\027\277\366.\344>n\026P\275I\244\277\275\234\206\205\276\241}\014?\277\004j>\311\267\240>\274\010_\276\034\256\303\276f\0361\276\321\305\357>\361\2435=\266\020\235\276\030\212L>\022\341\205\276\342\034\363=`\337\214\272ic\273=PQ\306\276\317\265o\276\331N\023>\3659\245\276\245q7\275\300\254G\276\025q\323\276\272\243\026>\233\212\262\275)\335\000\277c\234\216\276#\321\005\276S ;\276\212\310\270\276\270\2647>\006\353\312\276*Vw>\252\177\230\276\370\037k\275.\320\212\275tl\246\276\266\206\266\276(?\023\276\001\"\271>\374\0346?\341|\325>M\256~\276\301s\305\275\344a=>\267\345\250\276\347\245\030\277\245H\275=\261\344\312\2754\025p\276\304\327t\2766,U\275\271\230\014>\202M\271>$\313\217>\301\213\221>?\364\223\276\023\362\234>K\266\350>DJr>\375\354\234\273;\rP>R\016n\276\212\354\236>9\322\035\277\372k\205\275\000\360\343=\236]\222=\346\007\245\276\022\3413>6q;=\301\317\305=\265\025Z\277\250}\004?\031~\007>&\325\232\276I\254\004?\375\242\020\276\266\330\010\274\256\241\214>\037}\335\276\210\363\223\276\035\373\261>=\357\315\275\2175h?\217x\244\276\273\2135\276\373\342\035\276Tn3>:\263@\277\3647\323\276\246\030\264\276C~\006\275\004Z\272\276\210L\221>\363*b?\276\276\004\273\330]\376=\326\373g>Oe\034?\205K\244>;\347\202>\034\345\017>\215\277\376\276Vg\005?\271\366?>SC\370\275\326\233\005\277(\326\"\276,\325\207>\324\221\230\2767\270\021\276\203\2601?\2263*=\214\245\264>\3463\260\276\251\025N?D\244X\276\225\\B=\317\352\212\276\026\262m?\374f\024\276\317b=\220\3322>^\276\242=\024o\241=Q%\330\276\321\213\037?\033@\235>\003\375\222>\004\363\256\276\237\332N\277\310\347\020=\000\'\023\276\023n,\276\275\242\272\275\322\244\316>\252\007\372\276p\354J>\325}]\2765\322\001?\350\323\375\276\023o\355>\325[\037\275\272\257e?3t#\276\010T\345=\332ri?M\265\206\276\301o\315=\027@\231\2634q?\035\337\341\276r)\302\276\335\237\330\276\316\226\252\276\016t\346<\0109\t>\351\364\246>\374\257\243\2760\266\031?\305\310\027\275\010\247\312>\202p0?.k\027?K\317\205\276\324t\313\275\030\310C?pM_\276\247L\274\2754b\002\277\361\031\361=\020(\034\276\335\326e=\355\253\243\2767\305h=v\235\023\277\334<\022>\254\207\325=>\310\333>\215\364@?5\"y\276C\307-\275\331\010\274>\240\302(\275En\365=q\250\233\275\244\274\303\275D\321\356<\246\371\230>\250f\335\276?\365\253\275\267\325(\277\027\346?\321\262\002\276\242\315(>\263\363\266\276xZ\246>\001\375f\276\002!\022?L\327\007=$\177`=\245\036\221\276\'lG\276\"\356\021?\025,_\276m\361\200\275$k\376\276\317\"h\273LJ#?>\254\t?t\272/?\202\374\253>P\300\031\277 !\331>\0367\332\213\227\275\276\217\332M\277S\251\345\275\254M\'\276\035I\300>ks\216>i\016@\276\016\242(\275\300\034z<\222n{>\017\341\202>e\351\253=Pf\236>\315\346\250\273q\271\006\276\234\370\343\275g\232\334\276\257\246\237=\345\245\242\276\233\215p\276\2539\354=f\177\374=\200\252\301=)\035Z?\276\303\233>\023<\203>0\264{>\022\300\215\276\374?\007\276]\331t\276Z\037\244\274\204\246\342\274s/>?\213\327,==\211\254\274\257\323\374\275D>\217;\343\366r>0\263\\=\004\275\227>\005\035G>/fv>\303\221/=\314K\331\276z\255d\276K\323u\276> \254\276\371\302\332\275\276\372\"?Eh\025\277\316\245k=\013@\246=\031\310N\277,R\235>\347\341\250\275\2647\226\275jn\005\276\260*\217\276\037\340\373=\206F\303\276\355C\221>\305\370\013?\377r\267>G`\032?\035\203\321>\2531\251\276d\254\224>\"%H\276\315\367\025\277\362Ey\276tl\242\276\247\241\343>#x\330\276\025\370\217=\324\377\274\276\311/><\323)\022?d\375<>\222\030\267<0\313$?Q<\323\276H\034\262=)o\235\276\'\201|>b\312O=\030\250h>~\261O\276\200R\023>\247$\025?\334d\232\276E\235\320\276\031h\201=\354\341\232>d\272\241=x7]=\375\355\035?P\025+\276^\303\240\276\271\021r\276U\225\002\277\030\211\016\276 >G>\265\210\366\275\223\032\003>\364\257\317>B\334\013>s\010\245>Q\251\373<\221\207\254\2766\004\310\273\302\226\237>e\273\223>\2613 \275c\334\211>\265\207X\275\346j\013?A\340\212>n\371\364\275\245e\022>\336=\222\274\315\356\027?XtG?A\220\273>\256\337\205>\323\221\345>\016\201\312\276\237N\033\276\214\211\317\2767\372\277>%o\303\276S\273\270>\301\002\303>\333\247\337\276\001\330\t?\231\021\340\275\001G\035?\t\311\363\274\373\371\346\276\014\277O\245\274?\204\200>\213\337\350>\243r]=;s\021=\351v\245\276\235\253\231\275\375\365\203>\376\271\t?~\240w>SG!?oV\365=b0\215\276\027O\254=\211\303\262=\242\236\263\276\361Lv>!\2079\277\245*1\276\210\2229\277|\002\333>\354\013Y\276\275\217\215\276\247\273$3>\340\251\220>\311\226\207>\222\316\203=\332\016\007\277\"\302S\276\205y\301=\313-\223>U\326\213>\006{b\276\322\220\000=Q\221\246\274\236AS>|\222\272\2759\364\226=\360\245\217#\355\360;\255E\252\275gr_>\345\\\233\276w\263x=\341\346\275\276)\232\241>\250\211\303\275\350Y\231\274\001\242\322\276\253~\302\276\3140\025\276\202u)\276a\325\265\276\230\204\002\276\266\204\340\276\021@\277\276\230\205\345>a2\n\276\002=\351=\301m\341\276Q\350\307>\355\304%\276\272(\226\275\005\214]>\024os>\271,\322>\031%#>xB\363\275q\304\374>%\324I\277\335\226\263=\257\262\306\276\n\n\t\275m{\356\276\'\330\377\275\017\334\227>G\351.\276\013\000\021>\333\232m\277\216\276\233\276\332$\226>\360F\307\276\3043\215\275\300\220\225>d^o>\222\266\021\273\007<)<[UN\276(\013\222>\244\355a\276\263 \246\276\3666\261\276\221\375\227>\376(\224>\023C\007>\335\036I?zOZ?\020S\022?\325\020\241>\264\211b\275p\245\r>e\205\324\276?\307t?q,z\276\270\327_>\260?\340>\201\372O?\r\343\'?\372\3568=/J\262\276\363!s\276\217B\265\276`U\251>\006Y]>9\031\304\275\007\tT\276\214.\352\276\010\3135\2771\002\225>\036b!>\360\243\003?\362\017\360\275qC\264>Q\265X<`\266\022\277\262y\204>j\334\241>v\355\026\276aI\356\276P54\276\007~_\277\2519\031?\277\013\211>E\214\351>\361K/\277\344qb\276\226!\327=#\304\261=}\000p\274x\374\225>wq\274\276\006\026C\276>*\324\276F\2602>g\360\027>\274\325\321\276\376\351\250\276S\020X\276\326\322\352>\227->\276\\\353\200?\212L)>zT-\277\376\236\230>\272\262\005\276\022\005p>\211d\323>z\007,>\300M\211=e\035\226>\233\310\r\277\n\r\246\276\324L\024\276\006\221\271>\313\002\331>\177\026\010\277\352\374h\277\247\366\360<\007$+>\240}\272\274\3575\321>\236\360&\276\366\352:\2765\371n\274\301h\030>G\376\230\275\027\221\030\277H\022K\276\220ZV>\\\020Y<`l\323>\232\353\244=\003\233l>*\356P\276\322\340J>46a\276\217\033\271\276\342YO>d\237z\276\303\333\240\276T\013\257\276\375y\311>\231\026\025\277\375\350E>wf/\276\277`\004\276\201Y\244\275\261~\322>\333\316\267\276\204\216h\273\241\323\365\276\317\211\202\276\304\2055\277\301\260!>0Bs\276v\335\331\276q1\365\276\351P\307<\326h)>\353\024\321\275\021\357\267\275#\266\351\276wJ\000=\003\217p\276jTW\275x\002G>\256A\364\275X*?\276C|\032\273\377\031q=_k\005?\353\226j\276\213\307g>(b\332\276\263Re\277\240Y\305=\2137\007\276\203\311\264>h\000 \277H\332\227\2740\326\250>P\342\375\274\2272\221>\276A\230<`\315\325\276M\355\233>\033\310\264>-\024\356\276\260uh\276\307\270&\276\211\351\"\277\265n\245\274R\266}\276\016g\304>R\227\354=\325~\226\276Q\235\303>\005\206\251>\017\216\367>\240\200\243>*L\315\276\2201\021\277\210.J>s\357\214\276\226\277\314\275j{:\270\tw\001\276\376W\r>nO&>\355v6=\335\376\226\275/\203\234\276w|\320\276{\274G\276\002\307z=\317\361\250\276\252\302%\276ig\274>om\224\275\374\360\215\276\313\307\007?~\242Y>\021\303-=\240\302)\275/\333\215>Zq\002\276\313\327g>\261<\237>\272\210i>g\227\253>5%\332=\3222\250\2752F\204>Q\266r>^\234\270\275\020\024\\=\217\022\273>~\243\030>\370\203\0328^\241\304>:\016&a~y?\233\035\016\276\222\003\367<\201\272:=\212\2726\277\000(\023\252p\304>\200\317-\276\342\227\330\276\227\326\017>t\241\256\276\3700\326\276\346\026\020\277B\275\211>\317sw\275\277\373C\276\014\"$\276\361J!\2777\252\217\275\230\236\365\276 !F=\204`\362>\254rq\276\2512\252\275\243\307\036>\253\374\345\276\356HR\276u\013-\276\021%\210\275\360\257\203\275\370\262\013\275\276\354\222=\036\305@\276\321d\375>\2146\307={\031\035>>\340\021\277G\221\375\275\024\232\241?\373\037\357\276rX&\274\215\371\330\276\r\272\006\277\207\002\006\276\240\200\250={\236\234\276u\217\312\276\272\271\263\276\245C\n\277W\375\273=+\245\347\276\354\274C\276\324\221\317\276\257n\230>\374\251e\276\351\0178\276\313\375\267>\023\000\212>We\010\276B\305\037\277\306\254\320\275\257\2231\2769\224\211\276t^\243<\024R\210\276\276\260>\277\\\302\343>\333\366{>\255\004\340>wY,>\242#\002\276\225\3304>\376\010*\274\367mN=s\202q=\223\037]\260>\231\274\257\275\0137e\276*\217\337<\256\247.\276\224\321\241>4\204\310=\270S\257\276\036\311\247\276\305 \262=A\t\n>\316w\233=\217\366W>\263\252\335=:\342\372>Y/\270\276\3325\237\276#\234\264<\337YN\276e\344+\276u\234V\276\344\374\'>4\322\333>[\376\370\276>\006\006\277\316G\364\274\325\014\314>\216\215>\276\357\214\324\276\352\361\037>\334c\034>\235)\270\276\003/c\277\373\273\364>\016C\346\276\2316\276<9Q\036\276\022A\251\276i~f>\314\370\247\274\361/k\276=\300a\276\236\373\354=\373}\207\276\nD\017\277\233\250\021\277t9\002=\\\r\221>_N\251>\300\013\004\276\010I\205>V5\303\276\223\304q>Z\242\261>\035\031\266=\206\031\322<\177Z2>\007\241\014>\1774)>\211,\004\277Q!x\276@!\217\276A\320\234\276\323\204p\275\351$R?\217\005\212>\311\335\311\276\322=\346\276\332\233\016\277\355+z\275\320\340N\276\357\r\374>GZO=\025\024\374>I\361\352\276a6\314\276\r\226\241>\242)\027\277t\306\204>\372\364\232>K\021=\276\355\340\001\276\314\377\200\2752v\027>\237\3445\276\233\\\343\276tm\342\276S\216\027?\321\033l>r\2426?u$h>\365\225\006\277\3548\324\276\034\220\356\276d\331/\274P\037\317\276\375\0047?\367\277\373\274+\221\026\277\304\260\023\277I\004t\277fIF>\215\346\342\276\366\2654\2772\251\377>\016\325\260\276+=\361\276\353\373\002=PU!\276\014\020u>\021\276\202?u\201Q>\215\363?\276.?s>#\376$\277\242\253\377=;\303*>\030/\356\276\221\333\264\273\327U\235\2731\226\021?\271\365\277<*_!=\034\231\232\275r\253\364\276]\341\326=e\370\017?\256\343\r\275\210\340\326>y\267E\276\242\277\367\276\2349W\276\272[\007\277\'f\325\276\377D[\273\305\367A\276\321\004\241>^\271^\276gP\234=\225\325\202\276K\212\353\275R\n\277>\007\264\317\276L\267J\276\375\t6\277XX\023\277U\243\301\274#&\035\276\355\363\210\276\"6*>u\203\023?n\336F=#+J\276*\3169\276I\202(?wq*>\300M\231>\014\235K\277Q[A>\267\304!\276\306\036t\276]\245\207\276\334}g>e\347\244\275J\306\376=\315\2125>+\2004\277\366X\245>\035\204\214\276D\250T\276\277\314\230\275\3606\260\276\265\307\322\274\327\266\363\276\223\257\260\275\013\2304\276)\366\237\276v7\222\276\376\273\340\275\367O\002\277\r9Y\275\031H#>G\033\347=\236E\376>\016),=\312pL\277G\2557\277\231\302l\275\216z\000\277\2724\030\276(\324\246>b\220\364>!\241\252>\316.\276>\233;\323\274\274\375#=]i\343\276U^\373>\003\371\223=I\016~\276\261Q\375\276\tX\003?\177p\016>%PV\276\020]\247<\362\013?\276\337\031s>\\&~>>\004\317\276U\\7>\207\325\034\277\362\\\220\276\007p\021>\334P\351=uB~=M\022\032=\241\'[>\254\3210?Cd\232=g\374\231>\224\353\262>!u\235\275\252K\014\271$}\217\276\231\362\361=u\277\215>\230\203\004\276d\264\302>IX\202>\301\260\312>\267\030\241\276~Q\\=\\%S>\345 \211\276\325n\277>\366\256\264\276\350>\027\275\232\315\266>]\006%\276\321\257Y>\242P\235=`\001\220>\375k\017\277\300T\220>\201\277\214\275\211p\306>\312[.?\200\274\354>\256\264\237>=\335_\276\035oi\276_\213\271=h\rW>\260\213\r>J\256\332\276\001..?r\256\254>*\314\234\276\216[\270>t\362\306\276\037$\343>\241\260x>\331\000~>\356\030t?\026\343F>b\005\313>\320:\241\276E\350+\2754\326\230\276\311\365\013\276\215\270\322=\000\256\340\276\337\"D>Pj\230>\325\324B\273\006\353\207\276\037\325 \275fEK\2764\236Y<\031\205f\275L\343\240>\234\373\005?\216\251\345\276\230\220\364>\216\332\202\276\237\2561\276\235\300\005\277_Y\034?\003Rj?\263\357\034? p>\276\030&\323=#\304\235>\300\342\347>\245\250f?\204\204v><\020\005=\024\301d>\026\260$>3\234\004\274\367Y\032\275\010`;?^\006\206\275\1770\225\276\364\231\200\277Ix\263\276\374\266\351>]\275v>F\305\253\2753\007\027\277\312\334\271=\330\361y\277;\"=\276}\326\346>Z\264\251\276+\353\214=\340\007\005?\261\"\225>\320-\000\275\026\305\246\275\177\200\213>b\243\327>\006\362;\277\033\230\316>j0\260=%:\210\276\263\362\004?\272\022\316\275\247\212\005\276\277r\230>\276\353\216\274{mu?\363\004\002?k0\247=<\351\257=/\352_>\277\316\221\276\235=*\275\007;\251\276\023\242\260>\345`\"?C\277\241\276v\341\234=\251\276\026?\032\304\236>0`\315\275\277\221\252\275\260\334=?\0049\203>\356\326\r\275\247\222\351\275I\374\272=\006=\035\277\346b\007\275*o3?+\366\336\276r\240\370>\312\270n>\365|/\276d\233Z>\371-Z\276M\032\254>z\033\203>\016\245M<\302\"\207>\031\265\025\277\013\204\264>\247\221\301\276\036\351\033\276+F\245>\336\034N?~\327\240=^+b\277\221\365\215\276\3167!?b+\235>\362q\344\276G\325\031>:\310\271\275\355\023Z>\004+\202\275IU\210\276\225\317\"\275\350\316q?EAI`C\237=4\307\266>\342\301}>\240\331\"\276\312\2416\276\262\246\323>\261\352\341\276\315M\036>B8\023?\0272G=\204k:=2\256\003?\336\274\217>\213Y\027?\363\270\251>6\026\216>\025\300\032?v\254m\275B`X\276\022\344\203>[\324\022\277\200i\035?\205\327\342=\234*\014\276+y)\276fx\204\276\316\256\250\276\025:O?\222\364<>N\234\237>\323C\327>\200\027\344\273\367\325\352>\007\315i>\tg,\275\025\021\277<\023+\276>M\243\327>}\261\242\275\216\310\373>\245\267\236\276\216)f>&z\220=/\216B?\365FT?T_\212\276<-\204\2769\233\032?\"\237\303>\201\316\374\276\215 \323>rO\026\276\\|2\276\025\021B\276\351\360\227\276\201G\322=vj.\276K\324\005?\256i\313\276\216\226\343>\247\365s=\255\354\313>j\177\366u\0322=\321\023(=/\204L\276\202\000C<\355fO>ii\306>\260Cn\276ESF\277J\271G>oZ\212\273\274\255\270>\237\0020>\277\207\357\276y\334\355\275\307\316\017?\235\342y\276g\204\031>E\342\224\277,9->*\320\236\276\332\236\274\276\375q\034\274&[\000\275\231\033\031?\333\356\230;\270^\333>p[\242>r\204G\276UQ\035?\222\032.\273\3317\204>I\201\034?\347\306\347=\003\203\372>w\314\312\276\030(s\277\265\333\'>\236P(\275\321\252)?\371\366\221>\250\030F\276\352\n\022?\235\220*\r\271\276?\"i>\2511\t\275z\366\340>s\374\266\276\363\360J?76\256>I\237\367\274\026\006\227\275\027_\215\276\245=\332\276\216\240\241=\'\345l\276\213\261\271\276\321<\365=\316[\325\276\007\211\210\276\324\304\216\276u<\001\276+BA\276\2168;?\217h\017>-3_?M/\277>R\340,\27471\312\276\034\016\250\275\344\201\207\271\331at>\215\263^>rF\244\2764qF=\215\343a\275\342\022\315\274\273\262\262\276\313\257\353\276\323\026@\276\226\226\264>\257\233\307\275\206\225\273>\373u\205\276\rX\267\275\235\315J?g\243\362=\246\210\001=\356\356\341<\237\352\025>\014t\226>\362\243\252\276\346\235Y>K\010\216>F\225=\275A\325\253\276\024\362)\276\r#R\276\037j6?\257+\275\275&0=\276\351u\206>\302#\367>C\026\001?\3646\266\275\216\030\365>R\340\344=\304O\">m\272X?%F\207>{\233j=\0323\314=\243?\222\276\250\311\033\276\251\035\332\275\356A\032\276\233\315\235>\023\316\314\276\325\246o?\315\251\340\276W^%>\332\240\001?\207IK\276\177)\237=J\240)\276\262\3001\277\262\037\321=\332\216\260\275\n%\252>\323\023 >\263\354\257\275\334\\!\275\356\010)?\310\016t>i6\251>\031\300\037\276\346\330\345\276\370$\033\276\346}\330\275X\352G\275\305\013\361=\341\225\271\2759) ?(\212\330=\351\257\321\276\227\324@\276L\357\376>\215\337\212\276\"\355%?@Q\023>(\026Q>5\337\321\275\314\313k\276\307\326S\277\331\004\217\275w\200\245\275\201(\023>\263\000\001\277\013y\037?\352\002\000?HB7\276\257\361U\276sQ\"=\252\n\314\276\253JF\276\025\232\317>\210\233W\276\370\370k>\313\251\354=o\010\320\276\277\233\327<*Z\330\276\211\343\360>A3\027<\341\250\201\273\300\244\017>\343w\242\272\244\346H\276\236\214]>\213\336\313;\231\234\022\274\311\247\247>\220\357G>\253\007\353\276\317\357\366>\207\007l>\"\354\334E\'4>\225Z\202>\n0j=e\3045\277\306e\267\274\021:p>\212\263T\275\212\257\324\276\273w\241>rnX?\007\356\340>\322@\032\276\325C\312\276[WF>7\232\240\276e\314\335\276d\311\362\276\325\201\264>\333\330\306<\n~\230\276\306\016\310>\035\242\225>\005\321]\277\344\210\365\275\205\252\010\276\017\3659>\326\031x>M\372\366>j\034\000\276\372\005\220>i\337#\277\305\254(\277\0241\022\277M\177\341\276\312\246[\275[\356p>\0146\217>\rz\271\276\241\314\016\277\256\237\222\2760l\026\276\210\341\013?Ns\364=\217\365\254\276\323\t\r\277\250\211m>\344\021\257\276\307\215E>\006\205\272=D\352^>\201\320+>\317>O\274\0170\005>q\277\253\2766c\340\275\342\363\203\273\277\013\226>\261d\323=A\023\\\277\263>\253>\213>\300\276X\301\202>\224Cp\276\204\321\'\276\374\002D\276f\364\007?\315\356\014\277\201rO\330\n\276\022\210\007\276v\367z\276\016\224\261>\007\033x\276\341\033/?\347\316K>\257\276\257=d$&\277*\330\273\276KcQ\276\305\303`\276\000\014\"\277\001{p\276\273\362\024?\022\262\307=5\236\204<\365\301\355\275N\271\310>\344\020\350\274\254\207`\275f\347\010\277@\243\201>;ow\277\376\333\324\274W!$<\344\252V\276\311\262\232>@\030\352=\231 \300\275\340\376\255\276\227\206\014\276\303_\236\275R\206v>\337\0340>\272u}>\254?\017?Q-\026\276\237\265\325\275\r\261\006\276:@\253\276\221\326B?\225\006\034\273<\210\371>e\376\210\275\212z\036>\355V\215>,\031\214\2763\327\352>\321\377\273\272S(\030\275\313\315\342K\351\326=\301\273\322>gb\237=\0068k>\376\220\324\276e4\326<\216\022\343\273\347\207j<\020+\352\274g\027\n?\360\241*>8\307#>\201\007\276\276\010,]>\242_}>\374\314\211=K\216\311\275q\367o>\324\007\025\275b\241-?V\233\336=\036[\215>\005\315\032\276\206~\207>c+\243>!w\227>\263\275\022\276\205N.>#\225\306=\352\024\323>\3436t=\342,4>\213\356\020?\252\207|>\232PB\276(z;\275y\301\300=cV\311>\365\036\307\276\305\334\264\276\312\223\001\276\361\260\350\276Y\"\365\276\"\266g=\340\326\033\276\260\311V\276\002j\254>x\240\270\276\037h\325= \261B>\256\306\342<\277\315%?\323:u\276\035\020\356>\226f\210\276U\202[\276\230\327\216\276LH\246>\333|\354\275\177H\331=x\\U=n\304A\276)\000\235>\331\336\245\275\342\240F\276?\014\263>\336\277\202\275\331\003+\276\223\304e>}9=\277\263\223\214>\361\262\n\276\273\357g=\227\3222\275\010W|>\207\343P\276\350^\327\276\316\0304\276[\245\273=\304\212i\276\321w\177\276\002g+\276\001g\341\276`^h\276\2274\004\275Me\340=c\334N\276\235\'9\277\364Y\2534X\005>\255\326yY\335\035?\342\276\302>cZT\277T\365S>@5&\276\212\374\366=\244\233\324>j\352&\2768\016\022\275Fap\276\343\311}\274\212!\262\2758\350\265\276\312\314\017?\362Z\323\276\3036\331\276\000\2175>=\n\210\275,a\245\275\026\237\275=\246\322\232=\350?#?\226\300\245>!\2406>\263|%\277}\233\375>S\312$=$\014\233>:E\321\275\033q\300\275\2600#\275\"G\312\276\256\226\332>\206\335]?\313\003\250\275M\023\200\276\226D\254\274u]\251>\202w\271\274b\264\224\276$\020}>\236\017\226\276i\360\007\277\345\262\217\277\034\345\364\276f\263V\274\363\351=\276\030\030\222\276h\322\302=\"K\222\276\301*\371=\027w \277c\223\301\276\014\372\371\276\005-\221=\330\342\260\276Z\317!\275\325\014\231<\216$\036\277\024\332z>\331rp=l\230\203>!\203Z\275\017\212\322;9O\333\275\035\\!\277s\324I\277\r\245\324\276dV\225\276\024\017s>I5\206\274\324^>\2743V\207>\363\033^>\211\177%>\306E\'\277\225\347L\276?\310\216\2766s\372=\014\303\025?\261l\235=\214\344t\277\363`\263>D\025w\274\244\242\024?\255\3670\276\273B\250\276\346\3438\277\252\314l=\034\2516\277\023J\240=\233\345\247\276\215\244/>\031\260;\277\244\223\250>Z\027\000\276\2324\030?#c\306>\222n\225=\177\325\257;\204)\n\275|\350x>\311g:>\301SD\277\227a{=\343\376\010\277\377\201\022\277]\352\257=[\356\244\276\304>\262\275\307f\027?\017B\204\276\265\253\222>\236\312\207\276:\366\003\275S\t\216\275\351\325\260\276\227X\214\276S\3107>\323\371R\275\234\232\022?F\257j>Z]\304\276\ta\037<=OL>\225\301\263\276\307st\275\341\205\213>H?\302>\246\030\307\273\300\272p>n\243\327=.E\274\275\223)\222> \277;\276\212Z\270\276\030+\225\276?\320(?\016\036\216J\223\230\276\307\243%\276H\030\312<\241\334\345=\355\373\223\275{Ek>M\3149\2775\317\305\276\2304\010?\031\324\'?\266q\234>D\357\207\2761\244\240\275\311\376\315\275\312\030\243\276<\322\217\277f\274a>\033t\261>*\262`>W\261\006\276-\324\234>\177y\352>/\324x\277u~\234\275\321\034s>\300q^\277z|\207>@\272\346>\331c\247\276q\024L=\201_\336\275\000h\227\275\227~$>6\246\303\275\022Pp>\326\006\033=\375\220B\277\032\331\202\2754\367f\276#P\017>\010<\035\277\255\370\'? \2463>9\224\372\276\316N\356\276d!\004?\365%\336>\204\220\241>\306\002h\276~@\177>E\233\247>\352>\030\276\227\372\315\276\236g\210>\265\210\214\276[^\324>\351\271\003\277J\254\312\276\256\003A>\211U\025\277\306\365\035\275xw\004\277\341\370R\2765\337\022>\337\374\300\274d\234*\277R\330\276\276\203y\'>\020\213\267>\362I\234\274\021a\332\276\305h\270=\270\213\263\276\205\265\356=\255m\200>\220z\036?S\253Z\277\226\341\013\277\244\364|\274\r\235\212>\212k\374\276\027\264B=\3128\t\276(\tj\276\035\272)\277\231\010\256>\303\273y\276>\020\260\276\265\312\363\276;9\243\276\313IJ=\013\333\006\277\007\272\234>\340\237L>\244\023\234?\357\244\221>\307\211e\276 \033->\334bS?\211N\235>#BO\275\300Q\252\276\301\271\371=\201\002\271\276\272\002\244\276\271\273\177\276\237\300Q\275\263 #\275\374\311\261>DU\035?\033\214\207>(\230\340\276=\277\221<\365\367\247=\010B&\276Iu\224=+\325\275>\351\363F?\307i\002>\232\025#\277\2733K>\200\223\227=\353\277\023=3iL\277\300O\203\276j\313z;g\033\366>\030\207\376>F\300\254\276\305\r\202\2768\274\272\276V2\022\277\221\033\262\276\032\346\375>\237\256\323\276\007)\203;?\017\252>\\ \003?\362\214\024>\363Wu=Q\224\030\277(T\004>\022A*\274\252U\017?\200\013\332=D\034\337;R\372\034\275\355m\361=\336\315\234=\003\342\312>\010\245D>Z\031\025?%.z\276\237~\364\275\311\303)<\031\253z\275\324B\017?@\245\010\275vk\241<\276\0048\276\242\335\276>(\205\243<}(\331\274*\250\303>Z3\361\276/=\267\274Kq\351\276\020{\227>6\354\246\276\021\272)>\323r+?\355/\003\276\275w\251\275\034\001\373;I\302D\276\310\375\250>\211\231\303=\334\000N\276\373\370,\276-}\370=\371\307\333\276\322\034V>\252\013\344>\005\002=?\334c\001>\'Gg>\374\334\327>\344\342\311=b|\261\275\\\177w\276G\212s\276k\356+\276\316y\270\276\374\241\271>\253\251\313>\034|\274>~\350\231=\2438\233>\254\033<\276\347\321\310>\376g\"\276\353\010\025\276\242\236\223>\305\020\271\276\225\363/\277\227\272\254\276\372\347<>\233\303\344=\022T\n\276\343?S\276\324\241@=?\252\212\276.\264\352=\334\030\363>\303\241\216>\374m:\276\242\217\002>\022\t\"=\210\233\313\276\341\335\230>\317EU\276N\264$?\342\215->9\227>\277\020<_>%o-?\036A\257>*{\223\276\"gq>\362Z,\277\210\332\276\274[\343\252>\314g\320>S&\310\275Ib\036\277\254\tl\275#\233_>\027\032d\276\271U\277\276\007\240*\2777\332\261<;zF> {\\\276\271\"\373=\214s\245\276\022\340c\276`\324v>\n\270\333\276b\304\223\276\0035J>\004\023\202>\252mH?l\025\303>\3648\261>\343B\006\275\007\313\264\276\345\032\r\277\215|\354>\272\327+?!\320.\275k\305$\277\010\326\252>\206L$\276G\\\252\276r\307\034\275!sS?\001\372\324\275Z\355i\273BF\201\277\222\031\314\275r\\\201\2769\033<\322\030k>\206s\313>k\010\222>\366\217\367>q\233<\276\366\013\212>\001UBCW\245>\037~\331\276\226\217L>n\237\361\275\272m\010\277\022+6=\2632\034\274\2206\001?f\304$>Y\321\210>P_\310\276\n\347\363>\371Z{\276\371m\320>f\257\177\276\215\350\277>k\215\022\276\202\020\234=\354,\370\276\314\024\343=W\234S>\267\320\235>\210\034\265>\354~\016\277\375t\007?\210N*\276R6\353>nF-\277Z\255\005=\024c\316=\211Id\276\225W\325<\270\257\336\273\030\327\001?\325>\016\276\010\273\002\276KJ\335<\332\\\313\n\2414=\253\342\200=>J\215\275\036\035\017=\355\352\303\275\205l\330>i\321\007\275\216\274\215\277Wkq\276\305\201u=\317\356\357<\306\203(\276\037\375\366>\343\025\243\275&\231\270\276\302\374\222>\353L\256\2761\201\277>`\331\237=^\327\246=\273\361\340\275l\254\342\272c\340\252\276\245\"\217\273\320\030/\2779\203j>\3134\213>\365\266\'\276+\212\270>]^\245\274x\311I=\302\t\247\275\337\364\311= \213\220=\260C\235=\236Y\017\277\245?\244\273s\333\217>\317n\202>\254\033\236>\214@\264>\222\366\300\276\303\003\376=\206R\214>\027 \370\276\216S\354>\335:\005\277\212UM>\263\027u>\016\354\332\276/\274\\\276\2714\000\277\235#g=$?G>]m\205\275K\327\353=&\001\246=`s \276\367\254\341\273 \376\214\2763\"\362\276x\360w\276\241\371*?\020\020f\276\214\310\374>M\373\177\275\0228&=\306\340%\276t\375)=\234\236\333\276u\307\r>\242ll>\370ma\2769\2073\276\263\352\221>B\233\033?WS\271\276\321\2450>m\271\272>c\270\256\276R_\266\276\264\252\271\275\356u\023\277b\037\301\276\026\022)>\345\206\232>\226d\217>(\354\375;\352\2470?\211\347\026>\2642\326>\342\214\332\2751\214\'<\361\026\322=;z\211\2715\362\037><\344\r\275u7\325>\036H\033\277\243\363&\276~\261y\276\224\214<\276\234a#\276\224z\374=\233\024\211\275\202\256\256>\243?\025?\037\222J>\240\204\006\277P\r<\276\022\326\213\277\201.\217=\215C\334>Ey\037?)3j>k\r\243>\334c\033\276Fu\350>\340\001?>a\017\215\277\266lP?\006\364\203=\373?\000\277h\233^\275\373\022\250>0\335f\275\014T\202\276xN\305\273\005\325\224\276\036 \004\276G\242\005\276\217\260\257\276)**?\351\343\355\276\037\242\273>\253V\214>\321\'\373;|\320\031\277s>N>\020z\010?\272\353\232=D>/>\227\355\311>\237\0078?\360[\315={C\214\276wo\352\275\034R\000?,\203{\276\204\024Q?\037\336\030\276\035\216i>\025\214*=\237\234\346<\177]\231\276%\362\217\275\177\316\365\276h\234L?\264,\214>\006-\327\276\270k!>*\272_>g\307\313\275\014\272\014?\204\240D?\322\352\330>\361\330\200>\320\271v\276~\263\356\275g6\217>B\350\263>\tA\022\276h\265\034\277\273\311\335>\230\"\344\276\371l.\276\0373\273\275\250\374\333>1\340\267>9|\364=\362i\375>\032\217V?!\323q\276\225\262\371\276q3\002\276\037\372\307>\230C\212>)\016\r\277\306\315T>\256\322D?\232X\303=\030]\362=:\264\016\276\021\215\200<\336\223\017\277\255B\211>\243M\"\277\341\327\233\275\n\252\201>c\262\177\274#\351\017\276\236@z>j\330\226\276g\256#?\204\351\376>\242\262w\276P\024\r\276\236$\215=\216U\306>\253\2255>\310\375\304\276tA\n?\312\230|>\307p\300\275\336\226\216\275\220\031w=\340\260\272\275\227\000\357\274\365NV=Ro\371=MW\200>\360\021\242\276\004\021#\277d\006\350>W\246\334\275\3220!=\256t\247\2743\007~\276\310\2135\277\301\000\200\274\214/\220>S\372\256>l,\375<\242\270@\2765\272/>^\021\260\2768\325\246=l\331\202>LM!>a\000\257=\365\005\231>T\207\273>/\352*\276[O\t\2768CN\276\362}\304>\316\264\232>\024\330\234=G`\024>f~\235\276\17730\2762\272\330\276\\\300\250>\026Q\r\274g\177\004?\001\2326\276\331\311\272\276\337M*>\301\352p\276\3275\240>\214\326\\>V\341\213=\251\307\271\275Le\211\275\341\324y\262\236b\276\356-\373<\316\372K\275\212\212\340=\024\206\270\275?\312\253>\031\223:\276MN\260\275B 1?\211\032\014\275-;\243>fz\367\275\026\206#\277\221\376\256\275\274\254\027\276\013B\035\276\023\321\302\276l\030\233=\225\212?\277\342\224\016\276\022R=\275\237,\217\276\261\001[\276\325\316\013<\263\216\233\276\227s#?l\235\352=E\237\n>\312e\323\2751Pq\276\371s\233\276\033\272\365>a\223\314\276\037H5\276\021\\\335\275%\221\030>Y\013\037\276\250\033@\276\007s0>`\221\220\276\033p\242<\276w\002\2763\256\300\276\336\rY\276\216\036Z>$Z\244>r}\327\274\275\2218=1y@>\235k\207\275\321\032\022>\265pA?\251\377\343\276l4\260\275\"O\031>\230\274^>]EU\274\016(Y>@\273\006>\"\324\017>\333\204O>,\254\313>\253\307\323\275I\250:?,\0304?\234\'\302\276\210\224o\277\330\003.\275;\350\343=\260\315\253\276%\335\277\273aV\025?\023Bp>\2354\271\276\\\306L\275\261\227\307\275&\032\273\275\375K\004>9I\207\276\3368\247>\177y\237>KGc\275[\2148\250\320X\276E\024\312=\324p]>x\n\303>d\025\n\276\036\220\240<\274\3262\276\212\212\347=\217f\250\276\343\362\351\276Vr\030?J\007\334\276\305\035\205\275\353\177\223\276\3759\272\275\235\323\243\276u\266\244\276\324)\367\275\255\222\000\277\013\231.\277\222;\377\276\214`\371>\312\006\033\277W\324\341>s\214\013?\177\304\222\274\271\342\300\274\360S)\277\001A\225=97\217\276\235\003\013=\271\t\327>\300\376\355>;\356j>H%\227\276\000\207\317>\247\231D>\370k]>\327c=?\221^\\\277o\\\036=\020(j\276\373\262\004>\226\0165>\226\222\233\276C\237\004?\224\322\307>\027\314\213>S\307\025=\233\005\236\276/\333\t>\362\330&\276\361\271\014>\205CE\275h\320\247>\262s\300=bL\345>\270\206\250\276\266\357\270\276\250\261o\275(\251\222\276\324e\315\276\013\340e>-\333\335>\324 \006>\262F\377\274@\000\242>\375E\363>\247L3\276\205\0240?\312&+\276\344M\203\276r.\264\273\'\254`\276\356\324\236>P\017\304\276\214\310\001>xs-\276I\234\300\275\025\023\307;c\277\376=\303\264\002\276\365\247\001=\201\250\203>V;Y>m\252\024?\267\3002>\240\350.>\245\314\307\276\243\004\321=\212o\241>\267r\010?\000\002\023?\315w\200>\037\nX=\365\350W\276\315\014\002\276\356\346\306\276\320t\327\275\264\230\335\276\323\236\006?+{\350\275\234\245\335\276 \\\352\276\363a\003?\371\223G>SdJ>_.\032\277\257s\270\274(\211\306\274\322\351[>\311\374j\274\362\'\221\276\022\321\305>gj\366\276c\000\037<\034\343X\276y-\234\276\345\220\014\274\234 \216>H\2524>\223\260:>\330R\033\277x\327)>\030I5<\300%f\277\336$\205\276B3\271=\023\377\264\276b\272\225\276<\310\225>\0045\240\275A\210\200\275\223\215\311C66?\333\r\221\276\t\032=\2763w\343>BV\014>\275[\313\276l\027B\276<\016\264\276I_\007\277\205,\021\277\244\343}\276\344L\373\275\325\346\320\275\265I\307>[\311w\276\246\274\325=\020\325\033\276\330\224\n\277\212Y\330\275I\225\376\276\240K#\276X\204~\276\264\230\276\276\023\024\\\276#h\305\274\276F\243>{\225\027\277*\\\331\276\343T)>\263=\304=\212\354\236\2764N7\276\364\234\260\275\0252\033>\0318\262\276\027\355\023\2779\234+\276\346I\351\276\026\360B\277is\215\276K\317\370\276\007\347\207\277\344\234<>\262\246)\276\207~K\277\374+i\277\212\217\245\276\353\210\252\275t*\255\276\371\n\377\276\276\024\013\277\226\315\246\276}\232\002\276M\016\350\276}\334\'?\315\243\220\276C\177\220\276\206\312\005\2767\227\337\276\316k\317\276p.\376=\302\016\016\277\377\335\007?\302\272M=\326,x>\235\271\021\276\257\233\273<1\r\312\276\246\300b\276\316\246X\276\2554\353\276<\216\n?~\353\311\276-\2604>1^\260\276V\274\343\276\332V~\277iU\r\2779i\206\277\345\034\233\276/\221\221\276#3-\276/#\356>\377\007\220>p\330\330>\241\\\251\276\025\262\235=\001N<\277\201!\322\275Y\367\214\276\3143o\276>\276\235>\312\024\">\031\037\177\276a\262\000\277:\331\004\274\351z\273\276\270B!\276\207\243\014?g\357K<\265\014\006\275\030`\025\276\245<\020>\236\014\004\277\257\305g>\247\027\252\2753\334\021\276\022\325[>0\031P\276\225O\317\275v\013+\276\357\251\243\274\273\267\357\276b\213f\277=w\231\276^\365B=1\232\003\277{#\035\277]J\201>\301\026\244\275\202\376\007\276&\216S\276\030\225\022>*\342\257\274u\271\260\276\307\3672=\246w;\276\315\027n>\276\nM\276M\r%\276\324\353\027\277\342\217\326\251\177\013\276i\026=\277\"\316\300\276\200\220\334=,\361\001\277(\243\007\277\374}\322=a\201\213\276\3032\270>K\324\322\275TO\323\274\205n\264\2769\177\020\276C\262~\277\377\030\234\276\030\2509>a\340\277\273\312\367\016\276q\367\242>y\035\312<\tB\274\276lm\007=\274=\322\275D\362)\276\353*E\276\343nE\274:\2574\276h\307\367\275a\001S\276\325?:>\347\303\244=\034\247^\274\275~\236>\252\220\265=\303\302\035\276Ilh\276\366\301\036?\031\265\320\275\233(h\276r\340\253>]T\235=\270\311\367\276\250\334\021\276\260\224\275>\361\035:\277]i8=\033V\330=j\t\017\276\270F\241\275\001\350\226\275x\323\016?X\261\341\274\341\375\253:\006|$??\343\000\275)<#?\206\271\026?\267z\361=^\202\001>\362T^\277\370\304\312\273I\003\334>\222*\364><\">>ej\004?\002 Y>\363\205\002=\266\367v\276\367H\014\275\212\323o\275K\242\356>6\037$\277\361\327\227>\236\317\242\276s\307>>\304\351\205\276a\323\312=]\336\342=\201\330\251\275=pk=\257~\364=}\316\217=\033\266&\276\243\007\262\276\245a\361>\2407\254=\270@\205>Z| ?p\253&?\307\337\242>\242x\016? \266\332\276\251\205\213>D\2560\276#p\376>\020p\304>&H\215>\323\301\330\276\273\324F>\347b\316<\\\244\211=M\316\321\276\032\223%\273\312m\336\276\205z*\277>\347\303=#2\024>\340\266{\275\255\360<\275\263l\211>\244\273\257<\371\342\n>\247\270o>?\264\246>U,\347\274\360\377\205>\235\035\332\275\277\205\245>\201\2512>v+\312>\302]%>\003\273r>\245\326G=\007^r>!6\231\274\257>5\275\251\351\030?\3570\272>X\332H\276\270d\033\277 \365\004?:\203k\277)\030\236\276~\3652\276_\373\224\2765\266\374=\323\254\006\275\237\002\333>\037nI>x\036Z>\3471\313\275\235\004\035?\337H\\\275\301\336\273\276\272\272\342\276A\331\203\276i\307\277>\250\347\226>\247l\245<\213U\210\276\344\335\r?\221\314q\276T\030?\276\355\347\034?\355\271\270\275!\366@\276\340B\372\275/\331\246\275\002\341\202\276/\025\235>\265\343\343=\272\317\215>\315KQ<\336~\254\276\255|\340=\226\202-?\350\022\355>\313\2478\276k\r/\275\014\364\223\276p\372\331\275\326\010\332>\014\331{>\2037\004\277\217`\265=\253+\324>\235BH\276\023nF>=8\353>\323\316*\276s\342\246\276\030\032\234\276\013\303}\276\367P?\276\271;\262>\013\023\024\277\3067\270\275R\3102>F\274T>^\202\034\274\212@\324=\345s\016\276?J\203=\340\2058\277\203\355\202\275\310mJ\276\025\231\021\0026>?..\214\275\2320\206\2751^\t?pI\262\276T\\\354\275\213\255B?\013!\203\276f\324k\276\255+\323=\336\001\235=\367^c\276OQ\000\276\344C\375=\027\207\351\2755\332O\277\354\315J\2762\335\016>\301\253c\276\214\350\242\276>\010\026?_r\274>\375\215E?\341\021\265>S!\301\276?5_\276\262\257\245=E9\313>\001\367e>\233\235\272>\377h\001\277\362\214\200>z\313%\276\237\242N\276L0D?Cw\233\276\321\"\251\276\265n\362\274\324L\324=13\014>\235\031\235<\306$\310\276$\316\032>\014\035\361\276\033}\320\276A\236u\275m$\036?6\362\027\277\235\200E?\212\004\271=XUX>\027G\240\276mQ\354\017\275hO`=B\036W?\340!\304>\235u\244\2760h\270=\335\215\r\277B\342,>\027\321T?d*\322>\311\304\\\276\364\033{\276\2537W\203>>\335\340>/\367\006\277\375;\270>\303\032\036\277\340z4\277\347`E?_\2744\277;\362\306\275o\2079?/\330h\2766\\\216>ihk>Zg;?\351\251\236=\212\334\222\276.m\355=d>\224\276\3572\216\275\253m\242>\240:\200\320\025\362>h#K>\356\021\274>w$\032?\027\007\214\276\307\267\234\275Bh\000?\177ZH>K\343m\274?\233\221>\333V\242\2767t}\276\243\201\316>R\232o\276\001\365\331\274p\267\025?\273\361V>\260\235\006\277\301\356\005\276MR\035\276\273\037\371>uu\322>\313\216!?\205\206\206\275]\224\202>\324@\020>\232\363\303\276\006\354%\277=-G?\241.\222\276\033z\347<\030\341\226=\341\177\242>\306\266\205\276\2763\336>Xt1=\366\341\237\276\026\0220\276Q`\206\275\274C,>2\203.?\276z\177\276\027\nu=\216UG\276\275\326\206\276\266:\217\2765\340\370=\266\327\014>\2007\016>\330%2>\326=\311\27430\356\276\333\376\020?\254\366\t?7\\x\276\234f\223=i\005T\276\210N\365>;z\006>\365\224\004\2773\335\002=Z\204\263\276\363\310Y>\346/\004>\200T\021\276\315d(>q\356\272\276\320%g>\002\376\351>R\207\013\276R\216@\275iX0=\324a\325=\322\215\357\274\310\272\005\277Zz\263\276\320\007\343\276W\026\347>\302\032\327=v~\356=\034\271V\277\303\010.\277\241X;>\215L4>w\210\271\275\3725\200\275{\351\327\275]PY>\344C\n\277*q\017?\362\203\337:\256\005I\275\246sK=%W\215\275\374\356\033\275\316\351\352\276\202>p\275?\3165?\306gW=\354\326\337>\010C\233<\375\014>\2746\'\032>\022v\034\273\247r\206>?}\t\2754Ib\276o\006\236=\253T >\334\2170<\221\202\n>O\356\276>\342\302\212\276\336\r}?z]\032\277\330\373\356\275x\220\347=\337H\355=\231\361\\>\376\251\322>\200\014\365\275I\226\266>\327Y\301>\005\2328=\0058\247>7\001\324\276\000\260\032>\200T\264\276\245\220\226>\321\313\332\2761\370\350>\376T\226\276\324\226\322\276%\357j<\036\331\203\275\351=\302\276{_D\276\266\215\330\274q\216\000\277\234\302\031\276\327:{=\305\312\340> X0\276\033\355\225\276\342R^?\244T\033<\245\031\253\274e\240W\276\300\002y\276!3\264\275\230?~\275\017\364\217\276\272\317\023\277\026\261\017\276\2425\223\277W}a>N\250{>\313\364\000?I\210\324=\223.\373\274\361j#>4<\226\276\301\275\237\275nW\002>\232T\014\276Q\240\371\276\270`\322>\007\360\242>\270\224\344\276\270\302z>*~\220\276Kr\216>\036\034\342\276\2509\204\276\024_\260\276Q\316\277\276\210\231\202\274wU\262>\001K\024\274/\000#\277\327\213`\276\255o\n?\3030G\277~/\006\276\337\203q\275\217\314\026>`\315\024\274%\372\316\274\275\002\336\275\247P\035=\206\250\215>\271\265\226\276\240\341\r\277z\303\321\275?1\033>\362~f=A\017I\276T\331\256>\232\002H>\032\343\'\277>\340k\276\265\004\303>\346\352\327\276\203\315\376>o\273\275\274\376\232\354=\035\016\355\275x\254\367=b\237K\276\202\200\317=8o\335>j\251(>\3749\216\276k\\-\277\250\244\203=\241\200l=\236\220\344\275\367\376Z\276\362\303\231\276\360\317R\277\266\3278\277\367\225`\276\377?\374>Cb5>\321\000\237>\0027\273=\232D\275>\035W^\275\323\221\220>j\004\255\276\273\310E\2766\013\374>\226\251\365>\024oA<<,\206\276=\275\\\2761\037f\2768C\032?\347\277\003?\034#\226\276at\350\276\304v\373\276\360\315%>w)\271>\273\210\310\276\275)\016\277\215eA\276\353`==\023\256\033?\255H/=\332x\363=\324\346\237\276 J#\276\006\212\305>E\224u\274JJ\265>_\301\260<\325\325 \277\356\037\032\277%\344p=\255-\313>\230\310\325\276i\213\005\276Cq\004?\332>\251=\"q\207>!|\177\276M@\315>I\207\263\276+\204\365\276\357\030\007\275\025\230\326\276`\236\235\275\247,c>\320\333i\276\377\303\353\276T\307\355>\341\353\003\277R\002\024=\024\272.\277\355U/\277\223\025\322>\307\000\013\277cR<\276\211\326\016\277aX\207\273\005\261\207=:\352$?7BA\276\211O\277\276\t\305\272\275\344\353i\275Q)\266\2761\240\330=\220\037\023\276BI\354\273!S\221\276\312\027\024?\277\223\265\275S\357\336=\261#1\277M\212/?\247\262Y>\231\204\376\276j\237\000\276\021\205\324\276\030\344 >\213\002/>r\200\036=\005\311\020?b\330\366=\244\340_\276D\003\306\276\374\252>=\001\006\200>\031/?\277\255\000\034>\256Z\207\275QZ\004\277\031\335(>\221}<\274\321\343\033?U\0266=\221\354T\2746\322\003\277q\343\361=r !?\225\322\363>,\307\255\276\262\025\354\276\256\211\215\276!E\305<\307\336\241>:\003Q\276:\3060?\207\375,\277\304\032@=J\261O\277r\354\236>j\361\0249K\370\024>\005\225\327\276\033t\202>\023x\257>\324\365\222\275\201\276&\277\236K\352=\035Ik\276\316\030\016?\347X8\276$\335\252\276\223\005\351=JZ\322\276\311\243\001?F<\262\276\346\360*\276\216\363\244>\241\030?>\3256\326\276\030]$\277|1*?\360\364J\277:\317\227>\0322\234\2752\263\376>Z\374f\276\260\210{?\3319\272>\327\350\241=\265&\346\276q\036&\276sd\001\277|!K>\333b\233\276\034(\244>U\221\256\276\206\276\021\276v\030\201\27622,\276\342\025\361>\362!\252>\206\337\003\276w}t>k\347\305=1\230\233\276\315,\006>\213\022<\276\030P\n?\333S\354>\211\302\r>\000\006\373>\035|\260\275N\271\332=\300\364@?\005i!>\300qb\276\030p1<\332\014\255\275\233\n\006\277\351S\214\274a\276\271?\311\3777\277\325jr>\226\270\035>V+\211\274\013\271\010?\260\336\337\274AM\347\276\321\033\007\276\330\347\330=\232E\255>Js\360>\371\3013>\211\257\006=\\^.\276\013F\330\275\216Kl\276/29\277!\251\230\275Z\214\307=9\253c=T\345\314\276\353\361L>r\205\316>T\037\347=\234\010\021?\264\203\200>@wo>Aak>u%\014\277\005\312\247>\214\'\024=W\022\002?W[\310>\235m\263\276\251\213+>1\240\362=o\037\013\277?\0372=\"\260&?\227G\205\275\267\335\005\2764&^\276\331\212\031\277\204\243\250>N\341\224\276\025\264t>Z\\_\275l(b\276\023S\213=/`\020?\370\333\"?\262#\371\276\302i}>\267\004\200>\317\301\307>\302\312\200=\273\025\232=\006`\317\275\'<\346;\356E\235\276o\366\313>\345\356\224\275\365\212\325<\275Y\212\276\023N@\2763\2545>\036\2748\276\217\352B\275\202\200\211>\324\232?=H_\016\005%\211\276k\345+<\245\277%;\t\t\271\275{\243\030\276\361\334\334>\223\265\242>\003i\001>W\366;?\177\270\006\275\203~N<<\370\024\276#\261\306=n\220\277\276\231\317\235\276\276\030\006?\327\270d?\"K\347\275\024\t0\276\326l>\276\304\364(=\227F4>\247,\210\274\243\215\035\276n\242\333>u\243#>\235\360I<\014\341{\276\350\242\200=\355:\324>\225s,\276\233\212\334\276aW\236>\315\260\357>X\020b\276\210\227\324=\265\331\020>+\033\233>J\305Z?s\331\317\275\301\010c\276\na\327=\360\001;\277$\242\314\276\003J\316\276\303N\020\276\314Dm\276l\000E\276\003\227\316\276\346\003\033?>\007\224>\363\270J?\001\3127?A\224\277>\375?7>\207\031y>\200y3\267>\273P\203=\302]\335>\316K(\277\325wT>)\242\221\276\340A\013\276\247\321M>\"N\312=~\177\244\2768\276\364\275\313hW>\221\373\t?^|\263\276\335.\326\276\322\206H\276x\211T=G =>x\020\017?\341\2232\275\241\345\346\275\"\004\250=~E\260\277\030\376\321\275\360\255M>{\325\212\274#\261\225>\300\361\306>\032&.\277\266h\317\276\016\037\n\277\177\220\206\276sa|=Q\214\332=q\326q>>=\205\275\263G\225\274\354\017,?\234\207\225>`/3\277\241V\n\275\361\344&>}\373\277\274\'\007\201>\277F1\276(}\r?:\"\'>\337\355\357\276\272j\r?\007\360b>E\377\262>\233\014,\277C\333!\275l\360\357\275\344\226\344>\335/n>\2753\255\275\335\002i\276Glb>\214e\272\276\005M\334\276xyW>]Z\003?\246\221\211?R\210\222\276\'Di\276\003\036\273\276\204p\'>\004\312\254\276\240\257\t\275\r\2751\277TI\002>!\362K\275\231\357\007\277\272\261\334=\2353c?7\354\264\276\2263V>\316\343%\276\3558\020?\307\251\201;Q\365\221\276\320\355\254\276\367\324*?u\215\372=\207\234\217=\225y\200=1\350o\276\001\246\n>n`\255=~\205\313>f4O\275\360c\205\275(\351\037>\307\374\231<\364\363\257>\323\014\261\273\037_\325\2764\023\307>\345I`>78<\276\001\342\013\275\200\0038?7\371\032>\216~\010?\r\025\324>\222f\333>.\213b=\024\200\305\276\260Jn>\204\254\215>\031\017&>Of\204\276\313\241!>\037\265<>\310t\331\276X\276\234>\301&\205=m\343\215>`\'\261>\247\272\n\277\366\202q\276\320e\333>Nm\276\276\342G\231\276\336wi?\244v\260\276%;U>\341\202\354=^\006~\276\231\220\224=\025\242%\277\225\277\277>]\315\030\275\253N\375>MV!=%\020\360>\300\252\226=*\344\200\275\222\300F\275OO\355\274\222l\245<\267\\\344\275u\337@\276\025l\301>\350]t>9Hv>\271%\025=r1r\276l\372\304\275NJ\221>\227\335\216\276\016;\350:{I?\276\275\253\232\276\203\255\n\277\255u=\276\261R\346\275\023\272\317>\377\240\022\277ex\221><\326\263\276\314\357\356\275\321\313\007\274_\205W\276\364o}=iOi\275t\021\033?\227\032\004>\274\211\266\275A\027\363\276\311\250\325\276\246}5>\336@y>E:G=\204f\342;}*\026;0\000\354>\n\240\201\276p\255\216\275OsD>\"\006\304\276\366b)\276\000\327\004\277\326\035\307>\272\263\037=\n`\331\276J\223b>(\003->\370\177\330>F\227\"\275b`&\276*\2423>\375\001H\277\355\353\261\276\352\230\243>\177\301M\276\277\0255=y\367\254<\350\332\274\275\020p=\276\206\306\337\276kmH\2771N\347\275\000O\241>\342\204\346\275#\"u\277}\031\200\276\016\255X\275\205\274\256\2754\010\230=6\252\002\277\363\363h\277+\272V\277\211G\205?\331\257\210>DJS\277\302W/=\026\004\266\274\207#\007\276\215\345b\275\204\2466=\005\3729=\250\230\001?\022>\317\276ox\317\2763X\337\276\t\345\031>\255\215\034?w\257\013>:IF?r\253\221>v\224(\277\220\330\342\276\314\020\247\276/\212\033\275\240\240z\277\225!\263=}\036\333\276\370\227\205\276\364w\270\275!\277\305\276mj\223\276\035P(>\356\331\253=\017\216.\277\022\206\004\277\200]\253>\005\032)\276\252\006\260=\211\252\030\277Zy\263\276\217\350\261\276\276u\255\276\334\376>\276\234qW\276\356f\351\276g\245\213\276R\221\251\273\212\206\r\276\026\0234\276\271\004\337=\334\301\237\274\366\316\233\277\226\312\327=\252\034+\276\253\204\233<\342\365)\277q\262\2349\024.\363=\350N\001;\023\n#\276\345\265S\276\207~\026>\212\002\315>\211\025\210=\310j\326\274<\236\220=\346\013\270=\010z\034\276\0160\031>\320\360\247\276\225\303\326\275\007Y\241=\031%(=\020\3553\277\326\364\025\275\313,\354\276\270!\201>\034\260\357>\252\217\021\277\344nU>\362\221\230\275\177\213\363\274\004!\304>\375:t>\223\216\033>\222fD\276\"\020@\276\005\273~>\327\303\241=#\352\220=\246aW\275\026\004A= 8 >\304L\035>$k\274\276\355\2034\277`\377\351\276+\273\310=\0054\320>\t/W\275\333\274\354>\220[\023>PG$\276\310\023\271=z\206\000\277\001EN>\'\"\230\275}\025\352<\003\375\241\276\246\t\226\276\001\']\276\311s\343\276.\305\213\2764\307\177=\017-\256\276{v^\276\353\306\275\276\rl\251>!m\345>\310\321\252\276\213\264\372\276\375lo\276\235\303\214\276\340\007-\276\352\222]\275\372\357\354=\327;&\276\236\017\023\276\001:\200>\337\241\032>\352\304\217\276//g\276D@\335\276\261#\256\275-\234\237;\266*\214>\005N;>H\234\372\276#>\216\275\261zK\276\220\020\025\277\014\360G\276\212\372Z\2757\350<>\246\3640\276\025a\330=@K\336<\357\3058\276\021a\232=\350\254r<\341\201:\276*\334\330\276;\323\217\276\302 8?\207o!?=L\251<\331-\005?6\206Z=\216\333\212>\243\327\210?>I0\277\224\026\013>Y\371\264>\235\2344>T(\031?N\354<=M28\276\372\227r>\263\257\266\276\227j\240=\252\311:>\226\262\201>x\252\327<\247\325\312\276\2258\323<\347 \n\276\"6\232\276\273\343(>\3764A\276\244O\216>\026\374\'\275R\275:\276\246\333\305=\371\252\312\276\224\231+=\202\226\371\275\034\253P>\224\010\252>\352\270\253>\331D\345\276Gy\224=*Md>h\273+\276\206\215\030=\035-\350>#\347p?\003:\257\276^@\201>\006\337\231>\333\336S>\362\200\350=J\277\377\276\277\330\'?E\342\327>\320\330\007\277W\310\341\276\266\263\242\275\002R\341>y\323\266\276\001f\r?\253#D>U\346\376\275\207X5\276\312\277\027<\2725\301>\')\'=\370b\366=\306\032\247\276\006\271\n?\r\260\373\276L\t\244>\310\202\204>\340\030Q=j[\306=g\027\344>%\002|\276\235\256\n?h\210\010?5f\254\274\212\245\032?\013\376\260=/\324\'>\342\023\325=\221K\360>\016\237,>\332\374(>/<\312\276|\222\253?5\266\235>\372i=>$\266\325\276\266\337C>\327a\311\274[Z\037\276W\210\244\276\323\217`>\351\'\335=\315\005\'>~\365\320\275\202\3674\276/T\356\272\337\202\225>\362V\021\277\031\267\334=Ti\223>:7\202\217a;\272\220\366=\361g\010?\262w\326\276\354\324\325\273f\342x\276\346c\244\274\323n\321=\246\033+=\217\360\331>\373\263\356<9\202N>\210\244\034?\263\3315\276\200\264C>m\241\243=v\345\251>\264\212\207\276\334\357\260>la\327\276\337y\013\276\215\276\364>\3347\227=5\371W>\3102\201=;\227\324>\201\200\314>\206\262\271\275\346,\242>S\331\224<,\232s>l6\231>ggO>s\230\356=\332\342a\274\353ig=\3017\304>A\375\342\275\r1\234=\314\327s\275\347r\315\276VH\234>\370\360Q\276\032\324\277\276\312\311\353=~]\314\275\0025\250>\301\212\342\276]\001D\276\352\'\321\275-\352}>\003z\231>\374\227\377\275\337\357<\276\257\217\024?3\200%>L\232\256<\206\260\273\276\267L\347>A9\260\275\353\344\003\276\353\311\034>\263+\030\276\271\177C\276j0\022>q\373\247>\373\216)>S\376\251=\235*\225=E\216\262>\375\307s\276\251L\205=\3619\244\276Nq\312=\220\300\377>\315\010\037?\250\370\363>9CA>\003\263\224>e\033\306>,\264\330\276\241\306\331\276\273\366\242>\014\027\272\276\030\371W>\376\240\221\276@\305\n\276\315o\271>\037b\340\276\340\326\272\275\242;\233=\"\353\021?\245k\330\276\031\241\032\276:\024\233>\216\306\201>\3116\335\276\202q\250>\234\220\264\276\351\007\010\277\351\345}\276p\357\347\2769|\374\276\237\262\276\276\312\317\206\275C\034\371\276\035?\215?y\216\227\276NF\360\275TN\235\276\024\330\221\275\243\372x>\275X\271>\265d\266\276\314\241e\277j\224\334\275\364E\003\273\32210?tT/=U,\001>\352\304\030\277\022u\324\276Q\371\023>@-\274\276\344.\023\277\272+[\2764y\326\276j\t\013>y\311K>Ie\034\276SP\t>\305\021M\275COM=TD\307\275\021,\242\276\311x\214\276\336\372\271\276\013\225\n\277\311\205Y>\243\266D\2765J_\276\362\030\260\276\177b\240>\003B\352\276=\230u>\345\327\214\276\212\340\305\275\030\325 \275\\F\260\276p\315C\276r| \276\206cX\276\310X\025\276Ov$\277\315W!>\201\364<\277\215\242+\276i\202\210\274f\023\275>A\301\230\275)_&=\036,\252\273\207\255\321=\255\210\025\275\354\r\212\276\315q@\276\034\365\200\276*\344\363>\364cM\275\361\252\230\276\373]\207=\320\3438\276~\242/>c\001%\2763\376\261>2<\013\2768\341\000?t~\237\2761A\021\274k\352\347=\264\307\366\276\331\016.>\262\344\211\276#\350\r\277)\014\037=hB\263>FAg<\232\"\327\274\306:\230\275\347T\372=\207\033\365\275Lh\321\276\035\215\303\276|X\035=\037X=>8h)>\335j\241\276\372s\260\276X\342\341\276\004R\006\274\375V\210\276\367\251@?\356\316\002\276WH\325<\006\265\266\276\315\020\223\275\037\360\246>\0178\351\275\"\357\207\276\254~\302\275\340\221!\276\351\254\013\275\331Z\220>\272\364\303\276Q\3431\276\255%\261>\341t\373\275nH\337\276y\336l\277\341b\022=(i\032=\237lN\276\274\322\206=0I\205>\256\007\017\276Yn\265>l\243Z=\371\274{\276\306\251/\275\334\026\276\276\3300\031\277\260D\263\2766\206B>{\316\243\276o\267H\276V\005\243\276p\037\313\275/\314\203=\232\275l\276R\316E\276\2036\337\275t\231\307=\201\254\006\277[\224\017\276\265\n(=\032\036\215>\004o\343=y{\247\276@\035R>/N\244\275\215E\373\276\2048U;w0\036\276i\n\305=\307y\261\275\372\256\235\276\033xf\276\025\021\353\276\202%\225>\267\326\355\275t\300\003\276\207\316\246>R\030\304\275\272\356\024\272\326K\352\274\n>1\277\367\322\241>{\006\225<\303\277$?Z\030\022?\026uR=a\034%\277\211w\303\276E\361\333>\252\315\275>Z\246\245\276\330\306\325\275\366}\211=\362\023\260\276\345\312\243\276\350\375{\277\333\211\020>\320F\213\275\351a\306\276\226;\230>\3677\366\276\026\261\265\276\215\340\013\277\010\245\211\275\253\203\014\276`\217>\275\037\016\271\275\261\243T\276\306(\253;\230u\215\276\332L\016\277N\305\217\276\260\362\261\275F\025\225=\224\222\314\276\330x\332<\306\227\261\276\333J\315\276\236\311\216\276\234\2308>\025m\036\277\264@g\277\2366\222=\277]\240\276\214#\316\276\024\231\236\275\313\366$\276@\326\n\277S\r\376\276\364/\236\275{\212\030\274\340V(\277\373\244\202=\367K\317\276\237\2671\277E\305\311\276\014\315\336\276d\355\235\276\316\347\250\276\325$*\277\031R\016\277\267c\335\276Q\267\211\276\227,\251\274\tmp\274o\220\354=\361e\231\276vK\303\276\252%\177\277\262\254 \277[\343\007\277\375\024\271\276#X\213\274y\262\006\276|\213\027\277\367\263\221\275\021>\267\276o\326\026\276\004\003P\276x7\361\276\225\267\247=\211p\'?\265\216\206\276#\314&\277r*\006=\215\362\216\276\363\320\005\277\377\322\037\276\373\337\235\276\003\0264\276\317\242Y\276\3174\337=\231Q\341\276n1\356>\270t\026\277\235\255\205\276\367\']\277`a\t\277\222\377*\277\345\345\323\276\254\341\357\275\001O\004>\007\345A\276k\034\322\276\365\326\361<\256\251\265\275\222k\260\276q\315\364\276Q\0345\277-c\006\277E4\243=\'\245\014\277@\267\226?\371\257d>S\371\223\276\243\326\035\276]\005\337\276\356\373#\277.N\\\275\030j\236\274FN\007\277\360_\305\274\215\363\264\276GH\255\276\241\263\351\276\373<\236\275\302\236;\276\204\341W\276\332\2264\277\326wK\275\251\3249\277~\246D\277\325@\254\276\240\307C\277n4\037\276\341\212\363\275\\lQ\277\221o\300\276[\017&>\376\365\322\212aL\276\335k\253\276\207\244\201\277\311b\021\277\251L,\277\221\004\r\277\321-\336\275\335\341\230<\322\243\347\276\017\007\314\276\343\242\351\276>\025\211>\2372\371\276\330\305\230> \247\r\277\276\210\246\276W\301:\277\002\000\271>\303\340(\217^\036=P\356\316\276S\322\306\275\250\2640\277o\251`><\255M>`\337`\275$V\371\276d> ?\210\305\026\276\222\221$\276\027p\366\276\261\344!\277\257\353+=\257P\272\276X\034I\277g,\023\277\353L\035?\337 \367\276C\211\346\275\216+$\276\0278\307\276\244\034J\277\017\223m\277\264\326\377\276\352\235\233=j\253-\276\337\033\276=\350\306\233=\316\233\r\276\224\017\374\3102\277\2648\363>\006\020\327;lHD>\355\336\013\276\251\337\273\276\215\355\022?\264k\340>\227\245\256\276k\302\353\276\357\020\321>x\026\202\276@\277/?s\374\254<}D\214;\"9\244\276Q\304Q>\244\265]?\r!\370\276&\177\331>\2360 >J\341\023=c\372\032>\2018\262>\2007y>bzy\276\364\361\227\275\247BJ\274\016\023\240\241\237Z\276\262\310\022\277u\264\354>t\004\241=,\017\312\276\354\372\204>o\003\311>\363\307\226\276\031\330\204\275\310\022\037>\323\026\230\275\320\000\005?iJ\362>\245\230=>\335\325\022?\031\373\022>#\246\323\276JZ\371>\366\275\005?\226\342\032?\255\357\007?\336\377\034\276\224\315\301=\223\310\366>2\322-\276~e\301>4\235|>l2\260>\014\341O>4\364\326\210\372\030>{\256\305=\255\225\032>\n\271=><\212u>z\253M\276\237\003\030\276\371E\212\275\373\341\267>7\247Q\276\363\204A\276&v*>\265f>\277\200\337\322>$7b>\254\231\245<\027\022\241>G\364s<\215P\006?>\021\272=S\363\304\276la\223\275\341\333J?B\007\332=u\006\241\276\017\272\351\276\345l\251=^~M\276\234\227\r?;\t\021\277\202\237|>\020\224(=\025@\263\276a\177`>\211S\367>\363\243\253=\320U\232\275!\007\n\276%L\270\275x4)?%J\225>\006\334D>8\241\007=\n\206\'?\t\244!\276@\333\373\275\356\216\025\276\2238\273>J\255\024?1\254\n>: \375\275 \257\314\274#\007\271>\354\355\313\276\010\260\236=\002\351\243\276ga\351=\337-3?0y\202\2769;w>\305\332\221>\3369\220=\r2M}\201j>\227\367\255\274\375)\343>\005\266<\276\362\324G?\256\261J\276\364L=>\331\316\300>F\266}>utW\276!E\356>\376\017$?V\017\251>\035\316\336>Qi\327=\241\357\034>\023`)>\254\223g\275\356_\261\276B\276U>\3110M>\346(|\275\222\301\t\276\273\2415>\204\035\352\276\203\253\255>\036L[;\247\372\231\276\337~\025\277}y\027\276\202\265\305>\266\r\262\276,L\343>>\020\225?aR\003\276\362UP\277\371\210\230>\237Hd\276\247\337\237>\253\2674\276R\215\007\276T\321!\276\005Z\371=l)\275\276\364\232\360\2761\177\010?3\013\357>k\236m=9wd\276\253\001\226>8h\232>4\335\003?\365\333\267\276\257R\230<\005\333M\276\352\025\006>\234s\277\276\265C\347\275U\003\206\274\312\275\266\273\326\0348\277\212\367\236<\023\260\031\276\320A\271<\314\204\014\277\364\270\024\276\335$\374\275\373\026\314=\301\005\317\276\236\337\365\275\031\t\354\276\326\234\026>\351\030\347<\343=\034\275\032\026o\276\351\013\220\276\367\210<\276\n1\233\276\035\213\366>\034\022\367\276f\030\355\276\376\313:>\217\216\217\275\301\226_>h(\303\276\225\254)\276\240X\226\276\212G\343\3614\030>\307a\232\275\357\3771\276Qt\312\276\261\205\205\276<\203\354\276\265\356\351\276\013\213\236\276\3725\345<\271n\273\276T\277V\276\3159\001\277&\014;>P\373\322\276k\257\371>\314\327\027\276h\333\320\276\367\336\262=\310\333\016>\025\357\312>\327Y\313\275#\"\266><\226\312\275$\275\260\276\325\347k=\265\301#>\013DT=\037C\354\276L#j\275C\313\221\275w\"\\>\tZ\310=\305\237\362\274~G\203\276\002\366\237>\373\357\241\276\023\026;>{\235R<\276E\n\276u\017\266\276\247\346\256=Ub\026=\2579n\276\003\244\376\275\304\022\245>V\000$\277d\265^\276\353\243\004\2777\351\201=2\323\216\276\035\213\272>\3542\254\276\0143*>=\270\224>e+\035\276K\026{\276\000\261D>\340.\233<\272Mc\276(\351\212>\336\345\003>\324J?\2766V\033\277y\367\221\276\257T\242\276\000\021\234\303\371(\276q5\317<>\307j<\230\341\236\276\231*\234\275\226\234\252\275\332\226)=\033\232M\276({:>\201\026\316\275\366\247\202\276\032\327\325<\035\305\356\275\025`U\276L\325m>{g\337\276z\316\254\274u!\301=\207\034\213<\263\310\222\275\235\376\264\276\357\016\306\276\274\313\037\276\277g\276<\216l\226\276\355\314\007\277\037}\005\276\r\271\376\275\251\037\333= \373\211\274\337\341\204\276\260\354\311\276\323<\303\275|n\035\276\031+\257\276\241j\371<\370\245\250=\025\232K\276\274\310]\276\365X>\276\362\327\276\276\210\205\002>\356\255H\273\274X\256\276n\035@=Z\352\376\274|\354\375=\2516r=\323\340\254\276\245\024\037\276\376ia>[#\326=9\250\207\276\265W\016\276\311\360\222\275\334H\357\274@:\270\276\276a\360=\300\322\215\276\356\251i>\373;x\276\340\216\033>\262\341\272\276\266\014\021\272\357\300\213\276|\034\355\276\030\310\351=\243\272\027\276\255\221\325\274\274\003a\276\256\335\301\275\364\3267\276:$\030\276\303\335\237\276k\362\223\274(:\'>\276\020\315<\375\025\233\276\320\036\252\276<\326\337\271v\362\324\275\212\230$\276\362\246\373\274\365G\306\276\373\301\025\277\303\312\233;\315\243\204\276\361O\004\276\237\0336\276\373\202\327=h^\312>\271Eu\276\3447\314\276\255G\274\276h\267\325\352\317\r\276\002\213\346\273\311zJ>\034\345\355\276\275X\236=\305\036\306>\341\031F\275\336\300\017