
    iY                     d   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j8                  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jJ                  e&z  ejJ                  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jJ                  dejJ                  dejJ                  fd       Z1e0dejJ                  dejJ                  dejJ                  fd       Z2e0dejJ                  dejJ                  dejJ                  fd        Z3dede4fd!Z5deded"e'defd#Z6y)$    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	y)NodeInputOrOutputTypeN)
__name__
__module____qualname__enumautoFP32INT8FP16UNKNOWNFP32_OR_INT8     N/var/www/html/engine/venv/lib/python3.12/site-packages/torch/ao/ns/fx/utils.pyr   r      sE    499;D499;D499;DdiikG
 499;Lr   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 rIt        | |d
      }t        |t              st        dt        |             t        ||||      \  }}||fS t        j                  t        j                  fS | j                   dk(  r{| j                   dk7  rt        d| j                    d      t        | j                  t              s!t        dt        | j                               t        || j                        t        fd|
D              }t        |t         t"        f      s|rIt        | |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(  rp| j                  dk(  rWt        | |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 rIt        | |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   6   K   | ]  }t        |        y wN
isinstance.0target_typemods     r   	<genexpr>z7get_node_first_input_and_output_type.<locals>.<genexpr>R   s       1
 sK(1
   c              3   6   K   | ]  }t        |        y wr/   r0   r2   s     r   r6   z7get_node_first_input_and_output_type.<locals>.<genexpr>f          )
 sK()
r7   c              3   6   K   | ]  }t        |        y wr/   r0   r2   s     r   r6   z7get_node_first_input_and_output_type.<locals>.<genexpr>j   r9   r7   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   rC   rC   &   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r1=Ii.$':4	?:K%LMM 52z+C%% *+@AA)113H3P3PQQ	M	!77m# #>twwiq!IJJ$++s+ #9$t{{:K9L!MNNr4;;/-0 1
81
 .
*
 sZ7GHI1 1r1=Ii.$':4	?:K%LMM 52z+C%% *+@AA%( )
0)
 &
" &) )
0)
 &
" &)..0E0J0JKK')..0E0J0JKK)113H3P3PQQ	M	!;;,& 1r1=Ii.$':4	?:K%LMM 52z+C%% *+@+E+EFF[[D 
 1r1=Ii.$':4	?:K%LMM 52z+C%%
 %=T2q$I!$EMM9$,--HI  *+@+E+EFF[[660r1=Ii.$':4	?:K%LMM 52z+C%% *+@AA%--/D/L/LMM%--/D/L/LMMr   c                    t        | |d      }t        |t              sy|d   }d }|j                  dk(  r}|j                  t
        j                  u r |||dd      S |j                  t        j                  t        j                  t        j                  t        j                  fv r |||dd      S y|j                  d	k(  r t        |j                  t              s!t        d
t        |j                               t        ||j                        t        t         j"                  t         j$                  t         j&                  t(        j*                  t         j,                  t         j.                  t         j0                  t         j2                  t         j4                  t         j6                  t         j8                  t         j:                  t         j<                  t         j>                  t         j@                  t         jB                  t         jD                  t         jF                  t(        jH                  t(        jJ                  t(        jL                  t(        j*                  t(        jN                  t(        jP                  f      rjR                  jT                  fS tW        fd|D              }|rtY        |||      S y)z{
    Returns the qparams (scale, zero_point) of the first input to `node`,
    if they can be inferred from the graph.
    r   Nr(   c                    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	   rA   rB   r?   rD   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
*4Z@*d+ #6tJ7G6H!IJJ*++S1 #5d:;L;L6M5N!OPP'4( #6tG}o!FGG'..#. #5d7>>6J5K!LMM$R):):;	!"gnn56""r   r*   r
         r,   rZ   c              3   6   K   | ]  }t        |        y wr/   r0   )r3   r4   
module_objs     r   r6   z)get_node_input_qparams.<locals>.<genexpr>   s       1
 z;/1
r7   )-r@   r1   r	   r>   r?   rF   quantize_per_tensortoqaddadd_relumulmul_relurD   rA   rB   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_pointrE   get_node_input_qparams)r   r   r   rV   rN   ra   rS   re   s          @r   r   r      s    )r15Ii& 89T U# ||&u8883Ir1aHH#''3<<#,,!OO3Ir1aHH 
	&)**C0 #5d9;K;K6L5M!NOO%b)*:*:;








####""""""		1
: $$j&;&;<<-0 1
81
 .
