
    i6                       % S SK r S SKJr  S SKJrJrJrJrJrJ	r	J
r
  S SKrS SKJrJrJr  S SKJr  S SKJr  S SKJr  S SKJrJrJr  S S	KJrJr  S S
KJr  S SKJ r   S SK!J"r"  \
\\RF                  RH                  \%4   r&1 Skr'1 Skr(\RR                  \RT                  \RV                  \RX                  \RZ                  \R\                  \R^                  \R`                  \Rb                  \Rd                  \Rf                  \Rh                  \Rj                  \Rl                  \Rn                  \Rp                  0r9\\Rt                  \4   \;S'   \\Rt                     r<\Rf                  \Rj                  1r=\<\;S'   \R^                  \Rb                  1r>\<\;S'   \RZ                  1r?\<\;S'   \RR                  1r@\<\;S'   \A" \9R                  5       5      rC\<\;S'   \A" 5       rD\<\;S'   \=\>-  rE\<\;S'   \=\>-  \@-  rF\<\;S'    " S S5      rG\
\R                  R                  \\R                  R                     \	\R                  R                     4   rJS\R                  R                  S\)4S jrKS\R                  R                  S\)4S jrLS\R                  R                  S\)4S jrMS\R                  R                  S\)4S jrNS\S\)4S  jrOS\R                  R                  S\)4S! jrPS\R                  R                  S\)4S" jrQS\R                  R                  S\)4S# jrRS\R                  R                  S\)4S$ jrSS%\S\R                  R                  S\)4S& jrTS%\S\R                  R                  S\)4S' jrUS\R                  R                  S(\S\)4S) jrVS\R                  R                  S\)4S* jrWS\R                  R                  S\)4S+ jrXS\S\)4S, jrYS\S\)4S- jrZS\S\)4S. jr[S\R                  R                  S\\4S/ jr]S\R                  R                  S\\4S0 jr^S1\Rt                  S\4S2 jr_S\R                  R                  S\)4S3 jr`S\R                  R                  S\)4S4 jraS\R                  R                  S\)4S5 jrbS\R                  R                  S6\GS7\GS\	\)\%4   4S8 jrcS\R                  R                  S\)4S9 jrdS\S\\\   4S: jreS\R                  R                  S\)4S; jrfS\R                  R                  S\)4S< jrgS\R                  R                  S\)4S= jrhS\R                  R                  S\\\   4S> jriS?\\%   S\)4S@ jrjSA\S\R                  R                  S\%4SB jrkS\R                  R                  S\\R                  R                     4SC jrlS\R                  R                  S\\R                  R                     4SD jrmS\SE\%4SF jrn\	\\\\\\4   roSGrpSHrq\R                  \R                  1rt\\   \;SI'   \R                  \R                  \R                  1rx\\   \;SJ'   \R                  \R                  \R                  \R                  \R                  1r~\\   \;SK'   \x\~-  r\\   \;SL'   \\   r\
\\\   4   r\R                  S \R                  SM\R                  SN\R                  SN\R                  S \R                  SN\R                  SN0r\\\\4   \;SO'   SP\S\\4SQ jr\" SRSS9 " ST SU5      5       rS\R                  R                  SV\\S\\4SW jrS\R                  R                  S\)4SX jrSY\GR                  SP\S\o4SZ jrS[\oS\\oS\)4S] jrS^\GR                  S_\oS\\   4S` jr " Sa Sb5      r " Sc Sd5      r " Se Sf5      rSg\S\4Sh jrSi\Sj\S_\oS\4Sk jrSl\Sm\\R                  R                     S_\oS\4Sn jr\" \R                  1\R                  15      r\" \R                  1\A" 5       5      r\" \A" 5       \R                  15      r\" \A" 5       \R                  15      r\" \A" 5       \R                  15      r\" \R                  1\R                  15      r\" \R                  1\R                  15      r\" \A" 5       \x5      r\" \x\A" 5       5      r\" \x\x5      r\" \~\A" 5       5      r\" \R                  1\A" 5       5      r\" \R                  1\A" 5       5      r\" \R                  1\A" 5       5      r\" \R                  1\A" 5       5      r\" \R                  1\A" 5       5      r\" \R                  \R                  \R                  1\A" 5       5      r\" \A" 5       \A" 5       5      r\" \\5      r " So Sp5      r " Sq Sr5      rS\R                  R                  Ss\%S\)4St jrS\R                  R                  Ss\%4Su jrSS\R                  R                  Ss\%Sv\)4Sw jjrS\R                  R                  S\\   4Sx jrS\R                  R                  S\\   4Sy jrS\)4Sz jrS\R                  R                  S{\
\\4   4S| jrS\
\\4   4S} jrS~\R                  GR\                  GR^                  S\	\\R                  R                     \\R                  R                     \\R                  R                     4   4S jr SS\R                  GR\                  GR^                  S\\S\	\\R                  R                     \\R                  R                     4   4S jjrS\GRd                  S\)4S jrS\GRd                  S\)4S jrS\
\\\\\   4   S\\S\
\\\\\   4   4S jrS\\S\\S\\4S jrSi\S\%4S jrS\R                  R                  S\%4S jrSm\S\%4S jrS\R                  R                  S\%4S jrS%\S\%S\GRd                  SS4S jr  SS\S\R                  R                  S\GRd                  S\\S\)S\GRd                  4S jjrg)    N)	dataclass)AnyDictListOptionalSetTupleUnion)
VkDataTypeVkMemoryLayoutVkStorageType)format_target_name)EdgeOpOverload)
TensorSpec)	is_bufferis_lifted_tensor_constantis_param)
FakeTensorFakeTensorConverter)ExportedProgram)	InputKind)TensorArgument>   dequantize_affine.defaultdequantize_per_tensor.tensordequantize_per_token.defaultdequantize_per_tensor.defaultdequantize_per_channel.default$dequantize_per_channel_group.default>   quantize_affine.defaultquantize_per_tensor.tensorquantize_per_token.defaultquantize_per_tensor.defaultquantize_per_channel.default_VULKAN_DTYPESFP_TINT_TQINT8_TBOOL_TALL_TNONE_TFP_INT_TFP_INT_BOOL_Tc                   r    \ rS rSrSrS\\\\   4   4S jrS\	4S jr
S\	S\4S jrS\4S	 jrS\4S
 jrSrg)DtypeSetListL   z
Wrapper around a list of DtypeSet with broadcasting semantics.
If only one DtypeSet is provided, it applies to all positions.

