Ë
    ÝÍ:j£Â  ã                   óÊ   — d dl Z d dlZd dlZd dlZd dlmZ ddlmZm	Z	 ddl
mZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z  ddl!m"Z"  G d	„ d
e«      Z#y)é    N)Úonnx_pbé   )ÚBaseQuantizerÚQuantizationParams)Ú
TensorData)Ú	ONNXModel)ÚTENSOR_NAME_QUANT_SUFFIXÚQuantizationModeÚQuantizedValueÚQuantizedValueTypeÚ__producer__Ú__version__Úadd_infer_metadataÚattribute_to_kwargÚcompute_scale_zpÚcompute_scale_zp_float8Úfind_by_nameÚget_qmin_qmax_for_qTypeÚget_qrange_for_qTypeÚ	ms_domainÚquantize_onnx_initializerÚ&save_and_reload_model_with_shape_inferÚsnap_zero_point_to_uint8Útensor_proto_to_array)ÚCreateOpQuantizerc                   óˆ  — e Zd Z	 d&d„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d	„ Z
d'd
„Zd„ Zd„ Zd„ Zd„ Zd(d„Z	 d)d„Zd„ Z	 d&d„Zdej*                  dej*                  dedej0                  dedeeej*                  dz  f   fd„Zdedej*                  ddfd„Zd*d„Zd„ Zd'd„Z	 	 	 	 d+d„Z 	 	 	 	 	 d,d „Z!d-d!„Z"	 	 d.d"„Z#d#„ Z$d$„ Z%d%„ Z&y)/ÚONNXQuantizerNc                 ó<  — t        j                  | |||||||	|
||«       |�s| j                  j                  «        t	        | j                  j                  «      }|j
                  j                  D �ci c]  }|j                  |“Œ c}| _        | j                  j                  |j
                  j                  D �ci c]  }|j                  |“Œ c}«       | j                  j                  |j
                  j                  D �ci c]  }|j                  |“Œ c}«       t        |«      | _        || _        || _        | j                  dkD  | _        d| j"                  v xr | j"                  d   | _        g | _        d| _        i | _        | j*                  j                  |j
                  j                  D �ci c]  }|j                  d“Œ c}«       | j*                  j                  |j
                  j                  D �ci c]  }|j                  d“Œ c}«       | j                  j                  j
                  j,                  D ];  }| j*                  j                  t.        j1                  |j                  d«      «       Œ= | j                  t2        vrt5        d| j                  › �«      ‚| j7                  «       | _        d| _        d| _        d| _        d	| _         i | _!        | j                  jE                  «       | _#        y c c}w c c}w c c}w c c}w c c}w )
Né
   ÚMatMulConstBOnlyú/r   zunsupported quantization mode Úfixed_quantization_range_uint8Úfixed_quantization_range_int8Ú
fixed_zeroÚfixed_zero_zp)$r   Ú__init__ÚmodelÚreplace_gemm_with_matmulr   ÚgraphÚ
value_infoÚnameÚvalue_infosÚupdateÚoutputÚinputr   ÚmodeÚstaticÚopset_versionÚfuse_dynamic_quantÚextra_optionsÚq_matmul_const_b_onlyÚ	new_nodesÚgraph_scopeÚtensor_namesÚnodeÚdictÚfromkeysr
   Ú
ValueErrorÚcalculate_quantization_paramsÚquantization_paramsÚfixed_qrange_uint8_nameÚfixed_qrange_int8_nameÚfixed_zero_nameÚfixed_zero_zp_nameÚquantized_value_mapÚget_non_initializer_inputsÚgenerated_value_names)Úselfr'   Úper_channelÚreduce_ranger0   r1   Úweight_qTypeÚactivation_qTypeÚtensors_rangeÚnodes_to_quantizeÚnodes_to_excludeÚop_types_to_quantizer4   ÚviÚotÚitr9   s                    ú|/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/onnxruntime/quantization/onnx_quantizer.pyr&   zONNXQuantizer.__init__(   s‰  € ô 	×ÑØØØØØØØØØØ Øô	
ò Ø�J‰J×/Ñ/Ô1ä:¸4¿:¹:×;KÑ;KÓLˆEØ6;·k±k×6LÑ6LÖM° §¡¨¡ÒMˆDÔØ×Ñ×#Ñ#¸5¿;¹;×;MÑ;MÖ$N°R R§W¡W¨b¡[Ò$NÔOØ×Ñ×#Ñ#¸5¿;¹;×;LÑ;LÖ$M°R R§W¡W¨b¡[Ò$MÔNÜ" 5Ó)ˆDŒJàˆŒ	ØˆŒØ"&×"4Ñ"4°rÑ"9ˆÔà%7¸4×;MÑ;MÐ%MÒ%xÐRV×RdÑRdÐewÑRxˆÔ"àˆŒØˆÔØˆÔØ×Ñ× Ñ °u·{±{×7IÑ7IÖ!J° "§'¡'¨1¡*Ò!JÔKØ×Ñ× Ñ °u·{±{×7HÑ7HÖ!I° "§'¡'¨1¡*Ò!IÔJØ—J‘J×$Ñ$×*Ñ*×/Ñ/ò 	DˆDØ×Ñ×$Ñ$¤T§]¡]°4·;±;ÀÓ%BÕCð	Dð �9‰9Ô,Ñ,ÜÐ=¸d¿i¹i¸[ÐIÓJÐJà#'×#EÑ#EÓ#GˆÔ ð (HˆÔ$Ø&EˆÔ#à+ˆÔà"1ˆÔð $&ˆÔ ð &*§Z¡Z×%JÑ%JÓ%LˆÕ"ùòK  NùÚ$NùÚ$Mùò "KùÚ!Is   Á4LÂ=L
ÄLÆ8LÈ Lc                 ó:  — t         j                  j                  |d| j                  j                  j                  ¬«      }t        |«       t        || j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                   | j"                  «      }| |_        | j&                  › |› d�|_        |j)                  «        |j                  j                  j*                  S )z¾
        generate submodel for the subgraph, so that we re-utilize current quantization implementation.
        quantize the submodel
        update subgraph and set it back to node
        úonnx-quantizer)Úproducer_nameÚopset_importsr!   )ÚonnxÚhelperÚ
make_modelr'   Úopset_importr   r   rG   rH   r0   r1   rI   rJ   rK   rL   rM   rN   r4   Úparentr7   Úquantize_modelr)   )rF   ÚsubgraphÚ	graph_keyÚwarped_modelÚsub_quantizers        rR   Úquantize_subgraphzONNXQuantizer.quantize_subgraphq   sô   € ô —{‘{×-Ñ-ØØ*ØŸ*™*×*Ñ*×7Ñ7ð .ó 
ˆô
 	˜<Ô(Ü%ØØ×ÑØ×ÑØ�I‰IØ�K‰KØ×ÑØ×!Ñ!Ø×ÑØ×"Ñ"Ø×!Ñ!Ø×%Ñ%Ø×Ñó
ˆð  $ˆÔØ'+×'7Ñ'7Ð&8¸¸À1Ð$EˆÔ!Ø×$Ñ$Ô&Ø×"Ñ"×(Ñ(×.Ñ.Ð.ó    c                 ó6  — |j                   D �cg c]R  }|j                  t        j                  j                  k(  s'|j                  t        j                  j
                  k(  r|‘ŒT }}t        |«      dk(  r|S |j                  r|j                  n#|j                  › dt        | j                  «      › �}i }|j                   D �]  }|j                  t        j                  j                  k(  r8|j                  | j                  |j                  |› d|j                  › �«      i}n‘|j                  t        j                  j
                  k(  r_g }|j                  D ]?  }|j                  | j                  ||› d|j                  › dt        |«      › �«      g«       ŒA |j                  |i}nt        |«      }|j                  |«       �Œ t        j                   j"                  |j                  |j$                  |j&                  fd|j                  i|¤ŽS c c}w )z|
        Check subgraph, if any, quantize it and replace it.
        return new_nodes added for quantizing subgraph
        r   Ú_node_count_ú:r+   )Ú	attributeÚtyperW   ÚAttributeProtoÚGRAPHÚGRAPHSÚlenr+   Úop_typer6   ra   ÚgÚgraphsÚextendr   r-   rX   Ú	make_noder/   r.   )	rF   r9   ÚattrÚgraph_attrsÚ	node_nameÚkwargsÚkvÚvaluer]   s	            rR   Úquantize_node_with_sub_graphz*ONNXQuantizer.quantize_node_with_sub_graph�   sÅ  € ð Ÿ™ö
