def find_and_replace_pattern(self, graph: Graph): fifo_qd_shapes = defaultdict(list) for node in graph.get_op_nodes(): if node.op not in ["QueueDequeue", "QueueDequeueV2"]: continue new_inputs = "" fifo_qd_name = node.soft_get('name', node.id) for port_idx, port in node.out_ports().items(): if port.disconnected(): continue if not np_data_type_to_precision( node.types[port_idx]) in SUPPORTED_DATA_TYPES: raise Error("Data type {} is not supported for the" "node {}".format(node.types[port_idx], fifo_qd_name)) fifo_qd_shapes[fifo_qd_name].append( dict(shape=node.shapes[port_idx], out=port_idx, data_type=node.types[port_idx])) new_inputs += "{}:{}, ".format(fifo_qd_name, port_idx) log.error( "Found TF {} operation in the model. " "PLEASE NOTE, the model will contain new input(s) ".format( node.op) + new_inputs + "created due to automatically triggered pruning transformation for this operation.", extra={'is_warning': True}) add_input_ops(graph, fifo_qd_shapes, True)
def test_add_input_with_input_port_before_infer(self): shape = np.array([1, 2, 3, 4]) inputs = {'conv_1': [{'shape': shape, 'in': 0}]} nodes = { 'old_input': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'}, 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'}, 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'}, 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'} } edges = [ ('old_input', 'conv_1'), ('conv_1', 'relu_1'), ('relu_1', 'output') ] graph = build_graph(nodes, edges) add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True) # Check that graph graph_ref = build_graph(nodes, edges, update_attributes={'old_input': {'shape': shape}}) (flag, resp) = compare_graphs(graph, graph_ref, last_node='output') self.assertTrue(flag, resp) # also checks that new old_input was changed new_input = list(graph.in_edges('conv_1'))[0][0] self.assertFalse(graph.node['old_input']['is_input']) self.assertTrue(graph.node[new_input]['is_input']) self.assertTrue((new_input, 'conv_1') in graph.edges()) self.assertTrue(('old_input', 'conv_1') not in graph.edges())
def test_two_inputs_two_shapes_positive_1(self): shape_1 = [1, 2, 3, 4] shape_2 = [4, 3, 2, 1] inputs = {'node_1': [{'shape': shape_1}], 'node_4': [{'shape': shape_2}]} nodes = { 'input_1': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'}, 'input_2': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'}, 'node_1': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'}, 'node_2': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'}, 'node_3': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'}, 'node_4': {'type': 'Identity', 'kind': 'op', 'op': 'NotPlaceholder'}, 'output': {'kind': 'op', 'op': 'Result'} } edges = [ ('input_1', 'node_1'), ('node_1', 'node_2'), ('node_3', 'output'), ('input_2', 'node_4'), ('node_4', 'output') ] graph = build_graph(nodes, edges) add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True) new_input_1 = list(graph.in_edges('node_1'))[0][0] new_input_2 = list(graph.in_edges('node_4'))[0][0] self.assertFalse(graph.node['input_1']['is_input']) self.assertTrue(graph.node[new_input_1]['is_input']) self.assertTrue(graph.node[new_input_2]['is_input']) self.assertTrue((new_input_1, 'node_1') in graph.edges()) self.assertTrue((new_input_2, 'node_4') in graph.edges()) self.assertTrue(strict_compare_tensors(shape_1, graph.node[new_input_1]['shape'])) self.assertTrue(strict_compare_tensors(shape_2, graph.node[new_input_2]['shape']))
def test_one_input_no_shape(self): shape = None inputs = {'conv_1': [{'shape': shape}]} nodes = { 'old_input': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, 'old_input_data': {'kind': 'data', 'value': None, 'shape': np.array([-1, 224, 224, 3])}, 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'}, 'conv_1_data': {'kind': 'data', 'value': True, 'shape': np.array([-1, 224, 224, 3])}, 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'}, 'relu_1_data': {'kind': 'data', 'value': None, 'shape': np.array([-1, 112, 112, 64])}, 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'}, 'output_data': {'name': 'output_data', 'kind': 'data', 'shape': np.array([-1, 112, 112, 64])}, 'op_output': {'kind': 'op', 'op': 'Result'} } edges = [ ('old_input', 'old_input_data'), ('old_input_data', 'conv_1'), ('conv_1', 'conv_1_data'), ('conv_1_data', 'relu_1'), ('relu_1', 'relu_1_data'), ('relu_1_data', 'output'), ('output', 'output_data'), ('output_data', 'op_output') ] graph = build_graph(nodes, edges) graph.stage = 'middle' add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=False) new_input = list(graph.in_edges(list(graph.in_edges('conv_1'))[0][0]))[0][0] new_input_data = list(graph.in_edges('conv_1'))[0][0] self.assertFalse(graph.node['old_input']['is_input']) self.assertTrue(graph.node[new_input]['is_input']) self.assertTrue((new_input_data, 'conv_1') in graph.edges()) self.assertTrue(('old_input_data', 'conv_1') not in graph.edges()) self.assertIsNotNone(graph.node[new_input_data]['shape'])
def test_wrong_input_port_raise(self): graph = build_graph(self.nodes, self.edges) shape = np.array([1, 2, 3, 4]) inputs = {'conv_1': [{'shape': shape, 'in': 5}]} with self.assertRaisesRegex( Error, 'Input port index 5 is out of number of available input ports for node' ): add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
def test_none_out_port_raise(self): graph = build_graph(self.nodes, self.edges) shape = np.array([1, 2, 3, 4]) inputs = {'conv_1': [{'shape': shape, 'out': None}]} with self.assertRaisesRegex( Error, 'Output port for input node conv_1 should be specified, it cannot be None!' ): add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True)
def find_and_replace_pattern(self, graph: Graph): iter_get_next_shapes = defaultdict(list) for iter_get_next in graph.get_op_nodes(op='IteratorGetNext'): iter_get_next_name = iter_get_next.soft_get( 'name', iter_get_next.id) for port in iter_get_next.out_ports(): if not np_data_type_to_precision( iter_get_next.types[port]) in SUPPORTED_DATA_TYPES: raise Error( "In IteratorGetNext node '{}' data type '{}' is not supported" .format(iter_get_next_name, iter_get_next.types[port])) iter_get_next_shapes[iter_get_next_name].append( dict(shape=iter_get_next.shapes[port], out=port, data_type=iter_get_next.types[port])) add_input_ops(graph, iter_get_next_shapes, True)
def test_add_input_with_output_port_after_infer(self): shape = np.array([1, 2, 3, 4]) inputs = {'conv_1': [{'shape': shape, 'out': 0}]} nodes = { 'old_input': {'type': 'Parameter', 'kind': 'op', 'op': 'Parameter'}, 'inp_data' : {'kind': 'data', 'shape': shape + 1}, 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'}, 'conv_data': {'kind': 'data', 'shape': shape, 'value': None, 'data_attr': 'data_attr_value'}, 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'}, } edges = [ ('old_input', 'inp_data'), ('inp_data', 'conv_1'), ('conv_1', 'conv_data'), ('conv_data', 'relu_1', {'edge_attr': 'edge_value'}), ] graph = build_graph(nodes, edges) graph.stage = 'middle' add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=False) graph_ref = build_graph(nodes_attrs={'new_input': {'kind': 'op', 'op': 'Parameter', 'shape': shape}, **nodes}, edges=[('old_input', 'inp_data'), ('inp_data', 'conv_1'), ('new_input', 'conv_data'), ('conv_data', 'relu_1', {'edge_attr': 'edge_value'}), ],) # Check that new input is added right (with right ports !) (flag, resp) = compare_graphs(graph, graph_ref, last_node='relu_1') self.assertTrue(flag, resp) # Check that other graph is not damaged (flag, resp) = compare_graphs(graph, graph_ref, last_node='conv_1') self.assertTrue(flag, resp) # Checks for new input and edges self.assertTrue('conv_1/placeholder_out_port_0' in graph.nodes()) new_input = 'conv_1/placeholder_out_port_0' self.assertTrue(graph.node[new_input]['is_input']) self.assertTrue(Node(graph, 'relu_1').in_node(0)['data_attr'] == 'data_attr_value') self.assertTrue(Node(graph, 'relu_1').in_edge(0)['edge_attr'] == 'edge_value')
def test_add_input_with_output_port_before_infer(self): shape = np.array([1, 2, 3, 4]) inputs = {'conv_1': [{'shape': shape, 'out': 0}]} nodes = { 'old_input': {'type': 'Identity', 'kind': 'op', 'op': 'Parameter'}, 'conv_1': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'}, 'conv_2': {'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder'}, 'relu_1': {'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder'}, 'output': {'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder'} } edges = [ ('old_input', 'conv_1'), ('conv_1', 'relu_1'), ('conv_2', 'relu_1'), ('relu_1', 'output') ] graph = build_graph(nodes, edges) add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True) graph_ref = build_graph(nodes_attrs={'new_input': {'kind': 'op', 'op': 'Parameter', 'shape': shape}, **nodes}, edges=[('new_input', 'relu_1'), ('relu_1', 'output'), ('conv_2', 'relu_1'), ('old_input', 'conv_1'),],) # Check that new input is added right (with right ports !) (flag, resp) = compare_graphs(graph, graph_ref, last_node='output') self.assertTrue(flag, resp) # Check that other graph is not damaged (flag, resp) = compare_graphs(graph, graph_ref, last_node='conv_1') self.assertTrue(flag, resp) # Checks for new input and edges self.assertTrue('conv_1/placeholder_out_port_0' in graph.nodes()) new_input = 'conv_1/placeholder_out_port_0' self.assertTrue(graph.node[new_input]['is_input']) self.assertTrue((new_input, 'relu_1') in graph.edges()) self.assertTrue(('old_input', 'relu_1') not in graph.edges())
def test_one_input_one_shape(self): shape = np.array([1, 2, 3, 4]) inputs = {'conv_1': [{'shape': shape}]} nodes = { 'old_input': { 'type': 'Identity', 'kind': 'op', 'op': 'Parameter' }, 'conv_1': { 'type': 'Convolution', 'kind': 'op', 'op': 'NotPlaceholder' }, 'relu_1': { 'type': 'ReLU', 'kind': 'op', 'op': 'NotPlaceholder' }, 'output': { 'type': 'SoftMax', 'kind': 'op', 'op': 'NotPlaceholder' } } edges = [('old_input', 'conv_1'), ('conv_1', 'relu_1'), ('relu_1', 'output')] graph = build_graph(nodes, edges) add_input_ops(graph=graph, user_defined_inputs=inputs, before_infer=True) new_input = list(graph.in_edges('conv_1'))[0][0] self.assertFalse(graph.node['old_input']['is_input']) self.assertTrue(graph.node[new_input]['is_input']) self.assertTrue((new_input, 'conv_1') in graph.edges()) self.assertTrue(('old_input', 'conv_1') not in graph.edges()) shapes_are_equal = np.array_equal(graph.node[new_input]['shape'], shape) self.assertTrue(shapes_are_equal)
def find_and_replace_pattern(self, graph: Graph): add_input_ops(graph, graph.graph['user_shapes'], False)