+
    9i{                        ^ RI t ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
 ^ RIt^ RIt^ RIHtHtHtHt ^ RIt^RIHtHtHt R R ltR(R	 R
 llt ! R R4      t ! R R4      t ! R R]4      t ! R R] P8                  R7      t ! R R4      t ! R R]4      t ! R R]4      t  ! R R] 4      t! ! R R] 4      t" ! R R] 4      t# ! R  R!] P8                  R7      t$ ! R" R#]$4      t%RR$]PL                  R%R/ 3R& R' llt'R# ))    N)Sequence)Enum)Path)
ModelProtoTensorProtohelpernumpy_helper)
apply_plotload_model_with_shape_infersmooth_distributionc                x    V ^8  d   QhR\         P                  R\         P                  R\         P                  /# )   pkqkreturn)npndarray)formats   "`/var/www/html/photoedit/myenv/lib/python3.14/site-packages/onnxruntime/quantization/calibrate.py__annotate__r      s-        

     c                @   \         P                  ! V P                  V P                  R7      pV R,          \         P                  ! V R,          VR,          ,          4      ,          VR&   V ^ 8H  V^ 8  ,          p^ W#&   V ^ 8  V^ 8  ,          p\         P
                  W$( &   V# )z
See https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.rel_entr.html#scipy.special.rel_entr.
Python implementation.
dtype:NNN)r   emptyshaper   loginf)r   r   resc2c1s   &&   r   rel_entrr"      s    
 ((288288
,CURVVBqEBqEM**CF
'bAg	BCG
q&R!V	BvvCHJr   c          
          V ^8  d   QhR\         P                  R\         P                  R\        R,          R\        R\         P                  /# )r   r   r   baseNaxisr   )r   r   floatint)r   s   "r   r   r   '   sJ      





 $, 	
 ZZr   c                   Ve   V^ 8  g   Q R4       hVf   Q R4       h\         P                  ! V 4      P                  \         P                  4      p RV ,          \         P                  ! WRR7      ,          p \         P                  ! V4      P                  \         P                  4      p\         P
                  ! W4      w  rRV,          \         P                  ! WRR7      ,          p\        W4      p\         P                  ! WCR7      pVe   V\         P                  ! V4      ,          pVP                  V P                  4      # )z
Simplifeied version of entropy.
Source: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.entropy.html.
This avoids taking a dependency on scipy just for this function.
z0base={base} must be a positive number or `None`.z
qk is None      ?T)r%   keepdimsr%   )	r   asarrayastypefloat32sumbroadcast_arraysr"   r   r   )r   r   r$   r%   vecss   &&&&  r   entropyr3   '   s     <4!8W%WW#>'<'>	B		rzz	*B	rBFF248	8B	B		rzz	*B  (FB	rBFF248	8B
2
C
sA	RVVD\88BHHr   c                   t   a  ] tR t^Ct o ]! . RO4      t]! . RO4      tR t]R 4       t	]R 4       t
R tRtV tR# )	
TensorDatac                   \        VP                  4       4      V n        VP                  4        F  w  r#V\        P
                  9  d"   \        R V: R\        P
                   R24      hV\        P                  9   dy   \        VR4      '       g   \        R\        V4       RV: 24      hVP                  \        P                  \        P                  39  d   \        RVP                   RV: 24      h\        WV4       K  	  R# )zUnexpected value z not in .r   Unexpected type z for k=zUnexpected dtype N)listkeys_attrsitemsr5   _allowed