àØ�y‰yœD×/Ñ/×5Ñ5Ò5¸¿¹Äd×FYÑFY×F`ÑF`Ò9`ò ð
ˆð 
ô
 ˆ{Ó˜qÒ ØˆKØ!%§¢�D—I’I°4·<±<°.ÀÌSÐQU×Q_ÑQ_ÓM`ÐLaÐ0bˆ	ØˆØ—N‘Nó 	ˆDØ�y‰yœD×/Ñ/×5Ñ5Ò5Ø—i‘i ×!7Ñ!7¸¿¹À9À+ÈQÈtÏyÉyÈkÐ@ZÓ![Ð\‘Ø—‘œd×1Ñ1×8Ñ8Ò8Ø�Ø $§¡ò �HØ—L‘Là ×2Ñ2Ø (Ø#, +¨Q¨t¯y©y¨k¸¼3¸u»:¸,Ð Góðõðð —i‘i Ð'‘ä'¨Ó-�Ø�M‰M˜"Öð#	ô$ �{‰{×$Ñ$ T§\¡\°4·:±:¸t¿{¹{ÑeÐQU×QZÑQZÐeÐ^dÑeÐeùò7
s   �AHc                 óV   — t        d„ | j                  j                  «       D «       «      S )zQ
        Detect if model already has QuantizeLinear or DequantizeLinear.
        c              3   ó\   K  — | ]$  }|j                   d k(  xs |j                   dk(  –— Œ& y­w)ÚQuantizeLinearÚDequantizeLinearN)rl   )Ú.0r9   s     rR   ú	<genexpr>z.ONNXQuantizer.has_QDQ_nodes.<locals>.<genexpr>¶   s1   è ø€ ò 
ØW[ˆD�L‰LÐ,Ñ,ÒR°·±Ð@RÑ0RÓRñ
ùs   ‚*,)Úanyr'   Únodes)rF   s    rR   Úhas_QDQ_nodeszONNXQuantizer.has_QDQ_nodes²   s-   € ô ñ 
Ø_c×_iÑ_i×_oÑ_oÓ_qô
ó 
ð 	
rb   c                 óœ   — t        || j                  j                  «       «      �y| j                  �| j                  j	                  |«      S y)NTF)r   r'   Úinitializerr[   Úfind_initializer_in_path)rF   Úinitializer_names     rR   rƒ   z&ONNXQuantizer.find_initializer_in_pathº   sC   € ÜÐ(¨$¯*©*×*@Ñ*@Ó*BÓCÐOØØ�;‰;Ð"Ø—;‘;×7Ñ7Ð8HÓIÐIØrb   c                 ó    — | j                   j                  |«       |D ].  }|j                  D ]  }| j                  j	                  |«       Œ Œ0 y ©N)r6   ro   r.   rE   Úadd)rF   r   r9   Úoutput_names       rR   Úadd_new_nodeszONNXQuantizer.add_new_nodesÁ   sJ   € Ø�‰×Ñ˜eÔ$Øò 	<ˆDØ#Ÿ{™{ò <�Ø×*Ñ*×.Ñ.¨{Õ;ñ<ñ	<rb   c                 ó€  — | j                  «       rt        j                  d«       | j                  j	                  «       D ]­  }| j
                  r| j                  |«      }t        | j                  «      }t        | |«      }|j                  «        t        |t        | j                  «      «      D ];  }| j                  |   j                  D ]  }| j                  j                  |«       Œ Œ= Œ¯ | j                  «        | j                  j!                  «       j#                  d«       | j                  j!                  «       j$                  j'                  | j                  «       | j(                  €B| j                  j+                  «       \  }}t        |«      dkD  rt-        dt/        |«      z   «      ‚t0        | j                  j                  _        t4        | j                  j                  _        | j                  j                  j8                  D �cg c]  }|j:                  t<        k(  sŒ|‘Œ }	}|	sk| j                  D �cg c]  }|j:                  dk(  sŒ|‘Œ }
}|
r@| j                  j                  j8                  j                  «       }d|_        t<        |_        | j                  j                  S c c}w c c}w )Nz‹Please check if the model is already quantized. Note you don't need to quantize a QAT model. OnnxRuntime support to run QAT model directly.r9   r   z0Invalid model with unknown initializers/tensors.zcom.microsoftr   ) r€   ÚloggingÚwarningr'   r   Úenable_subgraph_quantizationrw   rk   r6   r   ÚquantizeÚranger.   rE   r‡   Ú_dequantize_outputsr)   Ú
ClearFieldr9   ro   r[   Úclean_initializersÚRuntimeErrorÚstrr   rU   r   Úproducer_versionrZ   Údomainr   Úversion)rF   r9   Únumber_of_existing_new_nodesÚop_quantizerÚirˆ   Ú_Úinitializers_not_foundÚopsetÚms_opsetÚms_nodess              rR   r\   zONNXQuantizer.quantize_modelÇ   s0  € Ø×ÑÔÜ�O‰Oðnôð
 —J‘J×$Ñ$Ó&ò 
	@ˆDà×0Ò0Ø×8Ñ8¸Ó>�ä+.¨t¯~©~Ó+>Ð(Ü,¨T°4Ó8ˆLØ×!Ñ!Ô#ÜÐ7¼¸T¿^¹^Ó9LÓMò @�Ø#'§>¡>°!Ñ#4×#;Ñ#;ò @�KØ×.Ñ.×2Ñ2°;Õ?ñ@ñ@ð
	@ð 	× Ñ Ô"ð 	�
‰
×ÑÓ×%Ñ% fÔ-Ø�
‰
×ÑÓ×Ñ×&Ñ& t§~¡~Ô6ð �;‰;ÐØ(,¯
©
×(EÑ(EÓ(GÑ%ˆAÐ%ÜÐ)Ó*¨QÒ.Ü"Ð#UÔX[Ð\rÓXsÑ#sÓtÐtä)5ˆ�
‰
×ÑÔ&Ü,7ˆ�
‰
×ÑÔ)à'+§z¡z×'7Ñ'7×'DÑ'DÖb˜eÈÏÉÔXaÓHa’EÐbˆÐbÙØ)-¯©ÖZ ¸4¿;¹;È/Ó;YšÐZˆHÐZÙØŸ
™
×(Ñ(×5Ñ5×9Ñ9Ó;�Ø !�”Ü(�”à�z‰z×ÑÐùò cùâZs   ÈJ6È-J6ÉJ;ÉJ;c                 ó¢   — d| j                   v r3t        j                  d|| j                   d   «       | j                   d   S t        d|›d�«      ‚)NÚDefaultTensorTypezDget_tensor_type returns DefaultTensorType for tensor name %r, use %dz)Unable to find data type for weight_name=a7  . shape_inference failed to return a type probably this node is from a different domain or using an input produced by such an operator. This may happen if you quantize a model already quantized. You may use extra_options `DefaultTensorType` to indicate the default weight type, usually `onnx.TensorProto.FLOAT`.)r4   r‹   Úinfor“   ©rF   Útensor_names     rR   Ú_get_default_tensor_typez&ONNXQuantizer._get_default_tensor_typeô   sf   € Ø $×"4Ñ"4Ñ4Ü�L‰LØVØØ×"Ñ"Ð#6Ñ7ôð
 ×%Ñ%Ð&9Ñ:Ð:ÜØ7¸°ð GIð Jó
ð 	
rb   c                 ó®  — t        || j                  j                  «       «      }|�|j                  S || j                  v r€| j                  |   }|j
                  j                  d«      rV|r4|j
                  j                  j                  dk(  r| j                  |«      S |j
                  j                  j                  S | j                  r| j                  €|r| j                  |«      S y | j                  j                  |«      }|�|S | j                  r+| j                  r| j                  j                  |«      }|�|S |r| j                  |«      S y )NÚtensor_typer   )r   r'   r‚   Ú	data_typer,   rg   ÚHasFieldr§   Ú	elem_typer¥   r�   r[   Úis_valid_quantize_weightÚget_tensor_type)rF   r¤   Ú	mandatoryÚweightrO   ÚotypeÚress          rR   r¬   zONNXQuantizer.get_tensor_type  s*  € Ü˜k¨4¯:©:×+AÑ+AÓ+CÓDˆØÐØ×#Ñ#Ð#Ø˜$×*Ñ*Ñ*Ø×!Ñ! +Ñ.ˆBØ�w‰w×Ñ Ô.Ù §¡×!4Ñ!4×!>Ñ!>À!Ò!CØ×8Ñ8¸ÓEÐEØ—w‘w×*Ñ*×4Ñ4Ð4Ø×1Ò1°t·{±{Ð7JÙØ×4Ñ4°[ÓAÐAØØ—‘×4Ñ4°[ÓAˆØÐØˆLØ×,Ò,°·²Ø—+‘+×-Ñ-¨kÓ:ˆCØˆØ�
