mct-nightly 2.3.0.20250325.524__py3-none-any.whl → 2.3.0.20250327.514__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mct-nightly
3
- Version: 2.3.0.20250325.524
3
+ Version: 2.3.0.20250327.514
4
4
  Summary: A Model Compression Toolkit for neural networks
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -1,6 +1,6 @@
1
- mct_nightly-2.3.0.20250325.524.dist-info/licenses/LICENSE.md,sha256=aYSSIb-5AFPeITTvXm1UAoe0uYBiMmSS8flvXaaFUks,10174
2
- model_compression_toolkit/__init__.py,sha256=QA19v194uXWUuLFh_Bg-8ll7InFUcGC8RGNV-Gi7qcc,1557
3
- model_compression_toolkit/constants.py,sha256=i_R6uXBfO1ph_X6DNJych2x59SUojfJbn7dNjs_mZnc,3846
1
+ mct_nightly-2.3.0.20250327.514.dist-info/licenses/LICENSE.md,sha256=aYSSIb-5AFPeITTvXm1UAoe0uYBiMmSS8flvXaaFUks,10174
2
+ model_compression_toolkit/__init__.py,sha256=kFad6b1992lrDWgleUg7OrJ6tqRaPUdWmvgibttVDTE,1557
3
+ model_compression_toolkit/constants.py,sha256=2ltuH-gdaLZoZV4CPUgKjC3S9ojz2z4OTVdenyVEypU,3912
4
4
  model_compression_toolkit/defaultdict.py,sha256=LSc-sbZYXENMCw3U9F4GiXuv67IKpdn0Qm7Fr11jy-4,2277
5
5
  model_compression_toolkit/logger.py,sha256=L3q7tn3Uht0i_7phnlOWMR2Te2zvzrt2HOz9vYEInts,4529
6
6
  model_compression_toolkit/metadata.py,sha256=x_Bk4VpzILdsFax6--CZ3X18qUTP28sbF_AhoQW8dNc,4003
@@ -40,7 +40,7 @@ model_compression_toolkit/core/common/graph/edge.py,sha256=buoSEUZwilWBK3WeBKpJ-
40
40
  model_compression_toolkit/core/common/graph/functional_node.py,sha256=GH5wStmw8SoAj5IdT_-ItN1Meo_P5NUTt_5bgJC4fak,3935
41
41
  model_compression_toolkit/core/common/graph/graph_matchers.py,sha256=CrDoHYq4iPaflgJWmoJ1K4ziLrRogJvFTVWg8P0UcDU,4744
42
42
  model_compression_toolkit/core/common/graph/graph_searches.py,sha256=2oKuW6L8hP-oL0lFO9PhQFt9fEFgVJwpc1u4fHExAtE,5128
43
- model_compression_toolkit/core/common/graph/virtual_activation_weights_node.py,sha256=gPlGMyC5jdUTQy8jYU_Rz7cPXSH6JhV4Dnwt3-1FAKM,9849
43
+ model_compression_toolkit/core/common/graph/virtual_activation_weights_node.py,sha256=JH33qnHTaqFXcYSzTVMpDc9N93503y2pY3hiVJELuZI,10704
44
44
  model_compression_toolkit/core/common/graph/memory_graph/__init__.py,sha256=cco4TmeIDIh32nj9ZZXVkws4dd9F2UDrmjKzTN8G0V0,697
45
45
  model_compression_toolkit/core/common/graph/memory_graph/bipartite_graph.py,sha256=X6FK3C3y8ixFRPjC_wm3ClloCX8_06SOdA1TRi7o_LA,3800
46
46
  model_compression_toolkit/core/common/graph/memory_graph/compute_graph_max_cut.py,sha256=oyz260JXDbvL8aI-DVtUvLHtLRWC2Yu4SBYlGL68c2Y,3498
@@ -101,7 +101,7 @@ model_compression_toolkit/core/common/pruning/mask/__init__.py,sha256=huHoBUcKNB
101
101
  model_compression_toolkit/core/common/pruning/mask/per_channel_mask.py,sha256=77DB1vqq_gHwbUjeCHRaq1Q-V4wEtdVdwkGezcZgToA,5021
102
102
  model_compression_toolkit/core/common/pruning/mask/per_simd_group_mask.py,sha256=_LcDAxLeC5I0KdMHS8jib5XxIKO2ZLavXYuSMIPIQBo,5868
