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'}), **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', 'result'), ] graph_ref = build_graph(nodes, edges_ref, {'some_op': {'name': 'my_output_name'}}) FakeOutputResolver().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result') self.assertTrue(flag, resp)
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_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(node, reverse_channels) self.check_graph_attrs(graph, ['placeholder'])
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_get_fw_index(self): graph = build_graph(nodes, [*connect('placeholder1', 'result')]) node = Node(graph, 'placeholder1') old_api_map = OldAPIMapOrder(version=0) node.rt_info.info[('old_api_map_order', old_api_map.get_version())] = old_api_map node.rt_info.info[( 'old_api_map_order', old_api_map.get_version())].old_api_transpose_parameter( [0, 2, 3, 1]) self.assertTrue(InsertReverseChannels.get_fw_index(node, 0) == 0) self.assertTrue(InsertReverseChannels.get_fw_index(node, 1) == 3) self.assertTrue(InsertReverseChannels.get_fw_index(node, 2) == 1) self.assertTrue(InsertReverseChannels.get_fw_index(node, 3) == 2) self.assertTrue(InsertReverseChannels.get_fw_index(node, -2) == 1) self.assertTrue( type(InsertReverseChannels.get_fw_index(node, 0)) == int)
def test_insert_layout(self): graph = build_graph(get_nodes([1, 10, 10, 3]), [*connect('placeholder1', '0:mul'), *connect('placeholder2', '1:mul'), *connect('mul', 'result')], nodes_with_edges_only=True, cli=Namespace(reverse_input_channels=True, layout_values={ 'placeholder1': {'source_layout': 'nhwc', 'target_layout': None}})) InsertReverseChannels().find_and_replace_pattern(graph) graph_ref = build_graph(get_nodes([1, 10, 10, 3], 3), [*connect('placeholder1', 'reverse_channels'), *connect('reverse_channels', '0:mul'), *connect('placeholder2', '1:mul'), *connect('mul', 'result')]) (flag, resp) = compare_graphs(graph, graph_ref, 'result', 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('dim', int64_array([1, 8, 1, 7, 7])), **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) V10ConvolutionWithGroupsResolver().find_and_replace_pattern(graph) nodes['convolution']['type'] = 'GroupConvolution' del nodes['convolution']['group'] 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_mean_values_explicit_and_scale_values_explicit_with_shape_of( self): graph_ref = build_graph(nodes, [ *connect('parameter', '0:add_mean'), *connect('mean', '1:add_mean'), *connect('add_mean', '0:mul_scale'), *connect('scale', '1:mul_scale'), *connect('mul_scale', 'result'), *connect_data('parameter', 'shape_of'), *connect('shape_of', 'result_2'), ], nodes_with_edges_only=True) argv = Namespace( mean_scale_values={ 'parameter': { 'mean': np.array([1, 2, 3]), 'scale': np.array([1, 2, 3]) } }) graph = build_graph(nodes, [ *connect('parameter', 'result'), *connect_data('parameter', 'shape_of'), *connect('shape_of', 'result_2'), ], nodes_with_edges_only=True, cli=argv) self.set_graph_attrs(graph, ['parameter']) self.set_graph_attrs(graph_ref, ['parameter']) graph.graph['layout'] = 'NCHW' AddMeanScaleValues().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) self.assertTrue(flag, resp) (flag, resp) = compare_graphs(graph, graph_ref, 'result_2', check_op_attrs=True) self.assertTrue(flag, resp) self.check_graph_attrs(graph, graph_ref, ['parameter'])
def test_insert_add_mean_scale_after_convert(self): graph_ref = build_graph(nodes, [ *connect('parameter', 'convert'), *connect('convert', '0:add_mean'), *connect('mean', '1:add_mean'), *connect('add_mean', '0:mul_scale'), *connect('scale', '1:mul_scale'), *connect('mul_scale', 'result'), ]) argv = Namespace(mean_scale_values=[[np.array([1., 2., 3.]), np.array([1., 2., 3.])]]) graph = build_graph(nodes, [*connect('parameter', 'convert'), *connect('convert', 'result')], nodes_with_edges_only=True, cli=argv) graph.graph['layout'] = 'NCHW' AddMeanScaleValues().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) self.assertTrue(flag, resp) self.check_graph_attrs(graph, graph_ref, [])
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_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)
def test_insert_add_mean_scale_after_convert_different_type(self): graph_ref = build_graph(nodes, [ *connect('parameter', 'convert'), *connect('convert', '0:add_mean'), *connect('mean', '1:add_mean'), *connect('add_mean', '0:mul_scale'), *connect('scale', '1:mul_scale'), *connect('mul_scale', 'result'), ]) argv = Namespace(mean_scale_values=[[np.array([1., 2., 3.]), np.array([1., 2., 3.])]]) graph = build_graph(nodes, [*connect('parameter', 'convert'), *connect('convert', 'result')], nodes_with_edges_only=True, cli=argv) graph.graph['layout'] = 'NCHW' AddMeanScaleValues().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) self.assertTrue(flag, resp) self.check_graph_attrs(graph, graph_ref, []) add_node = graph.get_op_nodes(type="Add")[0] self.assertTrue(add_node.in_port(1).get_connection().get_source().node['value'].dtype == np.float32)
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_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_mean_values_explicit_and_optimized_layout(self): graph_ref = build_graph(nodes, [ *connect('parameter', '0:add_mean'), *connect('mean', '1:add_mean'), *connect('add_mean', 'result'), *connect('parameter_2', 'result_2'), ]) argv = Namespace(mean_scale_values={ 'parameter': { 'mean': np.array([1., 2., 3.]) }, 'parameter_2': { 'mean': np.array([0., 0., 0.]) } }, layout_values={ 'parameter': { 'source_layout': 'nchw', 'target_layout': None }, 'parameter_2': { 'source_layout': 'nchw', 'target_layout': None } }) graph = build_graph(nodes, [ *connect('parameter', 'result'), *connect('parameter_2', 'result_2') ], nodes_with_edges_only=True, cli=argv) self.set_graph_attrs(graph, ['parameter', 'parameter_2']) self.set_graph_attrs(graph_ref, ['parameter', 'parameter_2']) graph.graph['layout'] = 'NHWC' AddMeanScaleValues().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) self.assertTrue(flag, resp) (flag, resp) = compare_graphs(graph, graph_ref, 'result_2', check_op_attrs=True) self.assertTrue(flag, resp) self.check_graph_attrs(graph, graph_ref, ['parameter', 'parameter_2'])
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) self.assertTrue(flag, resp)
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_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) self.assertTrue(flag, resp) self.assertEqual(graph.get_op_nodes(type='Squeeze')[0]['name'], 'my_rank', 'Name is not inherited from original node for RankDecomposer') print(output_type)
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_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 = -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)
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)
def test_insert_old_api_map(self): graph = build_graph(get_nodes([1, 10, 10, 3]), [*connect('placeholder1', '0:mul'), *connect('placeholder2', '1:mul'), *connect('mul', 'result')], nodes_with_edges_only=True, cli=Namespace(reverse_input_channels=True)) node = Node(graph, 'placeholder1') old_api_map = OldAPIMapOrder(version=0) node.rt_info.info[('old_api_map_order', old_api_map.get_version())] = old_api_map node.rt_info.info[('old_api_map_order', old_api_map.get_version())].old_api_transpose_parameter([0, 2, 3, 1]) InsertReverseChannels().find_and_replace_pattern(graph) graph_ref = build_graph(get_nodes([1, 10, 10, 3], 3), [*connect('placeholder1', 'reverse_channels'), *connect('reverse_channels', '0:mul'), *connect('placeholder2', '1:mul'), *connect('mul', 'result')]) node2 = Node(graph_ref, 'placeholder1') node2.rt_info = node.rt_info (flag, resp) = compare_graphs(graph, graph_ref, 'result', check_op_attrs=True) self.assertTrue(flag, resp)
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)
def test_accuracy(self, data, in_low, in_high, out_low, out_high, levels): 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) 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) self.assertTrue(flag, resp) (flag, resp) = compare_graphs(graph_ref, const_result_graph, 'output', check_op_attrs=True) self.assertTrue(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') self.assertEqual(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) self.assertTrue(flag, resp)
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) self.assertTrue(flag, resp)
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) self.assertTrue(flag, resp) self.assertEqual(graph.get_op_nodes(type='ReduceProd')[0]['name'], 'my_size', 'Name is not inherited from original node for SizeReplacer') print(output_type)
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)
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)
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))
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)