ValueError_floatshasattrtyper   r   float16r.   setattr)selfkwargskvs   &,  r   __init__TensorData.__init__G   s    6;;=)LLNDA
+++ #4QE*BUBUAVVW!XYYJ&&&q'**$'7Qyu%MNN772::rzz"::$'8	%NOODQ #r   c                    \        V R 4      '       d   \        V R4      '       g   \        R\        V 4       R24      hV P                  V P                  3# )lowesthighestz0Attributes 'lowest' and/or 'highest' missing in r7   )r@   AttributeErrordirrK   rL   rD   s   &r   range_valueTensorData.range_valueS   sL    tX&&gdI.F.F #STWX\T]S^^_!`aaT\\**r   c                    \        V R 4      '       d   \        V R4      '       g   \        R\        V 4       R24      hV P                  V P                  3# )avgstdz)Attributes 'avg' and/or 'std' missing in r7   )r@   rM   rN   rS   rT   rO   s   &r   avg_stdTensorData.avg_stdY   sI    tU##74+?+? #LSQUYKWX!YZZ$((##r   c                    V P                    Uu/ uF  q\        W4      bK  	  ppV P                  P                  VR &   V# u upi )CLS)r;   getattr	__class____name__)rD   rF   datas   &  r   to_dictTensorData.to_dict_   s?    -1[[9[74##[9nn--U :s   A )r;   N)rS   rT   rK   rL   hist
hist_edgesbins)rS   rT   rK   rL   r`   )r[   
__module____qualname____firstlineno__	frozensetr=   r?   rH   propertyrP   rU   r]   __static_attributes____classdictcell____classdict__s   @r   r5   r5   C   sR     Z[HIJG
  + +
 $ $
 r   r5   c                   b   a  ] tR t^ft o V 3R lR ltR tR tR tR tR t	R t
R	 tR
 tRtV tR# )TensorsDatac                F   < V ^8  d   QhRS[ S[S[S[,          3,          /# )r   r\   )dictstrr5   tuple)r   rj   s   "r   r   TensorsData.__annotate__g   s#      c:;M6M1N r   c           
        Wn         / V n        VP                  4        EF>  w  r4\        V\        4      '       g   \        R \        V4       R24      h\        V\        4      '       d   V\        P                  8X  d;   \        V4      ^8X  d+   \        V^ ,          V^,          R7      V P                  V&   K  \        V4      ^8X  d;   \        V^ ,          V^,          V^,          V^,          R7      V P                  V&   K  \        RVR R\        V4       RV R24      h\        V\        4      '       g   \        R\        V4       R24      hW@P                  V&   EKA  	  R	# )
zKeys must be strings not r7   rK   rL   )rK   rL   r_   ra   zUnexpected tuple for rz	, it has z elements: zValues must be TensorData not N)calibration_methodr\   r<   
isinstancero   	TypeErrorrA   rp   CalibrationMethodMinMaxlenr5   )rD   ru   r\   rF   rG   s   &&&  r   rH   TensorsData.__init__g   s"   "4	JJLDAa%%";DG9A FGG!U##%):)A)AAc!fPQk#-QqT1Q4#HDIIaLq6Q;#-QqT1Q4aPQdYZ[\Y]#^DIIaL"7!uIc!fX[YZX[[\ ]^^a,,"@a	 KLLIIaL !r   c              #  :   "   V P                    R j  xL
  R #  L5iNr\   rO   s   &r   __iter__TensorsData.__iter__y   s     99s   c                    WP                   9   # r}   r~   rD   keys   &&r   __contains__TensorsData.__contains__|   s    iir   c                (    V P                   V,          # r}   r~   r   s   &&r   __getitem__TensorsData.__getitem__   s    yy~r   c                b    WP                   9  d   \        R V: R24      hW P                   V&   R# )z)Only an existing tensor can be modified, z is not.N)r\   RuntimeError)rD   r   values   &&&r   __setitem__TensorsData.__setitem__   s-    ii!J3'QYZ[[		#r   c                6    V P                   P                  4       # r}   )r\   r:   rO   s   &r   r:   TensorsData.keys   s    yy~~r   c                6    V P                   P                  4       # r}   )r\   valuesrO   s   &r   r   TensorsData.values   s    yy!!r   c                6    V P                   P                  4       # r}   )r\   r<   rO   s   &r   r<   TensorsData.items   s    yy  r   c                f    R V P                   P                  RV P                  RV P                  /pV# )rX   r\   ru   )rZ   r[   r\   ru   )rD   r\   s   & r   r]   TensorsData.to_dict   s5     4>>**DII $"9"9

 r   )ru   r\   N)r[   rb   rc   rd   rH   r   r   r   r   r:   r   r<   r]   rg   rh   ri   s   @r   rl   rl   f   s<      $ 
 "! r   rl   c                   &    ] tR t^t^ t^t^t^tRtR# )rx    N)	r[   rb   rc   rd   ry   Entropy
PercentileDistributionrg   r   r   r   rx   rx      s    FGJLr   rx   c                      a  ] tR t^t o ]R 4       t]P                  V 3R lR l4       tR t	R t
R tV 3R lR ltR	tV tR
# )CalibrationDataReaderc                p    \        VR 4      ;'       d    \        VP                  4      ;'       g    \        # )get_next)r@   callabler   NotImplemented)clssubclasss   &&r   __subclasshook__&CalibrationDataReader.__subclasshook__   s+    *-MM(8;L;L2M``R``r   c                    < V ^8  d   QhRS[ /# r   r   )rn   )r   rj   s   "r   r   "CalibrationDataReader.__annotate__   s     " "$ "r   c                    \         h)z9generate the input data dict for ONNXinferenceSession runNotImplementedErrorrO   s   &r   r   CalibrationDataReader.get_next   s
     "!r   c                    V # r}   r   rO   s   &r   r   CalibrationDataReader.__iter__   s    r   c                :    V P                  4       pVf   \        hV# r}   )r   StopIteration)rD   results   & r   __next__CalibrationDataReader.__next__   s    >r   c                    \         hr}   r   rO   s   &r   __len__CalibrationDataReader.__len__       !!r   c                &   < V ^8  d   QhRS[ RS[ /# )r   start_index	end_index)r'   )r   rj   s   "r   r   r      s     " "S "S "r   c                    \         hr}   r   )rD   r   r   s   &&&r   	set_rangeCalibrationDataReader.set_range   r   r   r   N)r[   rb   rc   rd   classmethodr   abcabstractmethodr   r   r   r   r   rg   rh   ri   s   @r   r   r      sL     a a 	" """ "r   r   )	metaclassc                      a  ] tR t^t o RV 3R lR lltR.3R ltR tV 3R lR ltR	 tR
 t	V 3R lR lt
V 3R lR ltRtV tR# )CalibraterBaseNc                T   < V ^8  d   QhRS[ S[,          RS[S[ ,          R,          /# r   
model_pathop_types_to_calibrateNro   r   r   )r   rj   s   "r   r   CalibraterBase.__annotate__   s,      <  <$J <  (}t3 <r   c                2   \        V\        4      '       d   \        \        V4      4      V n        M2\        V\        4      '       d   \        V4      V n        M\        R4      hW n        W0n        W@n        WPn	        W`n
        RV n        RV n        R.V n        R# )a  
:param model_path: ONNX model to calibrate. It should be a model file path
:param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors.
:param augmented_model_path: save augmented model to this path.
:param symmetric: make range of tensor symmetric (central point is 0).
:param use_external_data_format: use external data format to store model which size is >= 2Gb.
:param per_channel: whether to compute ranges per each channel.
z model_path should be model path.NCPUExecutionProvider)rv   ro   r   r   modelr>   r   augmented_model_path	symmetricuse_external_data_formatper_channelaugment_modelinfer_sessionexecution_providers)rD   r   r   r   r   r   r   s   &&&&&&&r   rH   CalibraterBase.__init__   s    " j#&&4T*5EFDJ
D))4Z@DJ?@@%:"$8!"(@%&!!$:#; r   r   c                2    Wn         V P                  4        R# )zj
reset the execution providers to execute the collect_data. It triggers to re-creating inference session.
N)r   create_inference_session)rD   r   s   &&r   set_execution_providers&CalibraterBase.set_execution_providers   s     $7 %%'r   c                    \         P                  ! 4       p\         P                  P                  Vn        \         P
                  ! V P                  VV P                  R7      V n        R# )z)