103
103
  model_compression_toolkit/core/common/quantization/__init__.py,sha256=sw7LOPN1bM82o3SkMaklyH0jw-TLGK0-fl2Wq73rffI,697
104
- model_compression_toolkit/core/common/quantization/bit_width_config.py,sha256=YfZKUUeqRp5K5W6wmTOcFZR-MhxdbmtpC8k7IVXU_j4,4666
104
+ model_compression_toolkit/core/common/quantization/bit_width_config.py,sha256=0HA3CIZW-ZrA55ra-yJXRvAYnoR8i1SjpbnMDKcWYNQ,12819
105
105
  model_compression_toolkit/core/common/quantization/candidate_node_quantization_config.py,sha256=u7uueixA5wi3eYPrZKtLVxogkmgcgFL1w2pzMfd_ToU,4950
106
106
  model_compression_toolkit/core/common/quantization/core_config.py,sha256=yxCzWqldcHoe8GGxrH0tp99bhrc5jDT7SgZftnMUUBE,2374
107
107
  model_compression_toolkit/core/common/quantization/debug_config.py,sha256=zJP2W9apUPX9RstpPWWK71wr9xJsg7j-s7lGV4_bQdc,1510
@@ -112,7 +112,7 @@ model_compression_toolkit/core/common/quantization/quantization_fn_selection.py,
112
112
  model_compression_toolkit/core/common/quantization/quantization_params_fn_selection.py,sha256=7eG7dl1TcbdnHwgmvyjarxLs0o6Lw_9VAjXAm4rsiBk,3791
113
113
  model_compression_toolkit/core/common/quantization/quantize_graph_weights.py,sha256=N005MSvx8UypVpa7XrxNrB2G732n2wHj3RmLyjTgd3I,2728
114
114
  model_compression_toolkit/core/common/quantization/quantize_node.py,sha256=cdzGNWfT4MRogIU8ehs0tr3lVjnzAI-jeoS9b4TwVBo,2854
115
- model_compression_toolkit/core/common/quantization/set_node_quantization_config.py,sha256=mR6kNfjz6s6EnJJd0ZeUzcjP1qq8w16YRtenTq9OtyQ,21330
115
+ model_compression_toolkit/core/common/quantization/set_node_quantization_config.py,sha256=u0pVJawyUTgatn2L8qMNBac2Cut3HSPZSytBGDuBB0k,21341
116
116
  model_compression_toolkit/core/common/quantization/quantization_params_generation/__init__.py,sha256=eCDGwsWYLU6z7qbEVb4TozMW_nd5VEP_iCJ6PcvyEPw,1486
117
117
  model_compression_toolkit/core/common/quantization/quantization_params_generation/error_functions.py,sha256=_m-XkEMJMHf0gYwVIXAoHVjdRa2NXt_gYdwBlw76ZR8,24031
118
118
  model_compression_toolkit/core/common/quantization/quantization_params_generation/lut_kmeans_params.py,sha256=RL-PklAjGyC-26anSt8fU07a6pB_LBQFQy9o4e9giN0,8739
@@ -526,7 +526,7 @@ model_compression_toolkit/xquant/pytorch/model_analyzer.py,sha256=b93o800yVB3Z-i
526
526
  model_compression_toolkit/xquant/pytorch/pytorch_report_utils.py,sha256=UVN_S9ULHBEldBpShCOt8-soT8YTQ5oE362y96qF_FA,3950
527
527
  model_compression_toolkit/xquant/pytorch/similarity_functions.py,sha256=CERxq5K8rqaiE-DlwhZBTUd9x69dtYJlkHOPLB54vm8,2354
528
528
  model_compression_toolkit/xquant/pytorch/tensorboard_utils.py,sha256=mkoEktLFFHtEKzzFRn_jCnxjhJolK12TZ5AQeDHzUO8,9767