ÙØ×0Ñ0°Ó=Ð=Ørb   c                 óH  — | j                  |«      r| j                  |«      S || j                  v r¦| j                  |   }|j                  j	                  d«      rU|j                  j
                  j                  t        j                  j                  t        j                  j                  fv ryt        j                  d|›d|j                  › d�«       y| j                  r'| j                  r| j                  j                  |«      S t        j                  d|›d�«       y)	Nr§   Tz<Inference failed or unsupported type to quantize for tensor z
, type is ú.Fz%Failed to infer data type of tensor: zS. Please add data type info for this tensor if your model has customized operators.)Úis_input_a_initializerr«   r,   rg   r©   r§   rª   Ú
onnx_protoÚTensorProtoÚFLOATÚFLOAT16r‹   rŒ   r�   r[   Úis_float_tensor)rF   r¤   rO   s      rR   r¸   zONNXQuantizer.is_float_tensor  s  € Ø×&Ñ& {Ô3Ø×0Ñ0°Ó=Ð=à˜$×*Ñ*Ñ*Ø×!Ñ! +Ñ.ˆBØ�w‰w×Ñ Ô.°2·7±7×3FÑ3F×3PÑ3PÜ×&Ñ&×,Ñ,Ü×&Ñ&×.Ñ.ðUñ 4ð Ü�O‰OØNÈ{ÈoÐ]gÐhj×hoÑhoÐgpÐpqÐrôð à×,Ò,°·²Ø—;‘;×.Ñ.¨{Ó;Ð;ä�‰Ø3°K°?ð C6ð 7ô	
ð rb   c                 óà   — |t         j                  j                  k(  r| j                  |||«      S |t         j                  j                  k(  r| j                  |||«      S t        d|› d�«      ‚)a”  
        Create nodes for dynamic quantization of input and add them to nodes_list.
            parameter input_name: Name of the input.
            parameter nodes_list: new nodes are appended to this list.
            parameter qType: type to quantize to.
            parameter initial_type: type to quantize from
            return: scale_name, zero_point_name, scale_shape, zero_point_shape.
        zUnexpected value for qType=r²   )r´   rµ   ÚINT8Ú+_get_dynamic_input_quantization_params_int8ÚUINT8Ú,_get_dynamic_input_quantization_params_uint8r<   )rF   Ú
input_nameÚ
nodes_listÚqTypeÚinitial_types        rR   Ú&_get_dynamic_input_quantization_paramsz4ONNXQuantizer._get_dynamic_input_quantization_params7  so   € ð ”J×*Ñ*×/Ñ/Ò/Ø×CÑCÀJÐPZÐ\hÓiÐiØ”J×*Ñ*×0Ñ0Ò0Ø×DÑDÀZÐQ[Ð]iÓjÐjÜÐ6°u°g¸QÐ?Ó@Ð@rb   c                 ó  — t         j                  j                  }|dz   }|dz   }t        j                  j                  d|g|dz   g|d¬«      }|j                  |«       |dz   }t        j                  j                  d|g|dz   g|d¬«      }	|j                  |	«       |d	z   }
t        j                  j                  d
|j                  d   g|
dz   g|
«      }|j                  |«       |d	z   }t        j                  j                  d
|	j                  d   g|dz   g|«      }|j                  |«       |dz   }t        j                  j                  d|j                  d   |j                  d   g|dz   g|«      }|j                  |«       t        j                  j                  | j                  |g t        |«      dz  g«      }| j                  j                  |«       |dz   }t        j                  j                  d|j                  d   | j                  g|g|«      }|j                  |«       t        j                  j                  | j                  |g dg«      }| j                  j                  |«       || j                  g g fS )az  
        Create nodes for dynamic quantization of input to int8 and add them to nodes_list
            parameter input_name: Name of the input.
            parameter nodes_list: new nodes are appended to this list.
            parameter initial_type: initial weight type (FLOAT or FLOAT16)
            return: scale_name, zero_point_name, scale_shape, zero_point_shape.
        Ú_scaleÚ