create an OnnxRuntime InferenceSession.
)sess_options	providersN)	onnxruntimeSessionOptionsGraphOptimizationLevelORT_DISABLE_ALLgraph_optimization_levelInferenceSessionr   r   r   )rD   r   s   & r   r   'CalibraterBase.create_inference_session   sN     #1130;0R0R0b0b-(99%%%..
r   c                    < V ^8  d   QhRS[ /# )r   r   )r   )r   rj   s   "r   r   r      s     1 1 1r   c                   VP                   P                   Uu/ uF  q"P                  VbK  	  ppTP                  VP                   P                   Uu/ uF  qDP                  VbK  	  up4       TP                  VP                   P
                   Uu/ uF  qUP                  VbK  	  up4       VP                   P                   Uu0 uF  qfP                  kK  	  pp\        4       p\        P                  \        P                  0p	VP                   P                   F  p
V P                  '       d   V
P                  V P                  9   g   K2  \        P                  ! V
P
                  V
P                  4       Fv  pW9   g   K  W;,          pVP                   P#                  R4      '       g   K6  VP                   P$                  P&                  V	9   g   K]  W9  g   Ke  VP)                  V4       Kx  	  K  	  W3# u upi u upi u upi u upi )z
select input/output tensors of candidate nodes to calibrate.
returns:
    tensors (set): set of tensor name.
    value_infos (dict): tensor name to value info.
tensor_type)graph
value_infonameupdateoutputinputinitializersetr   FLOATFLOAT16noder   op_type	itertoolschainrA   HasFieldr   	elem_typeadd)rD   r   vivalue_infosotitinitr   tensors_to_calibratetensor_type_to_calibrater   tensor_names   &&          r   select_tensors_to_calibrate*CalibraterBase.select_tensors_to_calibrate   s    .3[[-C-CD-Crww{-CD%++2D2DE2DBGGRK2DEF%++2C2CD2CBGGRK2CDE-2[[-D-DE-DTyy-DE"u$/$5$5{7J7J#K KK$$D---A[A[1[#,??4::t{{#KK"1(5GG,,];;!#!4!4!>!>BZ!Z!,!?044[A $L % $00) EEDEs   G:G?HH	c                    V P                   # )z@
return: augmented onnx model. Call after calling augment_graph
)r   rO   s   &r   get_augment_model CalibraterBase.get_augment_model  s     zzr   c                    \         h)z
abstract method: augment the input model to prepare for collecting data. It will:
    1. augment the model to be able to collect desired statistics data
    2. save augmented model to augmented_model_paths
r   rO   s   &r   augment_graphCalibraterBase.augment_graph  s
     "!r   c                    < V ^8  d   QhRS[ /# r   data_readerr   )r   rj   s   "r   r   r     s     " "(= "r   c                    \         h)zp
abstract method: collect the tensors that will be used for range computation. It can be called multiple times.
r   )rD   r	  s   &&r   collect_dataCalibraterBase.collect_data  
     "!r   c                    < V ^8  d   QhRS[ /# r   rl   )r   rj   s   "r   r   r   "  s     " "k "r   c                    \         h)zU
abstract method: compute data based on the calibration method stored in TensorsData
r   rO   s   &r   compute_dataCalibraterBase.compute_data"  r  r   )	r   r   r   r   r   r   r   r   r   )Naugmented_model.onnxFFF)r[   rb   rc   rd   rH   r   r   r   r  r  r  r  rg   rh   ri   s   @r   r   r      sK      <  <D <R:R (

1 1:"" "" "r   r   c                   x   a a ] tR tRt oRV3R lV 3R llltR tR tV3R lR ltR tV3R	 lR
 lt	Rt
VtV ;t# )MinMaxCalibrateri)  c                T   < V ^8  d   QhRS[ S[,          RS[S[ ,          R,          /# r   r   )r   rj   s   "r   r   MinMaxCalibrater.__annotate__*  s0     'A 'A$J'A  (}t3'Ar   c
           	       < \         SV `  VVVVVV	R7       . V n        RV n        \	        V P
                  P                  P                  4      V n        V P
                  P                  P                   U
u0 uF  qP                  kK  	  up
V n
        W`n        V'       d   V^ 8  g   V^8  d   \        R4      hWpn        Wn        R# u up
i )a'  
:param model_path: ONNX model to calibrate. It is a model path
:param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors.
:param augmented_model_path: save augmented model to this path.
:param symmetric: make range of tensor symmetric (central point is 0).
:param use_external_data_format: use external data format to store model which size is >= 2Gb
:param moving_average: compute the moving average of the minimum and maximum values instead of the global minimum and maximum.
:param averaging_constant: constant smoothing factor to use when computing the moving average.
:param max_intermediate_outputs: maximum number of intermediate outputs before an intermediate range is computed.
:param per_channel: whether to compute ranges per each channel.
)r   r   r   r   r   Nz;Invalid averaging constant, which should not be < 0 or > 1.)superrH   intermediate_outputscalibrate_tensors_rangerz   r   r   r   num_model_outputsr   model_original_outputsmoving_averager>   averaging_constantmax_intermediate_outputs)rD   r   r   r   r   r   r  r   r!  r   r   rZ   s   &&&&&&&&&& r   rH   MinMaxCalibrater.__init__*  s    . 	"7!5%=# 	 	
 %'!'+$!$TZZ%5%5%<%<!=AEAQAQAXAX&YAXv{{AX&Y#,1A59Ka9OZ[["4(@% 'Zs   5Cc                "  a aaa S P                  S P                  4      w  r\        \        P                  ! 4       4      o\
        P                  ! \        P                  ! R	.\        P                  R7      S4      pS P                  P                  P                  P                  V4       R oV 3R loVVVV 3R lpV F  pV! VR4       V! VR4       K  	  \        P                  ! S P                  S P                  S P                   R7       R# )
z
Adds ReduceMin and ReduceMax nodes to all quantization_candidates op type nodes in
model and ensures their outputs are stored as part of the graph output
:return: augmented ONNX model
r   c                     VP                    F@  p\        P                  P                  WP                  4      '       g   K4  VP
                  u # 	  \        R V  R24      h)z&Model does not contain a version for 'z'.)opset_importonnxdefshasdomainversionr   )r   r   r%  s   && r   get_op_version6MinMaxCalibrater.augment_graph.<locals>.get_op_version^  sO     % 2 299==*=*=>>'/// !3 !GyPRSTTr   c                 T  <a  \        V 3R  l\        SP                  P                  P                  4       4       \        SP                  P                  P                  4      4      pV F;  pSP                  P                  P                  P                  W#4       V^,          pK=  	  R# )c              3   R   <"   T F  w  rSVP                   9   g   K  Vx  K  	  R # 5ir}   )r   ).0ixr   s   &  r   	<genexpr>GMinMaxCalibrater.augment_graph.<locals>.insert_nodes.<locals>.<genexpr>f  s%     Z?tq;RSRYRYCY?s   '
'N)next	enumerater   r   r   rz   insert)r   	new_nodesindexr   rD   s   f&  r   insert_nodes4MinMaxCalibrater.augment_graph.<locals>.insert_nodesd  sx    Zy)9)9)>)>?Z\_`d`j`j`p`p`u`u\vE "

  %%,,U9
 "r   c                 ,  < ^pV R,           V,           pVR,           p\         P                  P                  W.V.W#R7      p\         P                  P                  RVS.V.VR7      pSP                  P                  P
                   Uu/ uF  qwP                  VbK  	  ppTP                  SP                  P                  P                   U	u/ uF  qP                  V	bK  	  up	4       TP                  SP                  P                  P                   U
u/ uF  qP                  V
bK  	  up
4       W9   d(   W,          P                  P                  P                  pM\        RV : R24      hSP                  '       Ed5   \        W,          P                  P                  P                   P"                  4      p^ .\%        ^V4      OpS! VSP                  4      ^8  d2   VP&                  P)                  \        P*                  ! RV4      4       M\-        \.        P0                  ! 4       4      p\2        P4                  ! \6        P8                  ! V\6        P:                  R	7      V4      pVP                  P)                  V4       SP                  P                  P<                  P)                  V4       S! WV.4       SP                  P                  P                  P)                  \        P>                  ! W;R
.4      4       R
# u upi u up	i u up
i )   __Reshape)r*   r   Reshape)inputsoutputsr   z'Unable to guess tensor type for tensor zE, running shape inference before quantization may resolve this issue.axesr   N) r&  r   	make_noder   r   r   r   r   r   r   rA   r   r   r>   r   rz   r   dimrange	attributeappendmake_attributero   uuiduuid4r	   
from_arrayr   arrayint64r   make_tensor_value_info)r   reduce_op_namer*   reduce_outputintermediate_outputreduce_nodereshape_noder   r   or0  	onnx_typetensor_rankreduced_axesreduce_axes_namereduce_axesr+  r9  reshape_shape_namerD   s   &&              r   add_reduce_min_max:MinMaxCalibrater.augment_graph.<locals>.add_reduce_min_maxl  s    H (#->M"/*"<++//0C/Dx 0 K  ;;00+-?@&(	 1 L 261A1A1L1LM1L277B;1LKM4::3C3C3J3JK3Ja	3JKL4::3C3C3I3IJ3Ia	3IJK)'499EEOO	 =k_ MZ Z  !+":"?"?"K"K"Q"Q"U"UV !:E![$9:!.$**=B))001F1Fv|1\]'*4::<'8$"."9"9"((<WYW_W_:`br"sK%%,,-=>JJ$$0077DL&ABJJ##**6+H+Hdhci+jk3 NKJs   	LLL	ReduceMin	ReduceMaxsave_as_external_dataN)r   r   ro   rI  rJ  r	   rK  r   rL  rM  r   r   rG  r&  saver   r   )	rD   tensorsr=  reshape_shaper[  tensorr+  r9  rZ  s	   f     @@@r   r  MinMaxCalibrater.augment_graphS  s     55djjA
 .$//"RXX0NPbc

$$++M:	U	,	l ,	l\ Fv{3v{3  			JJ%%"&"?"?	
r   c                    . V n         R # r}   r  rO   s   &r   clear_collected_data%MinMaxCalibrater.clear_collected_data  
    $&!r   c                    < V ^8  d   QhRS[ /# r  r
  )r   rj   s   "r   r   r    s     $ $(= $r   c           	         VP                  4       pV'       g   MV P                  P                  \        V P                  P                  4       V P                  P                  RV4      RR7       UUu. uF$  w  r4VP                  V P                  9  d   TMRNK&  	  upp4       V P                  f   K  \        V P                  4      V P                  8X  g   K  V P                  4        K  \        V P                  4      ^ 8X  d   V P                  f   \        R4      hV P                  4       p\        V\         4      '       g   \#        R\%        V4       R24      hV P                  4        R# u uppi )TNFstrictNo data is collected.z+compute_data must return a TensorsData not r7   )r   r  rG  zipr   get_outputsrunr   r  r!  rz   ri  r  r>   r  rv   rl   rw   rA   )rD   r	  r@  sess_or   ts   &&    r   r  MinMaxCalibrater.collect_data  s;    ))+F%%,, *-**668$:L:L:P:PQUW]:^gl** $[[0K0KKEQUU* --9112d6S6SS))+t(()Q.43O3O3W455![))I$q'RSTUU!!#'s   3*E0
c                   V'       g   V# VP                  4        EFO  w  r4\        V\        4      '       d(   VP                  ^ ,          pVP                  ^,          pMVw  rV\        W#,          \        4      '       d4   W#,          P                  ^ ,          pW#,          P                  ^,          pM
W#,          w  rxV P                  '       d@   WPP
                  Wu,
          ,          ,           p	W`P
                  W,
          ,          ,           p
M\        WW4      p	\        Wh4      p
\        V\        4      '       g   \        W#,          \        4      '       d   \        WR7      W#&   EKJ  W3W#&   EKR  	  V# )r   rs   )r<   rv   r5   rP   r  r   minmax)rD   	old_range	new_ranger   r   old_minold_maxnew_minnew_max	min_value	max_values   &&&        r   merge_rangeMinMaxCalibrater.merge_range  s   #//+JC%,,++A.++A.#( ).*55#.44Q7#.44Q7#,> """#&=&=AR&SS	#&=&=AR&SS	1	1	 %,,
9>:0V0V!+9!P	"+!7	3 ,6 r   c                    < V ^8  d   QhRS[ /# r   r  )r   rj   s   "r   r   r    s     3, 3,k 3,r   c                   \        V P                  4      ^ 8X  d   V P                  # \        \        V P                  ^ ,          4      4       Uu. uF-  qP                  P                  4       V,          P                  NK/  	  ppV P                   Uu. uF  p\        \        W#RR7      4      NK  	  pp/ pV F=  pVP                  4        F&  w  rxVP                  V. 4      P                  V4       K(  	  K?  	  W P                  R p	\        ^ \        V	4      ^4       Uu. uF!  qV,          P                  R4      ^ ,          NK#  	  p
pV Uu/ uF  qV P                  9  g   K  WV,          bK   	  pp. p\        ^ \        V	4      ^4       EF6  pV P                  '       dS   \         P"                  ! WV,          ,          ^ R7      p\         P"                  ! WV^,           ,          ,          ^ R7      pMQ\         P$                  ! WV,          ,          ^ R7      p\         P&                  ! WV^,           ,          ,          ^ R7      pV P(                  '       dZ   \         P&                  ! \         P*                  ! V4      \         P*                  ! V4      .^ R7      pVP                  V) V34       EK$  VP                  W34       EK9  	  \-        \.        P0                  \        \        WRR7      4      4      pV P                  '       d.   V P3                  V P                  V4      V n        V P                  # VV n        V P                  # u upi u upi u upi u upi )zt
Compute the min-max range of tensor
:return: dictionary mapping: {added node names: (ReduceMin, ReduceMax) pairs }
Frn  Nr=  r+   )rz   r  r  rE  r   rr  r   rn   rq  r<   
setdefaultrG  r  
rpartitionr  r  r   nanmeannanminnanmaxr   absrl   rx   ry   r  )rD   r0  output_namesrQ  output_dicts_listmerged_output_dictdrF   rG   added_output_namescalibrate_tensor_namesmerged_added_output_dictpairsmin_value_arraymax_value_arraymax_absolute_valuenew_calibrate_tensors_ranges   &                r   r  MinMaxCalibrater.compute_data  s    t(()Q.///JOPSTXTmTmnoTpPqJrsJrQ**668;@@Jrs (,'@'@
'@# \uEF'@ 	 

  "A	"--a4;;A> " # **@*@*BC>CAsK]G^`a>b"
>bq!,,S1!44>b 	 "

 /A$
.@TMhMhDh$A!$$.@ 	! $
 q#0115A""""$**-EYZF[-\cd"e"$**-EYZ]^Y^F_-`gh"i"$)),DXYEZ,[bc"d"$)),DXY\]X]E^,_fg"h~~~%'YY0GP_I`/ahi%j"113EFGo?@ 6 '2$$d3/EUZ+[&\'
# '''+/+;+;D<X<XZu+vD( +++ ,GD(+++U t
"
$
s   3MM'M
M!M)r   r  r  r!  r  r  r  )Nr  FFF{Gz?NF)r[   rb   rc   rd   rH   r  ri  r  r  r  rg   rh   __classcell__rZ   rj   s   @@r   r  r  )  s=     'A 'ARO
b'$ $6B3, 3, 3,r   r  c                   r   a a ] tR tRt oRV3R lV 3R llltR tR tV3R lR ltV3R lR	 ltR
t	Vt
V ;t# )HistogramCalibrateri  c                T   < V ^8  d   QhRS[ S[,          RS[S[ ,          R,          /# r   r   )r   rj   s   "r   r    HistogramCalibrater.__annotate__  s,     *! *!$J*!  (}t3*!r   c                  < \         SV `  VVVVVR7       . V n        RV n        \	        V P
                  P                  P                  4      V n        V P
                  P                  P                   Uu0 uF  qP                  kK  	  upV n
        RV n        WPn        Wpn        Wn        Wn        RV n        Wn        R# u upi )a  
:param model_path: ONNX model to calibrate. It is a model path.
:param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors.
:param augmented_model_path: save augmented model to this path.
:param use_external_data_format: use external data format to store model which size is >= 2Gb
:param method: A string. One of ['entropy', 'percentile'].
:param symmetric: make range of tensor symmetric (central point is 0).
:param num_bins: number of bins to create a new histogram for collecting tensor values.
:param num_quantized_bins: number of quantized bins. Default 128.
:param percentile: A float number between [0, 100]. Default 99.99.
:param scenario: see :class:`DistributionCalibrater`
)r   r   r   r   N)r  rH   r  r  rz   r   r   r   r  r   r  	collectormethodnum_binsnum_quantized_bins
percentiler   scenario)rD   r   r   r   r   r  r   r  r  r  r  r   rZ   s   &&&&&&&&&&& r   rH   HistogramCalibrater.__init__  s    2 	"7!5%= 	 	
 %'!'+$!$TZZ%5%5%<%<!=AEAQAQAXAX&YAXv{{AX&Y# "4$$(!  'Zs   4B>c                n   V P                  V P                  4      w  V n        pV P                   FJ  pW P                  9  g   K  V P                  P                  P
                  P                  W,          4       KL  	  \        P                  ! V P                  V P                  V P                  R7       R# )zk
make all quantization_candidates op type nodes as part of the graph output.
:return: augmented ONNX model
r_  N)r   r   r   r  r   r   rG  r&  rb  r   r   )rD   r   re  s   &  r   r  !HistogramCalibrater.augment_graphF  s    
 261Q1QRVR\R\1].!;//F888

  ''..{/BC 0 			JJ%%"&"?"?	
r   c                    . V n         R # r}   rh  rO   s   &r   ri  (HistogramCalibrater.clear_collected_dataV  rk  r   c                    < V ^8  d   QhRS[ /# r  r
  )r   rj   s   "r   r   r  Y  s     2$ 2$(= 2$r   c                   V P                   P                  4        Uu0 uF  q"P                  kK  	  ppV P                   P                  4        Uu. uF  q"P                  NK  	  pp VP	                  4       pV'       g   MV P                   P                  RV4      p. p\        V4       FJ  w  rWH,          V9   d(   VP                  \        P                  ! V	4      4       K9  VP                  V	4       KL  	  V P                  P                  V4       K  \        V P                  4      ^ 8X  d   \        R4      hV P                   U
