
    9iY                        d dl Z d dlZd dlmZ d dlZd dlmc mc mc m	Z
 d dlmc mc m	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 d dlmZ dd	lmZmZ ej        j	        Z G d
 de j                  Zdededede e!e"e         f         de#eef         f
dZ$dedede e!e"e         f         de#ej%        e&z  ej%        e'z  f         dz  fdZ(dededefdZ)dedede'fdZ*dede+e'         fdZ,dedede!fdZ-dede!defdZ.deddfdZ/d Z0e0dej%        dej%        dej%        fd            Z1e0dej%        dej%        dej%        fd            Z2e0dej%        dej%        dej%        fd             Z3dede4fd!Z5deded"e'defd#Z6dS )$    N)Callable)FakeQuantizeBaseObserverBase)_is_activation_post_process)getattr_from_fqn)GraphModule)Node   )NSNodeTargetTypeNSResultsTypec                       e Zd Z ej                    Z ej                    Z ej                    Z ej                    Z ej                    Z	dS )NodeInputOrOutputTypeN)
__name__
__module____qualname__enumautoFP32INT8FP16UNKNOWNFP32_OR_INT8     G/var/www/icac/venv/lib/python3.11/site-packages/torch/ao/ns/fx/utils.pyr   r      sQ        49;;D49;;D49;;DdikkG
 49;;LLLr   r   nodegm
logger_clsnode_type_to_io_type_mapreturnc                 
	   |d         }|d         }|d         }|d         }|d         }|d         }	|d         }
|d         }| j         d	k    r| j        |v rt          j        t          j        fS | j        |v rt          j        t          j        fS | j        |v rt          j        t          j        fS | j        |v r^t          | |d
          }t          |t                    st          dt          |                     t          ||||          \  }}||fS t          j        t          j        fS | j         dk    r| j         dk    rt          d| j          d          t          | j        t                    s$t          dt          | j                             t          || j                  t          fd|
D                       }t          |t           t"          f          s|r^t          | |d
          }t          |t                    st          dt          |                     t          ||||          \  }}||fS t          fd|D                       }t          fd|	D                       }|rt          j        t          j        fS |rt          j        t          j        fS t          j        t          j        fS | j         dk    r| j        dk    rht          | |d
          }t          |t                    st          dt          |                     t          ||||          \  }}|t          j        fS | j        dk    rt          | |d
          }t          |t                    st          dt          |                     t          ||||          \  }}t          | |d          }|t$          j        urt          | d          |t          j        fS | j        |v r^t          | |d
          }t          |t                    st          dt          |                     t          ||||          \  }}||fS t          j        t          j        fS t          j        t          j        fS )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   Expected Node, got call_modulezExpected call_module, got ''zExpected str, but got c              3   8   K   | ]}t          |          V  d S N
isinstance.0target_typemods     r   	<genexpr>z7get_node_first_input_and_output_type.<locals>.<genexpr>R   sA       1
 1
 sK((1
 1
 1
 1
 1
 1
r   c              3   8   K   | ]}t          |          V  d S r/   r0   r2   s     r   r6   z7get_node_first_input_and_output_type.<locals>.<genexpr>f   A       )
 )
 sK(()
 )
 )
 )
 )
 )
r   c              3   8   K   | ]}t          |          V  d S r/   r0   r2   s     r   r6   z7get_node_first_input_and_output_type.<locals>.<genexpr>j   r8   r   call_method
dequantizetor
   z handling needs to be added)optargetr   r   r   r   get_normalized_nth_inputr1   r	   AssertionErrortype$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_targetr5   s                       @r   rB   rB   &   sf    11DE01DE01DE 89T U01DE01DE 89T U!9:V!Ww/!!;+++).0E0JKK;+++).0E0JKK[---).0E0JKK[5550r1==Ii.. N$%L4	??%L%LMMM 52z+C %% *+@AA)13H3PQQ	M	!	!7m## !Itw!I!I!IJJJ$+s++ 	O !M$t{:K:K!M!MNNNr4;//-0 1
 1
 1
 1