_ReduceMinÚ	ReduceMinú:0r   ©ÚkeepdimsÚ
_ReduceMaxÚ	ReduceMaxÚ_AbsÚAbsÚ_Abs_MaxÚMaxç       @Ú	scale_DivÚDiv)r´   rµ   rº   rW   rX   rp   Úappendr.   Úmake_tensorr@   r   r'   Úadd_initializerrB   )rF   r¾   r¿   rÁ   rÀ   Úinput_scale_nameÚreduce_min_nameÚreduce_min_nodeÚreduce_max_nameÚreduce_max_nodeÚreduce_min_abs_nameÚreduce_min_abs_nodeÚreduce_max_abs_nameÚreduce_max_abs_nodeÚabs_max_nameÚabs_max_nodeÚinitializer_divÚscale_div_nameÚscale_div_nodeÚinitializer_zps                       rR   r»   z9ONNXQuantizer._get_dynamic_input_quantization_params_int8F  s¨  € ô ×&Ñ&×+Ñ+ˆð &¨Ñ0Ðà$ |Ñ3ˆÜŸ+™+×/Ñ/ØØˆLØ˜tÑ#Ð$ØØð 0ó 
ˆð 	×Ñ˜/Ô*à$ |Ñ3ˆÜŸ+™+×/Ñ/ØØˆLØ˜tÑ#Ð$ØØð 0ó 
ˆð 	×Ñ˜/Ô*ð .°Ñ6ÐÜ"Ÿk™k×3Ñ3ØØ×#Ñ# AÑ&Ð'Ø  4Ñ'Ð(Øó	
Ðð 	×ÑÐ-Ô.à-°Ñ6ÐÜ"Ÿk™k×3Ñ3ØØ×#Ñ# AÑ&Ð'Ø  4Ñ'Ð(Øó	
Ðð 	×ÑÐ-Ô.à! JÑ.ˆÜ—{‘{×,Ñ,ØØ ×'Ñ'¨Ñ*Ð,?×,FÑ,FÀqÑ,IÐJØ˜DÑ Ð!Øó	
ˆð 	×Ñ˜,Ô'äŸ+™+×1Ñ1Ø×'Ñ'ØØÜ! %Ó(¨3Ñ.Ð/ó	
ˆð 	�
‰
×"Ñ" ?Ô3Ø# kÑ1ˆÜŸ™×.Ñ.ØØ× Ñ  Ñ# T×%@Ñ%@ÐAØÐØó	
ˆð 	×Ñ˜.Ô)ô Ÿ™×0Ñ0°×1HÑ1HÈ%ÐQSÐVWÐUXÓYˆØ�
‰
×"Ñ" >Ô2à ×!8Ñ!8¸"¸bÐ@Ð@rb   c                 ó.  — t         j                  j                  }|dz   }|dz   }|dz   }t        j                  j                  d|g|dz   g|d¬«      }|j                  |«       |dz   }	t        j                  j                  d	|g|	dz   g|	d¬«      }
|j                  |
«       t        j                  j                  | j                  |g t        |«      g«      }| j                  j                  |«       t        j                  j                  | j                  |g d
g«      }| j                  j                  |«       |dz   }t        j                  j                  d|
j                  d   |j                  d   g|dz   g|«      }|j                  |«       |dz   }t        j                  j                  d|j                  d   | j                  g|g|«      }|j                  |«       |dz   }t        j                  j                  d| j                  |j                  d   g|dz   g|«      }|j                  |«       |dz   }t        j                  j                  d|j                  d   |g|dz   g|«      }|j                  |«       |dz   }t        j                  j                  d|j                  |dz   g|«      }|j                  |«       |dz   }t        j                  j                  d|j                  |g||¬«      }|j                  |«       ||g g fS )a{  
        Create nodes for dynamic quantization of input to uint8 and add them to nodes_list
            parameter input_name: Name of the input.
            parameter nodes_list: new nodes are appended to this list.
            parameter initial_type: initial weight type (FLAOT or FLOAT16)
            return: scale_name, zero_point_name, scale_shape, zero_point_shape.
        rÄ   Ú_zero_pointrÅ   rÆ   rÇ   r   rÈ   rÊ   rË   ç        Ú
_scale_SubÚSubÚ
_scale_DivrÒ   Ú_zero_point_SubÚ_zero_point_DivÚ_zero_point_FloorÚFloorÚ_zero_point_CastÚCast)Úto)r´   rµ   r¼   rW   rX   rp   rÓ   rÔ   r?   r   r'   rÕ   rA   r.   )rF   r¾   r¿   rÁ   rÀ   rÖ   Úinput_zp_namer×   rØ   rÙ   rÚ   Úinitializer_qrangeÚinitializer_qvalueÚscale_sub_nameÚscale_sub_noderâ   rã   Úzp_sub_nameÚzp_sub_nodeÚzp_div_nameÚzp_div_nodeÚzp_floor_nameÚzp_floor_nodeÚzp_cast_nameÚzp_cast_nodes                            rR   r½   z:ONNXQuantizer._get_dynamic_input_quantization_params_uint8š  s6  € ô ×&Ñ&×,Ñ,ˆà%¨Ñ0ÐØ" ]Ñ2ˆà$ |Ñ3ˆÜŸ+™+×/Ñ/ØØˆLØ˜tÑ#Ð$ØØð 0ó 
ˆð 	×Ñ˜/Ô*à$ |Ñ3ˆÜŸ+™+×/Ñ/ØØˆLØ˜tÑ#Ð$ØØð 0ó 
ˆð 	×Ñ˜/Ô*ô "Ÿ[™[×4Ñ4Ø×(Ñ(ØØÜ! %Ó(Ð)ó	
Ðð 	�
‰
×"Ñ"Ð#5Ô6Ü!Ÿ[™[×4Ñ4°T×5IÑ5IÈ<ÐY[Ð^aÐ]bÓcÐØ�
‰
×"Ñ"Ð#5Ô6ð $ lÑ2ˆÜŸ™×.Ñ.ØØ×#Ñ# AÑ&¨×(>Ñ(>¸qÑ(AÐBØ˜dÑ"Ð#Øó	
ˆð 	×Ñ˜.Ô)à# lÑ2ˆÜŸ™×.Ñ.ØØ×"Ñ" 1Ñ% t×'CÑ'CÐDØÐØó	
ˆð 	×Ñ˜.Ô)ð !Ð#4Ñ4ˆÜ—k‘k×+Ñ+ØØ×!Ñ! ?×#9Ñ#9¸!Ñ#<Ð=Ø˜4ÑÐ Øó	
ˆð 	×Ñ˜+Ô&à Ð#4Ñ4ˆÜ—k‘k×+Ñ+ØØ×Ñ Ñ"Ð$4Ð5Ø˜4ÑÐ Øó	
ˆð 	×Ñ˜+Ô&à"Ð%8Ñ8ˆÜŸ™×-Ñ-¨g°{×7IÑ7IÈMÐ\`ÑL`ÐKaÐcpÓqˆØ×Ñ˜-Ô(à!Ð$6Ñ6ˆÜ—{‘{×,Ñ,¨V°]×5IÑ5IÈMÈ?Ð\hÐmrÐ,ÓsˆØ×Ñ˜,Ô'à °°BÐ6Ð6rb   c                 óH  — | j                   }|�|�€A| j                  �|| j                  vrt        j                  d|› d�«       y| j                  |   }t	        |t
        «      st        dt        |«      › d|›d�«      ‚|�t        |«      dk7  rt        d|› d	|› �«      ‚t        j                  |d
   g«      }t        |d   d«      r/|d   j                  t        j                  t        j                  fvrt        dt        |d   «      › d|›�«      ‚t        j                  |d   g«      }|j                  t        j                   k7  sJ ‚|d   }n~t        j                  |g«      }t        j                  |g«      }| j                  |   }d|v r |d   j                  }|j#                  |«      }|j                  t        j                   k7  sJ ‚g }	|dz   }
g }|dz   }t$        j&                  j)                  |
||	|j+                  «       j-                  «       «      }| j.                  j1                  |«       |j                  t        j                  k(  rt2        j4                  j6                  }nS|j                  t        j                  k(  rt2        j4                  j8                  }nt        d|j                  › d|›�«      ‚t$        j&                  j)                  ||||j;                  d«      j-                  «       «      }| j.                  j1                  |«       d||
||	fS )a\  
        Create initializers and inputs in the graph for zero point and scale of output.
        Zero point and scale values are obtained from self.quantization_params if specified.
            parameter param_name: Name of the quantization parameter.
            return: result, scale_name, zero_point_name, scale_shape, zero_point_shape.
        z$Quantization parameters for tensor:"z" not specified)FÚ r   r   r   úUnexpected type ú for r²   é   zbQuantization parameters should contain zero point, scale, quant type. Specified values for output z: Ú
