Skip to content

Commit 759b7fd

Browse files
committed
Fix PR comments
1 parent 9a2e4ab commit 759b7fd

File tree

3 files changed

+29
-69
lines changed

3 files changed

+29
-69
lines changed

tests_pytest/_test_util/graph_builder_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def full_attr_name(canonical_name: Union[str, dict, Iterable]):
7070

7171

7272
def build_nbits_qc(a_nbits=8, a_enable=True, w_attr=None, pos_attr=(32, False, ()),
73-
convert_canonical_attr=True) -> CandidateNodeQuantizationConfig:
73+
convert_canonical_attr=True, q_preserving=False) -> CandidateNodeQuantizationConfig:
7474
"""
7575
Build quantization config with configurable nbits and enabling/disabling quantization only.
7676
@@ -87,6 +87,8 @@ def build_nbits_qc(a_nbits=8, a_enable=True, w_attr=None, pos_attr=(32, False, (
8787
Returns:
8888
8989
"""
90+
assert not(a_enable and q_preserving)
91+
9092
w_attr = w_attr or {}
9193
attr_weights_configs_mapping = {
9294
k: AttributeQuantizationConfig(weights_n_bits=v[0], enable_weights_quantization=v[1])
@@ -102,7 +104,7 @@ def build_nbits_qc(a_nbits=8, a_enable=True, w_attr=None, pos_attr=(32, False, (
102104
default_weight_attr_config=AttributeQuantizationConfig(weights_n_bits=pos_attr[0],
103105
enable_weights_quantization=pos_attr[1]),
104106
activation_quantization_method=QuantizationMethod.POWER_OF_TWO,
105-
quantization_preserving=False,
107+
quantization_preserving=q_preserving,
106108
supported_input_activation_n_bits=[2, 4, 8],
107109
fixed_scale=None,
108110
fixed_zero_point=None,

tests_pytest/common_tests/unit_tests/core/graph/test_quantization_preserving_node.py

Lines changed: 6 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -15,70 +15,18 @@
1515
from model_compression_toolkit.core.common import Graph
1616
from model_compression_toolkit.core.common.graph.edge import Edge
1717

18-
from mct_quantizers import QuantizationMethod
19-
from model_compression_toolkit.core import QuantizationConfig
20-
21-
from model_compression_toolkit.core.common.quantization.candidate_node_quantization_config import \
22-
CandidateNodeQuantizationConfig
23-
from model_compression_toolkit.core.common.quantization.node_quantization_config import \
24-
NodeActivationQuantizationConfig, NodeWeightsQuantizationConfig
25-
from model_compression_toolkit.target_platform_capabilities import AttributeQuantizationConfig, OpQuantizationConfig, \
26-
Signedness
27-
28-
from tests_pytest._test_util.graph_builder_utils import build_node
29-
30-
31-
def build_quant_preserving_qc(a_enable=True, qp_enable=False) -> CandidateNodeQuantizationConfig:
32-
"""
33-
Build quantization config with enabling/disabling quantization and quantization preserving only.
34-
35-
Args:
36-
a_enable: whether to enable activation quantization.
37-
qp_enable: whether to enable activation quantization preserving flag.
38-
39-
Returns:
40-
CandidateNodeQuantizationConfig object.
41-
42-
"""
43-
qc = QuantizationConfig()
44-
# positional attrs are set via default weight config (so all pos attrs have the same q config)
45-
op_cfg = OpQuantizationConfig(
46-
# canonical names (as 'kernel')
47-
attr_weights_configs_mapping={},
48-
activation_n_bits=8,
49-
enable_activation_quantization=a_enable,
50-
default_weight_attr_config=AttributeQuantizationConfig(weights_n_bits=8,
51-
enable_weights_quantization=False),
52-
activation_quantization_method=QuantizationMethod.POWER_OF_TWO,
53-
quantization_preserving=qp_enable,
54-
supported_input_activation_n_bits=[2, 4, 8],
55-
fixed_scale=None,
56-
fixed_zero_point=None,
57-
simd_size=None,
58-
signedness=Signedness.AUTO
59-
)
60-
a_qcfg = NodeActivationQuantizationConfig(qc=qc, op_cfg=op_cfg,
61-
activation_quantization_fn=None,
62-
activation_quantization_params_fn=None)
63-
# full names from the layers
64-
w_qcfg = NodeWeightsQuantizationConfig(qc=qc, op_cfg=op_cfg,
65-
weights_channels_axis=None,
66-
node_attrs_list=[])
67-
qc = CandidateNodeQuantizationConfig(activation_quantization_cfg=a_qcfg,
68-
weights_quantization_cfg=w_qcfg)
69-
70-
return qc
18+
from tests_pytest._test_util.graph_builder_utils import build_node, build_nbits_qc
7119

7220

7321
class TestQuantizationPreservingNode:
7422

7523
def test_activation_preserving_candidate(self):
7624
""" Tests that the correct activation quantization candidate is selected. """
77-
n1 = build_node('qact_node', qcs=[build_quant_preserving_qc()])
78-
n2 = build_node('qp1a_node', qcs=[build_quant_preserving_qc(a_enable=False, qp_enable=True)])
79-
n3 = build_node('qp1b_node', qcs=[build_quant_preserving_qc(a_enable=False, qp_enable=True)])
80-
n4 = build_node('qp2a_node', qcs=[build_quant_preserving_qc()])
81-
n5 = build_node('qp2b_node', qcs=[build_quant_preserving_qc(a_enable=False, qp_enable=True)])
25+
n1 = build_node('qact_node', qcs=[build_nbits_qc()])
26+
n2 = build_node('qp1a_node', qcs=[build_nbits_qc(a_enable=False, q_preserving=True)])
27+
n3 = build_node('qp1b_node', qcs=[build_nbits_qc(a_enable=False, q_preserving=True)])
28+
n4 = build_node('qp2a_node', qcs=[build_nbits_qc()])
29+
n5 = build_node('qp2b_node', qcs=[build_nbits_qc(a_enable=False, q_preserving=True)])
8230
graph = Graph('g', input_nodes=[n1], nodes=[n2, n4], output_nodes=[n3, n5],
8331
edge_list=[Edge(n1, n2, 0, 0), Edge(n2, n3, 0, 0),
8432
Edge(n1, n4, 0, 0), Edge(n4, n5, 0, 0)])

tests_pytest/common_tests/unit_tests/core/mixed_precision/resource_utilization_tools/test_resource_utilization_calculator.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)