81
 1
 1
 .
 .
*
 sZ7GHII	B1	B 1r1==Ii.. N$%L4	??%L%LMMM 52z+C %% *+@AA%( )
 )
 )
 )
0)
 )
 )
 &
 &
" &) )
 )
 )
 )
0)
 )
 )
 &
 &
" & 	R).0E0JKK' 	R).0E0JKK)13H3PQQ	M	!	!;,&& 1r1==Ii.. N$%L4	??%L%LMMM 52z+C %% *+@+EFF[D  
 1r1==Ii.. N$%L4	??%L%LMMM 52z+C %%
 %=T2q$I$I!$EM99$,III   *+@+EFF[6660r1==Ii.. N$%L4	??%L%LMMM 52z+C %% *+@AA%-/D/LMM%-/D/LMMr   c                    t          | |d          }t          |t                    sdS |d         }d }|j        dk    rf|j        t
          j        u r |||dd          S |j        t          j        t          j	        t          j
        t          j        fv r |||dd          S dS |j        d	k    rt          |j        t                    s$t          d
t          |j                             t          ||j                  t          t           j        t           j        t           j        t(          j        t           j        t           j        t           j        t           j        t           j        t           j        t           j        t           j        t           j        t           j        t           j         t           j!        t           j"        t           j#        t(          j$        t(          j%        t(          j&        t(          j        t(          j'        t(          j(        f          rj)        j*        fS tW          fd|D                       }|rtY          |||          S dS )z{
    Returns the qparams (scale, zero_point) of the first input to `node`,
    if they can be inferred from the graph.
    r   Nr(   c                 j   t          | ||          }t          | ||          }t          |t                    st          dt	          |                     t          |j        t                    s$t          dt	          |j                             t          |t                    st          dt	          |                     t          |j        t                    s$t          dt	          |j                             t          ||j                  }t          ||j                  }||fS )Nr+   Expected str, got )r?   r1   r	   r@   rA   r>   rC   r   )r   r   scale_arg_idx
zp_arg_idx
scale_nodezp_node	scale_objzp_objs           r    _get_scale_zp_from_function_argsz@get_node_input_qparams.<locals>._get_scale_zp_from_function_args   s"   -dBFF
*4Z@@*d++ 	K !ItJ7G7G!I!IJJJ*+S11 	Q !Od:;L6M6M!O!OPPP'4(( 	H !FtG}}!F!FGGG'.#.. 	N !Ld7>6J6J!L!LMMM$R):;;	!"gn556""r   r*   r
         r,   rY   c              3   8   K   | ]}t          |          V  d S r/   r0   )r3   r4   
module_objs     r   r6   z)get_node_input_qparams.<locals>.<genexpr>   sA       1
 1
 z;//1
 1
 1
 1
 1
 1
