def test_build_quantizer_propagation_state_graph_from_ip_graph(self): ip_graph = InsertionPointGraph(get_two_branch_mock_model_graph()) quant_prop_graph = QPSG(ip_graph) assert len(ip_graph.nodes) == len(quant_prop_graph.nodes) assert len(ip_graph.edges) == len(quant_prop_graph.edges) for ip_graph_node_key, ip_graph_node in ip_graph.nodes.items(): qpg_node = quant_prop_graph.nodes[ip_graph_node_key] assert qpg_node[QPSG.NODE_TYPE_NODE_ATTR] == QPSG.ipg_node_type_to_qpsg_node_type(ip_graph_node[ InsertionPointGraph.NODE_TYPE_NODE_ATTR]) qpg_node_type = qpg_node[QPSG.NODE_TYPE_NODE_ATTR] if qpg_node_type == QuantizerPropagationStateGraphNodeType.INSERTION_POINT: assert qpg_node[QPSG.PROPAGATING_QUANTIZER_NODE_ATTR] is None assert not qpg_node[QPSG.AFFECTING_PROPAGATING_QUANTIZERS_ATTR] assert qpg_node[QPSG.INSERTION_POINT_DATA_NODE_ATTR] == ip_graph_node[ InsertionPointGraph.INSERTION_POINT_DATA_NODE_ATTR] elif qpg_node_type == QuantizerPropagationStateGraphNodeType.OPERATOR: assert not qpg_node[QPSG.ALLOWED_INPUT_QUANTIZATION_TYPES_NODE_ATTR] assert qpg_node[QPSG.QUANTIZATION_TRAIT_NODE_ATTR] == QuantizationTrait.NON_QUANTIZABLE assert not qpg_node[QPSG.AFFECTING_PROPAGATING_QUANTIZERS_ATTR] for from_node, to_node, edge_data in ip_graph.edges(data=True): qpg_edge_data = quant_prop_graph.edges[from_node, to_node] assert not qpg_edge_data[QPSG.AFFECTING_PROPAGATING_QUANTIZERS_ATTR] for key, value in edge_data.items(): assert qpg_edge_data[key] == value quant_prop_graph.run_consistency_check()
def mock_qp_graph(): ip_graph = InsertionPointGraph(get_two_branch_mock_model_graph()) qpsg = QPSG(ip_graph) qpsg.skip_check = False yield qpsg if not qpsg.skip_check: qpsg.run_consistency_check()
def test_merge_redundant_subsequent_quantizers_across_graph(self, model_graph_qpsg: QPSG, redundant_pq_merge_test_struct: RedundantQuantizerMergeTestStruct): model_graph_qpsg = redundant_pq_merge_test_struct.prepare_qpsg_state(model_graph_qpsg) model_graph_qpsg.merge_redundant_subsequent_quantizers_across_graph() remaining_pqs = model_graph_qpsg.collect_all_propagating_quantizers() ref_remaining_pq_positions = redundant_pq_merge_test_struct.ref_remaining_pq_positions for pq in remaining_pqs: assert pq.current_location_node_key in ref_remaining_pq_positions assert len(remaining_pqs) == len(ref_remaining_pq_positions)
def _setup_and_propagate_quantizers(self, qpsg: QPSG) -> QPSG: pq_1 = qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('F')) qpsg.propagate_quantizer_via_path(pq_1, [ (InsertionPointGraph.get_post_hook_node_key('C'), InsertionPointGraph.get_pre_hook_node_key('F')) ]) _ = qpsg.add_propagating_quantizer([QuantizerConfig(bits=6)], InsertionPointGraph.get_pre_hook_node_key('F')) return qpsg
def test_merge_quantizer_into_path(self, merge_quantizer_into_path_test_struct): mock_graph = self.get_model_graph() ip_graph = InsertionPointGraph(mock_graph) quant_prop_graph = QPSG(ip_graph) for quantizers_test_struct in merge_quantizer_into_path_test_struct.start_set_quantizers: init_node_to_trait_and_configs_dict = quantizers_test_struct.init_node_to_trait_and_configs_dict starting_quantizer_ip_node = quantizers_test_struct.starting_quantizer_ip_node target_node = quantizers_test_struct.target_node_for_quantizer is_merged = quantizers_test_struct.is_merged prop_path = quantizers_test_struct.prop_path for node in quant_prop_graph.nodes.values(): node[ QPSG. QUANTIZATION_TRAIT_NODE_ATTR] = QuantizationTrait.QUANTIZATION_AGNOSTIC master_prop_quant = None merged_prop_quant = [] for node_key, trait_and_configs_tuple in init_node_to_trait_and_configs_dict.items( ): trait = trait_and_configs_tuple[0] qconfigs = trait_and_configs_tuple[1] quant_prop_graph.nodes[node_key][ QPSG.QUANTIZATION_TRAIT_NODE_ATTR] = trait if trait == QuantizationTrait.INPUTS_QUANTIZABLE: ip_node_key = InsertionPointGraph.get_pre_hook_node_key( node_key) prop_quant = quant_prop_graph.add_propagating_quantizer( qconfigs, ip_node_key) if ip_node_key == starting_quantizer_ip_node: master_prop_quant = prop_quant path = get_edge_paths_for_propagation(quant_prop_graph, target_node, starting_quantizer_ip_node) master_prop_quant = quant_prop_graph.propagate_quantizer_via_path( master_prop_quant, path[0]) if is_merged: merged_prop_quant.append((master_prop_quant, prop_path)) for prop_quant, prop_path in merged_prop_quant: quant_prop_graph.merge_quantizer_into_path(prop_quant, prop_path) expected_quantizers_test_struct = merge_quantizer_into_path_test_struct.expected_set_quantizers self.check_final_state_qpsg(quant_prop_graph, expected_quantizers_test_struct)
def _setup_and_propagate_quantizers(self, qpsg: QPSG) -> QPSG: # This case will fail if, after going depth-first through the 'D' branch of the graph, # the merge traversal function state is not reset (which is incorrect behavior) # when starting to traverse the 'C' branch. qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('I', in_port_id=0)) qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('I', in_port_id=1)) qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('C')) qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('D')) return qpsg
def _setup_and_propagate_quantizers(self, qpsg: QPSG) -> QPSG: pq_1 = qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('C')) pq_2 = qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('D')) qpsg.merge_quantizers_for_branching_node([pq_1, pq_2], [QuantizerConfig()], [None, None], InsertionPointGraph.get_post_hook_node_key('B')) qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('E')) return qpsg
def _setup_and_propagate_quantizers(self, qpsg: QPSG) -> QPSG: pq_1 = qpsg.add_propagating_quantizer([QuantizerConfig(per_channel=True)], InsertionPointGraph.get_pre_hook_node_key('C')) pq_2 = qpsg.add_propagating_quantizer([QuantizerConfig(per_channel=True)], InsertionPointGraph.get_pre_hook_node_key('D')) qpsg.merge_quantizers_for_branching_node([pq_1, pq_2], [QuantizerConfig(per_channel=True)], [None, None], InsertionPointGraph.get_post_hook_node_key('B')) pq_3 = qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('E')) paths = get_edge_paths_for_propagation(qpsg, InsertionPointGraph.get_pre_hook_node_key('D'), InsertionPointGraph.get_pre_hook_node_key('E')) path = paths[0] qpsg.propagate_quantizer_via_path(pq_3, path) return qpsg
def _setup_and_propagate_quantizers(self, qpsg: QPSG) -> QPSG: qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('B')) qpsg.add_propagating_quantizer([QuantizerConfig()], InsertionPointGraph.get_pre_hook_node_key('E')) return qpsg