* .))R9QRRr   c                 F   | j                   dk(  rt        || j                        }t        |      rnt	        | j
                        dk7  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k7  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+   rZ   )r>   r   r?   r   lenargsrA   r1   r	   rB   rD   r   r   node_objs      r   return_first_non_observer_noder     sT    ww-#B4&x0499~"$?DII?OP  diilD1$':4		!;M:N%OPP99Q<Ddkk3/$'9$t{{:K9L%MNN'DKK8H*84tyy>Q&(CC		NCST  "$))A,5(+>tDIIaL?Q>R)STTyy|Kr   c                     | j                   dk(  r1t        || j                        }t        |t        j
                        ryy)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,   rb   r
   )r>   r   r?   r1   nnLSTMr   s      r   get_number_of_non_param_argsr   +  s6    " ww-#B4h( r   c                    t        | j                        dk(  rg S | j                  dk(  r| j                  t        j
                  t        j                  j                  j
                  t        j
                  fv sO| j                  t        j                  t        j                  j                  j                  t        j                  fv r9t        d      D cg c]#  }t        | j                  |         t        u s"|% }}|S dgS c c}w )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*   rb   )r   r   r>   r?   rF   rh   ops	quantizedoperatorrj   rangerB   r	   )r   iresults      r    get_arg_indices_of_inputs_to_logr   E  s     499~	ww/!		599#6#6#:#:HLLII;;599eii&9&9&=&=x||LL"1XDdiil);t)C!DD3J Es   #D9Dc                 R   d}| j                   dv r!t        j                  | j                        }|S | j                   dk(  rft	        | 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,   rZ   )	r>   rF   typenamer?   r1   rD   rA   rB   r   )r   r   r4   
target_mods       r   get_target_type_strr   ]  s    
 Kww22nnT[[1  
M	!$++s+ #5d4;;6G5H!IJJ%b$++6
nnZ0r   results
model_namec                     i }| j                         D ]h  \  }}d}|j                         D ]A  }|j                         D ],  \  }}||k(  r"t        |      dk(  rt        d      |d   d   }-. C ||||<   d|||<   j |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   rA   )	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..%;%B%B%D 	!3H3N3N3P /!Z/?+q0,-WXX%4Q%7%HN	 %*@K'*@K'A r   c                    d}| j                         D ]L  }|j                         D ]6  }|j                         D ]   \  }}t        |      dkD  s|d   d   |} n  n  n |rw| j                         D ]c  }|j                         D ]N  }||   }|j                         D ]4  \  }}||k(  rt        t        |            D ]  }||   d   }|||   d<    6 P e yy)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     s-     ").."2 %;%B%B%D 	!-B-H-H-J )
M}%)$Q'.:/9,	
 	 	 &-nn&6 		6")?)F)F)H 6%$9:N$O!1F1L1L1N 6-J!%99 "3}#56 6/25925a(/6	66		6 r   c                       fdS )Nc                  f   | ^}}}t        |t              rt        |t              s t        |t              rFt        |t              r6g }t        ||      D ]#  \  }}||g|}|j	                   
|i |       % |S t        |t
        j                        rRt        |t
        j                        r8|j                  r|j                         }|j                  r|j                         }|j                  t
        j                  k7  s|j                  t
        j                  k7  ry ||g|} 	|i |S r/   )r1   tuplelistzipappendrF   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  s   Br5!jU&;r4 ZD%9GBK ;S/w/uh9&9:; NELL)jU\\.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                     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
       )rF   normlog10)r   r   PsPns       r   compute_sqnrr     s;     
AB	AE	BBG$$$r   c                 |    t        j                  | |z
  dz  j                         | dz  j                         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
    rb   )rF   sqrtsumr   r   s     r   compute_normalized_l2_errorr     s3     ::A!|((*adZZ\9::r   c                     | j                  dd      } |j                  dd      }t        j                  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
   )reshaperF   r   
functionalcosine_similarityr   s     r   compute_cosine_similarityr     sA     	
		!RA			!RA8800A66r   c                     | j                   dk(  ri| j                  t        j                  t        j                  t
        j                  t
        j                  t        j                  t        j                  fv ryy)Nr*   FT)r>   r?   rF   rh   rj   r   catstack)r   s    r   op_type_supports_shadowingr   
  sQ    ww/!;;IIIILLLLIIKK
 
 r   idxc           
      n   	 | j                  |d      }|t|\  }}t        |      t        |      z   |k  r&t        d| dt        |      t        |      z          |t        |      k  r||   S t        |j	                               |   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                  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                  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   rA   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0C7$SE!8Y#kJZ9Z8[\  S^# ~% K..01#66499~DKK 00C7$SE!8TYY#dkkJZ9Z8[\  S^#yy~% 3tyy>1
DKK..01*== : tyy>C,,3 4S^c$++FV5V4WX TYY99S>!s499~-J**,-j99:s,   A,E /E BE =E BH43>H43H4)7r   r   collections.abcr   rF   torch.ao.nn.intrinsic.quantizedaor   	intrinsicr   rp   torch.ao.nn.quantizedrl   torch.nntorch.ao.quantizationr   r   torch.ao.quantization.observerr   torch.ao.quantization.utilsr   torch.fxr   torch.fx.graphr	   ns_typesr   r   r   rg   Enumr   dictrD   setr   rC   r   r   intr   r   r   r   r   r   r   r   r   r   r   r   boolr   r@   r   r   r   <module>r      s     $  . . # #  @ F 8    5 ii
	DII 	DN
DNDN DN #3,<(=#=>	DN
  "778DNNU
UU #3,<(=#=>U 5<<%!334t;	Up#
## 
#L
 	44 DI 0d    %%% %P 6M  6d  6F: :%ELL %U\\ %ell % :%  :;5<< ;ELL ;U\\ ; :; :7 7%,, 75<< 7 :7&T d *:4 *:[ *:s *:t *:r   