u. uF  p
\        \        WJRR7      4      NK  	  pp
/ pV F=  pVP                  4        F&  w  rVP                  V. 4      P                  V4       K(  	  K?  	  V Uu/ uF   pVV P                   9   g   K  VVV,          bK"  	  ppV P"                  '       gS   \%        V P&                  V P(                  V P*                  V P,                  V P.                  V P0                  R7      V n        V P"                  P3                  V4       V P5                  4        R# u upi u upi u up
i u upi )zi
Entropy Calibrator collects operators' tensors as well as generates tensor histogram for each operator.
Nrp  Frn  )r  r   r  r  r  r  )r   
get_inputsr   rr  r   rs  r5  rG  copyr  rz   r>   rn   rq  r<   r  r   r  HistogramCollectorr  r   r  r  r  r  collectri  )rD   r	  node_arginput_names_setr  r@  rA  fixed_outputsoutput_indexr   rQ  r  merged_dictr  rF   rG   r0  clean_merged_dicts   &&                r   r   HistogramCalibrater.collect_dataY  s    :>9K9K9V9V9XY9XX==9XY6:6H6H6T6T6VW6V(6VW ))+F((,,T6:G M(1'(:$-@!((6):;!((0	 ); %%,,];t(()Q.455 (,'@'@
'@# \uEF'@ 	 

 "A	&&q"-44Q7 " # 9Df1qDLeLeGe.QA.f~~~/{{..#'#:#:??DN 	01!!#] ZW,
 gs   I)I.I30I8I8c                    < V ^8  d   QhRS[ /# r   r  )r   rj   s   "r   r   r    s     L Lk Lr   c                   V P                   '       g   \        R4      h\        V \        4      '       d   \        P
                  pMf\        V \        4      '       d   \        P                  pM?\        V \        4      '       d   \        P                  pM\        R\        V 4       R24      h\        WP                   P                  4       4      # )zh
Compute the min-max range of tensor
:return: dictionary mapping: {tensor name: (min value, max value)}
z9No collector created and can't generate calibration data.zUnknown calibrater z". This method must be overwritten.)r  r>   rv   EntropyCalibraterrx   r   PercentileCalibraterr   DistributionCalibraterr   rw   rA   rl   compute_collection_result)rD   cals   & r   r   HistogramCalibrater.compute_data  s    
 ~~~XYYd-..#++C233#..C455#00C1$t*=_`aa3 H H JKKr   )r  r  r  r  r  r  r  r  r  r  r   )	Nr  Fr  F      -X@same)r[   rb   rc   rd   rH   r  ri  r  r  rg   rh   r  r  s   @@r   r  r    s7     *! *!X
 '2$ 2$hL L Lr   r  c                   B   a a ] tR tRt oRV3R lV 3R llltRtVtV ;t# )r  i  c                T   < V ^8  d   QhRS[ S[,          RS[S[ ,          R,          /# r   r   )r   rj   s   "r   r   EntropyCalibrater.__annotate__  ,     
 
$J
  (}t3
r   c	                6   < \         S	V `  VVVVVVVVR7       R# )a|  
:param model_path: ONNX model to calibrate. It is a model path
:param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors.
:param augmented_model_path: save augmented model to this path.
:param use_external_data_format: use external data format to store model which size is >= 2Gb
:param method: A string. One of ['entropy', 'percentile', 'distribution'].
:param symmetric: make range of tensor symmetric (central point is 0).
:param num_bins: number of bins to create a new histogram for collecting tensor values.
:param num_quantized_bins: number of quantized bins. Default 128.
)r  r   r  r  Nr  rH   )
rD   r   r   r   r   r  r   r  r  rZ   s
   &&&&&&&&&r   rH   EntropyCalibrater.__init__  s/    * 	! $1 	 		
r   r   )Nr  Fr3   Fr  r  r[   rb   rc   rd   rH   rg   rh   r  r  s   @@r   r  r         
 
 
r   r  c                   B   a a ] tR tRt oRV3R lV 3R llltRtVtV ;t# )r  i  c                T   < V ^8  d   QhRS[ S[,          RS[S[ ,          R,          /# r   r   )r   rj   s   "r   r   !PercentileCalibrater.__annotate__  r  r   c	                6   < \         S	V `  VVVVVVVVR7       R# )ag  
:param model_path: ONNX model to calibrate. It is a model path
:param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors.
:param augmented_model_path: save augmented model to this path.
:param use_external_data_format: use external data format to store model which size is >= 2Gb
:param method: A string. One of ['entropy', 'percentile', 'distribution'].
:param symmetric: make range of tensor symmetric (central point is 0).
:param num_quantized_bins: number of quantized bins. Default 128.
:param percentile: A float number between [0, 100]. Default 99.99.
)r  r   r  r  Nr  )
rD   r   r   r   r   r  r   r  r  rZ   s
   &&&&&&&&&r   rH   PercentileCalibrater.__init__  s/    * 	! $! 	 		
r   r   )Nr  Fr  Fr  r  r  r  s   @@r   r  r    r  r   r  c                   B   a a ] tR tRt oRV3R lV 3R llltRtVtV ;t# )r  i  c                T   < V ^8  d   QhRS[ S[,          RS[S[ ,          R,          /# r   r   )r   rj   s   "r   r   #DistributionCalibrater.__annotate__  s,     
 
