§
    ¹¯Å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 ddl m!Z!  G d	„ d
e¦  «        Z"dS )é    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Ú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j        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 	 	 	 	 	 d0d$„Z!d1d%„Z"	 	 d2d&„Z#d'„ Z$d(„ Z%d)„ Z&dS )3ÚONNXQuantizerNc                 ó´  — t          j        | |||||||	|
||¦  «         |s½| j                             ¦   «          t	          | j        j        ¦  «        }d„ |j        j        D ¦   «         | _        | j                             d„ |j        j	        D ¦   «         ¦  «         | j                             d„ |j        j
        D ¦   «         ¦  «         t          |¦  «        | _        || _        || _        | j        dk    | _        d| j        v o| j        d         | _        g | _        d| _        i | _        | j                             d„ |j        j	        D ¦   «         ¦  «         | j                             d„ |j        j
        D ¦   «         ¦  «         | j        j        j        j        D ]:}| j                             t,                               |j	        d	¦  «        ¦  «         Œ;| j        t0          vrt3          d
| j        › �¦  «        ‚|                      ¦   «         | _        d| _        d| _        d| _        d| _        i | _         | j         !                    ¦   «         | _"        d S )Nc                 ó   — i | ]
}|j         |“ŒS © ©Úname)Ú.0Úvis     úXC:\Projects\Historical\venv\Lib\site-packages\onnxruntime/quantization/onnx_quantizer.pyú
<dictcomp>z*ONNXQuantizer.__init__.<locals>.<dictcomp>H   s   € ÐMÐMÐM° ¤¨ÐMÐMÐMó    c                 ó   — i | ]
}|j         |“ŒS r   r    ©r"   Úots     r$   r%   z*ONNXQuantizer.__init__.<locals>.<dictcomp>I   s   € Ð$NÐ$NÐ$N°R R¤W¨bÐ$NÐ$NÐ$Nr&   c                 ó   — i | ]
}|j         |“ŒS r   r    ©r"   Úits     r$   r%   z*ONNXQuantizer.__init__.<locals>.<dictcomp>J   s   € Ð$MÐ$MÐ$M°R R¤W¨bÐ$MÐ$MÐ$Mr&   é
   ÚMatMulConstBOnlyú/c                 ó   — i | ]
}|j         d “ŒS ©r   r    r(   s     r$   r%   z*ONNXQuantizer.__init__.<locals>.<dictcomp>V   s   € Ð!JÐ!JÐ!J° "¤'¨1Ð!JÐ!JÐ!Jr&   c                 ó   — i | ]
}|j         d “ŒS r1   r    r+   s     r$   r%   z*ONNXQuantizer.__init__.<locals>.<dictcomp>W   s   € Ð!IÐ!IÐ!I° "¤'¨1Ð!IÐ!IÐ!Ir&   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Ú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)Úselfr8   Úper_channelÚreduce_ranger@   rA   Úweight_qTypeÚactivation_qTypeÚtensors_rangeÚnodes_to_quantizeÚnodes_to_excludeÚop_types_to_quantizerD   rI   s                 r$   r7   zONNXQuantizer.__init__'   s`  € õ 	ÔØØØØØØØØØØ Øñ	
ô 	
ð 	
ð ð 	*ØŒJ×/Ò/Ñ1Ô1Ð1å:¸4¼:Ô;KÑLÔLˆEØMÐM°e´kÔ6LÐMÑMÔMˆDÔØÔ×#Ò#Ð$NÐ$N¸5¼;Ô;MÐ$NÑ$NÔ$NÑOÔOÐOØÔ×#Ò#Ð$MÐ$M¸5¼;Ô;LÐ$MÑ$MÔ$MÑNÔNÐNÝ" 5Ñ)Ô)ˆDŒJàˆŒ	ØˆŒØ"&Ô"4°rÒ"9ˆÔà%7¸4Ô;MÐ%MÐ%xÐRVÔRdÐewÔRxˆÔ"àˆŒØˆÔØˆÔØÔ× Ò Ð!JÐ!J°u´{Ô7IÐ!JÑ!JÔ!JÑKÔKÐKØÔ× Ò Ð!IÐ!I°u´{Ô7HÐ!IÑ!IÔ!IÑJÔJÐJØ”JÔ$Ô*Ô/ð 	Dð 	DˆDØÔ×$Ò$¥T§]¢]°4´;ÀÑ%BÔ%BÑCÔCÐCÐCàŒ9Õ,Ð,Ð,ÝÐI¸d¼iÐIÐIÑJÔJÐJà#'×#EÒ#EÑ#GÔ#GˆÔ ð (HˆÔ$Ø&EˆÔ#à+ˆÔà"1ˆÔð $&ˆÔ ð &*¤Z×%JÒ%JÑ%LÔ%LˆÔ"Ð"Ð"r&   c                 óž  — t           j                             |d| j        j        j        ¬¦  «        }t          |¦  «         t          || j        | j        | j	        | j
        | j        | j        | j        | j        | j        | j        | j        ¦  «        }| |_        | j        › |› d�|_        |                     ¦   «          |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_modelr8   Úopset_importr   r   rW   rX   r@   rA   rY   rZ   r[   r\   r]   r^   rD   ÚparentrG   Úquantize_modelr:   )rV   ÚsubgraphÚ	graph_keyÚwarped_modelÚsub_quantizers        r$   Úquantize_subgraphzONNXQuantizer.quantize_subgraphp   s×   € õ ”{×-Ò-ØØ*Øœ*Ô*Ô7ð .ñ 
ô 
ˆõ
 	˜<Ñ(Ô(Ð(Ý%ØØÔØÔØŒIØŒKØÔØÔ!ØÔØÔ"ØÔ!ØÔ%ØÔñ
ô 
ˆð  $ˆÔØ'+Ô'7Ð$E¸Ð$EÐ$EÐ$EˆÔ!Ø×$Ò$Ñ&Ô&Ð&ØÔ"Ô(Ô.Ð.r&   c                 óÚ  — d„ |j         D ¦   «         }t          |¦  «        dk    r|S |j        r|j        n|j        › dt          | j        ¦  «        › �}i }|j         D ]á}|j        t          j        j        k    r-|j        |  	                    |j
        |› d|j        › �¦  «        i}nƒ|j        t          j        j        k    rZg }|j        D ]F}|                     |  	                    ||› d|j        › dt          |¦  «        › �¦  «        g¦  «         ŒG|j        |i}nt          |¦  «        }|                     |¦  «         Œât          j        j        |j        |j        |j        fd|j        i|¤ŽS )z|
        Check subgraph, if any, quantize it and replace it.
        return new_nodes added for quantizing subgraph
        c                 óz   — g | ]8}|j         t          j        j        k    s|j         t          j        j        k    ¯6|‘Œ9S r   )Útyperc   ÚAttributeProtoÚGRAPHÚGRAPHS)r"   Úattrs     r$   ú
<listcomp>z>ONNXQuantizer.quantize_node_with_sub_graph.<locals>.<listcomp>”   sG   € ð 
ð 
ð 
àØŒy�DÔ/Ô5Ò5Ð5¸¼ÅdÔFYÔF`Ò9`Ð9`ð à9`Ð9`Ð9`r&   r   Ú_node_count_ú:r!   )Ú	attributeÚlenr!   Úop_typerF   rp   rc   rq   rr   rm   Úgrs   ÚgraphsÚextendr   r=   rd   Ú	make_noder?   r>   )	rV   rI   Úgraph_attrsÚ	node_nameÚkwargsrt   ÚkvÚvalueri   s	            r$   Úquantize_node_with_sub_graphz*ONNXQuantizer.quantize_node_with_sub_graph�   s¤  € ð

