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 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', {'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 replace_pattern(graph: Graph, match: dict): node = match['conv'] node_name = node.soft_get('name', node.id) dst_dtype = np.float32 # even if data_type=FP16 use float32 for shape values # create Reshape before convolution # shape = [in_shape[0], in_shape[1]/patch_stride, 1, patch_stride] i_shape = Shape(graph, {'name': node_name + '/Shape'}).create_node() shape = Cast(graph, { 'name': node_name + '/to_float', 'dst_type': dst_dtype }).create_node() i_shape.in_port(0).connect(node.in_port(0).get_source()) shape.in_port(0).connect(i_shape.out_port(0)) N, H = node_to_get_shape_value_of_indices( shape, [0]), node_to_get_shape_value_of_indices(shape, [1]) div = create_op_with_const_inputs( graph, Div, {1: float32_array([node.patch_stride])}, {'name': node_name + '/div_stride_h'}) div.in_port(0).connect(H.out_port(0)) concat = create_op_with_const_inputs( graph, Concat, { 2: float32_array([1]), 3: float32_array([node.patch_stride]) }, { 'name': node_name + '/concat_all_dims', 'in_ports_count': 4, 'axis': 0 }) concat.in_port(0).connect(N.out_port(0)) concat.in_port(1).connect(div.out_port(0)) reshape_pattern = Cast(graph, { 'name': node_name + '/to_int', 'dst_type': np.int64 }).create_node() concat.out_port(0).connect(reshape_pattern.in_port(0)) reshape_in = Reshape(graph, { 'name': node_name + '/reshape_in' }).create_node() reshape_in.in_port(1).connect(reshape_pattern.out_port(0)) # create Reshape after Convolution reshape_out = create_op_node_with_second_input( graph, Reshape, int64_array([0, -1]), {'name': node_name + '/reshape_out'}) # connect input_reshape_node source = node.in_port(0).get_source() node.in_port(0).get_connection().set_source(reshape_in.out_port(0)) reshape_in.in_port(0).connect(source) # connect output_reshape_node node.out_port(0).get_connection().set_source(reshape_out.out_port(0)) node.out_port(0).connect(reshape_out.in_port(0))
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 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': np.array([1]), 'end_mask': np.array([1]), 'new_axis_mask': np.array([0]), 'shrink_axis_mask': np.array([0]), 'ellipsis_mask': np.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 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))
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': np.array([1]), 'end_mask': np.array([1]), 'new_axis_mask': np.array([0]), 'shrink_axis_mask': np.array([0]), 'ellipsis_mask': np.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': np.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 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) 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 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
}), **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': 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': 1 }), **result('result'), } class ReverseInputChannelsTest(unittest.TestCase): def check_graph_attrs(self, graph: Graph, parameter_node_names: list): for node in graph.get_op_nodes():
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') self.assertTrue(flag, resp)
**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': 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': 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': 3}), **regular_op_with_shaped_data('reverse_channels_down', [1, 3, 10, 10], {'type': 'ReverseChannels', 'axis': 1}),
# SPDX-License-Identifier: Apache-2.0 import unittest import numpy as np from extensions.front.AttributedRandomUniformToRandomUniform import AttributedRandomUniformToRandomUniform from mo.front.common.partial_infer.utils import int64_array, float32_array from 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}),
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)
def replace_pattern(self, graph: Graph, match: dict): unsqueeze_node = match['unsqueeze'] unsqueeze_name = unsqueeze_node.name second_input_of_unsqueeze = unsqueeze_node.in_port( 1).get_connection().get_source().node if not second_input_of_unsqueeze.has_valid('value'): return d_idx = int(second_input_of_unsqueeze.value) second_input_of_tile = match['tile'].in_port( 1).get_connection().get_source().node if not second_input_of_tile.has_valid('value'): return input_shape_of_unsqueeze = unsqueeze_node.in_port(0).data.get_shape() if len(input_shape_of_unsqueeze) not in {4, 5}: return scale = float32_array([second_input_of_tile.value[d_idx]]) axis = d_idx - 1 axis_node = Const(graph, { 'name': unsqueeze_name + '/axis', 'value': int64_array([axis]) }).create_node() shape_node = Shape(graph, dict(name=unsqueeze_name + '/Shape')).create_node() scales_node = Const(graph, dict(name=unsqueeze_name + '/scales', value=scale)).create_node() mul_node = Mul(graph, dict(name=unsqueeze_name + '/Mul')).create_node() scales_node.out_port(0).connect(mul_node.in_port(1)) slice_begin = Const( graph, dict(name=unsqueeze_name + '/slice_begin', value=int64_array([axis]))).create_node() slice_end = Const( graph, dict(name=unsqueeze_name + '/slice_end', value=int64_array([axis + 1]))).create_node() strided_slice_node = StridedSlice( graph, { 'name': unsqueeze_name + '/StridedSlice', 'begin_mask': int64_array([1]), 'end_mask': int64_array([1]), 'new_axis_mask': int64_array([0]), 'shrink_axis_mask': int64_array([0]), 'ellipsis_mask': int64_array([0]), }).create_node() shape_node.out_port(0).connect(strided_slice_node.in_port(0)) slice_begin.out_port(0).connect(strided_slice_node.in_port(1)) slice_end.out_port(0).connect(strided_slice_node.in_port(2)) 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(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': unsqueeze_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)) 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 = match['unsqueeze'].in_port(0).get_connection() before_unsqueeze = unsqueeze_connection.get_source().node unsqueeze_connection.set_destination(interp_node.in_port(0)) before_unsqueeze.out_port(0).connect(shape_node.in_port(0))