$J
  (}t3
r   c           
     4   < \         SV `  VVVVVVVR7       R# )a,  
:param model_path: ONNX model to calibrate. It is a model path
:param op_types_to_calibrate: operator types to calibrate. By default, calibrate all the float32/float16 tensors.
:param augmented_model_path: save augmented model to this path.
:param use_external_data_format: use external data format to store model which size is >= 2Gb
:param method: A string. One of ['entropy', 'percentile', 'distribution'].
:param symmetric: make range of tensor symmetric (central point is 0).
:param num_bins: number of bins to create a new histogram for collecting tensor values.
:param scenario: for float 8 only, if `scenario="same"`,
    the algorithm weights and float 8 follow the same distribution,
    if `scenario="p3"`, it assumes the weights follow
    a gaussian law and float 8 ~ X^3 where X is a gaussian law
)r  r  r  Nr  )	rD   r   r   r   r   r  r  r  rZ   s	   &&&&&&&&r   rH   DistributionCalibrater.__init__  s,    . 	! $ 	 	
r   r   )Nr  Fdistributionr  r  r  r  s   @@r   r  r    s     
 
 
r   r  c                   l   a  ] tR tRt o Rt]P                  R 4       t]P                  R 4       tRt	V t
R# )CalibrationDataCollectori  zD
Base class for collecting data for calibration-based quantization.
c                    \         h)zk
Generate informative data based on given data.
    name_to_arr : dict
        tensor name to NDArray data
r   rD   name_to_arrs   &&r   r   CalibrationDataCollector.collect  s
     "!r   c                    \         h)z/
Get the optimal result among collection data.
r   rO   s   &r   r  2CalibrationDataCollector.compute_collection_result  s
    
 "!r   r   N)r[   rb   rc   rd   __doc__r   r   r  r  rg   rh   ri   s   @r   r  r    s>      	" " 	" "r   r  c                   z   a  ] tR tRt o RtR tR tR tR tR t	R t
R	 tR
 tR t]RR l4       tR tR tRtV tR# )r  i  aL  
Collecting histogram for each tensor. Percentile and Entropy method are supported.

ref: https://github.com//apache/incubator-mxnet/blob/master/python/mxnet/contrib/quantization.py
ref: https://docs.nvidia.com/deeplearning/tensorrt/pytorch-quantization-toolkit/docs/_modules/
             pytorch_quantization/calib/histogram.html
c                \    / V n         Wn        W n        W0n        W@n        WPn        W`n        R # r}   )histogram_dictr  r   r  r  r  r  )rD   r  r   r  r  r  r  s   &&&&&&&r   rH   HistogramCollector.__init__&  s)     " "4$ r   c                    V P                   # r}   )r  rO   s   &r   get_histogram_dict%HistogramCollector.get_histogram_dict/  s    """r   c                    \        R 4       V P                  R9   d   V P                  V4      # V P                  R8X  d5   V P                  '       d   V P	                  V4      # V P                  V4      # \        R4      h)z/Collecting tensor data and making histogram ...r  DOnly 'entropy', 'percentile' or 'distribution' methods are supported>   r3   r  )printr  collect_valuer   collect_absolute_valuer>   r  s   &&r   r  HistogramCollector.collect2  sn    ?@ ;;55%%k22[[L(~~~22;??))+66cddr   c                   VP                  4        EF  w  r#\        V\        4      '       d   V F:  p\        V\        P                  4      '       d   K%  Q R\        V4       RV: 24       h	  V Uu0 uF  qUP                  kK  	  pp\        V4      ^8X  g   Q RV RV: 24       h\        P                  ! V4      pM=\        V\        P                  4      '       g   \        R\        V4       RV: 24      hTpVP                  4       pVP                  ^ 8  d.   \        P                  ! V4      p\        P                  ! V4      p	MD\        P                  ! ^ VP                  R7      p\        P                  ! ^ VP                  R7      p	\        P                  ! V4      pW P                   9  dy   \        P"                  ! WpP$                  R7      w  rVP'                  VP                  4      pVP                  \        P(                  8w  g   Q R4       hWW3V P                   V&   EK  V P                   V,          pV^,          pV^,          p\+        VR4      '       g   Q R\        V4       24       h\+        VR4      '       g   Q R\        V4       24       hV^ ,          pV^,          p\        P                  ! V4      pVVR
,          8  d]   V^,          V^ ,          ,
          p\        P,                  ! VR