529
- mct_nightly-2.3.0.20250325.524.dist-info/METADATA,sha256=AhiPNPdqyMvdK9V7IcGS0EUifEcnl9RhI_IsME0A5-U,27098
530
- mct_nightly-2.3.0.20250325.524.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
531
- mct_nightly-2.3.0.20250325.524.dist-info/top_level.txt,sha256=gsYA8juk0Z-ZmQRKULkb3JLGdOdz8jW_cMRjisn9ga4,26
532
- mct_nightly-2.3.0.20250325.524.dist-info/RECORD,,
529
+ mct_nightly-2.3.0.20250327.514.dist-info/METADATA,sha256=K55wi2oh756TtflrXc2PsNWrzPqiTzTRWMoylK-kILk,27098
530
+ mct_nightly-2.3.0.20250327.514.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
531
+ mct_nightly-2.3.0.20250327.514.dist-info/top_level.txt,sha256=gsYA8juk0Z-ZmQRKULkb3JLGdOdz8jW_cMRjisn9ga4,26
532
+ mct_nightly-2.3.0.20250327.514.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.0.2)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -27,4 +27,4 @@ from model_compression_toolkit import data_generation
27
27
  from model_compression_toolkit import pruning
28
28
  from model_compression_toolkit.trainable_infrastructure.keras.load_model import keras_load_quantized_model
29
29
 
30
- __version__ = "2.3.0.20250325.000524"
30
+ __version__ = "2.3.0.20250327.000514"
@@ -57,6 +57,8 @@ FLOAT_BITWIDTH = 32
57
57
  # In Mixed-Precision, a node can have multiple candidates for weights and activations quantization configuration.
58
58
  # In order to display a single view of a node (for example, for logging in TensorBoard) we need to track the attributes
59
59
  # that are shared among different candidates:
60
+ WEIGHTS_ATTRIBUTE = 'weights'
61
+ ACTIVATION_ATTRIBUTE = 'activation'
60
62
  WEIGHTS_NBITS_ATTRIBUTE = 'weights_n_bits'
61
63
  CORRECTED_BIAS_ATTRIBUTE = 'corrected_bias'
62
64
  ACTIVATION_N_BITS_ATTRIBUTE = 'activation_n_bits'
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
+ import uuid
15
16
 
16
17
  from typing import Dict, Any, Tuple
17
18
 
@@ -139,23 +140,34 @@ class VirtualActivationWeightsNode(BaseNode):
139
140
  """
140
141
  # Validate weights node
141
142
  kernel_attrs = fw_info.get_kernel_op_attributes(weights_node.type)
142
- assert len(kernel_attrs) == 1 and kernel_attrs[0] is not None, 'Expected exactly one kernel attr.'
143
+ assert len(kernel_attrs) == 1 and kernel_attrs[0] is not None, f'Expected exactly one kernel attr, {kernel_attrs}'
143
144
  kernel_attr = kernel_attrs[0]
144
145
  conf_weights = [attr for attr in weights_node.weights if weights_node.is_configurable_weight(attr)]
145
146
  if len(conf_weights) > 1 or len(conf_weights) == 1 and not weights_node.is_configurable_weight(kernel_attr):
146
- raise NotImplementedError('Only kernel weight can be configurable.') # pragma: no cover
147
+ raise NotImplementedError(f'Only kernel weight can be configurable. Got configurable {conf_weights}.')
147
148
 
148
- weights = weights_node.weights
149
+ weights = weights_node.weights.copy()
150
+ act_node_w_rename = {}
149
151
  if act_node.weights:
150
- assert fw_info.get_kernel_op_attributes(act_node)[0] is None, \
151
- f'Node {act_node} with kernel cannot be used as activation for VirtualActivationWeightsNode.'
152
- if set(weights_node.weights.keys()).intersection(set(act_node.weights.keys())):
153
- raise ValueError('Activation and weight nodes are not expected to have the same weight attribute') # pragma: no cover
152
+ if not fw_info.get_kernel_op_attributes(act_node)[0] is None:
153
+ raise NotImplementedError(f'Node {act_node} with kernel cannot be used as activation for '
154
+ f'VirtualActivationWeightsNode.')
154
155
  if act_node.has_any_configurable_weight():
155
- raise NotImplementedError('Node with a configurable weight cannot be used as activation for '
156
- 'VirtualActivationWeightsNode.') # pragma: no cover
156
+ raise NotImplementedError(f'Node {act_node} with a configurable weight cannot be used as activation for '
157
+ 'VirtualActivationWeightsNode.')
157
158
  # combine weights from activation and weights
158
- weights.update(act_node.weights)
159
+ for w_id, w in act_node.weights.items():
160
+ if w_id not in weights and not (isinstance(w_id, str) and kernel_attr in w_id):
161
+ weights[w_id] = w
162
+ continue
163
+ # if same identifier is used as in weight nodes (or contains the kernel substring), generate a new
164
+ # unique id. If positional, generate a new (and clearly made up) index.
165
+ # This only serves for resource utilization computation so in theory this shouldn't matter, as long as
166
+ # quantization config dict keys are updated accordingly.
167
+ uniq_id = uuid.uuid4().hex[:8] if isinstance(w_id, str) else (100 + w_id)
168
+ assert uniq_id not in weights
169
+ act_node_w_rename[w_id] = uniq_id
170
+ weights[uniq_id] = w
159
171
 
160
172
  name = f"{VIRTUAL_ACTIVATION_WEIGHTS_NODE_PREFIX}_{act_node.name}_{weights_node.name}"
161
173
  super().__init__(name,
@@ -181,10 +193,12 @@ class VirtualActivationWeightsNode(BaseNode):
181
193
  if act_node.weights:
182
194
  # add non-kernel weights cfg from activation node to the composed node's weights cfg
183
195
  composed_candidate.weights_quantization_cfg.attributes_config_mapping.update(
184
- c_a.weights_quantization_cfg.attributes_config_mapping
196
+ {act_node_w_rename.get(k, k): v
197
+ for k, v in c_a.weights_quantization_cfg.attributes_config_mapping.items()}
185
198
  )
186
199
  composed_candidate.weights_quantization_cfg.pos_attributes_config_mapping.update(
187
- c_a.weights_quantization_cfg.pos_attributes_config_mapping
200
+ {act_node_w_rename.get(k, k): v
201
+ for k, v in c_a.weights_quantization_cfg.pos_attributes_config_mapping.items()}
188
202
  )
189
203
  v_candidates.append(composed_candidate)
190
204
 
@@ -19,19 +19,31 @@ from model_compression_toolkit.core.common import Graph
19
19
  from model_compression_toolkit.core.common.matchers.node_matcher import BaseNodeMatcher
20
20
  from model_compression_toolkit.logger import Logger
21
21
 
22
+ from model_compression_toolkit.core.common.graph.base_node import WeightAttrT
22
23
 
23
24
  @dataclass
24
25
  class ManualBitWidthSelection:
25
26
  """