ð 
àœð
ñ 
ô 
ˆõ
 ˆ{ÑÔ˜qÒ Ð ØˆKØ!%¤Ðb�D”I�I°4´<Ð0bÐ0bÍSÐQUÔQ_ÑM`ÔM`Ð0bÐ0bˆ	ØˆØ”Nð 	ð 	ˆDØŒy�DÔ/Ô5Ò5Ð5Ø”i ×!7Ò!7¸¼À9Ð@ZÐ@ZÈtÌyÐ@ZÐ@ZÑ![Ô![Ð\��Ø”�dÔ1Ô8Ò8Ð8Ø�Ø $¤ð ð �HØ—L’Là ×2Ò2Ø (Ø#,Ð GÐ G¨t¬yÐ GÐ G½3¸u¹:¼:Ð GÐ Gñô ðñô ð ð ð ”i Ð'��å'¨Ñ-Ô-�Ø�MŠM˜"ÑÔÐÐÝŒ{Ô$ T¤\°4´:¸t¼{ÐeÐeÐQUÔQZÐeÐ^dÐeÐeÐer&   c                 ób   — t          d„ | j                             ¦   «         D ¦   «         ¦  «        S )zQ
        Detect if model already has QuantizeLinear or DequantizeLinear.
        c              3   óB   K  — | ]}|j         d k    p
|j         dk    V — ŒdS )ÚQuantizeLinearÚDequantizeLinearN)rz   ©r"   rI   s     r$   ú	<genexpr>z.ONNXQuantizer.has_QDQ_nodes.<locals>.<genexpr>µ   sH   è è € ð 
ð 
ØW[ˆDŒLÐ,Ò,ÐR°´Ð@RÒ0Rð
ð 
ð 
ð 
ð 
ð 
r&   )Úanyr8   Únodes)rV   s    r$   Úhas_QDQ_nodeszONNXQuantizer.has_QDQ_nodes±   sA   € õ ð 
ð 
Ø_cÔ_i×_oÒ_oÑ_qÔ_qð
ñ 
ô 
ñ 
ô 
ð 	
r&   c                 óš   — t          || j                             ¦   «         ¦  «        �dS | j        �| j                             |¦  «        S dS )NTF)r   r8   Úinitializerrg   Úfind_initializer_in_path)rV   Úinitializer_names     r$   r�   z&ONNXQuantizer.find_initializer_in_path¹   sJ   € ÝÐ(¨$¬*×*@Ò*@Ñ*BÔ*BÑCÔCÐOØ�4ØŒ;Ð"Ø”;×7Ò7Ð8HÑIÔIÐIØˆur&   c                 óŒ   — | j                              |¦  «         |D ]&}|j        D ]}| j                             |¦  «         ŒŒ'd S ©N)rF   r}   r>   rU   Úadd)rV   rŒ   rI   Úoutput_names       r$   Úadd_new_nodeszONNXQuantizer.add_new_nodesÀ   sa   € ØŒ×Ò˜eÑ$Ô$Ð$Øð 	<ð 	<ˆDØ#œ{ð <ð <�ØÔ*×.Ò.¨{Ñ;Ô;Ð;Ð;ð<ð	<ð 	<r&   c                 ó¬  — |                       ¦   «         rt          j        d¦  «         | j                             ¦   «         D ]ª}| j        r|                      |¦  «        }t          | j        ¦  «        }t          | |¦  «        }| 
                    ¦   «          t          |t          | j        ¦  «        ¦  «        D ]1}| j        |         j        D ]}| j                             |¦  «         ŒŒ2Œ«|                      ¦   «          | j                             ¦   «                              d¦  «         | j                             ¦   «         j                             | j        ¦  «         | j        €N| j                             ¦   «         \  }}t          |¦  «        dk    rt-          dt/          |¦  «        z   ¦  «        ‚t0          | j        j        _        t4          | j        j        _        d„ | j        j        j        D ¦   «         }|sId„ | j        D ¦   «         }	|	r6| j        j        j                             ¦   «         }