zero_pointÚscaleÚdtypez and param_name=Ú
quant_typeræ   rÄ   zUnexpected dtype=z for param_name=)éÿÿÿÿT)rJ   r>   r‹   r¢   Ú
isinstancer   Ú	TypeErrorrg   rk   r<   ÚnpÚarrayÚhasattrr  Úfloat32Úfloat16Úfloat64ÚastyperW   rX   rÔ   ÚravelÚtolistr'   rÕ   r´   rµ   r¶   r·   Úreshape)rF   Ú
param_nameÚ	use_scaleÚuse_zeropointÚzero_point_typeÚparamsÚzero_point_valuesÚscale_valuesr  Úzero_point_shapeÚzero_point_nameÚscale_shapeÚ
scale_nameÚinit_zpÚ
scale_typeÚ
init_scales                   rR   Ú_get_quantization_paramsz&ONNXQuantizer._get_quantization_paramsø  sõ  € ð ×/Ñ/ˆàÐ Ñ 5Ø×'Ñ'Ð/°:ÀT×E]ÑE]Ñ3]Ü—‘ÐCÀJÀ<ÈÐ_Ô`Ø,à×-Ñ-¨jÑ9ˆFÜ˜fÔ&8Ô9ÜÐ"2´4¸³<°.ÀÀjÀ^ÐSTÐ UÓVÐVØˆ~¤ V£°Ò!1Ü ð3Ø3=°,¸bÀÀðJóð ô
 !#§¡¨&°Ñ*>Ð)?Ó @ÐÜ˜6 '™?¨GÔ4¸¸w¹×8MÑ8MÔVX×V`ÑV`Ôbd×blÑblÐUmÑ8mÜ Ð#3´D¸À¹Ó4IÐ3JÐJZÐ[eÐZhÐ!iÓjÐjÜŸ8™8 V¨G¡_Ð$5Ó6ˆLØ×%Ñ%¬¯©Ò3Ð3Ð3Ø$ \Ñ2‰Oä "§¡¨-¨Ó 9ÐÜŸ8™8 Y KÓ0ˆLØ×-Ñ-¨jÑ9ˆFØ˜&Ñ Ø˜w™×-Ñ-�Ø+×2Ñ2°5Ó9�Ø×%Ñ%¬¯©Ò3Ð3Ð3àÐØ$ }Ñ4ˆØˆØ (Ñ*ˆ
ô —+‘+×)Ñ)Ø˜_Ð.>Ð@Q×@WÑ@WÓ@Y×@`Ñ@`Ó@bó
ˆð 	�
‰
×"Ñ" 7Ô+Ø×Ñ¤§¡Ò+Ü#×/Ñ/×5Ñ5‰JØ×Ñ¤2§:¡:Ò-Ü#×/Ñ/×7Ñ7‰JäÐ0°×1CÑ1CÐ0DÐDTÐU_ÐTbÐcÓdÐdÜ—[‘[×,Ñ,¨Z¸À[ÐR^×RfÑRfÐglÓRm×RtÑRtÓRvÓwˆ
Ø�
‰
×"Ñ" :Ô.à�Z °+Ð?OÐOÐOrb   c           	      óª  — |j                   |   }|dk7  sJ d«       ‚|t        z   }|dz   }	|�	|�d||}}}
n| j                  |«      \  }
}}}}g }|
r't        j                  j                  d|||g|g|	«      }n¼| j                  ry| j                  rN|t        j                  j                  k(  r1|dz   }|dz   }t        j                  j                  d	|g|||g|	«      }nU|€J d
|›d|› d|› d|› �«       ‚| j                  ||||¬«      \  }}}}t        j                  j                  d|||g|g|	«      }t        |||||«      | j                  |<   g |¢|‘S )aÊ  
        Given an input for a node (which is not a initializer), this function

        - add nodes to compute zero point and scale for this input if they don't exist.
        - add new QuantizeLinear node to quantize the input.

        :param node: node being quantized in NodeProto format.
        :param input_index: index of input in node.input.
        :param qType: type to quantize to.
        :param given_scale_name: if those inputs need to be quanitzed using this scale tensor.
        :param given_zp_name: if those inputs to be quantized using this zeropoint tensor.
        :param initial_type: type of the weight to quantize
        :return: List of newly created nodes in NodeProto format.
        r   z*Cannot access undefined variable in graph.Ú_QuantizeLinearNTrz   rÄ   ræ   ÚDynamicQuantizeLinearzCCannot quantize input without knowing the initial type, input_name=z, input_index=z, qType=z, node=©rÁ   )r/   r	   r#  rW   rX   rp   r1   r3   r´   rµ   r¼   rÂ   r   rC   )rF   r9   Úinput_indexrÀ   Úgiven_scale_nameÚgiven_zp_namerÁ   r¾   rˆ   Úql_node_nameÚ
data_foundr  Úzp_namer›   r   Úqlinear_noder  Úzp_shapes                     rR   Ú_get_quantize_input_nodesz'ONNXQuantizer._get_quantize_input_nodes3  sÌ  € ð" —Z‘Z Ñ,ˆ
Ø˜RÒÐMÐ!MÓMÐØ Ô#;Ñ;ˆØ!Ð$5Ñ5ˆàÐ(¨}Ð/HØ/3Ð5EÀ} G˜
‰Jà48×4QÑ4QÐR\Ó4]Ñ1ˆJ˜
 G¨Q°àˆÙÜŸ;™;×0Ñ0Ø Ø˜Z¨Ð1Ø�Øó	‰Lð �{Š{Øð ×&Ò&¨5´J×4JÑ4J×4PÑ4PÒ+PØ'¨(Ñ2�
Ø$ }Ñ4�Ü#Ÿ{™{×4Ñ4Ø+Ø�LØ  *¨gÐ6Ø ó	 ‘ð $Ð/ð ð"Ø", ¨~¸k¸]È(ÐSXÐRYÐY`ÐaeÐ`fðhóÐ/ð ×?Ñ?À
ÈEÐSXÐgsÐ?ÓtñØØØØä#Ÿ{™{×4Ñ4Ø$Ø ¨WÐ5Ø �MØ ó	 �ô 0>¸jÈ+ÐWaÐcjÐlqÓ/rˆ× Ñ  Ñ,Ø%�Ð%˜Ð%Ð%rb   c                 óŒ   — || j                   v r| j                   |   S | j                  �| j                  j                  |«      S y r†   )rC   r[   Úfind_quantized_value)rF   r¾   s     rR   r2  z"ONNXQuantizer.find_quantized_valuey  sC   € Ø˜×1Ñ1Ñ1Ø×+Ñ+¨JÑ7Ð7Ø�;‰;Ð"Ø—;‘;×3Ñ3°JÓ?Ð?Ørb   c
                 ó&  — t        j                  |«      }
|d|
z  z  |z  }t        j                  |j                  «       t         j                  ¬«      }t        j                  |j                  «       t         j                  ¬«      }||z  }||k  r~|dkD  ry||z  }||z  }|	€8t        j                  d|› d|› d|› d�«       dt        j                  ||¬«      fS t        j                  d	|	› d
|› d|› d|› d�	«       d|j                  |«      fS d|fS )zHAdjust a single weight scale to ensure the int32 bias does not overflow.rÐ   ©r  rç   zIncreasing scale for weight `z` by the ratio z to ensure bias `z` has a valid scale.TzIncreased scale[z] for weight `z` by ratio F)r  Úabsr  Úitemr  r‹   r¢   r  )rF   Úbias_valÚinput_scaleÚweight_scaleÚweight_scale_dtypeÚweight_nameÚ	bias_nameÚqrangeÚmultiplicative_epsilonÚidxÚabsmaxÚbias_smallest_valid_scaleÚinput_scale_fp64Úweight_scale_fp64Úbias_candidate_scaleÚratioÚ	new_scales                    rR   Ú$adjust_single_weight_scale_if_neededz2ONNXQuantizer.adjust_single_weight_scale_if_needed€  s:  € ô —‘˜Ó!ˆØ$:¸cÀF¹lÑ$KÈfÑ$TÐ!äŸ8™8 K×$4Ñ$4Ó$6¼b¿j¹jÔIÐÜŸH™H \×%6Ñ%6Ó%8ÄÇ
Á
ÔKÐØ/Ð2CÑCÐà Ð#<Ò<ÐCWÐZ]ÒC]Ø-Ð0DÑDˆEØ)¨EÑ1ˆIØˆ{Ü—‘Ø3°K°=ÀÐPUÈwð W$Ø$- ;Ð.BðDôð œRŸX™X iÐ7IÔJÐJÐJä—‘Ø& s e¨>¸+¸ÀkÐRWÐQXð Y'Ø'0 kÐ1EðGôð ˜Y×-Ñ-Ð.@ÓAÐAÐAØ�lÐ"Ð"rb   r8  r9  r;  Úbias_tpÚis_per_channelÚreturnc                 óJ  — |j                   syt        |«      }t        j                  t        j                  «      }d}t        j
                  |j                  t        j                  ¬«      t        j
                  |j                  dz   t        j                  ¬«      z
  }	|j                  }
d}|sùt        j                  |j                  «       t        j
                  dt        j                  ¬«      «      }t        j                  |j                  «       t        j
                  dt        j                  ¬«      «      }t        j                  t        j                  |«      t        j                  |«      «      }| j                  ||||
||j                  |	|«      \  }}|r|}d}||fS |j                  rlt!        |j                  «      dk(  rTt#        |j                  d   «      D ]9  }| j                  ||   |||   |
||j                  |	||¬«	      \  }}|sŒ3|||<   d}Œ; ||fS )	zOChecks if the bias scale is too small and increases the weight scale if needed.)FNgq¬‹Ûh ð?r4  r   Fr   T)r?  )Úsizer   r  ÚiinfoÚint32r  Úmaxr  Úminr  ÚminimumÚmaximumr5  rG  r+   Úshaperk   r�   )rF   r8  r9  r;  rH  rI  Úbias_float_dataÚ
int32_infor>  r=  r:  ÚupdatedÚrminÚrmaxr@  ÚchangedrF  rš   s                     rR   Ú#_adjust_weight_scale_for_int32_biasz1ONNXQuantizer._adjust_weight_scale_for_int32_bias¥  sÛ  € ð × Ò Øä/°Ó8ˆÜ—X‘XœbŸh™hÓ'ˆ
Ø!'ÐÜ—‘˜*Ÿ.™.´·
±
Ô;¼b¿h¹hÀzÇ~Á~ÐXYÑGYÔac×akÑakÔ>lÑlˆØ)×/Ñ/ÐØˆáÜ—:‘:˜o×1Ñ1Ó3´R·X±X¸aÄrÇzÁzÔ5RÓSˆDÜ—:‘:˜o×1Ñ1Ó3´R·X±X¸aÄrÇzÁzÔ5RÓSˆDÜ—Z‘Z¤§¡ t£¬b¯f©f°T«lÓ;ˆFØ!%×!JÑ!JØØØØ"ØØ—‘ØØ&ó	"ÑˆG�Yñ Ø(�Ø�ð$ ˜Ð$Ð$ð# ×Ò¤C¨×(:Ñ(:Ó$;¸qÒ$@Ü˜<×-Ñ-¨aÑ0Ó1ò #�Ø%)×%NÑ%NØ# AÑ&ØØ  ‘OØ&ØØ—L‘LØØ*Øð &Oó 
&Ñ"�˜ò Ø&/�L ‘OØ"‘Gð#ð  ˜Ð$Ð$rb   rF  c                 ó(  — || j                   vry| j                   |   }t        || j                  j                  «       «      }t        |j                  | j                  j                  «       «      }t        |j
                  | j                  j                  «       «      }t        |j                  | j                  j                  «       «      }|�|�|�|€y| j                  j                  |«       | j                  j                  |«       t        j                  j                  |«      }|j                  }	t        j                  |t        j                  j                  |j                   «      ¬«      }
t        j                  j#                  |
j%                  |j&                  «      |j                  «      }| j                  j)                  |«       t+        || j,                  ||
|	|j                  ¬«      }| j                  j)                  |«       y)zCRe-quantizes the given weight initializer using the provided scale.Nr4  )Úquant_weight_name)rC   r   r'   r‚   r  r-  Úq_nameÚremove_initializerrW   Únumpy_helperÚto_arrayÚaxisr  ÚasarrayrX   Útensor_dtype_to_np_dtyper¨   Ú
from_arrayr  ÚdimsrÕ   r   rI   )rF   r;  rF  ÚqvÚ	weight_tpÚ
scale_initÚzp_initÚq_weight_initÚweight_zero_pointra  Úscale_npÚnew_scale_initÚnew_q_weights                rR   Ú_requantize_weightz ONNXQuantizer._requantize_weightÝ  s”  € ð ˜d×6Ñ6Ñ6Øà×%Ñ% kÑ2ˆä  ¨d¯j©j×.DÑ.DÓ.FÓGˆ	Ü! "§-¡-°·±×1GÑ1GÓ1IÓJˆ
Ü˜rŸz™z¨4¯:©:×+AÑ+AÓ+CÓDˆÜ$ R§Y¡Y°·
±
×0FÑ0FÓ0HÓIˆàÐ 
Ð 2°g°oÈÐI^Øà�
‰
×%Ñ% jÔ1Ø�
‰
×%Ñ% mÔ4ä ×-Ñ-×6Ñ6°wÓ?ÐØ�w‰wˆô —:‘:˜i¬t¯{©{×/SÑ/SÐT]×TgÑTgÓ/hÔiˆÜ×*Ñ*×5Ñ5°h×6FÑ6FÀzÇÁÓ6WÐY[×YfÑYfÓgˆØ�
‰
×"Ñ" >Ô2ô 1ØØ×ÑØØØØ Ÿi™iô
ˆð 	�
‰
×"Ñ" <Õ0rb   c           
      óÚ  — || j                   v r| j                   |   j                  S | j                   |   j                  }t        || j                  j                  «       «      }t        |«      }|| j                   v r| j                   |   j                  }n5|| j                  v r| j                  |«      \  }	}}	}	}	nt        d|› d�«      ‚t        || j                  j                  «       «      }
t        |
«      }| j                   |   j                  }t        || j                  j                  «       «      }|�t        j                  j                  |«      nd}| j                  }|�•|j                  r‰|j!                  «       sy| j"                  t$        j&                  j(                  fv rRt        || j                  j                  «       «      }| j+                  |||||«      \  }}|r| j-                  ||«       |}| j/                  ||||«      \  }}}}}}|| j                   vsJ ‚t1        ||||t2        j4                  |j                  dkD  rdnd||¬«      }|| j                   |<   |S )z]
        Quantized the bias. Zero Point == 0 and Scale == Input_Scale * Weight_Scale
        z	Expected z5 to be in quantized value map for static quantizationNr   r   )Ú	node_typeÚ
node_qtype)rC   r]  r  r   r'   r‚   r   r>   r#  r<   r-  rW   r_  r`  rG   rL  r~   rI   r´   rµ   rº   rZ  ro  Úquantize_bias_static_implr   r   ÚInitializer)rF   r<  r¾   r;  ÚbetaÚweight_scale_nameÚweight_initializerr9  rÖ   r›   Úinputscale_initializerr8  Úweight_zp_nameÚweight_zp_initrk  rI  Úbias_initializerÚ
did_updateÚnew_weight_scaleÚquantized_bias_nameÚquantized_bias_scale_nameÚquantized_bias_zp_nameÚbias_scale_datarq  rr  Úquantized_values                             rR   Úquantize_bias_staticz"ONNXQuantizer.quantize_bias_static  st  € ð ˜×0Ñ0Ñ0Ø×+Ñ+¨IÑ6×=Ñ=Ð=ð !×4Ñ4°[ÑA×LÑLÐÜ)Ð*;¸T¿Z¹Z×=SÑ=SÓ=UÓVÐÜ,Ð-?Ó@ˆð ˜×1Ñ1Ñ1Ø#×7Ñ7¸
ÑC×NÑNÑØ˜4×3Ñ3Ñ3Ø+/×+HÑ+HÈÓ+TÑ(ˆAÐ  A¡qä˜y¨¨Ð4iÐjÓkÐkä!-Ð.>ÀÇ
Á
×@VÑ@VÓ@XÓ!YÐÜ+Ð,BÓCˆð ×1Ñ1°+Ñ>×FÑFˆÜ% n°d·j±j×6LÑ6LÓ6NÓOˆØJXÐJdœD×-Ñ-×6Ñ6°~ÔFÐjnÐØ×)Ñ)ˆàÐ)Ø!×&Ò&Ø%×)Ñ)Ô+Ø×!Ñ!¤j×&<Ñ&<×&AÑ&AÐ%CÑCä+¨I°t·z±z×7MÑ7MÓ7OÓPÐØ+/×+SÑ+SØØØØ Øó,Ñ(ˆJÐ(ñ Ø×'Ñ'¨Ð5EÔFØ/�ð ×*Ñ*¨9°kÀ<ÐQUÓVñ	
ØØ%Ø"ØØØð  × 8Ñ 8Ñ8Ð8Ð8Ü(ØØØ%Ø"Ü×*Ñ*Ø ×%Ñ%¨Ò)‰A¨tØØ!ô	
ˆð />ˆ× Ñ  Ñ+à"Ð"rb   c                 ó^   — || j                   v xs || j                  v xs || j                  v S )zq
        only check for value info and newly generated tensor names, initializers are checked separately
        )r,   r8   rE   r£   s     rR   Úcontains_tensorzONNXQuantizer.contains_tensorK  s=   € ð
 ˜D×,Ñ,Ð,ò ;Ø˜t×0Ñ0Ð0ò;à˜t×9Ñ9Ð9ð	
