
    [ThsP                        S SK r S SKrS SKJrJrJr  S SKrS SKJs  J	s  J
s  Jr  S SKJs  J	s  Jr  S SKJ	r	  S SKJrJr  S SKJr  S SKJr  S SKJr  S SKJr  SS	KJrJr  \R<                  R                  r " S
 S\ R@                  5      r!S\S\S\S\"\#\$\   4   S\%\!\!4   4
S jr&S\S\S\"\#\$\   4   S\\%\\RN                  \(4   \\RN                  \)4   4      4S jr*S\S\S\4S jr+S\S\S\)4S jr,S\S\-\)   4S jr.S\S\S\#4S jr/S\S\#S\4S jr0S\SS4S jr1S r2\2S\RN                  S\RN                  S\RN                  4S j5       r3\2S\RN                  S\RN                  S\RN                  4S j5       r4\2S\RN                  S\RN                  S\RN                  4S  j5       r5S\S\64S! jr7S\S\S"\)S\4S# jr8g)$    N)CallableOptionalUnion)FakeQuantizeBaseObserverBase)_is_activation_post_process)getattr_from_fqn)GraphModule)Node   )NSNodeTargetTypeNSResultsTypec                       \ rS rSr\R
                  " 5       r\R
                  " 5       r\R
                  " 5       r\R
                  " 5       r	\R
                  " 5       r
Srg)NodeInputOrOutputType    N)__name__
__module____qualname____firstlineno__enumautoFP32INT8FP16UNKNOWNFP32_OR_INT8__static_attributes__r       L/var/www/auris/envauris/lib/python3.13/site-packages/torch/ao/ns/fx/utils.pyr   r      s;    99;D99;D99;DiikG
 99;Lr   r   nodegm