,          V,           VV,           V4      p\        P.                  ! VV34      p\        P"                  ! VVR7      w  rVP'                  VP                  4      pV
R	\        V4      ;;; V,          uuu% VP                  \        P(                  8w  g   Q R4       hW\1        W4      \3        W4      3V P                   V&   EK  	  R	# u upi )z%
Collect histogram on absolute value
r8   z for tensor=z6The calibration expects only one element type but got r   )ra   zMonly float32 or float16 is supported, every constant must be explicitly typedr   z'old_min should be a numpy array but is Nra  )r<   rv   r9   r   r   rA   r   rz   r,   r>   flattensizer  r  rL  absoluter  	histogramr  r-   float64r@   arangehstackrx  ry  )rD   r  re  data_arrarradtypesdata_arr_npr  r  r_   r`   old_histogramr|  r}  old_histold_hist_edges	temp_amaxwidthnew_bin_edgess   &&                  r   r  )HistogramCollector.collect_absolute_valueA  sE    !, 1 1 3F(D))#C%c2::66l:J4PS9+Uabhak8ll6 $+348a''846{a' LVHT`ag`jk' !jj2"**55 #3DN3C<PVz!Z[[&%--/K!#IIk2	IIk2	HHQk.?.?@	HHQk.?.?@	++k2K000#%<<--#P '..{/@/@A
"((BJJ6 c6 04.V##F+ $ 3 3F ;'*'*w00k4[\`ah\i[j2kk0w00k4[\`ah\i[j2kk0(+!.q!1IIk2	~b11*1-q0AAE$&IInR.@5.H)V[J[]b$cM%'YY/N%ON#%<<.#Q '..{/@/@A
_s8}%1%"((BJJ6 c6 04WAXZ]^eZq.r##F+i !4 5s   1Oc           	     
   VP                  4        EFm  w  r#\        P                  ! V4      pVP                  4       pVP                  ^ 8  d.   \        P
                  ! V4      p\        P                  ! V4      pMD\        P                  ! ^ VP                  R7      p\        P                  ! ^ VP                  R7      p\        P                  ! \        \        V4      \        V4      4      VP                  R7      pW P                  9   d7   V P                  V,          pV P                  WsWEV4      V P                  V&   EK2  \        P                  ! W0P                  V) V3R7      w  rVV	VVV3V P                  V&   EKp  	  R# )z!