26
- Class to encapsulate the manual bit width selection configuration for a specific filter.
27
+ Class to encapsulate the manual bit width selection configuration for a specific filter.
27
28
 
28
- Attributes:
29
+ Attributes:
29
30
  filter (BaseNodeMatcher): The filter used to select nodes for bit width manipulation.
30
31
  bit_width (int): The bit width to be applied to the selected nodes.
31
- """
32
+ """
32
33
  filter: BaseNodeMatcher
33
34
  bit_width: int
34
35
 
36
+ @dataclass
37
+ class ManualWeightsBitWidthSelection(ManualBitWidthSelection):
38
+ """
39
+ Class to encapsulate the manual weights bit width selection configuration for a specific filter.
40
+
41
+ Attributes:
42
+ filter (BaseNodeMatcher): The filter used to select nodes for bit width manipulation.
43
+ bit_width (int): The bit width to be applied to the selected nodes.
44
+ attr (str): The filtered node's attributes to apply bit-width manipulation to.
45
+ """
46
+ attr: WeightAttrT
35
47
 
36
48
  @dataclass
37
49
  class BitWidthConfig:
@@ -39,35 +51,64 @@ class BitWidthConfig:
39
51
  Class to manage manual bit-width configurations.
40
52
 
41
53
  Attributes:
42
- manual_activation_bit_width_selection_list (List[ManualBitWidthSelection]): A list of ManualBitWidthSelection objects defining manual bit-width configurations.
54
+ manual_activation_bit_width_selection_list (List[ManualBitWidthSelection]): A list of ManualBitWidthSelection objects for activation defining manual bit-width configurations.
55
+ manual_weights_bit_width_selection_list (List[ManualWeightsBitWidthSelection]): A list of ManualWeightsBitWidthSelection for weights objects defining manual bit-width configurations.
43
56
  """
44
57
  manual_activation_bit_width_selection_list: List[ManualBitWidthSelection] = field(default_factory=list)
58
+ manual_weights_bit_width_selection_list: List[ManualWeightsBitWidthSelection] = field(default_factory=list)
45
59
 
46
60
  def set_manual_activation_bit_width(self,
47
- filters: Union[List[BaseNodeMatcher], BaseNodeMatcher],
48
- bit_widths: Union[List[int], int]):
61
+ filters: Union[List[BaseNodeMatcher], BaseNodeMatcher],
62
+ bit_widths: Union[List[int], int]):
49
63
  """