rb   c           	      ó2   — | j                  ||dddd|¬«      S )NFr  ©r9   ÚindicesÚinitializer_use_weight_qTyperH   Úop_level_per_channelra  Úfrom_subgraph©Ú_ONNXQuantizer__quantize_inputs)rF   r9   rˆ  r‹  s       rR   Úquantize_activationz!ONNXQuantizer.quantize_activationU  s/   € Ø×%Ñ%ØØØ).ØØ!&ØØ'ð &ó 
ð 	
rb   c           	      ó2   — | j                  ||d||||¬«      S )NTr‡  rŒ  )rF   r9   rˆ  rH   rŠ  ra  r‹  s          rR   Úquantize_weightzONNXQuantizer.quantize_weightb  s1   € ð ×%Ñ%ØØØ)-Ø%Ø!5ØØ'ð &ó 
ð 	
rb   c           
      ó’  — g }g }	g }
g }|D �]4  }|j                   |   }|| j                  v ra| j                  |   }|j                  |j                  «       |	j                  |j                  «       |
j                  |j
                  «       Œ‚|s4|
j                  d«       |j                  d«       |	j                  d«       Œ¸t        || j                  j                  «       «      }|�­| j                  r=|r;| j                  |j                  |r| j                  n| j                  ||«      \  }}}n/| j                  ||r| j                  n| j                  |«      \  }}}|
j                  |«       |	j                  |«       |j                  |«       �Œ‹| j                  |«      �r| j                  j!                  |dz   | j"                  | j                  j%                  «       «      }|�€|j                   |   }|| j&                  v rr| j&                  |   }|j)                  d«      sJ d|› d�«       ‚|j*                  j)                  d«      sJ d|› d�«       ‚|j*                  j,                  j.                  }n(|| j0                  v sJ d|›d	�«       ‚| j0                  |   }| j3                  ||| j                  |¬
«      }|€ y|r| j5                  |«       n|j7                  |«       |d   }|j8                  dk(  rY|
j7                  |j:                  «       |j                  |j                   d   «       |	j                  |j                   d   «       �ŒN|
j                  |j:                  d   «       |j                  |j:                  d   «       |	j                  |j:                  d   «       �Œª| j<                  �f| j<                  j?                  ||g||||d¬«      \  }}}}|
j                  |d   «       |j                  |d   «       |	j                  |d   «       �ŒtA        d|› d| jB                  › �«      ‚ |
|	||fS )a›  
        Given a node, this function quantizes the inputs as follows:
            - If input is an initializer, quantize the initializer data, replace old initializer
              with new initializer
            - Else, add QuantizeLinear nodes to perform quantization
            parameter node: node being quantized in NodeProto format.
            parameter indices: input indices to quantize.
            return: (List of quantized input names,
                     List of zero point names used for input quantization,
                     List of scale names used for input quantization,
                     List of new QuantizeLinear nodes created)
        r   r%  rg   zvalue_info=z has no type.r§   z is not a tensor.zshape inference failed for zF and attribute 'tensor_names' does not have any value for this tensor.r'  )NNNNr  rz   r   é   r   T)r‰  rH   rŠ  ra  r‹  z!Invalid tensor name to quantize: z @graph scope)"r/   rC   rÓ   r  r-  r]  r   r'   r‚   rG   Úquantize_weight_per_channelr+   rI   rJ   Úquantize_initializerr…  Úfind_node_by_namer6   r)   r,   r©   rg   r§   rª   r8   r0  r‰   ro   rl   r.   r[   r�  r<   r7   )rF   r9   rˆ  r‰  rH   rŠ  ra  r‹  Úscale_namesÚzero_point_namesÚquantized_input_namesr   r(  Ú
node_inputr‚  r‚   Úq_weight_namer-  r  r.  r¾   r*   rÁ   Úquantize_input_nodesÚparent_quantized_input_namesÚparent_zero_point_namesÚparent_scale_namesr›   s                               rR   Ú__quantize_inputszONNXQuantizer.__quantize_inputsu  sd  € ð. ˆØÐØ "ÐØˆà"ó c	rˆKØŸ™ KÑ0ˆJð ˜T×5Ñ5Ñ5Ø"&×":Ñ":¸:Ñ"F�Ø×"Ñ" ?×#=Ñ#=Ô>Ø ×'Ñ'¨×(?Ñ(?Ô@Ø%×,Ñ,¨_×-CÑ-CÔDØáØ%×,Ñ,¨RÔ0Ø×"Ñ" 2Ô&Ø ×'Ñ'¨Ô+Øä& z°4·:±:×3IÑ3IÓ3KÓLˆKØÐ&Ø×#Ò#Ñ(<ð
 ×8Ñ8Ø#×(Ñ(Ù-I˜×)Ò)Èt×OdÑOdØØ$ó	ñ	Ø%ØÙ"ð :>×9RÑ9RØ#Ù-I˜×)Ò)Èt×OdÑOdØ$ó:Ñ6�M 7¨Jð &×,Ñ,¨]Ô;Ø ×'Ñ'¨Ô0Ø×"Ñ" :Ö.Ø×%Ñ% jÕ1à#Ÿz™z×;Ñ;ØÐ!2Ñ2°D·N±NÀDÇJÁJ×DTÑDTÓDVó �ð  Ñ'Ø!%§¡¨KÑ!8�JØ! T×%5Ñ%5Ñ5Ø%)×%5Ñ%5°jÑ%A˜
Ø)×2Ñ2°6Ô:Ðc¸kÈ*ÈÐUbÐ<cÓcÐ:Ø)Ÿ™×7Ñ7¸ÔFÐsÈ+ÐV`ÐUaÐarÐHsÓsÐFØ'1§¡×'BÑ'B×'LÑ'L™ð  *¨T×->Ñ->Ñ>ð Ø9¸*¸ð H+ð ,óÐ>ð
 (,×'8Ñ'8¸Ñ'D˜Ø+/×+IÑ+IØ˜k¨4×+@Ñ+@È|ð ,Jó ,Ð(ð ,Ð3Ù7Ù$Ø×*Ñ*Ð+?Õ@àŸ™Ð%9Ô:Ø#7¸Ñ#;�Là×'Ñ'Ð+;Ò;Ø)×0Ñ0°×1DÑ1DÔEØ×&Ñ& |×'9Ñ'9¸!Ñ'<Ô=Ø$×+Ñ+¨L×,>Ñ,>¸qÑ,AÖBà)×0Ñ0°×1DÑ1DÀQÑ1GÔHØ×&Ñ& |×':Ñ':¸1Ñ'=Ô>Ø$×+Ñ+¨L×,?Ñ,?ÀÑ,BÖCØ—‘Ð(ð —K‘K×1Ñ1ØØ �MØ1MØ!-Ø)=ØØ"&ð 2ó ñØ0Ø+Ø&Øð &×,Ñ,Ð-IÈ!Ñ-LÔMØ×"Ñ"Ð#5°aÑ#8Ô9Ø ×'Ñ'Ð(?ÀÑ(BÖCô !Ð#DÀZÀLÐP]Ð^b×^nÑ^nÐ]oÐ!pÓqÐqðGc	rðJ %Ð&6¸ÀUÐJÐJrb   c                 óf  — |j                   | j                  v r<| j                  |j                      }|j                  |j                  |j                  fS | j                  ||||«      \  }}}t        |j                   |||t        j                  d«      }|| j                  |j                   <   |||fS )aš  
        :param weight: TensorProto initializer
        :param qType: type to quantize to
        :param keep_float_weight: Whether to quantize the weight. In some cases, we only want to qunatize scale and zero point.
                                  If keep_float_weight is False, quantize the weight, or don't quantize the weight.
        :return: quantized weight name, zero point name, scale name
        N)	r+   rC   r]  r-  r  Úquantize_initializer_implr   r   rt  )	rF   r®   rÀ   rH   Úkeep_float_weightr‚  rš  r-  r  s	            rR   r”  z"ONNXQuantizer.quantize_initializerø  s¾   € ð �;‰;˜$×2Ñ2Ñ2Ø"×6Ñ6°v·{±{ÑCˆOà×&Ñ&Ø×'Ñ'Ø×*Ñ*ðð ð .2×-KÑ-KØ�E˜<Ð):ó.
Ñ*ˆ�w 
ô
 )Ø�K‰KØØØÜ×*Ñ*Øó
ˆð 1@ˆ× Ñ  §¡Ñ-Ø˜g zÐ1Ð1rb   c                 ó  — || j                   v r2| j                   |   }|j                  |j                  |j                  fS | j	                  |||||«      \  }}}	t        |||	|t        j                  |«      }|| j                   |<   |||	fS r†   )rC   r]  r-  r  Ú quantize_weight_per_channel_implr   r   rt  )
rF   r;  rI   Úchannel_axisrH   r¢  r‚  rš  r-  r  s
             rR   r“  z)ONNXQuantizer.quantize_weight_per_channel  s°   € ð ˜$×2Ñ2Ñ2Ø"×6Ñ6°{ÑCˆOà×&Ñ&Ø×'Ñ'Ø×*Ñ*ðð ð .2×-RÑ-RØ˜ |°\ÐCTó.
Ñ*ˆ�w 
ô )ØØØØÜ×*Ñ*Øó
ˆð 1@ˆ× Ñ  Ñ-à˜g zÐ1Ð1rb   c                 ó  — || j                   v �r~|| j                  v�ro| j                   |   }t        |j                  | j                  j                  «       «      }| j                  j                  j                  dk7  s%| j                  j                  j                  dk(  r>|�<|j                  €0|�.t        j                  j                  |«      j                  dk(  sJ ‚|dz   }| j                  j                  || j                  | j                  j                  «       «      }|€T|j                  |j                  |j                   g}t        j"                  j%                  d||g||j                  ¬«      }|S ||j&                  d   k(  sJ ‚y)a¶  
        Given a value (input/output) which is quantized, add a DequantizeLinear node to dequantize
        it back to float32 or float16
            parameter value_name: value to dequantize
            parameter new_nodes_list: List of new nodes created before processing current node
            return: None if there is already a DequantizeLinear node that dequantizes it
                    A DequantizeLinear node otherwise
        rT   Nr   Ú_DequantizeLinearr{   )ra  r   )rC   rE   r   r  r'   r‚   rU   ra  rW   r_  r`  rL  r•  r6   r)   r]  r-  rX   rp   r.   )rF   Ú