logger_clsnode_type_to_io_type_mapreturnc                   ^ US   nUS   nUS   nUS   nUS   nUS   n	US   n
US   nU R                   S	:X  a  U R                  U;   a   [        R                  [        R                  4$ U R                  U;   a   [        R                  [        R                  4$ U R                  U;   a   [        R
                  [        R
                  4$ U R                  U;   a5  [        XS
5      n[        U[        5      (       d   e[        XX#5      u  nnX4$ [        R                  [        R                  4$ U R                   S:X  GaM  U R                   S:X  d   e[        U R                  [        5      (       d   e[        XR                  5      m[        U4S jU
 5       5      n[        TU[        [        45      (       d  U(       a5  [        XS
5      n[        U[        5      (       d   e[        XX#5      u  nnX4$ [        U4S jU 5       5      n[        U4S jU	 5       5      nU(       a   [        R                  [        R                  4$ U(       a   [        R
                  [        R
                  4$ [        R                  [        R                  4$ U R                   S:X  Ga8  U R                  S:X  aE  [        XS
5      n[        U[        5      (       d   e[        UXU5      u  nnU[        R                  4$ U R                  S:X  an  [        XS
5      n[        U[        5      (       d   e[        UXU5      u  nn[        XS5      nU[         R"                  L d
   U S35       eU[        R                  4$ U R                  U;   a5  [        XS
5      n[        U[        5      (       d   e[        XX#5      u  nnX4$ [        R                  [        R                  4$ [        R                  [        R                  4$ )Nfuns_io_type_fp32funs_io_type_fp16funs_io_type_int8funs_io_type_fp32_or_int8mods_io_type_fp32mods_io_type_int8mods_io_type_fp32_or_int8meths_io_type_fp32_or_int8call_functionr   call_modulec              3   <   >#    U  H  n[        TU5      v   M     g 7fN
isinstance.0target_typemods     r    	<genexpr>7get_node_first_input_and_output_type.<locals>.<genexpr>N   s      1
<U[JsK((<U   c              3   <   >#    U  H  n[        TU5      v   M     g 7fr2   r3   r5   s     r    r9   r:   `         )
<M[JsK((<Mr;   c              3   <   >#    U  H  n[        TU5      v   M     g 7fr2   r3   r5   s     r    r9   r:   c   r=   r;   call_method
dequantizetor   z handling needs to be added)optargetr   r   r   r   get_normalized_nth_inputr4   r   $get_node_first_input_and_output_typer   strr	   anyr   r   torchfloat16)r!   r"   r#   r$   FUNS_IO_TYPE_FP32FUNS_IO_TYPE_FP16FUNS_IO_TYPE_INT8FUNS_IO_TYPE_FP32_OR_INT8MODS_IO_TYPE_FP32MODS_IO_TYPE_INT8MODS_IO_TYPE_FP32_OR_INT8METHS_IO_TYPE_FP32_OR_INT8	first_arg_prev_node_input_typeprev_node_output_type"is_known_fp32_or_int8_input_moduleis_known_fp32_input_moduleis_known_int8_input_module	prev_nodecur_node_dtype_targetr8   s                       @r    rE   rE   &   s    11DE01DE01DE 89T U01DE01DE 89T U!9:V!Www/!;;++)..0E0J0JKK;;++)..0E0J0JKK[[--)..0E0J0JKK[[5501=Ii.... 5z%% *AA)113H3P3PQQ	M	!ww-'''$++s++++r;;/-0 1
<U1
 .
* sZ7GHII1 11=Ii.... 5z%% *AA%( )
<M)
 &
" &) )
<M)
 &
" &)..0E0J0JKK')..0E0J0JKK)113H3P3PQQ	M	!;;,& 11=Ii.... 52+C%% *+@+E+EFF[[D 
 11=Ii.... 52+C%%
 %=Tq$I!%6E'((CDE6 *+@+E+EFF[[6601=Ii.... 5z%% *AA%--/D/L/LMM%--/D/L/LMMr   c                 x  ^ [        XS5      n[        U[        5      (       d  gUS   nS nUR                  S:X  a  UR                  [
        R                  :X  a
  U" X1SS5      $ UR                  [        R                  [        R                  [        R                  [        R                  4;   a
  U" X1SS5      $ gUR                  S	:X  Ga  [        UR                  [        5      (       d   e[        XR                  5      m[        T[        R                  [        R                   [        R"                  [$        R&                  [        R(                  [        R*                  [        R,                  [        R.                  [        R0                  [        R2                  [        R4                  [        R6                  [        R8                  [        R:                  [        R<                  [        R>                  [        R@                  [        RB                  [$        RD                  [$        RF                  [$        RH                  [$        R&                  [$        RJ                  [$        RL                  45      (       a  TRN                  TRP                  4$ [S        U4S
 jU 5       5      nU(       a  [U        X1U5      $ g)zo
Returns the qparams (scale, zero_point) of the first input to `node`,
if they can be inferred from the graph.
r   Nr-   c                 d   [        XU5      n[        XU5      n[        U[        5      (       a  [        UR                  [        5      (       d   e[        U[        5      (       a  [        UR                  [        5      (       d   e[        XR                  5      n[        XR                  5      nXg4$ r2   )rD   r4   r   rC   rF   r	   )r!   r"   scale_arg_idx
zp_arg_idx
scale_nodezp_node	scale_objzp_objs           r     _get_scale_zp_from_function_args@get_node_input_qparams.<locals>._get_scale_zp_from_function_args   s    -dF
*4Z@*d++
:;L;Lc0R0RRR'4((Z-L-LLL$R):):;	!"nn5""r   r/   r         r0   c              3   <   >#    U  H  n[        TU5      v   M     g 7fr2   r3   )r6   r7   
module_objs     r    r9   )get_node_input_qparams.<locals>.<genexpr>   s      1
C\KJz;//C\r;   )+rD   r4   r   rB   rC   rH   quantize_per_tensortoqaddadd_relumulmul_relurF   r	   nnqLinearConv1dConv2dnniq
ConvReLU2dConv3dBatchNorm2dBatchNorm3dConvTranspose1dConvTranspose2dELU	GroupNormInstanceNorm1dInstanceNorm2dInstanceNorm3d	LayerNorm	Hardswish	LeakyReLUReLU6BNReLU2dBNReLU3d
ConvReLU1d
ConvReLU3d
LinearReLUscale
zero_pointrG   get_node_input_qparams)r!   r"   r$   rX   rP   rb   rU   rg   s          @r    r   r      s    )15Ii&& 89T U# ||&u8883I1aHH#''3<<#,,!OO3I1aHH 
	&)**C0000%b*:*:;








####""""""		1
 
: $$j&;&;<<-0 1
C\1
 .
* .))9QRRr   c                 6   U R                   S:X  Ga  [        XR                  5      n[        U5      (       a  [	        U R
                  5      S:X  d   e[        U R
                  S   [        5      (       d   eU R
                  S   n [        U R                  [        5      (       d   e[        XR                  5      n[        U5      (       aN  [	        U R
                  5      S:X  d   e[        U R
                  S   [        5      (       d   eU R
                  S   n U $ )ak  
If node is not an observer, returns it.  If node is an observer,
navigates up the graph and returns the first parent which is not an
observer.  For example,

graph: (node_non_obs), node = node_non_obs : returns node_non_obs
graph: (node_non_obs -> obs0), node = obs0 : returns node_non_obs
graph: (node_non_obs -> obs0 -> fq0), node = fq0 : returns node_non_obs
r0   r   r   )	rB   r	   rC   r   lenargsr4   r   rF   r!   r"   node_objs      r    return_first_non_observer_noder      s     ww-#B4&x00tyy>Q&&&diilD111199Q<Ddkk3////'KK8H*844499~***!$))A,5555yy|Kr   c                     U R                   S:X  a5  [        XR                  5      n[        U[        R
                  5      (       a  gg)a/  
Assumes that all non-param args occur first. Returns the number of
non-param args expected for a node.  For example, for

  F.linear(x, weight, bias)

Returns 1, because x is a non-param arg and weight and bias are params.
For

  lstm_mod(x, hid)

Returns 2, because both x and hid are non-param args.
r0   rd   r   )rB   r	   rC   r4   nnLSTMr   s      r    get_number_of_non_param_argsr     s7    " ww-#B4h(( r   c                 *   [        U R                  5      S:X  a  / $ U R                  S:X  a  U R                  [        R
                  [        R                  R                  R
                  [        R
                  4;   dQ  U R                  [        R                  [        R                  R                  R                  [        R                  4;   a?  [        S5       Vs/ s H'  n[        U R                  U   5      [        :X  d  M%  UPM)     nnU$ S/$ s  snf )a	  
Returns the indices of args of the node which we should attach
loggers to, if input logging is enabled.

For example,
* for (x + y), returns [0, 1]
* for (1 + y), returns [1]
* for (x + 1), returns [0]
* for (linear(x, w, b)) returns [0]
* by default, returns [0]
r   r/   rd   )r   r   rB   rC   rH   rk   ops	quantizedoperatorrm   rangetyper   )r!   iresults      r     get_arg_indices_of_inputs_to_logr   (  s     499~	ww/!		599#6#6#:#:HLLII;;599eii&9&9&=&=x||LL"1XDXdiil);t)C!XD3J Es   $DDc                 &   SnU R                   S;   a"  [        R                  " U R                  5      nU$ U R                   S:X  aL  [	        U R                  [
        5      (       d   e[        XR                  5      n[        R                  " U5      nU$ )z|
Returns a string representation of the type of the function or module
pointed to by this node, or '' for other node types.
 )r/   r?   r0   )rB   rH   typenamerC   r4   rF   r	   )r!   r"   r7   
target_mods       r    get_target_type_strr   @  sw    
 Kww22nnT[[1
 	 
M	!$++s++++%b++6
nnZ0r   results
model_namec                     0 nU R                  5        He  u  p4SnUR                  5        H=  nUR                  5        H&  u  pxXq:X  a  [        U5      (       d   eUS   S   nM&  M(     M?     Ub  XBU'   Ma  XBU'   Mg     U$ )a  
Rekeys the layer name of a results dictionary to use node names
from `model_name`.

For example, transforms

    {'base_op_1_0': {'node_output': {'model_a':
      [{'ref_node_name': 'linear1', ...}]}}}

into

    {'linear1': {'node_output': {'model_a':
      [{'ref_node_name': 'linear1', ...}]}}}

Note: we cannot use these node names directly because they are not
guaranteed to be consistent across models. This is why we extract
the results first and rekey afterwards.
Nr   ref_node_name)itemsvaluesr   )	r   r   new_resultsold_layer_nameresult_type_to_resultsnew_layer_namemodel_name_to_resultscur_model_namelist_of_resultss	            r    'rekey_logger_info_on_node_name_of_modelr   O  s    , K29--/.%;%B%B%D!3H3N3N3P/!/////%4Q%7%HN 4Q &E %*@'*@' 3B r   c                    SnU R                  5        HQ  nUR                  5        H:  nUR                  5        H#  u  pE[        U5      S:  d  M  US   S   c  M!  Un  O     O     O   U(       a|  U R                  5        Hg  nUR                  5        HP  nX1   nUR                  5        H5  u  pEXA:X  a  M  [        [        U5      5       H  nXg   S   nXU   S'   M     M7     MR     Mi     gg)aa  
If `fqn` entries are filled in for one of the models in `results`, copies
them over to any models which do not have them filled out.

A common use case benefitting from this is comparing a model prepared by
quantization to a quantized model. In this case, the model prepared by
quantization would have `fqn` entries, and the quantized model would not.
Nr   fqn)r   r   r   r   )	r   model_name_with_fqnsr   r   r   model_resultsref_model_resultsr   r   s	            r    maybe_add_missing_fqnsr   v  s      ").."2%;%B%B%D!-B-H-H-J)
}%)$Q'.:/9,	 .K
  &E 	 #3 &-nn&6")?)F)F)H%$9$O!1F1L1L1N-J!9 "3}#56/25925a(/ 7 2O *I '7 r   c                    ^ ^ U U4S jmT$ )Nc                    > U tp#n[        U[        5      (       a  [        U[        5      (       d*  [        U[        5      (       aJ  [        U[        5      (       a5  / n[        X#5       H"  u  pgXg/UQ7nUR	                  T
" U0 UD65        M$     U$ [        U[
        R                  5      (       aa  [        U[
        R                  5      (       aB  UR                  (       a  UR                  5       nUR                  (       a  UR                  5       nUR                  [
        R                  :w  d  UR                  [
        R                  :w  a  g X#/UQ7nT	" U0 UD6$ r2   )r4   tuplelistzipappendrH   Tensoris_quantizedr@   dtypefloat)r   kwargsa0a1a_otherr   el0el1new_argsfinners            r    r   Gmaybe_dequantize_first_two_tensor_args_and_handle_tuples.<locals>.inner  s   r5!!jU&;&;r4  ZD%9%9GK/w/uh9&9: ( NELL))jU\\.J.J]]_]]_ 88u{{"bhh%++&=%W%(%f%%r   r   )r   r   s   `@r    8maybe_dequantize_first_two_tensor_args_and_handle_tuplesr     s    &2 Lr   xyc                     [         R                  " U 5      n[         R                  " X-
  5      nS[         R                  " X#-  5      -  $ )z
Computes the SQNR between `x` and `y`.

Args:
    x: Tensor or tuple of tensors
    y: Tensor or tuple of tensors

Return:
    float or tuple of floats
   )rH   normlog10)r   r   PsPns       r    compute_sqnrr     s7     
AB	AE	BBG$$$r   c                 |    [         R                  " X-
  S-  R                  5       U S-  R                  5       -  5      $ )z
Computes the normalized L2 error between `x` and `y`.

Args:
    x: Tensor or tuple of tensors
    y: Tensor or tuple of tensors

Return:
    float or tuple of floats
rd   )rH   sqrtsumr   r   s     r    compute_normalized_l2_errorr     s1     ::!|((*adZZ\9::r   c                     U R                  SS5      n UR                  SS5      n[        R                  R                  R	                  X5      $ )z
Computes the cosine similarity between `x` and `y`.

Args:
    x: Tensor or tuple of tensors
    y: Tensor or tuple of tensors

Return:
    float or tuple of floats
r   )reshaperH   r   
functionalcosine_similarityr   s     r    compute_cosine_similarityr     s?     	
		!RA			!RA880066r   c                     U R                   S:X  ak  U R                  [        R                  [        R                  [
        R                  [
        R                  [        R                  [        R                  4;   a  gg)Nr/   FT)rB   rC   rH   rk   rm   r   catstack)r!   s    r    op_type_supports_shadowingr     sQ    ww/!;;IIIILLLLIIKK
 
 r   idxc                 J    U R                  USS9nUbP  Uu  pE[        U5      [        U5      -   U:  d   eU[        U5      :  a  XB   $ [        UR                  5       5      U   $ [        U R                  5      [        U R
                  5      -   U:  d   eU[        U R                  5      :  a  U R                  U   $ U[        U R                  5      -   n[        U R
                  R                  5       5      U   $ ! [         a    [        U R                  5      [        U R
                  5      -   U:  d   eU[        U R                  5      :  a  U R                  U   s $ U[        U R                  5      -   n[        U R
                  R                  5       5      U   s $ f = f)zi
Given a node, gets the n'th input to that node, normalizing
args and kwargs to the best of its ability.
T)normalize_to_only_use_kwargs)normalized_argumentsr   r   r   r   r   RuntimeError)r!   r"   r   norm_args_and_kwargs	norm_argsnorm_kwargs
kwargs_idxs          r    rD   rD     sp   
:#88T  9  
  +%9"Iy>C$44s:::S^# ~% K..01#66tyy>C$44s:::S^#yy~% 3tyy>1
DKK..01*== 	: 499~DKK 003666TYY99S>!s499~-J**,-j99	:s,   AC< 	C< %AC< >=C< <A#F"!>F"!F")9r   r   typingr   r   r   rH   torch.ao.nn.intrinsic.quantizedaor   	intrinsicr   rs   torch.ao.nn.quantizedro   torch.nntorch.ao.quantizationr   r   torch.ao.quantization.observerr   torch.ao.quantization.utilsr	   torch.fxr
   torch.fx.graphr   ns_typesr   r   r   rj   Enumr   dictrF   setr   rE   r   r   intr   r   r   r   r   r   r   r   r   r   r   r   boolr   rD   r   r   r    <module>r      s     , ,  . . # #  @ F 8    5 ii
	DII 	xN
xNxN xN #3,<(=#=>	xN
  "778xNvM
MM #3,<(=#=>M eE%,,-.ellC6G0HHIJ	M`
 
:
 	44 DI 0d   $$$ $N6M 6d 6D: :%ELL %U\\ %ell % :%  :;5<< ;ELL ;U\\ ; :; :7 7%,, 75<< 7 :7&T d !:4 !:[ !:s !:t !:r   