d|
_        t<          |
_        | j        j        S )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.rI   r   z0Invalid model with unknown initializers/tensors.c                 ó2   — g | ]}|j         t          k    ¯|‘ŒS r   )Údomainr   )r"   Úopsets     r$   ru   z0ONNXQuantizer.quantize_model.<locals>.<listcomp>é   s%   € ÐbÐbÐb˜eÈÌÕXaÒHaÐHa�EÐHaÐHaÐHar&   c                 ó(   — g | ]}|j         d k    ¯|‘ŒS )zcom.microsoft)r™   r‰   s     r$   ru   z0ONNXQuantizer.quantize_model.<locals>.<listcomp>ë   s$   € ÐZÐZÐZ ¸4¼;È/Ò;YÐ;Y˜Ð;YÐ;YÐ;Yr&   r   ) r�   ÚloggingÚwarningr8   rŒ   Úenable_subgraph_quantizationr„   ry   rF   r   ÚquantizeÚranger>   rU   r”   Ú_dequantize_outputsr:   Ú
ClearFieldrI   r}   rg   Úclean_initializersÚRuntimeErrorÚstrr   ra   r   Úproducer_versionrf   Úversionr   r™   )rV   rI   Únumber_of_existing_new_nodesÚop_quantizerÚir•   Ú_Úinitializers_not_foundÚms_opsetÚms_nodesrš   s              r$   rh   zONNXQuantizer.quantize_modelÆ   sG  € Ø×ÒÑÔð 	ÝŒOðnñô ð ð
 ”J×$Ò$Ñ&Ô&ð 
	@ð 
	@ˆDàÔ0ð ?Ø×8Ò8¸Ñ>Ô>�å+.¨t¬~Ñ+>Ô+>Ð(Ý,¨T°4Ñ8Ô8ˆLØ×!Ò!Ñ#Ô#Ð#ÝÐ7½¸T¼^Ñ9LÔ9LÑMÔMð @ð @�Ø#'¤>°!Ô#4Ô#;ð @ð @�KØÔ.×2Ò2°;Ñ?Ô?Ð?Ð?ð@ð@ð 	× Ò Ñ"Ô"Ð"ð 	Œ
×ÒÑÔ×%Ò% fÑ-Ô-Ð-ØŒ
×ÒÑÔÔ×&Ò& t¤~Ñ6Ô6Ð6ð Œ;ÐØ(,¬
×(EÒ(EÑ(GÔ(GÑ%ˆAÐ%ÝÐ)Ñ*Ô*¨QÒ.Ð.Ý"Ð#UÕX[Ð\rÑXsÔXsÑ#sÑtÔtÐtå)5ˆŒ
ÔÔ&Ý,7ˆŒ
ÔÔ)àbÐb t¤zÔ'7Ô'DÐbÑbÔbˆØð 	)ØZÐZ¨¬ÐZÑZÔZˆHØð )Øœ
Ô(Ô5×9Ò9Ñ;Ô;�Ø !�”Ý(�”àŒzÔÐr&   c                 ó–   — d| j         v r.t          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`.)rD   rœ   Úinfor¤   ©rV   Útensor_names     r$   Ú_get_default_tensor_typez&ONNXQuantizer._get_default_tensor_typeó   ss   € Ø $Ô"4Ð4Ð4ÝŒLØVØØÔ"Ð#6Ô7ñô ð ð
 Ô%Ð&9Ô:Ð:ÝðJ¸ð Jð Jð Jñ
ô 
ð 	
r&   Fc                 óP  — t          || j                             ¦   «         ¦  «        }|�|j        S || j        v rd| j        |         }|j                             d¦  «        r=|r*|j        j        j        dk    r|  	                    |¦  «        S |j        j        j        S | j
        r| j        €|r|  	                    |¦  «        S d S | j                             |¦  «        }|�|S | j
        r%| j        r| j                             |¦  «        }|�|S |r|  	                    |¦  «        S d S )NÚtensor_typer   )r   r8   r�   Ú	data_typer<   rp   ÚHasFieldr¶   Ú	elem_typer´   rž   rg   Úis_valid_quantize_weightÚget_tensor_type)rV   r³   Ú	mandatoryÚweightr#   ÚotypeÚress          r$   r»   zONNXQuantizer.get_tensor_type  sF  € Ý˜k¨4¬:×+AÒ+AÑ+CÔ+CÑDÔDˆØÐØÔ#Ð#Ø˜$Ô*Ð*Ð*ØÔ! +Ô.ˆBØŒw×Ò Ñ.Ô.ð 5Øð F ¤Ô!4Ô!>À!Ò!CÐ!CØ×8Ò8¸ÑEÔEÐEØ”wÔ*Ô4Ð4ØÔ1ð 	°t´{Ð7JØð BØ×4Ò4°[ÑAÔAÐAØ�4Ø”×4Ò4°[ÑAÔAˆØÐØˆLØÔ,ð 	°´ð 	Ø”+×-Ò-¨kÑ:Ô:ˆCØˆØ�
Øð 	>Ø×0Ò0°Ñ=Ô=Ð=Øˆtr&   c                 óè  — |                       |¦  «        r|                      |¦  «        S || j        v r~| j        |         }|j                             d¦  «        r5|j        j        j        t          j        j	        t          j        j
        fv rdS t          j        d|›d|j        › d�¦  «         dS | j        r!| j        r| j                             |¦  «        S t          j        d|›d�¦  «         dS )	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<   rp   r¸   r¶   r¹   Ú
onnx_protoÚTensorProtoÚFLOATÚFLOAT16rœ   r�   rž   rg   Úis_float_tensor)rV   r³   r#   s      r$   rÇ   zONNXQuantizer.is_float_tensor  s"  € Ø×&Ò& {Ñ3Ô3ð 	>Ø×0Ò0°Ñ=Ô=Ð=à˜$Ô*Ð*Ð*ØÔ! +Ô.ˆBØŒw×Ò Ñ.Ô.ð °2´7Ô3FÔ3PÝÔ&Ô,ÝÔ&Ô.ðUð 4ð 4ð �tÝŒOØrÈ{ÐrÐrÐhjÔhoÐrÐrÐrñô ð ð �5àÔ,ð 	<°´ð 	<Ø”;×.Ò.¨{Ñ;Ô;Ð;åŒð7°Kð 7ð 7ð 7ñ	
ô 	
ð 	
ð ˆur&   c                 óØ   — |t           j        j        k    r|                      |||¦  «        S |t           j        j        k    r|                      |||¦  «        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_uint8rL   )rV   Ú
input_nameÚ
nodes_listÚqTypeÚinitial_types        r$   Ú&_get_dynamic_input_quantization_paramsz4ONNXQuantizer._get_dynamic_input_quantization_params6  st   € ð •JÔ*Ô/Ò/Ð/Ø×CÒCÀJÐPZÐ\hÑiÔiÐiØ•JÔ*Ô0Ò0Ð0Ø×DÒDÀZÐQ[Ð]iÑjÔjÐjÝÐ?°uÐ?Ð?Ð?Ñ@Ô@Ð@r&   c                 óö  — t           j        j        }|dz   }|dz   }t          j                             d|g|dz   g|d¬¦  «        }|                     |¦  «         |dz   }t          j                             d|g|dz   g|d¬¦  «        }	|                     |	¦  «         |d	z   }
t          j                             d
|j        d         g|
dz   g|
¦  «        }|                     |¦  «         |d	z   }t          j                             d
|	j        d         g|dz   g|¦  «        }|                     |¦  «         |dz   }t          j                             d|j        d         |j        d         g|dz   g|¦  «        }|                     |¦  «         t          j                             | j	        |g t          |¦  «        dz  g¦  «        }| j                             |¦  «         |dz   }t          j                             d|j        d         | j	        g|g|¦  «        }|                     |¦  «         t          j                             | j        |g dg¦  «        }| 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É   rc   rd   r~   Úappendr>   Úmake_tensorrP   r   r8   Úadd_initializerrR   )rV   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                       r$   rÊ   z9ONNXQuantizer._get_dynamic_input_quantization_params_int8E  sÌ  € õ Ô&Ô+ˆð &¨Ñ0Ðà$ |Ñ3ˆÝœ+×/Ò/ØØˆLØ˜tÑ#Ð$ØØð 0ñ 
ô 
ˆð 	×Ò˜/Ñ*Ô*Ð*à$ |Ñ3ˆÝœ+×/Ò/ØØˆLØ˜tÑ#Ð$ØØð 0ñ 
ô 
ˆð 	×Ò˜/Ñ*Ô*Ð*ð .°Ñ6ÐÝ"œk×3Ò3ØØÔ# AÔ&Ð'Ø  4Ñ'Ð(Øñ	
ô 
Ðð 	×ÒÐ-Ñ.Ô.Ð.à-°Ñ6ÐÝ"œk×3Ò3ØØÔ# AÔ&Ð'Ø  4Ñ'Ð(Øñ	
ô 
Ðð 	×ÒÐ-Ñ.Ô.Ð.à! JÑ.ˆÝ”{×,Ò,ØØ Ô'¨Ô*Ð,?Ô,FÀqÔ,IÐJØ˜DÑ Ð!Øñ	
ô 
ˆð 	×Ò˜,Ñ'Ô'Ð'åœ+×1Ò1ØÔ'ØØÝ! %Ñ(Ô(¨3Ñ.Ð/ñ	
ô 
ˆð 	Œ
×"Ò" ?Ñ3Ô3Ð3Ø# kÑ1ˆÝœ×.Ò.ØØÔ  Ô# TÔ%@ÐAØÐØñ	
ô 
ˆð 	×Ò˜.Ñ)Ô)Ð)õ œ×0Ò0°Ô1HÈ%ÐQSÐVWÐUXÑYÔYˆØŒ
×"Ò" >Ñ2Ô2Ð2à Ô!8¸"¸bÐ@Ð@r&   c                 ó  — t           j        j        }|dz   }|dz   }|dz   }t          j                             d|g|dz   g|d¬¦  «        }|                     |¦  «         |dz   }	t          j                             d	|g|	dz   g|	d¬¦  «        }
|                     |
¦  «         t          j                             | j        |g t          |¦  «        g¦  «        }| j
                             |¦  «         t          j                             | j        |g d
g¦  «        }| j
                             |¦  «         |dz   }t          j                             d|
j        d         |j        d         g|dz   g|¦  «        }|                     |¦  «         |dz   }t          j                             d|j        d         | j        g|g|¦  «        }|                     |¦  «         |dz   }t          j                             d| j        |j        d         g|dz   g|¦  «        }|                     |¦  «         |dz   }t          j                             d|j        d         |g|dz   g|¦  «        }|                     |¦  «         |dz   }t          j                             d|j        |dz   g|¦  «        }|                     |¦  «         |dz   }t          j                             d|j        |g||¬¦  «        }|                     |¦  «         ||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Ë   rc   rd   r~   râ   rã   rO   r   r8   rä   rQ   r>   )rV   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                            r$   rÌ   z:ONNXQuantizer._get_dynamic_input_quantization_params_uint8™  sb  € õ Ô&Ô,ˆà%¨Ñ0ÐØ" ]Ñ2ˆà$ |Ñ3ˆÝœ+×/Ò/ØØˆLØ˜tÑ#Ð$ØØð 0ñ 
ô 
ˆð 	×Ò˜/Ñ*Ô*Ð*à$ |Ñ3ˆÝœ+×/Ò/ØØˆLØ˜tÑ#Ð$ØØð 0ñ 
ô 
ˆð 	×Ò˜/Ñ*Ô*Ð*õ "œ[×4Ò4ØÔ(ØØÝ! %Ñ(Ô(Ð)ñ	
ô 
Ðð 	Œ
×"Ò"Ð#5Ñ6Ô6Ð6Ý!œ[×4Ò4°TÔ5IÈ<ÐY[Ð^aÐ]bÑcÔcÐØŒ
×"Ò"Ð#5Ñ6Ô6Ð6ð $ lÑ2ˆÝœ×.Ò.ØØÔ# AÔ&¨Ô(>¸qÔ(AÐBØ˜dÑ"Ð#Øñ	
ô 
ˆð 	×Ò˜.Ñ)Ô)Ð)à# lÑ2ˆÝœ×.Ò.ØØÔ" 1Ô% tÔ'CÐDØÐØñ	
ô 
ˆð 	×Ò˜.Ñ)Ô)Ð)ð !Ð#4Ñ4ˆÝ”k×+Ò+ØØÔ! ?Ô#9¸!Ô#<Ð=Ø˜4ÑÐ Øñ	
ô 
ˆð 	×Ò˜+Ñ&Ô&Ð&à Ð#4Ñ4ˆÝ”k×+Ò+ØØÔ Ô"Ð$4Ð5Ø˜4ÑÐ Øñ	
ô 
ˆð 	×Ò˜+Ñ&Ô&Ð&à"Ð%8Ñ8ˆÝœ×-Ò-¨g°{Ô7IÈMÐ\`ÑL`ÐKaÐcpÑqÔqˆØ×Ò˜-Ñ(Ô(Ð(à!Ð$6Ñ6ˆÝ”{×,Ò,¨V°]Ô5IÈMÈ?Ð\hÐmrÐ,ÑsÔsˆØ×Ò˜,Ñ'Ô'Ð'à °°BÐ6Ð6r&   c                 ó"  — | j         }|�|�€R| j        �	|| j        vrt          j        d|› d�¦  «         dS | j        |         }t	          |t
          ¦  «        s#t          dt          |¦  «        › d|›d�¦  «        ‚|�t          |¦  «        dk    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        k    sJ ‚|d         }ntt          j        |g¦  «        }t          j        |g¦  «        }| j        |         }d|v r"|d         j        }|                     |¦  «        }|j        t          j        k    sJ ‚g }	|dz   }
g }|dz   }t$          j                             |
||	|                     ¦   «                              ¦   «         ¦  «        }| j                             |¦  «         |j        t          j        k    rt2          j        j        }nA|j        t          j        k    rt2          j        j        }nt          d|j        › d|›�¦  «        ‚t$          j                             ||||                     d¦  «                             ¦   «         ¦  «        }| j                             |¦  «         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.
        Nz$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)rZ   rN   rœ   r±   Ú