50
- Add a manual bit-width selection to the configuration.
64
+ Add a manual bit-width selection for activation to the configuration.
51
65
 
52
66
  Args:
53
- filter (Union[List[BaseNodeMatcher], BaseNodeMatcher]): The filters used to select nodes for bit-width manipulation.
54
- bit_width (Union[List[int], int]): The bit widths to be applied to the selected nodes.
67
+ filters (Union[List[BaseNodeMatcher], BaseNodeMatcher]): The filters used to select nodes for bit-width manipulation.
68
+ bit_widths (Union[List[int], int]): The bit widths to be applied to the selected nodes.
55
69
  If a single value is given it will be applied to all the filters
56
70
  """
57
- filters = [filters] if not isinstance(filters, list) else filters
58
- bit_widths = [bit_widths] if not isinstance(bit_widths, list) else bit_widths
59
- if len(bit_widths) > 1 and len(bit_widths) != len(filters):
60
- Logger.critical(f"Configuration Error: The number of provided bit_width values {len(bit_widths)} "
61
- f"must match the number of filters {len(filters)}, or a single bit_width value "
62
- f"should be provided for all filters.")
63
- elif len(bit_widths) == 1 and len(filters) > 1:
64
- bit_widths = [bit_widths[0] for f in filters]
71
+ if filters is None:
72
+ Logger.critical(f"The filters cannot be None.")
73
+ _, bit_widths, filters = self._expand_to_list(filters, bit_widths)
65
74
  for bit_width, filter in zip (bit_widths, filters):
66
75
  self.manual_activation_bit_width_selection_list += [ManualBitWidthSelection(filter, bit_width)]
67
76
 
68
- def get_nodes_to_manipulate_bit_widths(self, graph: Graph) -> Dict:
77
+ def set_manual_weights_bit_width(self,
78
+ filters: Union[List[BaseNodeMatcher], BaseNodeMatcher],
79
+ bit_widths: Union[List[int], int],
80
+ attrs: Union[List[WeightAttrT], WeightAttrT]):
81
+ """
82
+ Add a manual bit-width selection for weights to the configuration.
83
+
84
+ Args:
85
+ filters (Union[List[BaseNodeMatcher], BaseNodeMatcher]): The filters used to select nodes for bit-width manipulation.
86
+ bit_widths (Union[List[int], int]): The bit widths for specified by attrs to be applied to the selected nodes.
87
+ attrs (Union[List[WeightAttrT], WeightAttrT]): The filtered node's attributes to apply bit-width manipulation to.
88
+ If a single value is given it will be applied to all the filters
89
+ """
90
+ if filters is None:
91
+ Logger.critical(f"The filters cannot be None.")
92
+ attrs, bit_widths, filters = self._expand_to_list(filters, bit_widths, attrs)
93
+ for attr, bit_width, filter in zip (attrs, bit_widths, filters):
94
+ self.manual_weights_bit_width_selection_list += [ManualWeightsBitWidthSelection(filter, bit_width, attr)]
95
+
96
+ def get_nodes_to_manipulate_activation_bit_widths(self, graph: Graph) -> Dict:
97
+ """
98
+ Retrieve nodes from the graph that need their bit-widths for activation changed according to the manual bit-width selections.
99
+
100
+ Args:
101
+ graph (Graph): The graph containing the nodes to be filtered and manipulated.
102
+
103
+ Returns:
104
+ Dict: A dictionary mapping nodes to their new bit-widths.
105
+ """
106
+ activation_nodes_to_change_bit_width = self._construct_node_to_new_activation_bit_mapping(graph)
107
+ return activation_nodes_to_change_bit_width
108
+
109
+ def get_nodes_to_manipulate_weights_bit_widths(self, graph: Graph) -> Dict:
69
110
  """
70
- Retrieve nodes from the graph that need their bit-widths changed according to the manual bit-width selections.
111
+ Retrieve nodes from the graph that need their bit-widths for weights changed according to the manual bit-width selections.
71
112
 
72
113
  Args:
73
114
  graph (Graph): The graph containing the nodes to be filtered and manipulated.
