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)
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 find_and_replace_pattern(self, graph: Graph): fw = graph.graph['fw'] argv = graph.graph['cmd_params'] layout = graph.graph['layout'] for_graph_and_each_sub_graph_recursively(graph, fuse_pad) for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up()) # Mark nodes with attr 'can_be_fused': False to disable fusing for specified nodes for_graph_and_each_sub_graph_recursively(graph, lambda graph: mark_unfused_nodes(graph, argv.finegrain_fusing)) # 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 not argv.disable_fusing: 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()) if not argv.disable_gfusing: for_graph_and_each_sub_graph_recursively(graph, grouped_convolutions_fusing) for_graph_and_each_sub_graph_recursively(graph, lambda G: G.clean_up()) if not argv.disable_fusing: 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()) 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' and not argv.disable_resnet_optimization: stride_optimization(graph)