isinstancer   Ú	TypeErrorrp   ry   rL   ÚnpÚarrayÚhasattrr  Úfloat32Úfloat16Úfloat64Úastyperc   rd   rã   ÚravelÚtolistr8   rä   rÃ   rÄ   rÅ   rÆ   Úreshape)rV   Ú
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                   r$   Ú_get_quantization_paramsz&ONNXQuantizer._get_quantization_params÷  s5  € ð Ô/ˆàÐ Ñ 5ØÔ'Ð/°:ÀTÔE]Ð3]Ð3]Ý”Ð_ÀJÐ_Ð_Ð_Ñ`Ô`Ð`Ø,Ð,àÔ-¨jÔ9ˆFÝ˜fÕ&8Ñ9Ô9ð WÝÐ Uµ4¸±<´<Ð UÐ UÀjÐ UÐ UÐ UÑVÔVÐVØˆ~¥ V¡¤°Ò!1Ð!1Ý ðJØ3=ðJð JØAGðJð Jñô ð õ
 !#¤¨&°Ô*>Ð)?Ñ @Ô @ÐÝ˜6 'œ?¨GÑ4Ô4ð k¸¸w¼Ô8MÕVXÔV`ÕbdÔblÐUmÐ8mÐ8mÝ Ð!iµD¸À¼Ñ4IÔ4IÐ!iÐ!iÐ[eÐ!iÐ!iÑjÔjÐjÝœ8 V¨G¤_Ð$5Ñ6Ô6ˆLØÔ%­¬Ò3Ð3Ð3Ð3Ø$ \Ô2ˆOˆOå "¤¨-¨Ñ 9Ô 9ÐÝœ8 Y KÑ0Ô0ˆLØÔ-¨jÔ9ˆFØ˜&Ð Ð Ø˜wœÔ-�Ø+×2Ò2°5Ñ9Ô9�ØÔ%­¬Ò3Ð3Ð3Ð3àÐØ$ }Ñ4ˆØˆØ (Ñ*ˆ
õ ”+×)Ò)Ø˜_Ð.>Ð@Q×@WÒ@WÑ@YÔ@Y×@`Ò@`Ñ@bÔ@bñ
ô 
ˆð 	Œ
×"Ò" 7Ñ+Ô+Ð+ØÔ¥¤Ò+Ð+Ý#Ô/Ô5ˆJˆJØÔ¥2¤:Ò-Ð-Ý#Ô/Ô7ˆJˆJåÐc°Ô1CÐcÐcÐU_ÐcÐcÑdÔdÐdÝ”[×,Ò,¨Z¸À[ÐR^×RfÒRfÐglÑRmÔRm×RtÒRtÑRvÔRvÑwÔwˆ
ØŒ
×"Ò" :Ñ.Ô.Ð.à�Z °+Ð?OÐOÐOr&   c           	      ó¢  — |j         |         }|dk    s
J d¦   «         ‚|t          z   }|dz   }	|�	|�d||}}}
n|                      |¦  «        \  }
}}}}g }|
r't          j                             d|||g|g|	¦  «        }n²| j        rdS | j        rF|t          j	        j
        k    r1|dz   }|dz   }t          j                             d	|g|||g|	¦  «        }n\|€J d