r   )-r?   r1   r	   r=   r>   rE   quantize_per_tensortoqaddadd_relumulmul_relurC   r@   rA   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_pointrD   get_node_input_qparams)r   r   r   rU   rM   r`   rR   rd   s          @r   r   r      s    )r155Ii&& t 89T U# # # |&&u88833Ir1aHHH#'3<#,!OOO33Ir1aHHHt 
	&	&)*C00 	P !Nd9;K6L6L!N!NOOO%b)*:;;




##"""	1
 
 	=: $j&;<<-0 1
 1
 1
 1
81
 1
 1
 .
 .
* . 	S))R9QRRR4r   c                 x   | j         dk    rt          || j                  }t          |          rt	          | j                  dk    r$t          dt	          | j                             t          | j        d         t                    s*t          dt          | j        d                              | j        d         } t          | j        t                    s$t          dt          | j                             t          || j                  }t          |          rt	          | j                  dk    r$t          dt	          | j                             t          | j        d         t                    s*t          dt          | j        d                              | j        d         } | S )a  
    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
    r,   r
   z)Expected node.args to have length 1, got r   r+   rY   )r=   r   r>   r   lenargsr@   r1   r	   rA   rC   r   r   node_objs      r   return_first_non_observer_noder     s    w-#B44&x00 	$49~~""$PDIPP   dilD11 Q$%O4	!;M;M%O%OPPP9Q<Ddk3// O$%M$t{:K:K%M%MNNN'DK88H*844 $ty>>Q&&(TC	NNTT   "$)A,55 U()StDIaL?Q?Q)S)STTTy|Kr   c                 ~    | j         dk    r1t          || j                  }t          |t          j                  rdS dS )aO  
    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.
    r,   ra   r
   )r=   r   r>   r1   nnLSTMr   s      r   get_number_of_non_param_argsr   +  sB    " w-#B44h(( 	1 1r   c                 ^    t           j                  dk    rg S  j        dk    r j        t          j        t          j        j        j        t          j        fv s4 j        t          j	        t          j        j        j	        t          j	        fv r fdt          d          D             }|S dgS )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*   c                 V    g | ]%}t          j        |                   t          u #|&S r   )rA   r   r	   )r3   ir   s     r   
<listcomp>z4get_arg_indices_of_inputs_to_log.<locals>.<listcomp>X  s1    DDDdil););t)C)C!)C)C)Cr   ra   )r   r   r=   r>   rE   rg   ops	quantizedoperatorri   range)r   results   ` r    get_arg_indices_of_inputs_to_logr   E  s     49~~	w/!!	59#6#:HLIII;59ei&9&=x|LLLDDDDU1XXDDD3Jr   c                 4   d}| j         dv rt          j        | j                  }nr| j         dk    rgt	          | j        t
                    s$t          dt          | j                             t          || j                  }t          j        |          }|S )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:   r,   rY   )	r=   rE   typenamer>   r1   rC   r@   rA   r   )r   r   r4   
target_mods       r   get_target_type_strr   ]  s    
 Kw222nT[11	M	!	!$+s++ 	K !Id4;6G6G!I!IJJJ%b$+66
nZ00r   results
model_namec                 ,   i }|                                  D ]|\  }}d}|                                D ]S}|                                 D ]<\  }}||k    r1t          |          dk    rt          d          |d         d         }<=T||||<   w|||<   }|S )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   z(Expected list_of_results to be not emptyref_node_name)itemsvaluesr   r@   )	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   m  s    , K29--// A A..%;%B%B%D%D 	 	!3H3N3N3P3P  /!Z//?++q00,-WXXX%4Q%7%HNN %*@K''*@K''r   c                 
   d}|                                  D ]X}|                                 D ]A}|                                D ]*\  }}t          |          dk    r|d         d         |} n+  |r|                                  D ]|}|                                 D ]c}||         }|                                D ]D\  }}||k    rt          t          |                    D ]}||         d         }|||         d<   Ed{dS dS )ay  
    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     sq     ").."2"2  %;%B%B%D%D 	 	!-B-H-H-J-J  )
M}%%))$Q'.:/9, 
6&-nn&6&6 		6 		6")?)F)F)H)H 6 6%$9:N$O!1F1L1L1N1N 6 6-J!%999 "3}#5#566 6 6/25925a(//6	66
6 
6		6 		6r   c                       fdS )Nc                  x   | ^}}}t          |t                    rt          |t                    s*t          |t                    rQt          |t                    r<g }t          ||          D ]'\  }}||g|R }|                     
|i |           (|S t          |t
          j                  rPt          |t
          j                  r6|j        r|                                }|j        r|                                }|j	        t
          j
        k    s|j	        t
          j
        k    rd S ||g|R } 	|i |S r/   )r1   tuplelistzipappendrE   Tensoris_quantizedr;   dtypefloat)r   kwargsa0a1a_otherr   el0el1new_argsfinners            r   r   zGmaybe_dequantize_first_two_tensor_args_and_handle_tuples.<locals>.inner  sS   Br5!! 	%jU&;&; 	%r4  	%%/D%9%9	% GBKK ; ;S/w//uuh9&99::::NEL)) 	%jU\.J.J 	% %]]__ %]]__ 8u{""bh%+&=&=4%W%%q(%f%%%r   r   )r   r   s   `@r   8maybe_dequantize_first_two_tensor_args_and_handle_tuplesr     s)    & & & & & &2 Lr   xyc                     t          j        |           }t          j        | |z
            }dt          j        ||z            z  S )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
       )rE   normlog10)r   r   PsPns       r   compute_sqnrr     s=     
