@@ -298,9 +298,10 @@ class TestComputeActivationTensorsUtilization:
298298 """ Tests for activation tensors utilization public apis. """
299299 def test_compute_node_activation_tensor_utilization (self , graph_mock , fw_impl_mock , fw_info_mock ):
300300 mp_reuse = build_node ('mp_reuse' , output_shape = (None , 3 , 14 ), qcs = [build_qc (4 ), build_qc (16 )], reuse = True )
301+ qp = build_node ('qp' , output_shape = (None , 15 , 9 ), qcs = [build_qc (a_enable = False , q_preserving = True )])
301302 noq = build_node ('noq' , output_shape = (None , 15 , 9 ), qcs = [build_qc (a_enable = False )])
302- graph_mock .nodes = [mp_reuse , noq ]
303- graph_mock .retrieve_preserved_quantization_node = _identity_func
303+ graph_mock .nodes = [mp_reuse , qp , noq ]
304+ graph_mock .retrieve_preserved_quantization_node = lambda n : mp_reuse if n is qp else n
304305
305306 ru_calc = ResourceUtilizationCalculator (graph_mock , fw_impl_mock , fw_info_mock )
306307 # _get_activation_nbits is already fully checked, just make sure we use it, and use correctly
@@ -313,6 +314,9 @@ def test_compute_node_activation_tensor_utilization(self, graph_mock, fw_impl_mo
313314 # reused is not ignored
314315 res = ru_calc .compute_node_activation_tensor_utilization (mp_reuse , TIC .QConfigurable , BM .QMinBit )
315316 assert res == Utilization (42 , 21. )
317+ # quantization preserving uses custom_qc.
318+ res = ru_calc .compute_node_activation_tensor_utilization (qp , TIC .AnyQuantized , BM .QCustom , custom_qc )
319+ assert res == Utilization (135 , 270. )
316320 # not a target node
317321 res = ru_calc .compute_node_activation_tensor_utilization (noq , TIC .AnyQuantized , BM .QCustom , custom_qc )
318322 assert res == Utilization (0 , 0 )
@@ -394,11 +398,14 @@ def test_compute_cuts_integration(self, graph_mock, fw_impl_mock, fw_info_mock,
394398 """ Test integration with max cut computation. """
395399 # Test a simple linear dummy graph with the real max cut computation.
396400 n1 = build_node ('n1' , qcs = [build_qc ()], input_shape = (None , 10 , 20 , 3 ), output_shape = (None , 10 , 20 , 3 ))
401+ n1_qp = build_node ('n1_qp' , qcs = [build_qc (a_enable = False , q_preserving = True )],
402+ input_shape = (None , 10 , 20 , 3 ), output_shape = (None , 10 , 20 , 3 ))
397403 n2 = build_node ('n2' , qcs = [build_qc ()], input_shape = (None , 10 , 20 , 3 ), output_shape = (None , 5 , 10 ))
398404 n3 = build_node ('n3' , qcs = [build_qc ()], input_shape = (None , 5 , 10 ), output_shape = (None , 5 , 10 ))
399405 n4 = build_node ('n4' , qcs = [build_qc ()], input_shape = (None , 5 , 10 , 32 ), output_shape = (None , 5 , 10 , 32 ))
400- edges = [Edge (n1 , n2 , 0 , 0 ), Edge (n2 , n3 , 0 , 0 ), Edge (n3 , n4 , 0 , 0 )]
401- graph = Graph ('g' , input_nodes = [n1 ], nodes = [n2 , n3 ], output_nodes = [n4 ], edge_list = edges )
406+ edges = [Edge (n1 , n1_qp , 0 , 0 ), Edge (n1_qp , n2 , 0 , 0 ),
407+ Edge (n2 , n3 , 0 , 0 ), Edge (n3 , n4 , 0 , 0 )]
408+ graph = Graph ('g' , input_nodes = [n1 ], nodes = [n1_qp , n2 , n3 ], output_nodes = [n4 ], edge_list = edges )
402409 ru_calc = ResourceUtilizationCalculator (graph , fw_impl_mock , fw_info_mock )
403410 # wrap the real implementation
404411 maxcut_spy = mocker .patch ('model_compression_toolkit.core.common.mixed_precision.resource_utilization_tools.'
@@ -408,11 +415,11 @@ def test_compute_cuts_integration(self, graph_mock, fw_impl_mock, fw_info_mock,
408415 cuts_cache = ru_calc .cuts
409416
410417 # verify the cache
411- assert len (cuts_cache ) == 5
418+ assert len (cuts_cache ) == 6
412419 assert all (isinstance (k , Cut ) for k in cuts_cache .keys ())
413420 # for each cut we save a list of its nodes
414421 cuts_nodes = {tuple (sorted (n .name for n in nodes )) for nodes in cuts_cache .values ()}
415- assert cuts_nodes == {('n1' ,), ('n4' ,), ('n1' , 'n2' ), ('n2' , 'n3' ), ('n3' , 'n4' )}
422+ assert cuts_nodes == {('n1' ,), ('n4' ,), ('n1' , 'n1_qp' ), ( 'n1_qp' , ' n2' ), ('n2' , 'n3' ), ('n3' , 'n4' )}
416423
417424 # verify cuts computation only happens the first time
418425 cuts_cache2 = ru_calc .cuts
@@ -423,7 +430,8 @@ def test_compute_cuts_integration(self, graph_mock, fw_impl_mock, fw_info_mock,
423430 nodes_to_cuts = {tuple (sorted (elem .node_name for elem in cut .mem_elements .elements )): cut
424431 for cut in cuts_cache .keys ()}
425432 cut1 = nodes_to_cuts [('n1' ,)]
426- cut12 = nodes_to_cuts [('n1' , 'n2' )]
433+ cut11 = nodes_to_cuts [('n1' , 'n1_qp' )]
434+ cut12 = nodes_to_cuts [('n1_qp' , 'n2' )]
427435 cut23 = nodes_to_cuts [('n2' , 'n3' )]
428436 cut34 = nodes_to_cuts [('n3' , 'n4' )]
429437 cut4 = nodes_to_cuts [('n4' ,)]
@@ -433,7 +441,8 @@ def test_compute_cuts_integration(self, graph_mock, fw_impl_mock, fw_info_mock,
433441 bitwidth_mode = BM .QDefaultSP )
434442
435443 assert per_cut_per_node == {cut1 : {'n1' : Utilization (10 * 20 * 3 , 600 )},
436- cut12 : {'n1' : Utilization (10 * 20 * 3 , 600 ),
444+ cut11 : {'n1' : Utilization (10 * 20 * 3 , 600 ), 'n1_qp' : Utilization (10 * 20 * 3 , 600 )},
445+ cut12 : {'n1_qp' : Utilization (10 * 20 * 3 , 600 ),
437446 'n2' : Utilization (5 * 10 , 50 )},
438447 cut23 : {'n2' : Utilization (5 * 10 , 50 ),
439448 'n3' : Utilization (5 * 10 , 50 )},
@@ -442,7 +451,8 @@ def test_compute_cuts_integration(self, graph_mock, fw_impl_mock, fw_info_mock,
442451 cut4 : {'n4' : Utilization (5 * 10 * 32 , 1600 )}}
443452 assert per_cut == {
444453 nodes_to_cuts [('n1' ,)]: Utilization (600 , 600 ),
445- nodes_to_cuts [('n1' , 'n2' )]: Utilization (650 , 650 ),
454+ nodes_to_cuts [('n1' , 'n1_qp' )]: Utilization (1200 , 1200 ),
455+ nodes_to_cuts [('n1_qp' , 'n2' )]: Utilization (650 , 650 ),
446456 nodes_to_cuts [('n2' , 'n3' )]: Utilization (100 , 100 ),
447457 nodes_to_cuts [('n3' , 'n4' )]: Utilization (1650 , 1650 ),
448458 nodes_to_cuts [('n4' ,)]: Utilization (1600 , 1600 )
0 commit comments