|›d|› d|› d|› �¦   «         ‚|                      ||||¬¦  «        \  }}}}t          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.Ú_QuantizeLinearNTr‡   rÓ   rõ   ÚDynamicQuantizeLinearzCCannot quantize input without knowing the initial type, input_name=z, input_index=z, qType=z, node=©rÐ   )r?   r	   r2  rc   rd   r~   rA   rC   rÃ   rÄ   rË   rÑ   r   rS   )rV   rI   Úinput_indexrÏ   Úgiven_scale_nameÚgiven_zp_namerÐ   rÍ   r•   Úql_node_nameÚ
data_foundr.  Úzp_namer«   rŒ   Úqlinear_noder-  Úzp_shapes                     r$   Ú_get_quantize_input_nodesz'ONNXQuantizer._get_quantize_input_nodes2  s
  € ð" ”Z Ô,ˆ
Ø˜RÒÐÐÐ!MÑÔÐØ Õ#;Ñ;ˆØ!Ð$5Ñ5ˆàÐ(¨}Ð/HØ/3Ð5EÀ} G˜
ˆJˆJà48×4QÒ4QÐR\Ñ4]Ô4]Ñ1ˆJ˜
 G¨Q°àˆØð %	Ýœ;×0Ò0Ø Ø˜Z¨Ð1Ø�Øñ	ô ˆLˆLð Œ{ð Ø�tð Ô&ð ¨5µJÔ4JÔ4PÒ+PÐ+PØ'¨(Ñ2�
Ø$ }Ñ4�Ý#œ{×4Ò4Ø+Ø�LØ  *¨gÐ6Ø ñ	 ô  ��ð $Ð/Ð/ðhØ",ðhð hØ>Iðhð hØSXðhð hØaeðhð hñ 0Ô/Ð/ð ×?Ò?À
ÈEÐSXÐgsÐ?ÑtÔtñØØØØå#œ{×4Ò4Ø$Ø ¨WÐ5Ø �MØ ñ	 ô  �õ 0>¸jÈ+ÐWaÐcjÐlqÑ/rÔ/rˆÔ  Ñ,Ø%�Ð%˜Ð%Ð%r&   c                 ót   — || j         v r| j         |         S | j        �| j                             |¦  «        S d S r“   )rS   rg   Úfind_quantized_value)rV   rÍ   s     r$   rA  z"ONNXQuantizer.find_quantized_valuex  sA   € Ø˜Ô1Ð1Ð1ØÔ+¨JÔ7Ð7ØŒ;Ð"Ø”;×3Ò3°JÑ?Ô?Ð?Øˆtr&   c
                 ó&  — t          j        |¦  «        }
|d|
z  z  |z  }t          j        |                     ¦   «         t           j        ¬¦  «        }t          j        |                     ¦   «         t           j        ¬¦  «        }||z  }||k     r€|dk    rz||z  }||z  }|	€6t          j        d|› d|› d|› d�¦  «         d	t          j        ||¬¦  «        fS t          j        d
|	› d|› d|› d|› d�	¦  «         d	|                     |¦  «        fS d|fS )zHAdjust a single weight scale to ensure the int32 bias does not overflow.rß   ©r  rö   Nz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   )rV   Ú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                    r$   Ú$adjust_single_weight_scale_if_neededz2ONNXQuantizer.adjust_single_weight_scale_if_needed  s•  € õ ”˜Ñ!Ô!ˆØ$:¸cÀF¹lÑ$KÈfÑ$TÐ!åœ8 K×$4Ò$4Ñ$6Ô$6½b¼jÐIÑIÔIÐÝœH \×%6Ò%6Ñ%8Ô%8ÅÄ
ÐKÑKÔKÐØ/Ð2CÑCÐà Ð#<Ò<Ð<ÐCWÐZ]ÒC]ÐC]Ø-Ð0DÑDˆEØ)¨EÑ1ˆIØˆ{Ý”ðD°Kð Dð DÐPUð Dð DØ$-ðDð Dð Dñô ð ð �RœX iÐ7IÐJÑJÔJÐJÐJå”ðG sð Gð G¸+ð Gð GÐRWð Gð GØ'0ðGð Gð Gñô ð ð ˜Y×-Ò-Ð.@ÑAÔAÐAÐAØ�lÐ"Ð"r&   rG  rH  rJ  Úbias_tpÚis_per_channelÚreturnc                 óö  — |j         sdS t          |¦  «        }t          j        t          j        ¦  «        }d}t          j        |j        t          j        ¬¦  «        t          j        |j        dz   t          j        ¬¦  «        z
  }	|j	        }
d}|sît          j
        |                     ¦   «         t          j        dt          j        ¬¦  «        ¦  «        }t          j        |                     ¦   «         t          j        dt          j        ¬¦  «        ¦  «        }t          j        t          j        |¦  «        t          j        |¦  «        ¦  «        }|                      ||||
||j        |	|¦  «        \  }}|r|}d}nw|j        rpt!          |j        ¦  «        dk    rXt#          |j        d         ¦  «        D ]=}|                      ||         |||         |
||j        |	||¬¦	  «	        \  }}|r|||<   d}Œ>||fS )	zOChecks if the bias scale is too small and increases the weight scale if needed.)FNgq¬‹Ûh ð?rC  r   Fr   T)rN  )Úsizer   r  ÚiinfoÚint32r  Úmaxr  Úminr  ÚminimumÚmaximumrD  rV  r!   Úshapery   r    )rV   rG  rH  rJ  rW  rX  Úbias_float_dataÚ
int32_inforM  rL  rI  ÚupdatedÚrminÚrmaxrO  ÚchangedrU  rª   s                     r$   Ú#_adjust_weight_scale_for_int32_biasz1ONNXQuantizer._adjust_weight_scale_for_int32_bias¤  sõ  € ð Ô ð 	Ø�;å/°Ñ8Ô8ˆÝ”X�bœhÑ'Ô'ˆ
Ø!'ÐÝ”˜*œ.µ´
Ð;Ñ;Ô;½b¼hÀzÄ~ÐXYÑGYÕacÔakÐ>lÑ>lÔ>lÑlˆØ)Ô/ÐØˆàð  	#Ý”:˜o×1Ò1Ñ3Ô3µR´X¸aÅrÄzÐ5RÑ5RÔ5RÑSÔSˆDÝ”:˜o×1Ò1Ñ3Ô3µR´X¸aÅrÄzÐ5RÑ5RÔ5RÑSÔSˆDÝ”Z¥¤ t¡¤­b¬f°T©l¬lÑ;Ô;ˆFØ!%×!JÒ!JØØØØ"ØØ”ØØ&ñ	"ô 	"ÑˆG�Yð ð Ø(�Ø�øØÔð 	#¥C¨Ô(:Ñ$;Ô$;¸qÒ$@Ð$@Ý˜<Ô-¨aÔ0Ñ1Ô1ð #ð #�Ø%)×%NÒ%NØ# AÔ&ØØ  ”OØ&ØØ”LØØ*Øð &Oñ 
&ô 
&Ñ"�˜ð ð #Ø&/�L ‘OØ"�Gøà˜Ð$Ð$r&   rU  c                 óä  — || j         vrdS | j         |         }t          || j                             ¦   «         ¦  «        }t          |j        | j                             ¦   «         ¦  «        }t          |j        | j                             ¦   «         ¦  «        }t          |j        | j                             ¦   «         ¦  «        }|�|�|�|€dS | j                             |¦  «         | j                             |¦  «         t          j	         
                    |¦  «        }|j        }	t          j        |t          j                             |j        ¦  «        ¬¦  «        }