Collect histogram on real value
r   rE  N)r<   r   r,   r  r  r  r  rL  r   ry  r  r  merge_histogramr  r  )
rD   r  re  r  r  r  	thresholdr  r_   r`   s
   &&        r   r   HistogramCollector.collect_value{  s+    !, 1 1 3Fzz(+H'')H}}q IIh/	IIh/	HHQhnn=	HHQhnn=	S^S^!DHNN[I,,, $ 3 3F ;.2.B.B!Y9/##F+ $&<<--QZPZ\eOf#g /##F+) !4r   c                h   Vw  rgrp
WZ8:  dG   \         P                  ! V\        V4      V
) V
3R 7      w  rW,           V\        W4      \	        W4      V
3# V
^ 8X  d1   \         P                  ! V\        V4      V) V3R 7      w  rW,          pM\        V4      p^V
,          V,          p\        WZ,
          V,          ^,           4      pV^V,          ,           pVV,          V
,           p\         P                  ! VVV) V3R 7      w  rVVVV,
          ;;; V,          uuu% VV\        W4      \	        W4      V3# )r  )r   r  rz   rx  ry  r'   )rD   r  r  r~  r  new_thresholdr  r  r|  r}  old_thresholdnew_histr=  r_   r`   old_num_bins
old_stridehalf_increased_binsnew_num_binss   &&&&&&             r   r  "HistogramCollector.merge_histogram  s:   FSC7]),,xX~WdFefKH#G%G%  !#%<<#h-Q^P^`mOn#o  "8}.=
&)=+HZ*WZ[*[&\#+a2E.EE 3j @= P#%<<,P]~_lNm#n (<:M+MNRZZNG%G% r   c                   V P                   '       d   \        V P                   4      ^ 8X  d   \        R4      h\        RV P                  : R24       V P                  R8X  d   V P                  4       # V P                  R8X  d   V P                  4       # V P                  R8X  d   V P                  4       # \        R4      h)r   z=Histogram has not been collected. Please run collect() first.z0Finding optimal threshold for each tensor using z algorithm ...r3   r  r  r  )r  rz   r>   r  r  compute_entropycompute_percentilecompute_distributionrO   s   &r   r  ,HistogramCollector.compute_collection_result  s    """c$*=*=&>!&C\]]@~^_;;)#''))[[L(**,,[[N*,,..cddr   c                Z   V P                   ^ 8  g   V P                   ^d8  d   \        R4      hV P                  pV P                   p/ p\        R\	        V4       24       \        RV P
                   24       \        RRV,
           RV R24       VP                  4        EF  w  rEV^ ,          pV^,          pVP                  4       p\        P                  ! Wh,          4      p	V P                  '       dr   \        P                  ! WR,          4      p
\        P                  ! Wz,          VP                  R7      ) \        P                  ! Wz,          VP                  R7      3W4&   MRV,
          R	,          p\        P                  ! V	R
V,
          4      p
\        P                  ! W4      p\        P                  ! W|,          VP                  R7      \        P                  ! Wz,          VP                  R7      3W4&   V^,          pV^,          pW4,          ^ ,          V8  d   WV,          ^,          3W4&   W4,          ^,          V8  d   W4,          ^ ,          V3W4&   . W4,          OVR,          O5W4&   \        P                  P!                  RR4      R9   g   EK  \#        Wg4       EK	  	  V# )r   z<Invalid percentile. Must be in range 0 <= percentile <= 100.Number of tensors : Number of histogram bins : zPercentile : (g      Y@,)r   g      i@r)   Nr   NQUANTIZATION_DEBUG0r<  1)r  r>   r  r  rz   r  r<   r/   r   cumsumr   searchsortedrL  r   osenvirongetr
   )rD   r  r  thresholds_dictre  r  r_   r`   totalcdf	idx_rightpercent_to_cut_one_sideidx_leftr  r  s   &              r   r  %HistogramCollector.compute_percentile  s.   ??Q$//C"7[\\,,__
$S%8$9:;+DMM?;<uz12!J<qAB!/!5!5!7FQ<D"1JHHJE))DL)C~~~OOCe1CD	 XXj3:;K;KLLHHZ2*:J:JK+'
 ,1:+=*F'OOC7N1NO	??3HHHZ19I9IJHHZ2*:J:JK+' "!I!!I&q)I5+4f6Ma6P*Q'&q)I5+:+B1+Ey*Q'&K(?&K$r(&KO#zz~~2C8HD4,; "8> r   c                   V P                   pV P                  p/ p\        R \        V4       24       \        RV P                   R24       \        RV P                   24       VP                  4        Fk  w  rEV P                  WR4      pWcV&   . VOVR,          O5W4&   \        P                  P                  RR4      R9   g   KQ  \        V^ ,          V^,          4       Km  	  V# )r  r  z: (The number may increase depends on the data it collects)zNumber of quantized bins : r  r  r  r  )r  r  r  rz   r  r<   get_entropy_thresholdr"  r#  r$  r
   )rD   r  r  r%  re  r  optimal_thresholds   &      r   r  "HistogramCollector.compute_entropy  s    ,,!44$S%8$9:;+DMM?:tuv+D,C,C+DEF!/!5!5!7F $ : :9 Y&7F#&J(9&JIbM&JO# zz~~2C8HD9Q<16 "8 r   c                   V^ 8:  d   \        RV R24      hVRR VR,          ,           R,          pV^8X  d   W,          P                  4       V P                  4       ,          pW^,          ,          P                  4       V P                  4       ,          V^,          ,
          R,          p\        P                  ! WAP                  R7      \        P                  ! WQP                  R7      3# \        V4      V8X  d   \        V4      ^,          ^8X  d   WV,          ,          P                  4       V P                  4       ,          pWV,          V,
          ^,          ,          P                  4       V P                  4       ,          R,          p\        P                  ! WAP                  R7      \        P                  ! WQP                  R7      3# \        P                  ! V4      V,          p^V\        P                  ! V4      &   ^V\        P                  ! V4      &   \        P                  ! V4      V,          V,          pW,          P                  4       V P                  4       ,          pW^,          ,          P                  4       V P                  4       ,          V^,          ,
          R,          p\        P                  ! WAP                  R7      \        P                  ! WQP                  R7      3# )r   zpower=z <= 0 is invalid.N:r<  NNg      ?r   ra  )	r>   r/   r   rL  r   r'   r  isnanisinf)r_   r`   powerr   rS   rT   facts   &&&    r   _avg_stdHistogramCollector._avg_std  s   A:veW,=>??Sb/JrN2c9A:=%%'$((*4C19$))+dhhj836AcIC88C'7'78"((3N^N^:___u:3u:>Q#6%-',,.;CEMC/A55::<txxzIcQC88C'7'78"((3N^N^:___vvf~& RXXd^ RXXd^5(4/}!!#dhhj0qy %%'$((*4sAv=#Exx#3#34bhhsJZJZ6[[[r   c           
        V P                   R 8  d   \        R4      hV P                  p/ p\        R\	        V4       24       \        RV P                    24       \        RV P
                  : R24       VP                  4        EFW  w  r4V^ ,          pV^,          pVP                  \        P                  8w  g   Q hV P
                  R8X  d   V P                  WV^R7      w  rxM2V P
                  R8X  d   V P                  WVRR7      w  rxM\        R	4      hVP                  \        P                  8w  g   Q hVP                  \        P                  8w  g   Q hVP                  \        P                  8w  g   Q h\        VVVVVP                  4       VP                  4       R