@@ -75,16 +116,127 @@ class BitWidthConfig:
75
116
  Returns:
76
117
  Dict: A dictionary mapping nodes to their new bit-widths.
77
118
  """
78
- nodes_to_change_bit_width = {}
119
+ weights_nodes_to_change_bit_width = self._construct_node_to_new_weights_bit_mapping(graph)
120
+ return weights_nodes_to_change_bit_width
121
+
122
+ @staticmethod
123
+ def _expand_to_list_core(
124
+ filters: Union[List[BaseNodeMatcher], BaseNodeMatcher],
125
+ vals: Union[List[Union[WeightAttrT, int]], Union[WeightAttrT, int]]) -> list:
126
+ """
127
+ Extend the length of vals to match the length of filters.
128
+
129
+ Args:
130
+ filters (Union[List[BaseNodeMatcher], BaseNodeMatcher]): The filters used to select nodes for bit-width manipulation.
131
+ vals Union[List[Union[WeightAttrT, int], Union[WeightAttrT, int]]]): The bit widths or The filtered node's attributes.
132
+
133
+ Returns:
134
+ list: Extended vals to match the length of filters.
135
+ """
136
+ vals = [vals] if not isinstance(vals, list) else vals
137
+ if len(vals) > 1 and len(vals) != len(filters):
138
+ Logger.critical(f"Configuration Error: The number of provided bit_width values {len(vals)} "
139
+ f"must match the number of filters {len(filters)}, or a single bit_width value "
140
+ f"should be provided for all filters.")
141
+ elif len(vals) == 1 and len(filters) > 1:
142
+ vals = [vals[0] for f in filters]
143
+ return vals
144
+
145
+ @staticmethod
146
+ def _expand_to_list(
147
+ filters: Union[List[BaseNodeMatcher]],
148
+ bit_widths: Union[List[int], int],
149
+ attrs: Union[List[WeightAttrT], WeightAttrT] = None) -> [List]:
150
+ """
151
+ Extend the length of filters, bit-widths and The filtered node's attributes to match the length of filters.
152
+
153
+ Args:
154
+ filters (Union[List[BaseNodeMatcher], BaseNodeMatcher]): The filters used to select nodes for bit-width manipulation.
155
+ bit_widths (Union[List[int], int]): The bit widths for specified by attrs to be applied to the selected nodes.
156
+ attrs (Union[List[WeightAttrT], WeightAttrT]): The filtered node's attributes to apply bit-width manipulation to.
157
+
158
+ Returns:
159
+ [List]: A List of extended input arguments.
160
+ """
161
+ filters = [filters] if not isinstance(filters, list) else filters
162
+ bit_widths = BitWidthConfig._expand_to_list_core(filters, bit_widths)
163
+ if attrs is not None:
164
+ attrs = BitWidthConfig._expand_to_list_core(filters, attrs)
165
+ return attrs, bit_widths, filters
166
+
167
+ def _construct_node_to_new_activation_bit_mapping(self, graph) -> Dict:
168
+ """
169
+ Retrieve nodes from the graph that need their activation bit-widths changed according to the manual bit-width selections.
170
+
171
+ Args:
172
+ graph (Graph): The graph containing the nodes to be filtered and manipulated.
173
+
174
+ Returns:
175
+ Dict: A dictionary retrieved nodes from the graph.
176
+ """
177
+ unit_nodes_to_change_bit_width = {}
79
178
  for manual_bit_width_selection in self.manual_activation_bit_width_selection_list:
80
179
  filtered_nodes = graph.filter(manual_bit_width_selection.filter)
81
180
  if len(filtered_nodes) == 0:
82
- Logger.critical(f"Node Filtering Error: No nodes found in the graph for filter {manual_bit_width_selection.filter.__dict__} "
83
- f"to change their bit width to {manual_bit_width_selection.bit_width}.")
181
+ Logger.critical(
182
+ f"Node Filtering Error: No nodes found in the graph for filter {manual_bit_width_selection.filter.__dict__} "
183
+ f"to change their bit width to {manual_bit_width_selection.bit_width}.")
84
184
  for n in filtered_nodes:
85
185
  # check if a manual configuration exists for this node
86
- if n in nodes_to_change_bit_width:
186
+ if n in unit_nodes_to_change_bit_width:
87
187
  Logger.info(
88
- f"Node {n} has an existing manual bit width configuration of {nodes_to_change_bit_width.get(n)}. A new manual configuration request of {manual_bit_width_selection.bit_width} has been received, and the previous value is being overridden.")
89
- nodes_to_change_bit_width.update({n: manual_bit_width_selection.bit_width})
90
- return nodes_to_change_bit_width
188
+ f"Node {n} has an existing manual bit width configuration of {unit_nodes_to_change_bit_width.get(n)}."
189
+ f"A new manual configuration request of {manual_bit_width_selection.bit_width} has been received, and the previous value is being overridden.")
190
+ unit_nodes_to_change_bit_width.update({n: manual_bit_width_selection.bit_width})
191
+ return unit_nodes_to_change_bit_width
192
+
193
+ def _construct_node_to_new_weights_bit_mapping(self, graph) -> Dict:
194
+ """
195
+ Retrieve nodes from the graph that need their weights bit-widths changed according to the manual bit-width selections.
196
+
197
+ Args:
198
+ graph (Graph): The graph containing the nodes to be filtered and manipulated.
199
+
200
+ Returns:
201
+ Dict: A dictionary retrieved nodes from the graph.
202
+ """
203
+ unit_nodes_to_change_bit_width = {}
204
+
205
+ for manual_bit_width_selection in self.manual_weights_bit_width_selection_list:
206
+ filtered_nodes = graph.filter(manual_bit_width_selection.filter)
207
+ if len(filtered_nodes) == 0:
208
+ Logger.critical(
209
+ f"Node Filtering Error: No nodes found in the graph for filter {manual_bit_width_selection.filter.__dict__} "
210
+ f"to change their bit width to {manual_bit_width_selection.bit_width}.")
211
+
212
+ for n in filtered_nodes:
213
+ attr_to_change_bit_width = []
214
+
215
+ attrs_str = n.get_node_weights_attributes()
216
+ if len(attrs_str) == 0:
217
+ Logger.critical(f'The requested attribute {manual_bit_width_selection.attr} to change the bit width for {n} does not exist.')
218
+
219
+ attr = []
220
+ for attr_str in attrs_str:
221
+ if isinstance(attr_str, str) and isinstance(manual_bit_width_selection.attr, str):
222
+ if attr_str.find(manual_bit_width_selection.attr) != -1:
223
+ attr.append(attr_str)
224
+ elif isinstance(attr_str, int) and isinstance(manual_bit_width_selection.attr, int):
225
+ if attr_str == manual_bit_width_selection.attr:
226
+ attr.append(attr_str)
227
+ if len(attr) == 0:
228
+ Logger.critical(f'The requested attribute {manual_bit_width_selection.attr} to change the bit width for {n} does not exist.')
229
+
230
+ if n in unit_nodes_to_change_bit_width:
231
+ attr_to_change_bit_width = unit_nodes_to_change_bit_width[n]
232
+ for i, attr_to_bitwidth in enumerate(attr_to_change_bit_width):
233
+ if attr_to_bitwidth[1] == manual_bit_width_selection.attr:
234
+ del attr_to_change_bit_width[i]
235
+ Logger.info(
236
+ f"Node {n} has an existing manual bit width configuration of {manual_bit_width_selection.attr}."
237
+ f"A new manual configuration request of {manual_bit_width_selection.bit_width} has been received, and the previous value is being overridden.")
238
+
239
+ attr_to_change_bit_width.append([manual_bit_width_selection.bit_width, manual_bit_width_selection.attr])
240
+ unit_nodes_to_change_bit_width.update({n: attr_to_change_bit_width})
241
+
242
+ return unit_nodes_to_change_bit_width
@@ -65,7 +65,7 @@ def set_quantization_configuration_to_graph(graph: Graph,
65
65
  Logger.warning("Using the HMSE error method for weights quantization parameters search. "
66
66
  "Note: This method may significantly increase runtime during the parameter search process.")
67
67
 
68
- nodes_to_manipulate_bit_widths = {} if bit_width_config is None else bit_width_config.get_nodes_to_manipulate_bit_widths(graph)
68
+ nodes_to_manipulate_bit_widths = {} if bit_width_config is None else bit_width_config.get_nodes_to_manipulate_activation_bit_widths(graph)
69
69
 
70
70
  for n in graph.nodes:
71
71
  set_quantization_configs_to_node(node=n,