t          j	                             |
                     |j        ¦  «        |j        ¦  «        }| j                             |¦  «         t+          || j        ||
|	|j        ¬¦  «        }| j                             |¦  «         dS )zCRe-quantizes the given weight initializer using the provided scale.NrC  )Úquant_weight_name)rS   r   r8   r�   r.  r<  Úq_nameÚremove_initializerrc   Únumpy_helperÚto_arrayÚaxisr  Úasarrayrd   Útensor_dtype_to_np_dtyper·   Ú
from_arrayr#  Údimsrä   r   rY   )rV   rJ  rU  ÚqvÚ	weight_tpÚ
scale_initÚzp_initÚq_weight_initÚweight_zero_pointrp  Úscale_npÚnew_scale_initÚnew_q_weights                r$   Ú_requantize_weightz ONNXQuantizer._requantize_weightÜ  s¸  € ð ˜dÔ6Ð6Ð6ØˆFàÔ% kÔ2ˆå  ¨d¬j×.DÒ.DÑ.FÔ.FÑGÔGˆ	Ý! "¤-°´×1GÒ1GÑ1IÔ1IÑJÔJˆ
Ý˜rœz¨4¬:×+AÒ+AÑ+CÔ+CÑDÔDˆÝ$ R¤Y°´
×0FÒ0FÑ0HÔ0HÑIÔIˆàÐ 
Ð 2°g°oÈÐI^ØˆFàŒ
×%Ò% jÑ1Ô1Ð1ØŒ
×%Ò% mÑ4Ô4Ð4å Ô-×6Ò6°wÑ?Ô?ÐØŒwˆõ ”:˜i­t¬{×/SÒ/SÐT]ÔTgÑ/hÔ/hÐiÑiÔiˆÝÔ*×5Ò5°h×6FÒ6FÀzÄÑ6WÔ6WÐY[ÔYfÑgÔgˆØŒ
×"Ò" >Ñ2Ô2Ð2õ 1ØØÔØØØØ œið
ñ 
ô 
ˆð 	Œ
×"Ò" <Ñ0Ô0Ð0Ð0Ð0r&   ç      ð?c           
      ó�  — || j         v r| j         |         j        S | j         |         j        }t          || j                             ¦   «         ¦  «        }t          |¦  «        }|| j         v r| j         |         j        }n8|| j        v r|                      |¦  «        \  }	}}	}	}	nt          d|› d�¦  «        ‚t          || j                             ¦   «         ¦  «        }
t          |
¦  «        }| j         |         j
        }t          || j                             ¦   «         ¦  «        }|�t          j                             |¦  «        nd}| j        }|�‘|j        rŠ|                     ¦   «         sv| j        t$          j        j        fv r]t          || j                             ¦   «         ¦  «        }|                      |||||¦  «        \  }}|r|                      ||¦  «         |}|                      ||||¦  «        \  }}}}}}|| j         vsJ ‚t1          ||||t2          j        |j        dk    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)rS   rl  r.  r   r8   r�   r   rN   r2  rL   r<  rc   rn  ro  rW   r[  r‹   rY   rÃ   rÄ   rÉ   ri  r~  Úquantize_bias_static_implr   r   ÚInitializer)rV   rK  rÍ   rJ  ÚbetaÚweight_scale_nameÚweight_initializerrH  rå   r«   Úinputscale_initializerrG  Úweight_zp_nameÚweight_zp_initrz  rX  Úbias_initializerÚ
did_updateÚnew_weight_scaleÚquantized_bias_nameÚquantized_bias_scale_nameÚquantized_bias_zp_nameÚbias_scale_datar�  r‚  Úquantized_values                             r$   Úquantize_bias_staticz"ONNXQuantizer.quantize_bias_static  sž  € ð ˜Ô0Ð0Ð0ØÔ+¨IÔ6Ô=Ð=ð !Ô4°[ÔAÔLÐÝ)Ð*;¸T¼Z×=SÒ=SÑ=UÔ=UÑVÔVÐÝ,Ð-?Ñ@Ô@ˆð ˜Ô1Ð1Ð1Ø#Ô7¸
ÔCÔNÐÐØ˜4Ô3Ð3Ð3Ø+/×+HÒ+HÈÑ+TÔ+TÑ(ˆAÐ  A q qåÐj¨ÐjÐjÐjÑkÔkÐkå!-Ð.>ÀÄ
×@VÒ@VÑ@XÔ@XÑ!YÔ!YÐÝ+Ð,BÑCÔCˆð Ô1°+Ô>ÔFˆÝ% n°d´j×6LÒ6LÑ6NÔ6NÑOÔOˆØJXÐJd�DÔ-×6Ò6°~ÑFÔFÐFÐjnÐØÔ)ˆàÐ)Ø!Ô&ð *à%×)Ò)Ñ+Ô+ð *ð Ô!¥jÔ&<Ô&AÐ%CÐCÐCå+¨I°t´z×7MÒ7MÑ7OÔ7OÑPÔPÐØ+/×+SÒ+SØØØØ Øñ,ô ,Ñ(ˆJÐ(ð ð 0Ø×'Ò'¨Ð5EÑFÔFÐFØ/�ð ×*Ò*¨9°kÀ<ÐQUÑVÔVñ	
ØØ%Ø"ØØØð  Ô 8Ð8Ð8Ð8Ð8Ý(ØØØ%Ø"ÝÔ*Ø Ô%¨Ò)Ð)ˆAˆA¨tØØ!ð	
ñ 	
ô 	
ˆð />ˆÔ  Ñ+à"Ð"r&   c                 ó8   — || j         v p|| j        v p|| j        v S )zq
        only check for value info and newly generated tensor names, initializers are checked separately
        )r<   rH   rU   r²   s     r$   Úcontains_tensorzONNXQuantizer.contains_tensorJ  s4   € ð
 ˜DÔ,Ð,ð ;Ø˜tÔ0Ð0ð;à˜tÔ9Ð9ð	
r&   c           	      ó:   — |                       ||dddd|¬¦  «        S )NFr  ©rI   ÚindicesÚinitializer_use_weight_qTyperX   Úop_level_per_channelrp  Úfrom_subgraph©Ú_ONNXQuantizer__quantize_inputs)rV   rI   r˜  r›  s       r$   Úquantize_activationz!ONNXQuantizer.quantize_activationT  s4   € Ø×%Ò%ØØØ).ØØ!&ØØ'ð &ñ 
ô 
ð 	
r&   r  c           	      ó:   — |                       ||d||||¬¦  «        S )NTr—  rœ  )rV   rI   r˜  rX   rš  rp  r›  s          r$   Úquantize_weightzONNXQuantizer.quantize_weighta  s6   € ð ×%Ò%ØØØ)-Ø%Ø!5ØØ'ð &ñ 
ô 
ð 	
r&   Tc           
      óŽ  — g }g }	g }