value_namer‚  rh  Údqlinear_nameÚdqlinear_nodeÚdqlinear_inputsÚdequantize_nodes           rR   Ú_dequantize_valuezONNXQuantizer._dequantize_value9  sy  € ð ˜$×2Ñ2Ò2¸È4×KeÑKeÒ9eØ"×6Ñ6°zÑBˆOô & o×&@Ñ&@À$Ç*Á*×BXÑBXÓBZÓ[ˆJð �z‰z×Ñ×-Ñ-Ð1AÒAØ—
‘
× Ñ ×.Ñ.Ð2BÒBÀzÐG]ð #×'Ñ'Ð/Ø%Ð-´×1BÑ1B×1KÑ1KÈJÓ1W×1\Ñ1\Ð`aÒ1aÐaÐaà&Ð)<Ñ<ˆMØ ŸJ™J×8Ñ8¸ÈÏÉÐX\×XbÑXb×XhÑXhÓXjÓkˆMØÐ$à#×*Ñ*Ø#×.Ñ.Ø#×+Ñ+ð#�ô
 #'§+¡+×"7Ñ"7Ø&Ø#Ø�LØ!Ø(×-Ñ-ð #8ó #�ð 'Ð&ð " ]×%9Ñ%9¸!Ñ%<Ò<Ð<Ð<Ørb   c                 óÈ   — | j                   j                  «       j                  D ];  }| j                  |j                  «      }|€Œ!| j
                  j                  |«       Œ= y)zÃ
        Dequantize output if it is quantized
            parameter new_nodes_list: List of new nodes created before processing current node
            return: List of new nodes created
        N)r'   r)   r.   r­  r+   r6   rÓ   )rF   r.   r¬  s      rR   r�   z!ONNXQuantizer._dequantize_outputse  sR   € ð —j‘j×&Ñ&Ó(×/Ñ/ò 	7ˆFØ"×4Ñ4°V·[±[ÓAˆOØÑ*Ø—‘×%Ñ% oÕ6ñ	7rb   c           	      óØ  — | j                   €y | j                  «        i }| j                   D �]º  }| j                   |   }t        |t        «      st	        dt        |«      › d|›d�«      ‚| j                  j                  |i ¬«      }| j                  }d|v r|d   j                  }d|v rd|v r|d   |d   }}�n|t        j                  j                  k(  rt        ||j                  d   «      \  }}nâ|j                  d	|j                   d
   «      }|j                  d|j                   d   «      }	|j                  d| j"                  «      }