AB	AE		BBG$$$$r   c                     t          j        | |z
  dz                                  | dz                                  z            S )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
    ra   )rE   sqrtsumr   r   s     r   compute_normalized_l2_errorr     s9     :A!|((**adZZ\\9:::r   c                     |                      dd          } |                     dd          }t          j        j                            | |          S )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
   )reshaperE   r   
functionalcosine_similarityr   s     r   compute_cosine_similarityr     sE     	
		!RA			!RA800A666r   c                     | j         dk    rM| j        t          j        t          j        t
          j        t
          j        t          j        t          j        fv rdS dS )Nr*   FT)r=   r>   rE   rg   ri   r   catstack)r   s    r   op_type_supports_shadowingr   
  sM    w/!!;IILLIK
 
 
 54r   idxc           
         	 |                      |d          }||\  }}t          |          t          |          z   |k    r2t          d| dt          |          t          |          z              |t          |          k     r||         S t          |                                          |         S t          | j                  t          | j                  z   |k    r<t          d| dt          | j                  t          | j                  z              |t          | j                  k     r| j        |         S |t          | j                  z   }t          | j                                                  |         S # t          $ r t          | j                  t          | j                  z   |k    r=t          d| dt          | j                  t          | j                  z              d|t          | j                  k     r| j        |         cY S |t          | j                  z   }t          | j                                                  |         cY S w xY w)zu
    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_kwargsNzIndex z out of range: total = )normalized_argumentsr   r@   r   r   r   r   RuntimeError)r   r   r   norm_args_and_kwargs	norm_argsnorm_kwargs
kwargs_idxs          r   r?   r?     s]   
%:#88T  9  
  
  +%9"I{9~~K 0 00C77$\S\\Y#kJZJZ9Z\\   S^^## ~% K..0011#6649~~DK 0 00C77$\S\\TY#dkJZJZ9Z\\   S^^##y~% 3ty>>1
DK..0011*== : : : ty>>C,,,33 XXXS^^c$+FVFV5VXX  TY9S>!!!s49~~-J**,,--j9999:s.   BF &F 7BF AF BI)#AI)(I))7r   r   collections.abcr   rE   torch.ao.nn.intrinsic.quantizedaor   	intrinsicr   ro   torch.ao.nn.quantizedrk   torch.nntorch.ao.quantizationr   r   torch.ao.quantization.observerr   torch.ao.quantization.utilsr   torch.fxr   torch.fx.graphr	   ns_typesr   r   r   rf   Enumr   dictrC   setr   rB   r   r   intr   r   r   r   r   r   r   r   r   r   r   r   boolr   r?   r   r   r   <module>r      sC     $ $ $ $ $ $  . . . . . . . . . . . . . . . # # # # # # # # # # # #       @ @ @ @ @ @ @ @ F F F F F F 8 8 8 8 8 8                   5 5 5 5 5 5 5 5 i
	 	 	 	 	DI 	 	 	DN
DNDN DN #3,<(=#=>	DN
  "778DN DN DN DNNU
UU #3,<(=#=>U 5<%!334t;	U U U Up#
## 
# # # #L
 	   44 DI    0d       %%% % % % %P 6M  6d  6  6  6  6F  : :%EL %U\ %el % % % :9%  :;5< ;EL ;U\ ; ; ; :9; :7 7%, 75< 7 7 7 :97&T d    *:4 *:[ *:s *:t *: *: *: *: *: *:r   