g }|D �]4}|j         |         }|| j        v r\| j        |         }|                     |j        ¦  «         |	                     |j        ¦  «         |
                     |j        ¦  «         Œu|s@|
                     d¦  «         |                     d¦  «         |	                     d¦  «         Œ·t          || j                             ¦   «         ¦  «        }|�£| j	        r2|r0|  
                    |j        |r| j        n| j        ||¦  «        \  }}}n)|                      ||r| j        n| j        |¦  «        \  }}}|
                     |¦  «         |	                     |¦  «         |                     |¦  «         �Œƒ|                      |¦  «        �r| j                             |dz   | j        | j                             ¦   «         ¦  «        }|€ü|j         |         }|| j        v rj| j        |         }|                     d¦  «        sJ d|› d�¦   «         ‚|j                             d¦  «        sJ d|› d�¦   «         ‚|j        j        j        }n$|| j        v sJ d	|›d
�¦   «         ‚| j        |         }|                      ||| j        |¬¦  «        }|€ dS |r|                      |¦  «         n|                     |¦  «         |d         }|j        dk    r\|
                     |j        ¦  «         |                     |j         d         ¦  «         |	                     |j         d         ¦  «         �Œ9|
                     |j        d         ¦  «         |                     |j        d         ¦  «         |	                     |j        d         ¦  «         �Œ›| j        �z| j                             ||g||||d¬¦  «        \  }}}}|
                     |d         ¦  «         |                     |d         ¦  «         |	                     |d         ¦  «         �ŒtA          d|› d| j!        › �¦  «        ‚|
|	||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  Nr4  rp   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.r6  )NNNNr  r‡   r   é   r   T)r™  rX   rš  rp  r›  z!Invalid tensor name to quantize: z @graph scope)"r?   rS   râ   r.  r<  rl  r   r8   r�   rW   Úquantize_weight_per_channelr!   rY   rZ   Úquantize_initializerr•  Úfind_node_by_namerF   r:   r<   r¸   rp   r¶   r¹   rH   r?  r–   r}   rz   r>   rg   r�  rL   rG   )rV   rI   r˜  r™  rX   rš  rp  r›  Úscale_namesÚzero_point_namesÚquantized_input_namesrŒ   r7  Ú
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                               r$   Ú__quantize_inputszONNXQuantizer.__quantize_inputst  s  € ð. ˆØÐØ "ÐØˆà"ð c	rñ c	rˆKØœ KÔ0ˆJð ˜TÔ5Ð5Ð5Ø"&Ô":¸:Ô"F�Ø×"Ò" ?Ô#=Ñ>Ô>Ð>Ø ×'Ò'¨Ô(?Ñ@Ô@Ð@Ø%×,Ò,¨_Ô-CÑDÔDÐDØàð Ø%×,Ò,¨RÑ0Ô0Ð0Ø×"Ò" 2Ñ&Ô&Ð&Ø ×'Ò'¨Ñ+Ô+Ð+Øå& z°4´:×3IÒ3IÑ3KÔ3KÑLÔLˆKØÐ&ØÔ#ð Ð(<ð ð
 ×8Ò8Ø#Ô(Ø-IÐd˜Ô)Ð)ÈtÔOdØØ$ñ	ô ñ	Ø%ØØ"˜
ð :>×9RÒ9RØ#Ø-IÐd˜Ô)Ð)ÈtÔOdØ$ñ:ô :Ñ6�M 7¨Jð &×,Ò,¨]Ñ;Ô;Ð;Ø ×'Ò'¨Ñ0Ô0Ð0Ø×"Ò" :Ñ.Ô.Ð.Ñ.Ø×%Ò% jÑ1Ô1ñ ;rà#œz×;Ò;ØÐ!2Ñ2°D´NÀDÄJ×DTÒDTÑDVÔDVñ ô  �ð  Ð'Ø!%¤¨KÔ!8�JØ! TÔ%5Ð5Ð5Ø%)Ô%5°jÔ%A˜
Ø)×2Ò2°6Ñ:Ô:ÐcÐcÐ<cÈ*Ð<cÐ<cÐ<cÑcÔcÐ:Ø)œ×7Ò7¸ÑFÔFÐsÐsÐHsÐV`ÐHsÐHsÐHsÑsÔsÐFØ'1¤Ô'BÔ'L˜˜ð  *¨TÔ->Ð>Ð>Ð>ð,¸*ð ,ð ,ð ,ñ  ?Ô>Ð>ð
 (,Ô'8¸Ô'D˜Ø+/×+IÒ+IØ˜k¨4Ô+@È|ð ,Jñ ,ô ,Ð(ð ,Ð3Ø7Ð7Ð7Ø$ð ;Ø×*Ò*Ð+?Ñ@Ô@Ð@Ð@àŸšÐ%9Ñ:Ô:Ð:Ø#7¸Ô#;�LàÔ'Ð+;Ò;Ð;Ø)×0Ò0°Ô1DÑEÔEÐEØ×&Ò& |Ô'9¸!Ô'<Ñ=Ô=Ð=Ø$×+Ò+¨LÔ,>¸qÔ,AÑBÔBÐBÑBà)×0Ò0°Ô1DÀQÔ1GÑHÔHÐHØ×&Ò& |Ô':¸1Ô'=Ñ>Ô>Ð>Ø$×+Ò+¨LÔ,?ÀÔ,BÑCÔCÐCÑCØ”Ð(ð ”K×1Ò1ØØ �MØ1MØ!-Ø)=ØØ"&ð 2ñ ô ñØ0Ø+Ø&Øð &×,Ò,Ð-IÈ!Ô-LÑMÔMÐMØ×"Ò"Ð#5°aÔ#8Ñ9Ô9Ð9Ø ×'Ò'Ð(?ÀÔ(BÑCÔCÐCÑCõ !Ð!pÀZÐ!pÐ!pÐ^bÔ^nÐ!pÐ!pÑqÔqÐqà$Ð&6¸ÀUÐJÐJr&   c                 ó  — |j         | j        v r&| j        |j                  }|j        |j        |j        fS |                      ||||¦  «        \  }}}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!   rS   rl  r<  r.  Úquantize_initializer_implr   r   r„  )	rV   r½   rÏ   rX   Úkeep_float_weightr’  rª  r<  r.  s	            r$   r¤  z"ONNXQuantizer.quantize_initializer÷  s®   € ð Œ;˜$Ô2Ð2Ð2Ø"Ô6°v´{ÔCˆOàÔ&ØÔ'ØÔ*ðð ð .2×-KÒ-KØ�E˜<Ð):ñ.
ô .
Ñ*ˆ�w 
õ
 )ØŒKØØØÝÔ*Øñ
ô 
ˆð 1@ˆÔ  ¤Ñ-Ø˜g zÐ1Ð1r&   c                 óê   — || j         v r!| j         |         }|j        |j        |j        fS |                      |||||¦  «        \  }}}	t          |||	|t          j        d ¦  «        }|| j         |<   |||	fS r“   )rS   rl  r<  r.  Ú quantize_weight_per_channel_implr   r   r„  )
rV   rJ  rY   Úchannel_axisrX   r²  r’  rª  r<  r.  s
             r$   r£  z)ONNXQuantizer.quantize_weight_per_channel  s¨   € ð ˜$Ô2Ð2Ð2Ø"Ô6°{ÔCˆOàÔ&ØÔ'ØÔ*ðð ð .2×-RÒ-RØ˜ |°\ÐCTñ.
ô .
Ñ*ˆ�w 
õ )ØØØØÝÔ*Øñ
ô 
ˆð 1@ˆÔ  Ñ-à˜g zÐ1Ð1r&   c                 óf  — || j         v �r&|| j        v�r| j         |         }t          |j        | j                             ¦   «         ¦  «        }| j        j        j        dk    s| j        j        j        dk    r.|�,|�*t          j         	                    |¦  «        j
        dk    sJ ‚|dz   }| j                             || j        | j                             ¦   «         ¦  «        }|€9|j        |j        |j        g}t          j                             d||g|¦  «        }|S ||j        d         k    sJ ‚dS )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
        r`   Nr   Ú_DequantizeLinearrˆ   r   )rS   rU   r   r.  r8   r�   ra   rc   rn  ro  r[  r¥  rF   r:   rl  r<  rd   r~   r>   )rV   Ú
