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')
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({ **regular_op_with_shaped_data('shape', [2], {'type': 'Parameter'}), # start **valued_const_with_data('start', np.array(0)), # limit **valued_const_with_data('minus_one', np.array(-1)), **valued_const_with_data('zero', np.array(0)), **regular_op_with_empty_data('range_dim', {'type': 'Gather'}), # delta **valued_const_with_data('delta', np.array(1)), **regular_op_with_empty_data('range', {'type': 'Range'}), # keep dims **valued_const_with_data('axes', np.array([0])), **regular_op_with_empty_data('keep_shape', {'type': 'Unsqueeze'}), **regular_op_with_empty_data('bc', {'type': 'Broadcast'}), **result(), }, [ *connect('start', '0:range'), *connect('shape', '0:range_dim'), *connect('minus_one', '1:range_dim'), *connect('zero', '2:range_dim'), *connect('range_dim', '1:range'), *connect('delta', '2:range'), *connect('range', '0:keep_shape'), *connect('axes', '1:keep_shape'), *connect('keep_shape', '0:bc'), *connect_data('shape', '1:bc'), *connect('bc', 'output'), ], nodes_with_edges_only=True) (flag, resp) = compare_graphs(graph, graph_ref, 'output', check_op_attrs=True) self.assertTrue(flag, resp)
def test_one(self): nodes = { **regular_op('input', {'type': 'Parameter'}), **regular_op('some_op', {'type': 'SomeOp', 'name': 'some_op_name'}), **regular_op('fake_output', {'type': None, 'kind': 'op', 'op': 'FakeOutput', 'name': 'my_output_name'}), **result('result'), } edges = [('input', 'some_op'), ('some_op', 'fake_output'), ('fake_output', 'result'), ] graph = build_graph(nodes, edges) graph.graph['layout'] = 'NCHW' graph.stage = 'front' edges_ref = [('input', 'some_op'), ('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_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(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)
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_with_shaped_data( 'nms', None, { 'op': 'NonMaxSuppression', 'type': 'NonMaxSuppression', 'name': 'nms' }), **result('output'), } self.graph = build_graph(nodes, [ *connect('boxes', '0:nms'), *connect('scores', '1:nms'), *connect('max_output_per_class', '2:nms'), *connect('nms', 'output'), ], nodes_with_edges_only=True)
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_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 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 test_swish_with_sigmoid_without_beta_different_tensors(self): graph = build_graph_with_edge_attrs( { **regular_op('input', {'type': 'Parameter'}), **regular_op('input_2', {'type': 'Parameter'}), **regular_op('sigmoid', {'op': 'Sigmoid'}), **regular_op('mul', { 'op': 'Mul', 'name': 'final_mul' }), **result('result'), }, [('input_2', 'mul', { 'in': 0, 'out': 0 }), ('input', 'sigmoid', { 'in': 0, 'out': 0 }), ('sigmoid', 'mul', { 'in': 1, 'out': 0 }), ('mul', 'result', { 'in': 0, 'out': 0 })], {}) graph_ref = graph.copy() graph.stage = 'front' SwishWithSigmoidWithoutBeta().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result') self.assertTrue(flag, resp)
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 self.assertTrue( np.array_equal(int64_array(ref_res).shape, res_output_shape)) res_output_value = scatter_el_node.out_node().value self.assertTrue(np.array_equal(ref_res, res_output_value))
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 self.assertTrue( 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: self.assertTrue( np.array_equal(int64_array(ref_res), res_output_value))
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)
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', '3:concat'), *connect('concat', 'output'), ] graph = build_graph(nodes, edges_before, nodes_with_edges_only=True) ConcatOdInputEraser().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_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_v7_group_convolution_resolver_weight_are_in_the_right_layout( self): nodes = { **regular_op_with_shaped_data('input', None, { '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_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)
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)
class SoftplusFusionTest(unittest.TestCase): nodes = { **regular_op('input', {'type': 'Parameter'}), **regular_op('exp', {'op': 'Exp'}), **const('const_1', float_array([1.0])), **regular_op('add', {'op': 'Add'}), **regular_op('ln', { 'op': 'Log', 'name': 'final_log' }), **result('result'), } edges = [('input', 'exp', { 'in': 0, 'out': 0 }), ('const_1', 'add', { 'in': 0, 'out': 0 }), ('exp', 'add', { 'in': 1, 'out': 0 }), ('add', 'ln', { 'in': 0, 'out': 0 }), ('ln', 'result', { 'in': 0, 'out': 0 })] def test_softplus_fusion_test(self): graph = build_graph_with_edge_attrs(self.nodes, self.edges, {}) graph_ref = build_graph(ref_nodes, ref_edges) graph.stage = 'front' SoftplusFusion().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_log')) == 1 and graph.get_op_nodes(name='final_log')[0].op == 'SoftPlus') def test_softplus_fusion_test_wrong_const(self): graph = build_graph_with_edge_attrs( self.nodes, self.edges, {'const_1': { 'value': float_array([0.9999]) }}) graph_ref = graph.copy() graph.stage = 'front' SoftplusFusion().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result') self.assertTrue(flag, resp)
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) 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_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)
class SwishWithSigmoidWithBetaTest(unittest.TestCase): nodes = { **regular_op('input', {'type': 'Parameter'}), **regular_op('beta', {'type': 'Parameter'}), **regular_op('mul_beta', {'op': 'Mul'}), **regular_op('sigmoid', {'op': 'Sigmoid'}), **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}), **result('result'), } edges = [('input', 'mul_beta', {'in': 0, 'out': 0}), ('input', 'mul_2', {'in': 0, 'out': 0}), ('beta', 'mul_beta', {'in': 1, 'out': 0}), ('mul_beta', 'sigmoid', {'in': 0, 'out': 0}), ('sigmoid', 'mul_2', {'in': 1, 'out': 0}), ('mul_2', 'result', {'in': 0, 'out': 0})] def test_swish_with_sigmoid_with_beta_test(self): graph = build_graph_with_edge_attrs(self.nodes, self.edges, {}) new_ref_nodes = ref_nodes.copy() new_ref_nodes.update(**regular_op('beta', {'type': 'Parameter'})) graph_ref = build_graph(new_ref_nodes, ref_edges + [('beta', 'swish')]) graph.stage = 'front' SwishWithSigmoidWithBeta().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 == 'Swish') def test_swish_with_sigmoid_with_beta_different_tensors(self): graph = build_graph_with_edge_attrs({ **regular_op('input', {'type': 'Parameter'}), **regular_op('input_2', {'type': 'Parameter'}), **regular_op('beta', {'type': 'Parameter'}), **regular_op('mul_beta', {'op': 'Mul'}), **regular_op('sigmoid', {'op': 'Sigmoid'}), **regular_op('mul_2', {'op': 'Mul', 'name': 'final_mul'}), **result('result'), }, [('input', 'mul_beta', {'in': 0, 'out': 0}), ('input_2', 'mul_2', {'in': 0, 'out': 0}), ('beta', 'mul_beta', {'in': 1, 'out': 0}), ('mul_beta', 'sigmoid', {'in': 0, 'out': 0}), ('sigmoid', 'mul_2', {'in': 1, 'out': 0}), ('mul_2', 'result', {'in': 0, 'out': 0})], {}) graph_ref = graph.copy() graph.stage = 'front' SwishWithSigmoidWithBeta().find_and_replace_pattern(graph) (flag, resp) = compare_graphs(graph, graph_ref, 'result') self.assertTrue(flag, resp)
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)
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'}), **const_with_data('const1', int64_array(0)), **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)
def test_multi(self): nodes = { **regular_op('input', {'type': 'Parameter'}), **regular_op('some_op', {'type': 'SomeOp', 'name': 'some_op_name'}), **regular_op('fake_output1', {'type': None, 'kind': 'op', 'op': 'FakeOutput', 'name': 'my_output_name1'}), **regular_op('fake_output2', {'type': None, 'kind': 'op', 'op': 'FakeOutput', 'name': 'my_output_name2'}), **const('const1', int64_array(0)), **const('const2', int64_array(0)), **regular_op('add1', {'type': None, 'kind': 'op', 'op': 'Add', 'name': 'my_output_name1'}), **regular_op('add2', {'type': None, 'kind': 'op', 'op': 'Add', 'name': 'my_output_name2'}), **result('result1'), **result('result2'), } edges = [('input', 'some_op'), ('some_op', 'fake_output1'), ('some_op', 'fake_output2'), ('fake_output1', 'result1'), ('fake_output2', 'result2'), ] graph = build_graph(nodes, edges) graph.graph['layout'] = 'NCHW' graph.stage = 'front' edges_ref = [('input', 'some_op'), ('some_op', 'add1'), ('const1', 'add1'), ('some_op', 'add2'), ('const2', 'add2'), ('add1', 'result1'), ('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)
def nodes_dict(original, transformed=None, levels=255, data=None, il=[-127], ih=[127], ol=[-127], oh=[127]): 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) 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( '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', np.array([0])), **valued_const_with_data('scale', np.array([1])), **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() }
def test(self): nodes = { **regular_op('input', {'type': 'Parameter'}), **regular_op('shape', {'type': 'ShapeOf', 'kind': 'op', 'op': 'ShapeOf'}), **regular_op('random_uniform', {'type': 'RandomUniform', 'kind': 'op', 'op': 'RandomUniform', 'name': 'dropout/RU'}), **regular_op('mul', {'type': 'Mul', 'kind': 'op', 'op': 'Mul'}), **regular_op('add', {'type': 'Add', 'kind': 'op', 'op': 'Add'}), **regular_op('add2', {'type': 'Add', 'kind': 'op', 'op': 'Add'}), **regular_op('floor', {'type': 'Floor', 'kind': 'op', 'op': 'Floor'}), 'add_const': {'kind': 'op', 'op': 'Const', 'value': np.array(0.0), 'data_type': np.float32}, **result('result'), # new nodes to be added 'broadcast_const': {'kind': 'op', 'op': 'Const', 'value': np.array(0.5), 'data_type': np.float32}, **regular_op('broadcast', {'type': 'Broadcast', 'kind': 'op', 'op': 'Broadcast'}), } edges = [('input', 'shape'), ('shape', 'random_uniform'), ('random_uniform', 'mul'), ('mul', 'add'), ('add_const', 'add'), ('add', 'add2'), ('add2', 'floor'), ('floor', 'result')] graph = build_graph(nodes, edges, nodes_with_edges_only=True) graph.graph['layout'] = 'NCHW' graph.stage = 'front' DropoutWithRandomUniformReplacer().find_and_replace_pattern(graph) edges_ref = [('input', 'shape'), ('broadcast_const', 'broadcast'), ('shape', 'broadcast'), ('broadcast', 'mul'), ('mul', 'add'), ('add_const', 'add'), ('add', 'add2'), ('add2', 'floor'), ('floor', 'result')] graph_ref = build_graph(nodes, edges_ref, nodes_with_edges_only=True) # check graph structure after the transformation and output name (flag, resp) = compare_graphs(graph, graph_ref, 'result') self.assertTrue(flag, resp) self.assertTrue(graph.node[graph.get_nodes_with_attributes(op='Broadcast')[0]]['name'] == 'dropout/RU')
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_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)