|j                  dd«      }t%        |||
¬«      \  }}t'        ||	|||
| j(                  «      \  }}| j*                  r<|t        j                  j,                  k(  r|
st/        ||	||| j(                  ¬«      \  }}t1        |||¬«      ||<   �Œ½ |S )Nr  r  r²   )Údefault_valr  r  r  r   rW  r   rX  Ú	symmetricrH   F)rH   r±  )ÚqminÚqmaxÚmin_real_range)r  r  r  )rK   Úadjust_tensor_rangesr	  r   r
  rg   Útensor_quant_overridesÚget_per_tensor_overridesrJ   r§   rW   rµ   ÚFLOAT8E4M3FNr   Úavg_stdÚgetÚrange_valueÚis_activation_symmetricr   r   r´  Ú#is_activation_restricted_asymmetricr¼   r   r   )rF   r>   r¤   ÚtdÚquant_overridesr  Úzeror  rW  rX  r±  rH   r²  r³  s                 rR   r=   z+ONNXQuantizer.calculate_quantization_paramsq  só  € Ø×ÑÐ%Øà×!Ñ!Ô#à ÐØ×-Ñ-ó 	wˆKØ×#Ñ# KÑ0ˆBÜ˜b¤*Ô-ÜÐ"2´4¸³8°*¸EÀ+ÀÐPQÐ RÓSÐSà"×9Ñ9×RÑRÐS^ÐlnÐRÓoˆOà×.Ñ.ˆJØ˜Ñ.Ø,¨\Ñ:×FÑF�
à˜/Ñ)¨l¸oÑ.MØ-¨lÑ;¸_ÈWÑ=U�e’Øœt×/Ñ/×<Ñ<Ò<Ü5°jÀ"Ç*Á*ÈQÁ-ÓP‘�‘eà&×*Ñ*¨6°2·>±>À!Ñ3DÓE�Ø&×*Ñ*¨6°2·>±>À!Ñ3DÓE�Ø+×/Ñ/°¸T×=YÑ=YÓZ�	Ø.×2Ñ2°>À5ÓI�Ü4°ZÈlÐfoÔp‘
��dÜ.¨t°T¸4ÀÀyÐRV×ReÑReÓf‘��eØ×;Ò;À
Ìd×N^ÑN^×NdÑNdÒ@dÑmvä":Ø˜d¨°DÈ×I\ÑI\ô#‘K�D˜%ô 0BÈTÐY^ÐkuÔ/vÐ Ó,ð9	wð< #Ð"rb   r†   )F)NN)NNN)g      ð?)FFr  F)TFFr  F)FF)TF)'Ú__name__Ú
__module__Ú__qualname__r&   ra   rw   r€   rƒ   r‰   r\   r¥   r¬   r¸   rÂ   r»   r½   r#  r0  r2  rG  r  Úndarrayr”   rW   rµ   ÚboolÚtuplerZ  ro  rƒ  r…  rŽ  r�  r�  r”  r“  r­  r�   r=   © rb   rR   r   r   '   sZ  „ ð óFMòR/ò> fòD
òò<ò+ òZ
ó"ò2ò2AòRAòh\7ó|9Pðx aeóD&òLð" ó##ðJ6%à—Z‘Zð6%ð —j‘jð6%ð ð	6%ð
 ×!Ñ!ð6%ð ð6%ð 
ˆt�R—Z‘Z $Ñ&Ð&Ñ	'ó6%ðp$1¨cð $1¸b¿j¹jð $1ÈTó $1óLF#òP
ó	
ð" Ø"ØØó
ð. &*ØØ"ØØóAKóF2ðL Øó2ò@*òX
7ó%#rb   r   )$r‹   Únumpyr  rW   Úonnx.numpy_helperr   r´   Úbase_quantizerr   r   Ú	calibrater   Ú
onnx_modelr   Úquant_utilsr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Úregistryr   r   rÇ  rb   rR   ú<module>rÏ     sK   ðó ã Û Û Ý &ç =Ý !Ý !÷÷ ÷ ÷ ÷ õ( (ôo#�Mõ o#rb   