value_namer’  rw  Údqlinear_nameÚdqlinear_nodeÚdqlinear_inputsÚdequantize_nodes           r$   Ú_dequantize_valuezONNXQuantizer._dequantize_value8  sK  € ð ˜$Ô2Ð2Ñ2¸È4ÔKeÐ9eÑ9eØ"Ô6°zÔBˆOõ & oÔ&@À$Ä*×BXÒBXÑBZÔBZÑ[Ô[ˆJð ŒzÔÔ-Ð1AÒAÐAØ”
Ô Ô.Ð2BÒBÐBÀzÐG]ð "Ð)­TÔ->×-GÒ-GÈ
Ñ-SÔ-SÔ-XÐ\]Ò-]Ð-]Ð-]Ð]à&Ð)<Ñ<ˆMØ œJ×8Ò8¸ÈÌÐX\ÔXb×XhÒXhÑXjÔXjÑkÔkˆMØÐ$à#Ô*Ø#Ô.Ø#Ô+ð#�õ
 #'¤+×"7Ò"7Ø&¨¸*¸À}ñ#ô #�ð 'Ð&ð " ]Ô%9¸!Ô%<Ò<Ð<Ð<Ð<Øˆtr&   c                 ó´   — | j                              ¦   «         j        D ]8}|                      |j        ¦  «        }|�| j                             |¦  «         Œ9dS )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)r8   r:   r>   r½  r!   rF   râ   )rV   r>   r¼  s      r$   r¡   z!ONNXQuantizer._dequantize_outputs_  s`   € ð ”j×&Ò&Ñ(Ô(Ô/ð 	7ð 	7ˆFØ"×4Ò4°V´[ÑAÔAˆOØÐ*Ø”×%Ò% oÑ6Ô6Ð6øð	7ð 	7r&   c           	      óZ  — | j         €d S |                      ¦   «          i }| j         D �]‚}| j         |         }t          |t          ¦  «        s#t	          dt          |¦  «        › d|›d�¦  «        ‚| 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¤|                     d	|j        d
         ¦  «        }|                     d|j        d         ¦  «        }	|                     d| j        ¦  «        }
|                     dd¦  «        }t%          |||
¬¦  «        \  }}t'          ||	|||
| j        ¦  «        \  }}t+          |||¬¦  «        ||<   �Œ„|S )Nr  r  rÁ   )Údefault_valr  r  r  r   rf  r   rg  Ú	symmetricrX   F)rX   rÁ  )r  r  r  )r[   Úadjust_tensor_rangesr  r   r  rp   Útensor_quant_overridesÚget_per_tensor_overridesrZ   r¶   rc   rÄ   ÚFLOAT8E4M3FNr   Úavg_stdÚgetÚrange_valueÚis_activation_symmetricr   r   Úmin_real_ranger   )rV   rN   r³   ÚtdÚquant_overridesr  Úzeror  rf  rg  rÁ  rX   ÚqminÚqmaxs                 r$   rM   z+ONNXQuantizer.calculate_quantization_paramsk  sÙ  € ØÔÐ%Ø�4à×!Ò!Ñ#Ô#Ð#à ÐØÔ-ð 	wñ 	wˆKØÔ# KÔ0ˆBÝ˜b¥*Ñ-Ô-ð TÝÐ Rµ4¸±8´8Ð RÐ RÀ+Ð RÐ RÐ RÑSÔSÐSà"Ô9×RÒRÐS^ÐlnÐRÑoÔoˆOàÔ.ˆJØ˜Ð.Ð.Ø,¨\Ô:ÔF�
à˜/Ð)Ð)¨l¸oÐ.MÐ.MØ-¨lÔ;¸_ÈWÔ=U�e��Ø�tÔ/Ô<Ò<Ð<Ý5°jÀ"Ä*ÈQÄ-ÑPÔP‘��e�eà&×*Ò*¨6°2´>À!Ô3DÑEÔE�Ø&×*Ò*¨6°2´>À!Ô3DÑEÔE�Ø+×/Ò/°¸TÔ=YÑZÔZ�	Ø.×2Ò2°>À5ÑIÔI�Ý4°ZÈlÐfoÐpÑpÔp‘
��dÝ.¨t°T¸4ÀÀyÐRVÔReÑfÔf‘��eå/AÈTÐY^ÐkuÐ/vÑ/vÔ/vÐ Ñ,Ñ,à"Ð"r&   r“   )F)NN)NNN)r  )FFr  F)TFFr  F)FF)TF)'Ú__name__Ú
__module__Ú__qualname__r7   rm   r„   r�   r�   r–   rh   r´   r»   rÇ   rÑ   rÊ   rÌ   r2  r?  rA  rV  r  Úndarrayr¥   rc   rÄ   ÚboolÚtupleri  r~  r“  r•  rž  r   r�  r¤  r£  r½  r¡   rM   r   r&   r$   r   r   &   sã  € € € € € ð ðFMð FMð FMð FMðR/ð /ð /ð> fð  fð  fðD
ð 
ð 
ðð ð ð<ð <ð <ð+ ð + ð + ðZ
ð 
ð 
ð"ð ð ð ð2ð ð ð2Að Að AðRAð RAð RAðh\7ð \7ð \7ð|9Pð 9Pð 9Pð 9Pðx aeðD&ð D&ð D&ð D&ðLð ð ð" ð##ð ##ð ##ð ##ðJ6%à”Zð6%ð ”jð6%ð ð	6%ð
 Ô!ð6%ð ð6%ð 
ˆt�R”Z $Ñ&Ð&Ô	'ð6%ð 6%ð 6%ð 6%ðp$1¨cð $1¸b¼jð $1ÈTð $1ð $1ð $1ð $1ðLF#ð F#ð F#ð F#ðP
ð 
ð 
ð	
ð 	
ð 	
ð 	
ð" Ø"ØØð
ð 
ð 
ð 
ð. &*ØØ"ØØðAKð AKð AKð AKðF2ð 2ð 2ð 2ðL Øð2ð 2ð 2ð 2ð@%ð %ð %ðN
7ð 
7ð 
7ð #ð  #ð  #ð  #ð  #r&   r   )#rœ   Únumpyr  rc   Ú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   Úregistryr   r   r   r&   r$   ú<module>rÝ     s�  ðð €€€à Ð Ð Ð Ø €€€Ø Ð Ð Ð Ø &Ð &Ð &Ð &Ð &Ð &à =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ø !Ð !Ð !Ð !Ð !Ð !Ø !Ð !Ð !Ð !Ð !Ð !ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð& (Ð 'Ð 'Ð 'Ð 'Ð 'ðe#ð e#ð e#ð e#ð e#�Mñ e#ô e#ð e#ð e#ð e#r&   