dtype_setsc                 N    [        U[        5      (       a  UU l        g U/U l        g N
isinstancelistvals)selfr0   s     _/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/backends/vulkan/utils.py__init__DtypeSetList.__init__R   s$    $Z66J 		=GL 		    returnc                 ,    [        U R                  5      $ r2   lenr6   r7   s    r8   __len__DtypeSetList.__len__W       499~r;   idxc                 |    US:  a(  [        U R                  5      S:X  a  U R                  S   $ U R                  U   $ Nr      r>   r7   rD   s     r8   __getitem__DtypeSetList.__getitem__Z   s4    7s499~*99Q<yy~r;   c                 2    [        U R                  5      S:H  $ Nr   r>   r@   s    r8   is_emptyDtypeSetList.is_empty`   s    499~""r;   c                 :    [        S U R                   5       5      $ )z3Returns True if any position has dtype constraints.c              3   >   #    U  H  n[        U5      S :  v   M     g7f)r   N)r?   ).0ss     r8   	<genexpr>/DtypeSetList.any_constrained.<locals>.<genexpr>e   s     1y!3q6A:ys   )anyr6   r@   s    r8   any_constrainedDtypeSetList.any_constrainedc   s    1tyy111r;   r6   N)__name__
__module____qualname____firstlineno____doc__r
   DtypeSetr   r9   intrA   rI   boolrM   rV   __static_attributes__ r;   r8   r.   r.   L   sX    

54>)A#B 

 s x #$ #2 2r;   r.   noder<   c                     U R                   S:w  a  g[        U R                  [        5      (       a  g[        U R                  [        R
                  R                  5      (       a  gg)Ncall_functionFT)opr4   targetr   torch_ops
OpOverloadrc   s    r8   is_torch_op_noderl   p   sF    ww/!$++~..$++uzz4455r;   c                 t    U R                   S:w  a  g[        U R                  R                  5      nU[        ;   $ Nre   F)rf   r   rg   rY   _DQ_OPSrc   	node_names     r8   is_dequant_noderr   |   s0    ww/!"4;;#7#78Ir;   c                 t    U R                   S:w  a  g[        U R                  R                  5      nU[        ;   $ rn   )rf   r   rg   rY   _Q_OPSrp   s     r8   is_quant_noderu      s0    ww/!"4;;#7#78Ir;   c                 l    U R                   S:w  a  g[        U R                  R                  5      nSU;   $ )Nre   Fchoose_qparamsrf   r   rg   rY   rp   s     r8   is_choose_qparams_nodery      s0    ww/!"4;;#7#78Iy((r;   c                     [        U [        R                  R                  5      =(       a<    U R                  [
        R                  :H  =(       a    [        U R                  S   5      $ )zFCheck if a scale node is dynamically computed via a choose_qparams op.r   )	r4   rh   fxNoderg   operatorgetitemry   argsrk   s    r8   is_dynamic_qscaler      sG     	4' 	1KK8+++	1"499Q<0r;   c                 l    U R                   S:w  a  g[        U R                  R                  5      nUS:H  $ )Nre   Fr   rx   rp   s     r8   is_dequant_per_channel_noder      s1    ww/!"4;;#7#78I888r;   c                 l    U R                   S:w  a  g[        U R                  R                  5      nSU;   $ )Nre   F	view_copyrx   rp   s     r8   is_view_copy_noder      s0    ww/!"4;;#7#78I)##r;   c                 l    U R                   S:w  a  g[        U R                  R                  5      nUS:H  $ )Nre   Fzlinear.defaultrx   rp   s     r8   is_linear_noder      s1    ww/!"4;;#7#78I(((r;   c                 v    [        U [        R                  R                  5      =(       a    U R                  S:H  $ )Nget_attr)r4   rh   r{   r|   rf   rk   s    r8   is_get_attr_noder      s%    dEHHMM*Dtww*/DDr;   programc                 H    UR                   U R                  R                  ;   $ r2   )namegraph_signature!inputs_to_lifted_tensor_constantsr   rc   s     r8   is_constantr      s    99//QQQQr;   c                     [        U5      =(       d/    [        X5      =(       d    [        X5      =(       d    [        X5      $ )zD
Check if the given node is a parameter within the exported program
)r   r   r   r   r   s     r8   is_param_noder      s:    
 	 	4G"	4W#	4 %W3	r;   exported_programc                     U R                   UR                  R                  ;  a  gUR                  R                  U R                      nX!R                  R                  R	                  5       ;   $ )NF)rg   r   inputs_to_buffersbuffers_to_mutatevalues)rc   r   bufs      r8   is_mutable_buffer_noder      sX     {{*::LLL

*
*
<
<T[[
IC22DDKKMMMr;   c                     SU R                   ;  a  g[        U R                   S   [        R                  5      (       a  gg)z8
Returns true if the given node produces a SymInt value
valFT)metar4   rh   SymIntrk   s    r8   is_symint_noder      s3     DII$))E"ELL11r;   c                 l    SU R                   ;  a  g[        U R                   S   [        5      (       a  gg)z?
Returns true if the given node produces a single tensor value
r   FT)r   r4   r   rk   s    r8   is_single_tensor_noder      s/     DII$))E"J//r;   c                 @   [        U [        R                  R                  5      (       d  gSU R                  ;  a  g[        U R                  S   [
        5      (       d"  [        U R                  S   [        5      (       a  [        S U R                  S    5       5      $ g)zG
Returns true if the given node produces a collection of tensor values
Fr   c              3   B   #    U  H  n[        U[        5      v   M     g 7fr2   r4   r   rQ   xs     r8   rS   ,is_tensor_collection_node.<locals>.<genexpr>        G6F:a,,6F   )r4   rh   r{   r|   r   r5   tupleallrk   s    r8   is_tensor_collection_noder      ss     dEHHMM**DII$))E"D))Z		%8H%-P-PGdii6FGGGr;   c                    [        U [        R                  R                  5      (       d  gSU R                  ;  a  g[        U R                  S   [
        5      (       a  g[        U R                  S   [        5      (       d"  [        U R                  S   [        5      (       a  [        S U R                  S    5       5      $ g)zZ
Returns true if the given node produces a tensor value, or a collection of tensor values
Fr   Tc              3   B   #    U  H  n[        U[        5      v   M     g 7fr2   r   r   s     r8   rS   !is_tensor_node.<locals>.<genexpr>  r   r   )	r4   rh   r{   r|   r   r   r5   r   r   rk   s    r8   is_tensor_noder      s     dEHHMM**DII$))E"J//$))E"D))Z		%8H%-P-PGdii6FGGGr;   c                     [        U [        R                  R                  5      (       a  [	        U 5      $ [        U [
        [        45      (       a"  [        U 5      S:X  a  g[        S U  5       5      $ g)Nr   Fc              3   8   #    U  H  n[        U5      v   M     g 7fr2   )r   rQ   ns     r8   rS   %is_tensor_arg_node.<locals>.<genexpr>  s     3d>!$$d   )	r4   rh   r{   r|   r   r5   r   r?   r   rk   s    r8   is_tensor_arg_noder   	  sU    $&&d##	D4-	(	(t9>3d333r;   c                     SnU R                    HE  n[        U[        R                  R                  5      (       d  M.  [        U5      (       d  M@  US-  nMG     U$ )zY
For a given node, return the number of argument nodes that are associated with
tensors.
r   rG   )r   r4   rh   r{   r|   r   )rc   countarg_nodes      r8   num_tensor_arg_nodesr     sJ    
 EII(EHHMM22(##QJE	  Lr;   c                 l   SU R                   ;  a  g[        U R                   S   [        5      (       a  g[        U R                   S   [        5      (       d"  [        U R                   S   [        5      (       a<  [        S U R                   S    5       5      (       a  [        U R                   S   5      $ g)z7
Returns the number of tensors associated a given node
r   r   rG   c              3   B   #    U  H  n[        U[        5      v   M     g 7fr2   r   r   s     r8   rS   &num_tensors_in_node.<locals>.<genexpr>.  s     C2BQz!Z((2Br   )r   r4   r   r5   r   r   r?   rk   s    r8   num_tensors_in_noder   #  s     DII$))E"J//$))E"D))Z		%8H%-P-PC$))E2BCCCtyy'((r;   torch_dtypec                 F    U [         ;  a  [        SU  S35      e[         U    $ )z3
Returns Vulkan dtype corresponding to torch dtype
z%Invalid dtype for vulkan_preprocess ())r$   AssertionError)r   s    r8   get_vk_datatyper   4  s-     .(D[MQRSTT+&&r;   c                 h   [        U 5      (       d  gU R                  R                  SS5      nUc   e/ n[        U[        5      (       a  UR
                  /nOE[        U[        5      (       d  [        U[        5      (       a  U Vs/ s H  o3R
                  PM     nn[        S U 5       5      $ s  snf )zh
Returns true if the output of the given tensor node has dtype that
is supported by the Vulkan backend.
Tr   Nc              3   2   #    U  H  o[         ;   v   M     g 7fr2   )r$   )rQ   dtypes     r8   rS   .output_dtypes_are_supported.<locals>.<genexpr>R  s     BM5&Ms   )	r   r   getr4   r   r   r5   r   r   )rc   node_valtensor_dtypesr   s       r8   output_dtypes_are_supportedr   >  s    
 $ yy}}UD)H M(J''!(	Hd	#	#z(E'B'B*23(Q(3 BMBBB 4s   B/c                 2   [        U 5      (       d  gU R                   Hv  n[        U[        R                  R
                  5      (       a  [        U5      (       d    gM@  [        U[        [        45      (       d  M]  [        S U 5       5      (       a  Mv    g   g)zm
Returns true if all the inputs to the given tensor node have dtype that
is supported by the Vulkan backend.
TFc              3   8   #    U  H  n[        U5      v   M     g 7fr2   )r   r   s     r8   rS   -input_dtypes_are_supported.<locals>.<genexpr>d  s     Hx!2155xr   )
r   r   r4   rh   r{   r|   r   r5   r   r   rc   r   s     r8   input_dtypes_are_supportedr   U  st    
 $ IIh...x88 94-00HxHHH  r;   c                 H    [        U 5      (       d  g[        U 5      (       d  gg)zy
Returns true if all the inputs and outputs of the given tensor node have
dtype that is supported by the Vulkan backend.
FT)r   r   rk   s    r8   io_dtypes_are_supportedr   j  s#    
 't,,%d++r;   inputs_dtypesoutputs_dtypesc                 :   [        U R                  5       GH  u  p4X   n[        U5      S:X  a  M  [        U5      (       at  [	        UR
                  S   [        [        45      (       a  UR
                  S   S   R                  nOUR
                  S   R                  nXe;  a  SSU SU SU 34s  $ M  [	        U[        [        45      (       d  M  [        U5       HI  u  px[        U5      (       d  M  UR
                  S   R                  n	X;  d  M7  SSU SU SU	 SU 34s  s  $    GM     U R
                  R                  S5      n
[	        U
[        5      (       a9  US   n[        U5      S:  a$  U
R                  U;  a  SSU
R                   SU 34$ g
[	        U
[        [        45      (       ai  [        U
5       HZ  u  p;[	        U[        5      (       d  M  X#   n[        U5      S:  d  M1  UR                  U;  d  MC  SS	U SUR                   SU 34s  $    g
)z
Check if all tensor inputs/outputs have dtypes in the allowed sets.
Returns (is_valid, reason_string) for better error reporting.
r   r   Fzinput[z] dtype z not in z][zoutput dtype zoutput[)Tzdtypes valid)	enumerater   r?   r   r4   r   r5   r   r   r   r   )rc   r   r   iargallowed_dtypes	arg_dtypejsub_arg	sub_dtypeout_valts               r8   check_node_dtypesr   w  s    DII&&)~!###((5/D%=99HHUOA.44	HHUO11	.qc)H^DTUUU / dE]++'n
!'** 'U 3 9 9I 6!$QCr!HYKxGWX  	 -! '4 iimmE"G':&&'*~"w}}N'JM'--@PQQQ   
GdE]	+	+g&DA!Z((!/!2~&*qwwn/L GA3hqwwixGW"XXX	 '  r;   c                    [        U R                  S   [        5      (       a*  U R                  S   R                  [        R
                  :H  $ [        U R                  S   [        5      (       d"  [        U R                  S   [        5      (       aM  U R                  S    H:  n[        U[        5      (       d  M  UR                  [        R
                  :X  d  M:    g   g)z@
Returns true if a given node contains a tensor with bool dtype
r   TF)r4   r   r   r   rh   r`   r5   r   rc   fake_tensors     r8   tensor_node_is_boolr     s     $))E"J//yy%%33$))E"D))Z		%8H%-P-P99U+K+z22$$

2 , r;   c                 V    [        U 5      (       d  gU R                  S   R                  $ )zK
Returns the number of dimensions of the tensor produced by the given node
Nr   )r   r   ndimrk   s    r8   ndim_ofr     s'     !&&99U   r;   c                     [        U 5      (       d  gU R                  S   n[        U[        5      (       d   e[	        UR
                  5      S:  a  g[        S UR
                  SS  5       5      $ )z`
Returns True if the node's tensor has all dimensions equal to 1 except for the last dimension.
Fr   rG   c              3   *   #    U  H	  oS :H  v   M     g7f)rG   Nrb   )rQ   dims     r8   rS   'is_unsqueezed_vector.<locals>.<genexpr>  s     5#4Cax#4s   N)r   r   r4   r   r?   shaper   )rc   tensors     r8   is_unsqueezed_vectorr     sc     !&&YYuFfj))))
6<<156<<#4555r;   c                     [        U 5      (       a  [        U 5      (       a  gU R                   H'  n[        U5      (       d  M  [        U5      (       d  M'    g   g)zT
Returns true if the operator used to compute the given node contains a bool tensor
TF)r   r   r   r   s     r8   op_contains_bool_tensorr     sI     d 3D 9 9II(##(;H(E(E 
 r;   c                     [        U 5      (       a  [        U 5      (       a  gU R                   H'  n[        U5      (       d  M  [        U5      (       d  M'    g   g)zk
Returns true if the operator used to compute the given node contains a tensor
with more than 4 dimensions
TF)r   tensor_node_is_high_dimr   r   s     r8   op_contains_high_dim_tensorr     sI    
 d 7 = =II(##(?(I(I 
 r;   c                 z    S n[        UR                  5       H  u  p4U R                  U5      (       d  M  Us  $    U$ r2   )r   r   is_non_constant_tensor_node)r7   rc   primary_arg_idxr   r   s        r8   get_primary_arg_idxr     s:    %)O +++H55H , r;   nn_module_typenamesc                 V  ^ [        U [        [        45      (       a  [        U4S jU  5       5      $ [        U [        R
                  R                  5      (       d  gU R                  R                  SS 5      nUc  gUR                  5        H  u  p4Uu  p5T H  nXe;   d  M
      g   M     g)Nc              3   <   >#    U  H  n[        UT5      v   M     g 7fr2   )$node_comes_from_any_nn_module_in_set)rQ   r   r   s     r8   rS   7node_comes_from_any_nn_module_in_set.<locals>.<genexpr>  s!      
RVQ04GHHRVs   Fnn_module_stackT)
r4   r5   r   r   rh   r{   r|   r   r   items)rc   r   r   _packedtypenamepartial_names    `     r8   r   r     s     $u&& 
RV
 
 	
 dEHHMM**iimm$5t<O$**,	/L' 0 - r;   exp_progc                    Uc  g[        X5      (       a#  U R                  R                  UR                     $ [	        X5      (       a#  U R                  R
                  UR                     $ [        X5      (       a#  U R                  R                  UR                     $ [        UR                  [        5      (       d   eUR                  $ )N )r   r   inputs_to_parametersr   r   r   r   r   r4   rg   str)r  rc   s     r8   get_tensor_namer
    s    |''<<TYYGG	8	"	"''99$))DD	"8	2	2''II$))TT$++s++++{{r;   c                 R    U R                    H  n[        U5      (       d  M  Us  $    g)z
Search the direct users of the given node and return the first one that is a
dequantization op. Returns None if no dequantization op is found.
N)usersrr   rc   users     r8   find_dequant_userr  #  s'    
 

4  K  r;   c                 R    U R                    H  n[        U5      (       d  M  Us  $    g)z
Search the direct users of the given node and return the first one that is a
quantization op. Returns None if no quantization op is found.
N)r  ru   r  s     r8   find_quant_userr  .  s'    
 

K  r;   rg   c                     [        U S5      (       d  g[        U R                  [        5      (       a  U R                  U:H  $ [        U R                  S5      (       a  U R                  R	                  5       U:H  $ g)Nrg   Fr   )hasattrr4   rg   r	  r   )rc   rg   s     r8   node_has_targetr  :  s^    4""$++s##{{f$$	f	%	%{{!V++r;   ) @  r  i   i   all_storage_typesall_memory_layoutsall_quantized_memory_layoutsuniversal_memory_layout_setrG      _LAYOUT_TO_PACKED_DIMlayoutc                     [         U    $ r2   )r  )r  s    r8   packed_dim_ofr  v  s     ((r;   T)frozenc                   h    \ rS rSr% Sr\\S'   \\S'   \\R                  4S\
S\SS 4S jj5       rS	rg
)PackedDimInfoiz  z
Describes how tensor data is organized in physical memory, mirroring the
C++ PackedDimInfo struct in runtime/api/containers/Tensor.h.

packed_dimpacked_dim_block_sizememory_layoutstorage_typer<   c                 L   U[         R                  :H  nU[        R                  :X  a  U " SU(       a  SS9$ SS9$ U[        R                  :X  a  U " SU(       a  SS9$ SS9$ U[        R
                  :X  a  U " SU(       a  SS9$ SS9$ U[        R                  :X  a  U " SSS9$ U[        R                  :X  a  U " SSS9$ U[        R                  :X  a  U " SSS9$ U[        R                  :X  a  U " SU(       a  SS9$ SS9$ U[        R                  :X  a  U " SSS9$ [        SU 35      e)z
Construct a PackedDimInfo based on a memory layout and storage type,
mirroring calculate_packed_dim_info in runtime/api/containers/Tensor.cpp.
r   rG      )r"  r#  r     zUnknown memory layout: )r   BUFFERr   TENSOR_WIDTH_PACKEDTENSOR_HEIGHT_PACKEDTENSOR_CHANNELS_PACKEDPACKED_INT8_4WPACKED_INT8_4W4CPACKED_INT8_4H4WPACKED_INT8_4C1WPACKED_INT8_CONV2D
ValueError)clsr$  r%  r   s       r8   	from_reprPackedDimInfo.from_repr  s{    !M$8$88	N>>>+4a :;  nAAA+4a :;  nCCC+4a :;  n;;;&'  n===&'  n===&'  n===+4a :<  n???&' 
 6}oFGGr;   rb   N)rY   rZ   r[   r\   r]   r_   __annotations__classmethodr   r)  r   r4  ra   rb   r;   r8   r!  r!  z  sR    
 O '4&:&:4H%4H $4H 
	4H 4Hr;   r!  buffer_limitc                   ^ [        U 5      (       d   e[        U R                  S   [        5      (       a   U R                  S   R	                  5       T:  $ [        U R                  S   [
        5      (       d"  [        U R                  S   [        5      (       a"  [        U4S jU R                  S    5       5      $ [        S[        U R                  S   5       35      e)z
Checks whether the tensors produced by the given node can fit within the device's
GPU buffer limit, which represents the maximum number of elements that can be stored
in a GPU buffer.
r   c              3   H   >#    U  H  oR                  5       T:  v   M     g 7fr2   )numel)rQ   r   r8  s     r8   rS   &within_buffer_limit.<locals>.<genexpr>  s     F5E779|+5Es   "z!Cannot get numel for val of type )
r   r4   r   r   r;  r5   r   r   RuntimeErrortype)rc   r8  s    `r8   within_buffer_limitr?    s     $$))E"J//yy%%',66	DIIe$d	+	+z$))E:JE/R/RFTYYu5EFFF>tDIIeDT?U>VWXXr;   c                    [        U R                  S   [        5      (       a%  [        U R                  S   R                  5      S:  $ [        U R                  S   [
        5      (       d"  [        U R                  S   [        5      (       aH  U R                  S    H5  n[        U[        5      (       d  M  [        UR                  5      S:  d  M5    g   g)zL
Returns true if a given node contains a tensor with more than 4 dimensions
r   r'  TF)r4   r   r   r?   r   r5   r   r   s     r8   r   r     s     $))E"J//499U#))*Q..$))E"D))Z		%8H%-P-P99U+K+z22{(()A- , r;   sizesc                 f   [        U 5      S:  a  U S   OSn[        U 5      S:  a  U S   OSn[        U 5      S:  a  U S   OSn[        U 5      S:  a  U S   OSnU[        R                  :X  a	  US-   S-  nOU[        R                  :X  a	  US-   S-  nOU[        R                  :X  a	  US-   S-  nO}U[        R
                  :X  a  US-   S-  nUS-   S-  nOXU[        R                  :X  a  US-   S-  nUS-   S-  nO3U[        R                  :X  a  US-   S-  nUS-   S-  nO[        S	U 35      eX#XE-  4$ )
z
Calculate the image extents that will be used to represent a tensor with the given sizes
and memory layout in the Vulkan Delegate.
rG   r   r     r'  r   zUnsupported memory layout )	r?   r   r*  r+  r,  r.  r/  r1  r=  )rA  r  widthheightchannelsbatchs         r8   required_image_extentsrJ    sK   
 UqE"IaEe*/U2YqFJ!OuRyHE
aE!HQE333q 	>66	61*"	>88	8qLQ&	>22	2q qLQ&	>22	21*"q 	>44	4q qLQ&7x@AA(***r;   extentslimitsc                 V   ^ ^ [        U U4S j[        [        T 5      5       5       5      $ )Nc              3   :   >#    U  H  nTU   TU   :*  v   M     g 7fr2   rb   )rQ   r   rK  rL  s     r8   rS   $extents_are_valid.<locals>.<genexpr>  s      D0C1wqzVAY&0Cs   )r   ranger?   )rK  rL  s   ``r8   extents_are_validrQ    s    Dc'l0CDDDr;   tensor_sizestexture_limitsc                     [        5       n[        [        5       H1  n[        X5      n[	        XA5      (       d  M   UR                  U5        M3     U$ )z
Given tensor sizes, determine the set of memory layouts which will prodice a texture
that can fit within the specified device limits.
)setr5   r  rJ  rQ  add)rR  rS  valid_layoutsr  rK  s        r8   valid_texture_memory_layoutsrX    sF     EM)*(>W55f% +
 r;   c                   \    \ rS rSrSrS\S\4S jrS\4S jr	S\
S\4S	 jrS\
S\4S
 jrSrg)
TensorRepri  z
This class is a wrapper around a pair of VkStorageType and VkMemoryLayout which
describes how a tensor should be represented in the Vulkan Delegate.
r%  r$  c                     Xl         X l        g r2   r%  r$  )r7   r%  r$  s      r8   r9   TensorRepr.__init__  s    (*r;   r<   c                 <    SU R                    SU R                   S3$ )NzTensorRepr(, r   r\  r@   s    r8   __str__TensorRepr.__str__  s%    T../r$2D2D1EQGGr;   otherc                     [        U[        5      (       d  [        $ U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r2   )r4   rZ  NotImplementedr%  r$  r7   rb  s     r8   __eq__TensorRepr.__eq__  sG    %,,!!!3!33 :""e&9&99	
r;   c                 .    U R                  U5      (       + $ r2   rf  re  s     r8   __ne__TensorRepr.__ne__#      ;;u%%%r;   )r$  r%  N)rY   rZ   r[   r\   r]   r   r   r9   r	  r`  objectr`   rf  rj  ra   rb   r;   r8   rZ  rZ    sN    
+] +> +H H
F 
t 
&F &t &r;   rZ  c                       \ rS rSrSrS\\\\   4   4S jrS r	S\
S\4S jrS\
S	\SS
4S jrS\4S jr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jrSS\
S\4S jjrSrg
)TensorReprListi'  z
This class is a wrapper around a list of TensorRepr instances that automatically
applies a "broadcasting" mechanism. The broadcasting mechanism allows for a single
underlying TensorRepr to be used to represent multiple tensors.
tensor_reprsc                 N    [        U[        5      (       a  UU l        g U/U l        g r2   r3   )r7   rp  s     r8   r9   TensorReprList.__init__.  s$    &|T::L 		AM 		r;   c                 ,    [        U R                  5      $ r2   r>   r@   s    r8   rA   TensorReprList.__len__3  rC   r;   rD   r<   c                 h    US:  a  [        U 5      S:X  a  U R                  S   $ U R                  U   $ rF   r>   rH   s     r8   rI   TensorReprList.__getitem__6  /    7s4yA~99Q<99S>!r;   r   Nc                 h    US:  a  [        U 5      S:X  a  X R                  S'   g X R                  U'   g rF   r>   r7   rD   r   s      r8   __setitem__TensorReprList.__setitem__<  s)    7s4yA~IIaL IIcNr;   c                 N    SSR                  S U R                   5       5       S3$ )N[r_  c              3   8   #    U  H  n[        U5      v   M     g 7fr2   r	  rQ   tss     r8   rS   )TensorReprList.__str__.<locals>.<genexpr>C       9ySWWyr   ]joinr6   r@   s    r8   r`  TensorReprList.__str__B  %    4999tyy99:!<<r;   rb  c                     [        U[        5      (       d  [        $ [        U 5      [        U5      :X  a1  [	        U R
                  UR
                  5       H  u  p#X#:w  d  M    g   gg)NFT)r4   ro  rd  r?   zipr6   )r7   rb  self_val	other_vals       r8   rf  TensorReprList.__eq__E  sS    %00!!t9E
"'*499ejj'A#(  (B r;   c                 .    U R                  U5      (       + $ r2   ri  re  s     r8   rj  TensorReprList.__ne__R  rl  r;   c                 :    U R                   R                  U5        g r2   r6   appendr7   r   s     r8   r  TensorReprList.appendU  s    		r;   c                 4    U R                   U   R                  $ r2   )r6   r%  rH   s     r8   r%  TensorReprList.storage_typeX  s    yy~***r;   c                 4    U R                   U   R                  $ r2   )r6   r$  rH   s     r8   r$  TensorReprList.memory_layout[  s    yy~+++r;   rX   )r   )rY   rZ   r[   r\   r]   r
   rZ  r   r9   rA   r_   rI   rz  r	  r`  rm  r`   rf  rj  r  r   r%  r   r$  ra   rb   r;   r8   ro  ro  '  s    
U:tJ7G+G%H 

"s "z "!s ! ! != =F t &F &t &*  + +M +, ,^ , ,r;   ro  c                   D   \ rS rSrSrS\\   S\\   4S jrS\4S jr	S\
S\4S	 jrS\
S\4S
 jrSS jrS\4S jrS S jrS S jrS\S\4S jrSS S\4S jrS rS rS rS rS\4S jrS\4S jrS\4S jrS\\   4S jrSS S\4S jrSS S\4S jr    S S jr Sr!g)!TensorRepSeti_  z
This class describes the possible set of representations (i.e. TensorRepr) that may
be used to represent a tensor. This set is determined by the implementation of the
operator that the tensor participates in as well as the texture extents of the GPU.
buffer_memory_layoutstexture_memory_layoutsc                     Xl         X l        g r2   valid_buffer_layoutsvalid_texture_layouts)r7   r  r  s      r8   r9   TensorRepSet.__init__f  s    
 %:!%;"r;   r<   c                     SR                  S U R                   5       5      nSR                  S U R                   5       5      nSU SU S3$ )Nr_  c              3   8   #    U  H  oR                   v   M     g 7fr2   r   rQ   r  s     r8   rS   'TensorRepSet.__str__.<locals>.<genexpr>o  s     "W=V6;;=Vr   c              3   8   #    U  H  oR                   v   M     g 7fr2   r  r  s     r8   rS   r  p  s      $
&@FKK&@r   zTensorRepSet(Buffer Layouts: [z], Texture Layouts: [z]))r  r  r  )r7   buffer_layoutstexture_layoutss      r8   r`  TensorRepSet.__str__n  sY    "WT=V=V"WW)) $
&*&@&@$
 
 0/??TUdTeeghhr;   rb  c                     [        U[        5      (       d  [        $ U R                  UR                  :H  =(       a    U R                  UR                  :H  $ r2   )r4   r  rd  r  r  re  s     r8   rf  TensorRepSet.__eq__u  sH    %..!!%%)C)CC J**e.I.II	
r;   c                 .    U R                  U5      (       + $ r2   ri  re  s     r8   rj  TensorRepSet.__ne__}  rl  r;   c                 f    [        [        U R                  5      [        U R                  5      5      $ r2   )r  rU  r  r  r@   s    r8   copyTensorRepSet.copy  s*    ))*C0J0J,K
 	
r;   c                 p    [        U R                  5      S:H  =(       a    [        U R                  5      S:H  $ )zP
A TensorRepSet is "empty" if there are no valid representations of the tensor.
r   r?   r  r  r@   s    r8   rM   TensorRepSet.is_empty  s2    
 ))*a/XC8R8R4SWX4X	
r;   c                 v    [        U R                  UR                  -  U R                  UR                  -  5      $ )zm
Merge this TensorRepr with another TensorRepr, returning a new TensorRepr
with the intersection of the two.
r  r  r  re  s     r8   make_intersectTensorRepSet.make_intersect  9    
 %%(B(BB&&)D)DD
 	
r;   c                 v    [        U R                  UR                  -  U R                  UR                  -  5      $ )zl
Merge this TensorRepSet with another TensorRepSet, returning a new TensorRepSet
with the union of the two.
r  re  s     r8   
make_unionTensorRepSet.make_union  r  r;   storagec                    UR                   [        R                  :X  a  UR                  U R                  ;   $ UR                   [        R
                  :X  a  UR                  U R                  ;   $ [        SUR                    35      e)zE
Check if this TensorRepr is compatible with the given TensorRepSet.
Unsupported storage type )r%  r   r)  r$  r  
TEXTURE_3Dr  r=  )r7   r  s     r8   is_compatibleTensorRepSet.is_compatible  st     =#7#77((D,E,EEE!!]%=%==((D,F,FFF!:7;O;O:PQRRr;   c                     [        U R                  UR                  -  5      S:  =(       d%    [        U R                  UR                  -  5      S:  $ )zU
Check if this TensorRepr has any representations in common with another
TensorRepr.
r   r  re  s     r8   any_in_commonTensorRepSet.any_in_common  sK     ))E,F,FFG!K Q4--0K0KKLqP	
r;   c                 2    [        U R                  5      S:  $ rL   )r?   r  r@   s    r8   texture_is_validTensorRepSet.texture_is_valid  s    4--.22r;   c                 2    [        U R                  5      S:  $ rL   )r?   r  r@   s    r8   buffer_is_validTensorRepSet.buffer_is_valid  s    4,,-11r;   c                 2    [        U R                  5      S   $ rL   )r5   r  r@   s    r8   first_valid_buffer_layout&TensorRepSet.first_valid_buffer_layout  s    D--.q11r;   c                 2    [        U R                  5      S   $ rL   )r5   r  r@   s    r8   first_valid_texture_layout'TensorRepSet.first_valid_texture_layout  s    D../22r;   c                 F   U R                  5       (       a(  [        [        R                  [        R
                  5      $ U R                  5       (       a(  [        [        R                  U R                  5       5      $ [        [        R                  U R                  5       5      $ )z
Pick a representation (i.e. TensorRepr) from the set of possible representations.
If there are multiple valid representations, then:
1. Prefer texture storage over buffer storage
2. Pick the first available memory layout.
)rM   rZ  r   DEFAULT_STORAGEr   DEFAULT_LAYOUTr  r  r  r)  r  r@   s    r8   make_tensor_reprTensorRepSet.make_tensor_repr  s     ==?? --~/L/L    ""(($*I*I*K 
 m22D4R4R4TUUr;   c                     U R                  5       (       a  g[        U R                  5      S:X  a  [        U R                  5      S:X  a  g[        U R                  5      S:X  a  [        U R                  5      S:X  a  gg)a)  
A "constrained" RepSet is one that has either:
1. A single valid texture memory layout, and no valid buffer memory layouts
2. No valid texture memory layouts, and a single valid buffer memory layout
3. Is empty

In this case, it is unambiguous which representation should be used for the
tensor.
TrG   r   F)rM   r?   r  r  r@   s    r8   is_constrainedTensorRepSet.is_constrained  sg     ==??**+q0S9R9R5SWX5X**+q0S9R9R5SWX5Xr;   c                 ,    U R                  5       (       + $ )z7
An "ambiguous" RepSet is one that is not constrained.
)r  r@   s    r8   is_ambiguousTensorRepSet.is_ambiguous  s     &&(((r;   c                 H   [        5       n[        5       nU R                   H6  nUR                  [        R	                  U[
        R                  5      5        M8     U R                   H6  nUR                  [        R	                  U[
        R                  5      5        M8     X4$ r2   )	rU  r  rV  r!  r4  r   r)  r  r  )r7   
buffer_settexture_setr  s       r8   _possible_pdisTensorRepSet._possible_pdis  sw    U
e//FNN=226=;O;OPQ 000FOOM33FM<T<TUV 1&&r;   c                     UR                  5       u  p#U R                  5       u  pEU(       d  U(       d  gU(       d  U(       d  gX$:H  =(       a    X5:H  $ )z
Check if self and other produce the exact same sets of PackedDimInfo
for both buffer and texture storage types. Completely empty repsets
(no layouts for any storage type) are treated as matching any other
repset.
Tr  )r7   rb  other_buf_setother_tex_setbuf_settex_sets         r8   has_same_packed_dim_info_set)TensorRepSet.has_same_packed_dim_info_set  sI     (-';';'=$..0 w]'DM,DDr;   c                     UR                  5       u  p#U R                  5       u  pEU H
  nXd;  d  M
    g   U H
  nXe;  d  M
    g   g)z
Check if all PackedDimInfos from other are contained within self's
PackedDimInfo sets, i.e. self is a superset of other for both buffer
and texture PDI sets.
FTr  )r7   rb  r  r  r  r  pdis          r8   "has_compatible_packed_dim_info_set/TensorRepSet.has_compatible_packed_dim_info_set  sS     (-';';'=$..0 C! ! !C! ! r;   c                    UR                  5       u  p#U(       d  U(       d  U R                  5       $ U R                   Vs1 s H8  nU(       d  M  [        R	                  U[
        R                  5      U;   d  M6  UiM:     nnU R                   Vs1 s H8  nU(       d  M  [        R	                  U[
        R                  5      U;   d  M6  UiM:     nn[        XV5      $ s  snf s  snf )a!  
Return a new TensorRepSet containing only layouts from self whose
PackedDimInfo is present in other's PackedDimInfo sets. If other is
completely empty, return a copy of self unchanged. If other has layouts
for only one storage type, layouts for the missing storage type are
also removed.
)
r  r  r  r!  r4  r   r)  r  r  r  )r7   rb  r  r  r  new_bufnew_texs          r8   "constrain_to_compatible_packed_dim/TensorRepSet.constrain_to_compatible_packed_dim$  s     (-';';'=$ ]99; 33
3  ''0D0DEV 3 	 
 44
4  ''0H0HI 4 	 
 G--

s#   C&C8CC&CCr  N)r<   r  )rb  r  r<   r  )"rY   rZ   r[   r\   r]   r   r   r9   r	  r`  rm  r`   rf  rj  r  rM   r  r  rZ  r  r  r  r  r  r  r  r  r  r!  r  r  r  r  ra   rb   r;   r8   r  r  _  s)   <">2< !$N 3<i i
F 
t 
&F &t &


$ 


	SZ 	SD 	S
> 
d 
3223V* V. .)d )'M 2 'E. ET E$ 4 &.#.	.r;   r  tensor_reprc                 &   U R                   [        R                  :X  a  [        U R                  1[        5       5      $ U R                   [        R                  :X  a  [        [        5       U R                  15      $ [        SU R                    35      e)zN
Given a TensorRepr, return a TensorRepSet that contains only that TensorRepr
r  )r%  r   r)  r  r$  rU  r  r=  )r  s    r8   make_tensor_repsetr  D  sv     =#7#77[667??		!	!]%=%=	=CEK$=$=#>??6{7O7O6PQRRr;   
tensor_valtensor_repsetc                 H   [        5       nUR                   H<  n[        U R                  U5      n[	        XR5      (       d  M+  UR                  U5        M>     [        U R                  5      S:  a  [        UR                  [        5       5      $ [        UR                  U5      $ )a  
`tensor_val` represents an actual tensor participating in some operator computation.

`tensor_repset` represents the set of valid tensor representations that may be used
for that tensor that is supported by the op implementation.

`texture_limits` represents the maximum texture sizes that is supported by the GPU.

Given the above, return a new TensorRepSet that contains only texture layouts that
can be used to produce a valid image texture for the given tensor (i.e. fits within
texture limits).
r'  )	rU  r  rJ  r   rQ  rV  r?   r  r  )r  r  rS  r  r$  rK  s         r8   filter_invalid_reprsr  P  s    "  E&<<()9)9=IW55!%%m4 = :q M>>FF::<QRRr;   arg_repsetsr   c                     U nU HV  n[        U[        R                  R                  5      (       d   eUR	                  [        UR                  S   X25      5      nMX     U$ )z
Wrapper around filter_invalid_reprs for a list of nodes. This will happen
for the cat operator, where the first argument is a list of nodes.
r   )r4   rh   r{   r|   r  r  r   )r  r   rS  common_tensor_repsetsr   s        r8   "filter_invalid_reprs_for_node_listr  n  s[     (!UXX]]++++ 5 D D 0EV!
  ! r;   c                       \ rS rSrSrS\\\\   4   4S jrS r	S\
S\4S jrS\
S	\SS
4S jrS\4S jrS	\SS
4S jrS\4S jrSrg
)TensorRepSetListi  z
This class is a wrapper around a list of TensorRepSet instances that automatically
applies a "broadcasting" mechanism. The broadcasting mechanism allows for a single
underlying TensorRepSet to be used for multiple tensors.
tensor_repsetsc                 N    [        U[        5      (       a  UU l        g U/U l        g r2   r3   )r7   r   s     r8   r9   TensorRepSetList.__init__  s'    
 )>>N 		ESDT 		r;   c                 ,    [        U R                  5      $ r2   r>   r@   s    r8   rA   TensorRepSetList.__len__  rC   r;   rD   r<   c                 h    US:  a  [        U 5      S:X  a  U R                  S   $ U R                  U   $ rF   r>   rH   s     r8   rI   TensorRepSetList.__getitem__  rw  r;   r   Nc                 |    US:  a(  [        U R                  5      S:X  a  X R                  S'   g X R                  U'   g rF   r>   ry  s      r8   rz  TensorRepSetList.__setitem__  s.    7s499~*IIaL IIcNr;   c                 N    SSR                  S U R                   5       5       S3$ )Nr}  r_  c              3   8   #    U  H  n[        U5      v   M     g 7fr2   r  r  s     r8   rS   +TensorRepSetList.__str__.<locals>.<genexpr>  r  r   r  r  r@   s    r8   r`  TensorRepSetList.__str__  r  r;   c                 8    U R                   R                  U5      $ r2   r  r  s     r8   r  TensorRepSetList.append  s    yy$$r;   c                 n    [        U R                  5      S:X  a  g[        S U R                   5       5      $ )Nr   Tc              3   @   #    U  H  oR                  5       v   M     g 7fr2   )rM   )rQ   r  s     r8   rS   0TensorRepSetList.any_is_empty.<locals>.<genexpr>  s     GYk''))Ys   )r?   r6   rU   r@   s    r8   any_is_emptyTensorRepSetList.any_is_empty  s*    tyy>QGTYYGGGr;   rX   )rY   rZ   r[   r\   r]   r
   r  r   r9   rA   r_   rI   rz  r	  r`  r  r`   r  ra   rb   r;   r8   r  r    s    
lD,>>?
"s "| "!s ! !$ != =%, %4 %Hd Hr;   r  c                       \ rS rSrSrS\S\S\R                  R                  S\	4S jr
S\4S	 jrS
\S\S\	S\4S jrSS jrS\4S jrS\4S jrS\4S jrS\S\S\4S jrS\S\4S jrS\\\4   4S jrSrg)	OpRepSetsi  a  
This class is responsible for representing and managing the set of valid tensor
representations that may be used for all input and output tensors of an operator.
It is also responsible for maintaining synchronization rules between tensors
participating in the computation.

Currently, three synchronization rules exist:
1. All input tensors must use the same representation (e.g. binary ops)
2. The "primary" input and output tensors must use the same representation
   (e.g. group norm; the output is a tuple of out, mean, rstd; out must be the same
   representation as the first input x, but mean and rstd may use different
   representations as out)
3. All output tensors must use the same representation (e.g. choose qparams)

Note that "primary" input and output tensor refers to the first non-weight input
tensor and the first output tensor. Note that Some operators (such as arange) do not
have any tensor inputs.

Currently, the above three synchronization rules are sufficient to describe the
representation requirements of all ET-VK operators.

This class also provides utilities to constrain the repsets; when applying the
constraints, the synchronization rules will be maintained.
inputs_repsetsoutputs_repsetsop_noderS  c                    X0l         [        U5      S:  a  SU l        OSU l        [        U5      S:  a  SU l        OSU l        S U l        [        U R                   R                  5       H=  u  pVX   n[        U5      (       d  M  Uc  M   UR                  5       (       a  M7  XPl          O   U R                  S LU l	        U R                  b  XR                     US   :w  a  SU l	        [        / 5      n[        n	[        UR                  5       H  u  pVX   n
[        U5      (       d  UR                  [        5        M0  U
R                  5       (       a  UR                  [        5        M\  U
R                  5       (       a   eU R                  XU5      n
UR                  U
5        U	R                  U
5      n	M     [        / 5      n[        n[        U5      S:X  a/  [!        UR"                  S   US   U5      nUR                  U5        Oi[        UR"                  S   5       HM  u  p][%        U[&        5      (       d   e[!        XU   U5      nUR                  U5        UR                  U5      nMO     [(        nU R                  (       ay  U R                  (       a  U	OXR                     nU R                  (       a  UOUS   nUR                  U5      nUR+                  5       XR                  '   UR+                  5       US'   U R                  (       aB  U R                  (       a  UOU	n[-        [        U5      5       H  nUR+                  5       X'   M     U R                  (       aB  U R                  (       a  UOUn[-        [        U5      5       H  nUR+                  5       X'   M     Xl        Xl        U R3                  5         g )NrG   FTr   r   )r  r?   sync_args_reprsync_outs_reprr   r   r   r   rM   sync_primary_io_reprr  ALL_STORAGES_REPSETr  filter_invalid_reprs_for_argr  r   r  r   r4   r   
NO_STORAGEr  rP  args_repset_listouts_repset_listassert_sync_contraints)r7   r  r  r  rS  r   r   arg_node_repsetr   common_arg_repset
arg_repsetr!  common_out_repsetr   
out_repsetprimary_repsetprimary_in_repsetprimary_out_repsetcommon_repsets                      r8   r9   OpRepSets.__init__  s    
 ~""'D #'D
 !#"'D"&D
 /3$T\\%6%67KA,/O%h//&''))#$  8 %)$8$8$D!+223q7II,1) ,B//$W\\2KA'*J &h// ''(;< $$&& ''(;<%..0000!>>.
 !''
3$5$D$DZ$P!) 3. ,B//w'1, 4U#_Q%7! ##$56 $GLL$78!#z22221+^
 !''
3$5$D$DZ$P! 9 $$$ && "%&:&:;  &*%8%8!>Nq>Q  /==>PQN5C5H5H5J112"0"5"5"7Q "&";";AR  3/01&3&8&8&: # 2 "&";";AR  3/01&3&8&8&: # 2 !1 0 	##%r;   r<   c                 <    SU R                    SU R                   S3$ )NzOpRepSets(ins=z, outs=r   )r   r!  r@   s    r8   r`  OpRepSets.__str__  s&     5 56gd>S>S=TTUVVr;   r  r   c                 R   [        U[        R                  R                  5      (       a)  [	        U5      (       a  [        UR                  S   X5      $ [        U[        5      (       a#  [        S U 5       5      (       a  [        XU5      $ U R                  R                  [        R                  :X  ah  X R                  R                  S   :X  aL  U R                  R                  S   n[        U[        5      (       d   e[        UR                  S   U   X5      $ [!        SU 35      e)z.
Helper function to call filter_invalid_reprs
r   c              3   8   #    U  H  n[        U5      v   M     g 7fr2   )r   r   s     r8   rS   9OpRepSets.filter_invalid_reprs_for_arg.<locals>.<genexpr>  s      0
.6!!$$hr   r   rG   zUnhandled node type )r4   rh   r{   r|   r   r  r   r5   r   r  r  rg   r}   r~   r   r_   NotImplementedError)r7   r  r   rS  rD   s        r8   r  &OpRepSets.filter_invalid_reprs_for_arg  s    h..3H3R3R'e$k  $''C 0
.60
 -
 -
 6~  LL8#3#33LLDUDUVWDX8X,,##A&Cc3'''''e$S);  "$8
"CDDr;   Nc                 f   U R                   (       a  [        [        U R                  5      5       H  n[        US-   [        U R                  5      5       Hx  nU R                  U   nU R                  U   nUR	                  5       (       a  M8  UR	                  5       (       a  MO  UR                  U5      (       a  Mg   SU SU SU SU 35       e   M     U R                  (       a  [        [        U R                  5      5       H  n[        US-   [        U R                  5      5       Hx  nU R                  U   nU R                  U   nUR	                  5       (       a  M8  UR	                  5       (       a  MO  UR                  U5      (       a  Mg   SU SU SU SU 35       e   M     U R                  (       ax  U R                  U R                     nU R                  S   nUR	                  5       (       d:  UR	                  5       (       d$  UR                  U5      (       d   SU SU 35       eg g g g )	NrG   zSynced arg repsets z and z$ have incompatible packed dim info: z vs zSynced out repsets r   z?Primary arg and out repsets have incompatible packed dim info: )
r  rP  r?   r   rM   r  r  r!  r  r   )r7   r   r   rirjprimary_argprimary_outs          r8   r"   OpRepSets.assert_sync_contraints  s    3t4456q1uc$*?*?&@AA..q1B..q1B;;==!DD    m05;_`b_ccghjgklm  	 B 7 3t4456q1uc$*?*?&@AA..q1B..q1B;;==!DD    m05;_`b_ccghjgklm  	 B 7 $$//0D0DEK//2K''))+2F2F2H2H"EE  tTU`Taaefqerst  3I) %r;   c                 x    U R                   R                  5       =(       d    U R                  R                  5       $ r2   )r   r  r!  r@   s    r8   r  OpRepSets.any_is_empty  s-    !!..0XD4I4I4V4V4X	
r;   r   c                      U R                   U   $ r2   )r   r7   r   s     r8   get_arg_repsetOpRepSets.get_arg_repset      $$Q''r;   c                      U R                   U   $ r2   )r!  r=  s     r8   get_out_repsetOpRepSets.get_out_repset  r@  r;   arg_isource_repsetc                    U R                   U   nX2:X  a  gUR                  U5      (       d  gU R                  (       a&  U R                  S5      R	                  U5      (       d  gUR                  U5      nX@R                   U'   U R                  (       aW  [        [        U R                   5      5       H5  nXQ:w  d  M
  U R                   U   R                  U5      U R                   U'   M7     U R                  (       a  XR                  :X  d  U R                  (       a  U R                  S   R                  U5      U R                  S'   U R                  (       ae  [        [        U R                  5      5       HC  nUS:w  d  M  U R                  U   R                  U R                  S   5      U R                  U'   ME     U R                  5         g)a  
Attempt to constrain the repsets of the tensors participating in this operator
based on an "existing" repset of an argument. The existing repset can have two
sources:
* A representation may have been determined for the argument already from a
  prior operator
* The output repset of the operator which produces the argument

If the existing repset of the argument is compatible with the current operator,
then constrain the repsets of this operator and apply synchronization rules.

This process tries to minimize the number of transition nodes that will need to
be inserted by tag_memory_meta_pass.py by maintaining existing representations
for as long as possible.
Fr   T)r   r  r  rB  r  r  r  rP  r?   r  r   r!  r  r"  )r7   rD  rE  arg_current_repsetnarrowedr   s         r8   try_constrain_with_arg_repset'OpRepSets.try_constrain_with_arg_repset  s   $ "2259.!//>>$$&&q)LL   &44]C'/e$ 3t4456:/3/D/D088B ))!, 7 $$)))T-@-@'+'<'<(00: !!!$
 ""s4#8#89:AAv373H3H4<<T=R=RST=UV --a0 ; 	##%r;   required_repsetc                 >   U R                   S   nX!:X  a  gUR                  U5      (       d  gUR                  U5      nX0R                   S'   U R                  (       aX  [	        [        U R                   5      5       H6  nUS:w  d  M  U R                   U   R                  U5      U R                   U'   M8     U R                  (       a  U R                  U R                     R                  U5      U R                  U R                  '   U R                  (       ax  [	        [        U R                  5      5       HV  nX@R                  :w  d  M  U R                  U   R                  U R                  U R                     5      U R                  U'   MX     U R                  5         g)z
Attempt to constrain the output repsets of the tensors participating in this
operator based the repset required by a downstream operator.
r   FT)r!  r  r  r  rP  r?   r  r  r   r   r  r"  )r7   rK  out_current_repsetrH  r   s        r8   try_constrain_with_out_repset'OpRepSets.try_constrain_with_out_repset  sm   
 "22150!//@@%44_E#+a  3t44566/3/D/D088B ))!, 7 $$:>:O:O$$;00: !!$"6"67
 ""s4#8#89:A000373H3H4<< 11$2F2FG --a0 ; 	##%r;   c                    [        / 5      n[        / 5      n[        [        U R                  R                  5      5       H1  nU R
                  U   nUR                  UR                  5       5        M3     [        [        U R                  5      5       H1  nU R                  U   nUR                  UR                  5       5        M3     X4$ )zp
For each tensor participating in the op, pick a representation for it among the
possible represetntation sets.
)
ro  rP  r?   r  r   r   r  r  r   r!  )r7   args_repr_listouts_repr_listr   r%  r'  s         r8   pick_representationsOpRepSets.pick_representations7  s    
 (+'+s4<<,,-.A..q1J!!*"="="?@ / *4<<89A..q1J!!*"="="?@ : --r;   )r   r  r!  r   r  r  r  )r<   N)rY   rZ   r[   r\   r]   r  rh   r{   r|   ImageExtentsr9   r	  r`  r  r   r  r"  r`   r  r_   r>  rB  rI  rN  r	   ro  rS  ra   rb   r;   r8   r  r    s    2E&(E& *E& 	E&
 %E&NW WE'E36EHTE	E:t:
d 

( (( (==)5=	=~)\ )d )V.eNN,J&K .r;   r  attrc                 `    SU R                   ;   =(       a    [        U R                   S   U5      $ )Nspec)r   r  )rc   rV  s     r8   has_node_spec_attrrY  O  s&    TYYC7499V+<d#CCr;   c                 P   SU R                   ;   d   eU R                   S   n[        U[        5      (       a  [        X1U5        g [        U[        [
        45      (       a  [        U[        [
        45      (       aj  [        U5      [        U5      :X  aR  [        U5      [        U5      :X  d   e[        X25       H(  u  pE[        U[        5      (       d   e[        XAU5        M*     g U H&  n[        U[        5      (       d   e[        XAU5        M(     g [        S[        U5       35      e)NrX  z!Cannot set attr for spec of type )
r   r4   r   setattrr5   r   r?   r  r=  r>  )rc   rV  valuerX  rR   vs         r8   set_node_spec_attrr^  S  s    TYY99VD$
##E"	D4-	(	( edE]++D	SZ0Gt9E
***D(!!Z0000# )
 !!Z0000'  >tDzlKLLr;   return_firstc                    SU R                   ;   d   eU R                   S   n[        U[        5      (       a  [        X15      (       a  [	        X15      $ S $ [        U[
        [        45      (       aZ  U(       a%  [        US   U5      (       a  [	        US   U5      $ S $ U Vs/ s H   n[        XA5      (       a  [	        XA5      OS PM"     sn$ [        S[        U5       35      es  snf )NrX  r   z!Cannot get attr for spec of type )	r   r4   r   r  getattrr5   r   r=  r>  )rc   rV  r_  rX  rR   s        r8   get_node_spec_attrrb  j  s    TYY99VD$
##&-d&9&9wt"CtC	D4-	(	(-4T!Wd-C-C747D)MMLPQDq(8(8GA$dBDQQ>tDzlKLL Rs   'C c                     [        U S5      $ )Nvk_storage_typerb  rk   s    r8   get_node_storage_typerf  x  s    d$566r;   c                     [        U S5      $ )Nvk_memory_layoutre  rk   s    r8   get_node_memory_layoutri  |  s    d$677r;   c                 t    [        U [        [        45      (       a  [        S U  5       5      $ [	        U S5      $ )Nc              3   :   #    U  H  n[        US 5      v   M     g7f)etvk_node_reprN)rY  r   s     r8   rS    has_node_repr.<locals>.<genexpr>  s     IDq%a)9::Ds   rl  )r4   r5   r   r   rY  rk   s    r8   has_node_reprrn    s2    $u&&IDIII!$(899r;   	node_reprc                     [        U[        5      (       a4  [        [        U 5      5       Vs/ s H  o!U   PM	     nn[	        U SU5        g [	        U SU5        g s  snf )Nrl  )r4   ro  rP  r   r^  )rc   ro  r   node_repr_lists       r8   set_node_reprrr    sT    )^,, 166I$6O0PQ0P1A,0PQ4!1>B4!19= Rs   Ac                 h    [        U [        [        45      (       a  [        S5      e[	        U SS5      $ )Nz/get_node_repr not implemented for list of nodesrl  F)r4   r5   r   r2  rb  rk   s    r8   get_node_reprrt    s/    $u&&!"STT!$(8%@@r;   r   c                 b   [        U [        R                  R                  5      (       d  g[	        U 5      (       d-  [        U 5      (       a  [	        U R                  S   5      (       a  U n[        U 5      (       a  U R                  S   nUR                  S   n[        U[        R                  R                  5      (       d   eUR                  S   n[        U[        R                  R                  5      (       d   e[        U[        R                  R                  5      (       d   eX2U4$ U SS4$ )a  
Check if the given node argument is part of a Quantize/Dequantize chain produced by
the quant workflow. If so, return the source tensor that is the input to the Q/DQ
chain and the quantize/dequantize nodes in the chain. Otherwise, return the argument
as is and None, None
)NNNr   N)r4   rh   r{   r|   rr   r   r   )r   dequant_node
quant_node
source_args       r8   maybe_skip_q_dq_arg_chainry    s     c588==)) s#?388A;#?#?S!!88A;L!&&q)
*ehhmm4444__Q'
*ehhmm4444,6666|33D$r;   max_search_depthc                 r   U nSn[        U[        R                  R                  5      (       d  S/ 4$ U/nUR                  S:w  a  X1:  a  [        UR                  5      S:X  a  OfUR                  S   n[        U[        R                  R                  5      (       d  O-UR                  U5        US-  nUR                  S:w  a  X1:  a  M  [        U[        R                  R                  5      (       d  S/ 4$ UR                  S:w  a  S/ 4$ [        U[        R                  R                  5      (       d   eX$4$ )z
Trace through node.args[0] of a given initial node until a placeholder node is found
then return it and the list of nodes traversed. If no placeholder node is found,
returns None and an empty list.
r   NplaceholderrG   )r4   rh   r{   r|   rf   r?   r   r  )rc   rz  cur_nodesearch_depth	traverseds        r8   trace_args_until_placeholderr    s    HLh..Rx
I
++
&<+Jx}}"==#(EHHMM22" ++
&<+J h..Rx{{m#Rxh....r;   r   c                     U R                   [        R                  [        R                  4;  a  gU R	                  5       R                  5       S:  =(       a!    U R                  5       R                  5       S:*  $ )Y
Check if the given tensor is in the range of 4-bit quantization and is of integer type.
Fi   r   rh   int8uint8minitemmaxr   s    r8   is_in_4bit_ranger    sS     ||EJJ44::<"$A):):)<)AAr;   c                     U R                   [        R                  [        R                  4;  a  gU R	                  5       R                  5       S:  =(       a!    U R                  5       R                  5       S:*  $ )r  Fi   r  r  s    r8   is_in_8bit_ranger    sS     ||EJJ44::<$&E6::<+<+<+>#+EEr;   dimsr   c                     [        U [        5      (       a  U S:  a  X-  n U $ / nU  H  nUS:  a  X1-  nUR                  U5        M      U$ )zn
Normalize dimension indices to be non-negative and within [0, ndim).
Accepts a single int or a list of ints.
r   )r4   r_   r  )r  r   
normalizedds       r8   normalize_dimsr    sW    
 $!8LDJq5IA! 
 r;   nchw_dimc                 D    U S:  a  X-  n U S:  a  X:  d   eUS-
  U -
  nU$ rF   rb   )r  r   whcn_dims      r8   nchw_dim_to_whcn_dimr    s5    !|q=X_,,qH$HOr;   c                 8    U R                    SU R                   3$ )Nz: )r   r   )r  s    r8   get_tensor_val_strr    s!    r*"2"2!344r;   c                    [        U 5      (       a<  [        U R                  S   [        5      (       d   e[	        U R                  S   5      $ [        U 5      (       aS  [        U R                  S   [        [        45      (       d   eSSR                  S U R                  S    5       5       S3$ SU R                  ;  a  [        U 5      $ [        U R                  S   5      $ )Nr   r}  r_  c              3   8   #    U  H  n[        U5      v   M     g 7fr2   )r  )rQ   r   s     r8   rS   #get_node_val_str.<locals>.<genexpr>  s     M<Lq/22<Lr   r  )
r   r4   r   r   r  r   r5   r   r  r	  rk   s    r8   get_node_val_strr    s    T""$))E*J7777!$))E"233	"4	(	($))E*T5M::::499MDIIe<LMMNaPP		!t9499U#$$r;   c                     [        U [        R                  R                  5      (       a  [	        U 5      $ [        U [
        [        45      (       a  SSR                  S U  5       5       S3$ [        U 5      $ )Nr}  r_  c              3   8   #    U  H  n[        U5      v   M     g 7fr2   )get_arg_node_val_strr   s     r8   rS   'get_arg_node_val_str.<locals>.<genexpr>*  s     Gh1!44hr   r  )	r4   rh   r{   r|   r  r5   r   r  r	  )r   s    r8   r  r  &  s\    (EHHMM**))	HtUm	,	,499GhGGHJJ8}r;   c                    U R                   n[        U[        5      (       a$  [        U[        5      (       d   eUR                  nOp[        U[        R
                  R                  5      (       a<  [        U[        R
                  R                  5      (       d   eUR                  5       nO[        U5      n[        U 5       SU S3nU R                   H  nU[        U5      S-   -  nM     US-  nU$ )Nz = (r_  z ...))rg   r4   r   rY   rh   ri   rj   r   r	  r  r   r  )rc   rg   target_nameout_strr   s        r8   node_io_strr  /  s    [[F&.))&.1111oo	FEJJ11	2	2&%**"7"78888kkm&k!$'(K=:Gyy',t33  wGNr;   buffer_nameupdated_tensorc                    S nS nU R                   R                   H  nUR                  [        R                  [        R
                  4;   d  M3  [        UR                  [        5      (       d  MT  UR                  R                  U:X  d  Mp  UR                  nUR                  n  O   Uc   SU S35       eX0R                  ;   d
   SU 35       eU[        R
                  :X  a  [        R                  R                  USS9nX R                  U'   g )Nzcould not find z in source program signatureF)requires_grad)r   input_specskindr   r)  	PARAMETERr4   r   r   r   rg   
state_dictrh   nn	Parameter)r   r  r  r  r  input_s         r8   update_program_state_dictr  B  s    
 KD ))55KKI,,i.A.ABB6::~66

;.;;D --K 6 	C	%ABC,,,M}.MM,y"""++N%+P '5{#r;   ep
cur_tensoralign_toforce_updatec                    SnUR                   S   nXc-  S:w  aD  X6U-  -
  n[        R                  R                  R	                  USU45      R                  5       nSnOUnU(       d  U(       aV  [        XR                  U5        UR                  S   n	[        5       R                  U	R                  U5      UR                  S'   U$ )z
Align the width of the given tensor to the given alignment value and update the
state dict of the program with the aligned tensor.
Fr   r   Tr   )r   rh   r  
functionalpad
contiguousr  r   r   r   from_real_tensor	fake_mode)
r  rc   r  r  r  added_padding	cur_widthnum_paddingaligned_tensorcur_fake_tensors
             r8   !align_width_and_update_state_dictr  b  s     M  $Iq h"67,,00K(

*, 	 #!"ii@))E*.0AA%%
		%
 r;   )T)r'  )r'  F)r}   dataclassesr   typingr   r   r   r   r   r	   r
   rh   <executorch.backends.vulkan.serialization.vulkan_graph_schemar   r   r   Aexecutorch.exir.backend.canonical_partitioners.config_partitionerr   "executorch.exir.dialects.edge._opsr   executorch.exir.tensorr   torch._export.utilsr   r   r   torch._subclasses.fake_tensorr   r   torch.exportr   torch.export.exported_programr   torch.export.graph_signaturer   ri   rj   r	  TorchOpTypero   rt   r`   BOOLr  UINT8r  INT8int32INT32int64INT64float16FLOAT16float32FLOAT32float64FLOAT64r$   r   r6  r^   r%   r&   r'   r(   rU  keysr)   r*   r+   r,   r.   r{   r|   MaybeNodeListrl   rr   ru   ry   r   r   r   r   r   r   r   r   r   r   r   r   r   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r
  r  r  r  rU  DEFAULT_TEXTURE_LIMITSDEFAULT_BUFFER_LIMITr)  r  r  r*  r+  r,  r  r.  r/  r-  r0  r1  r  r  MemoryLayoutSetMemoryLayoutSetListr  r  r!  r?  r   SizerJ  rQ  rX  rZ  ro  r  r  r  r  CONTIGUOUS_ANYCONTIGUOUS_BUFFERWIDTH_PACKED_TEXTUREHEIGHT_PACKED_TEXTURECHANNELS_PACKED_TEXTURECHANNELS_PACKED_ANY,CHANNELS_PACKED_TEXTURE_OR_CONTIGUOUS_BUFFERANY_TEXTURE
ANY_BUFFERANY_STORAGEPACKED_INT8_BUFFERPACKED_INT8_4W4C_BUFFERPACKED_INT8_4H4W_BUFFERPACKED_INT8_4W_BUFFERPACKED_INT8_4C1W_BUFFERPACKED_INT8_CONV2D_BUFFER"PACKED_INT8_CHANNELS_PACKED_BUFFERr  r  r  r  rY  r^  rb  rf  ri  rn  rr  rt  rc   Argumentry  r  Tensorr  r  r  r  r  r  r  r  r  r  rb   r;   r8   <module>r     s    ! ? ? ?  
 > - N N I ( 3 7NEJJ$9$93>?
 
JJ
	KK!!	JJ
	KK!!	KK!!	MM:%%	MM:%%	MM:%%	1U[[*,- 	 u{{--/h /;;,x ,ZZL  JJ< n))+,x ,5  E\( !,/x /2 2B ehhmmT%((--%8%:NNO	588== 	T 	 %((--  D   $ ) )4 )C D 9ehhmm 9 9$EHHMM $d $) )4 )E588== ET ER R R$ R	? 	%((-- 	D 	N
((--N+:N	N
 
4 

 
$ 
C D    &S T uxx}}  ehhmm  "' ' 'Cehhmm C C.UXX]] t *
%((-- 
D 
0 
((--0 0  !0  49	0 fehhmm  !# !(3- !6uxx}} 6 6 %((-- D ehhmm   EHHMM hsm S 
2o UXX]] s  EHHMM huxx}}.E 	%((-- 	HUXX]],C 		# 	s 	  S#s]#- *  ) 3}%  &&''))+ C'  ####!!##%%5 c.1  55 S0  n%OT/-BBC  &&''))1##Q##Q##Q%%q4 tNC/0 ). )S ) $>H >H >HBYehhmm Y3 Y3 Y %((-- D +%** +n + +@E| E\ Ed E**.: & &25, 5,pb. b.J	SJ 	S< 	SSSS !S 	S<!!588==!! !! 	!4 ''(>+M+M*N !."D"D!EsuM #CEN,N,N+OP $SU^-P-P,QR &su~/T/T.UV "**+n.S.S-T  0<''(>+P+P*Q0 , 35"45,ce4
-/AB "">F &(G(G'H#%P &(G(G'H#%P $n&C&C%DceL &(G(G'H#%P (.*K*K)LceT %1''''))
 E& " #%'
"!< 
(H (HVc. c.VDUXX]] D# D$ DMUXX]] M# M.MUXX]] M# MT M7 7(=2I 78 88N3K 8:4 :> >%
N8R2S >A5^!;< A			
8EHHMM"HUXX]]$;Xehhmm=TTU> ;< 
((--
 
  47 
8EHHMM"D$778 FBU\\ Bd BFU\\ Fd FsDI~. c eCcN>S (3 c c 5: 5# 5
%588== 
%S 
%3 3 ehhmm  &555 LL5 
	5H !!
((--! ! 	!
 ! \\!r;   