7      W#&   \        P                  P!                  RR4      R9   g   EKL  \#        WV4       EKZ  	  V# )i   z3Invalid num_bins. Must be in range 512 <= num_bins.r  r  zScenario : r  r  )r3  p3z,Invalid scenario. Must be in {'same', 'p3'}.)rS   rT   r_   r`   rK   rL   r  r  gUUUUUU?r  )r  r>   r  r  rz   r  r<   r   r   r  r5  r5   rx  ry  r"  r#  r$  r
   )	rD   r  r%  re  r  r_   r`   avg_coefstd_coefs	   &        r   r  'HistogramCollector.compute_distribution"  s   ==3RSS,,$S%8$9:;+DMM?;<DMM,A./!/!5!5!7FQ<D"1J##rzz111}}&%)]]41]%M"($&%)]]49]%U"( !OPP>>RZZ///>>RZZ///##rzz111&0%!~~'"('O# zz~~2C8HD4,3 "86 r   c           	        V^ ,          pV^,          pVP                   pV^,          pV^,          pV^,          P                  p\        P                  ! Wg,
          ^,           4      p	\	        V	P                   4       U
u. uF3  p
\        P
                  ! ^ VR7      \        P
                  ! ^ VR7      3NK5  	  pp
\	        Wv^,           ^4       EFR  p
Wj,
          p\        Wj,           ^,           V4      pWL,          WM,          3WV,
          &   \        P                  ! W<V 4      pVP                  4       p\        VRV 4      p\        W=R 4      pV^ ;;,          V,          uu&   VR;;,          V,          uu&   V^ 8g  P                  \        P                  4      p\        P                  ! V\        P                  R7      pVP                   V,          p\	        V4       F&  pVV,          pVV,           p\        VVV 4      VV&   K(  	  VR;;,          \        WV,          R 4      ,          uu&   \        P                  ! VP                   \        P                  R7      p\	        V4       F?  pVV,          pVV,           p\        VVV 4      pV^ 8w  g   K,  VV,          V,          VVV% KA  	  \        V4      p\        V4      pVe   Vf(   \        P
                  ! \        P                  VR7      pM"\        P
                  ! \        VV4      VR7      pVWV,
          &   EKU  	  \        P                  ! V	4      pVV,          pV^,          pV^,          pV^ ,          V8  d   VV^,          3pV^,          V8  d   V^ ,          V3p\!        V^ ,          R4      '       g   Q h\!        V^,          R4      '       g   Q hV# u up
i )a&  Given a dataset, find the optimal threshold for quantizing it.
The reference distribution is `q`, and the candidate distribution is `p`.
`q` is a truncated version of the original distribution.
Ref: http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf
r   Nr   ra  )r  r   r   zerosrE  rL  rx  r  deepcopyr/   r-   rM  r   r   r3   argminr@   )rD   r  r  r_   r`   r  zero_bin_indexnum_half_quantized_binr   kl_divergencer0  
thresholdsr   r   sliced_distributionpleft_outliers_countright_outliers_countnonzerosquantized_binsnum_merged_binsr8  startendqnormdivmin_kl_divergence_idxr.  r  r  s   &&&                            r   r-  (HistogramCollector.get_entropy_thresholdJ  sU    |q\
99!Q!3q!8!""!H1!LMTYZgZlZlTmnTmqrxx/!51IJTm
n  -/A1EA(,KN.2H=I6@6MzOd5eJ112"&--0K"L $((*A"%d<K&8"9#&tJ'7#8 aD''DbE))E Qrxx0H  XX&8IN166:LLO 12/o-(+,?c,J(Ku% 3 2#&9:^:`&a"bb rxx0A12/o-8E#./19#1%#84#?AeCL 3 $A&A#A&AyAIhhrvvU3hhwq!}E:8;M445] F` !#		- 8&'<=aL	aL	Q)+!*,=a,@ AQ)+!21!5y A(+W5555(+W5555  U os   >9N>)r  r  r  r  r  r  r   N)r<  )r[   rb   rc   rd   r  rH   r  r  r  r  r  r  r  r  staticmethodr5  r  r-  rg   rh   ri   s   @r   r  r    sf     !#e8st@@e,\* \ \*&PX! X!r   r  r  Fc                j    V ^8  d   QhR\         \        ,          R\        \         ,          R,          /# )r   r   r   Nr   )r   s   "r   r   r     s1     NK NK:NK#C=4/NKr   c                    R pV\         P                  8X  dq   VP                  RR4      pVP                  RR4      p	VP                  RR4      p
VP                  RR 4      pVP                  RR4      p\        V VVVVV	V
VVR7	      pEMV\         P                  8X  dJ   VP                  R	^4      pVP                  R
^4      pVP                  RR4      p\        V VVVVVVR7      pMV\         P                  8X  dJ   VP                  R	R4      pVP                  RR4      pVP                  RR4      p\        V VVVVVVR7      pMJV\         P                  8X  d6   VP                  R	R4      pVP                  RR4      p\        V VVVVVR7      pV'       d1   VP                  4        V'       d   WWn        VP                  4        V# \        RV 24      h)Nr   Fr  r   r  r!  r   )r   r   r  r   r!  r   r  r  )r   r   r  r  r  r  r  T)r   r   r  r  r  r  )r   r  r  zUnsupported calibration method )rx   ry   r$  r  r   r  r   r  r   r  r  r   r   r>   )r   r   r   calibrate_methodr   r   extra_options
calibratorr   r  r   r!  r   r  r  r  r  s   &&&&&&&          r   create_calibratorrX    s    J,333!%%k59	&**+;UC*../CTJ#0#4#45OQU#V #''u=%! %=)1%=#


 
.66	6 $$Z5*../CSI!%%k59	&! %=1

 
.99	9 $$Z6"&&|V<
!%%k48	)! %=!

 
.;;	; $$Z6 $$Z8+! %=

   "-6*++-
67G6HI
JJr   )Nr   )(r   r  r   r"  rI  collections.abcr   enumr   pathlibr   numpyr   r&  r   r   r   r	   r   quant_utilsr
   r   r   r"   r3   r5   rl   rx   ABCMetar   r   r  r  r  r  r  r  r  ry   rX  r   r   r   <module>r_     s      	  $     > >  U U8   F1 1h "ckk "4k" k"\m,~ m,`DL. DLN
+ 
D
. 
D 
0  
F" ",E!1 E!T 37/&--"NK NKr   