
    i2                     &   % S r SSKrSSKrSSKJrJrJr  SSKrSSKJ	r	  SSK
JrJr  0 r\\	\4   \S'   0 r\\	\\	   4   \S'   0 r\\	\\	   4   \S'   0 r\\	\\	   4   \S	'   0 r\\	\\   4   \S
'   S\R&                  R                  S\\   4S jrS\	S\\   4S jrS\	S\\   4S jrS\S\\   4S jrS\S\\\4   4S jrS\S\S\	4S jrS\S\	4S jrS\	SS4S jrS\	S\\	\\   4   4S jrS\	S\\	   4S jrS\S\S\4S jr S\S\S\4S jr!g)a  
Handle the following op convertions:
- convert a functional op to an out variant op
- convert an out variant op to a scratch op.

We assume there is already a functionalization pass being done that removes aliases and inplace variants.

For the to_out_variant convertion, The functional variant will be represented
as qualified op name plus the overload name. The returned out variant constains
the following information
- the OpOverload for the out variant
- the list of keyward arguments names that are out variables. There should be
  at least one out variables. Some ops may also have multiple out variables,
  e.g. aten::topk.values returns both values and indices for the topk elements.

    N)DictOptionalTuple)
OpOverload)FunctionSchema
SchemaKind_op_overload_to_schema_cache_func_to_out_variant_map_out_variant_to_scratch_map_mutable_to_out_variant_map_schema_mismatch_mappybind_schemareturnc                     Sn [         R                  " [        U 5      5      nU$ ! [        [        [
        4 a&    [        R                  " S[        U 5       35         U$ f = f)a9  
We have 2 FunctionSchema definitions in python.
One is defined in torchgen (call it native FunctionSchema), another is a
pybind of c10::FunctionSchema (call it pybind FunctionSchema).
Because we want to leverage torchgen to handle out variant, we will
convert any pybind FunctionSchema to native FunctionSchema.
NzFail to parse function schema: )r   parsestrRuntimeErrorAssertionError
ValueErrorloggingdebug)r   native_schemas     _/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/exir/operator/convert.py_pybind_schema_to_native_schemar   4   sj     MN&,,S-?@$ # .*5 N 	7M8J7KLM
 #Ns   % 7A A op_overloadc                 z    [         R                  U 5      nU(       d  [        U R                  5      nU[         U '   U$ N)r	   getr   _schema)r   r   s     r   _get_overload_schemar    U   s6    044[AM78K8KL4A$[1    c                 *    [        [        U 5      5      $ r   )get_out_args_from_schemar    )r   s    r   get_out_args_from_opoverloadr$   ]   s    #$8$EFFr!   out_var_schemac                     U R                  5       (       d
   SU  35       e[        S U R                  R                   5       5      $ )z_
Assume the input is the schema for an out variant.
Return the name list of the out arguments.
z Expect an out variant, but get: c              3   8   #    U  H  oR                   v   M     g 7fr   )name).0args     r   	<genexpr>+get_out_args_from_schema.<locals>.<genexpr>i   s     B%Ac%As   )	is_out_fntuple	argumentsout)r%   s    r   r#   r#   a   sH     	  "";	).)9:;"B^%=%=%A%ABBBr!   qualified_opnamec                 t    U R                  S5      n[        U5      S:w  a  [        SU  35      e[        U5      $ )zj
Given a qualified opname like aten::add, return a tuple for namespace
(aten here) and op name (add here)
z::   zInvalid qualified_opname )splitlenr   r.   )r1   ns_and_opnames     r   parse_qualified_opnamer7   l   sA    
 %**40M
=Q67G6HIJJr!   overloadc                     [        U 5      u  p#U(       d  Sn[        [        [        [        R                  U5      U5      U5      $ )zq
Arguments:
    qualified_opname: string like {namespace}::{op name}
    overload: the overload string of the op
default)r7   getattrtorchops)r1   r8   nsopnames       r   get_op_overloadr@   w   s8     ((89JB77599b16:HEEr!   schemac                     [        U R                  R                  5      nU R                  R                  n[        X5      $ r   )r   r(   overload_namer@   )rA   qualified_namer8   s      r   schema_to_opoverloadrE      s0    ))*N{{((H>44r!   opc                    [        U R                  5      nUR                  5       [        R                  [        R
                  [        R                  4;   d   eUR                  5       [        R                  :X  a  U [        ;   a   eUR                  5       [        R
                  :X  a  U [        ;   a   eUR                  5       [        R                  :X  a  U [        ;   a   e[        U R                  R                  5      n[        R                  R                  U5       Vs/ s H  n[        U5      PM     nnU Vs/ s H	  oUc  M  UPM     nn0 nU H`  nUR                  5       n[         R"                  " USS9nUR                  5       nUR%                  U0 5      n	X;  d   SU SU 35       eXYU'   Mb     UR'                  5        GH,  n	U	R)                  [        R                  5      n
U	R)                  [        R
                  5      nU	R)                  [        R                  5      nU	R)                  [        R*                  5      nU
(       aL  U(       a  [-        U5      OS[        [-        U
5      '   Uc%  [/        S U 5       S5      nU[0        [-        U
5      '   U(       a$  U(       a  [-        U5      OS[        [-        U5      '   U(       d  GM  U(       a  [-        U5      OS[        [-        U5      '   GM/     gs  snf s  snf )a  
op can either be a functional op, mutable op, or out variant op.
This method is only called if
1. either op is a functional op and it's missing in the _func_to_out_variant_map cache.
2. or op is a out variant op and it's missing in the _out_variant_to_scratch_map cache.

Setup entries in _func_to_out_variant_map and _out_variant_to_scratch_map for all ops sharing the same
op name as the passed in OpOverload.
N )returnszSchema of kind z already exist for c              3   l   #    U  H*  oR                  5       [        R                  :X  d  M&  Uv   M,     g 7fr   )kindr   r0   )r)   ss     r   r+   %set_mapping_for_op.<locals>.<genexpr>   s!     J1vvx:>>/IQQs   %4	4)r   r   rK   r   
functionalr0   mutabler
   r   r   r   r(   r<   _C_jit_get_schemas_for_operator	signaturedataclassesreplace
setdefaultvaluesr   scratchrE   nextr   )rF   r   r1   r   all_schemasrA   group_by_signaturerR   rK   group_by_kindfunc_op_schemar%   mutable_op_schemascratch_schemamismatched_out_schemas                  r   set_mapping_for_opr`      s    4BJJ?M$    	
 5 55"@X:X  	
.29T3T  	
 2 22r=X7X  2::??+ #XXCCDTUUM 	(6U   )4Jf6KJFH$$&	  ''	2>	{{}*55iD%	?TF"5fX>	?%$d' , ,224&**:+@+@A&**:>>:)--j.@.@A&**:+=+=> 8F$^4D %%9.%IJ %BFJJDC% * %%9.%IJ 8F$^4D ((<^(LM 8F$^4D ((<=N(OP; 5A Ks   #K:>K?K?c                 j   [        U 5      nUR                  5       (       a  U [        U5      4$ UR                  5       [        R
                  :X  d=  UR                  5       [        R                  :X  d   SUR                  5        SU 35       eU [        ;  a  U [        ;  a  [        U 5        U [        ;   a
  [        U    nO[        R                  U 5      nU(       dL  SU S3nU [        ;   a1  [        U    (       a#  USU R                  5        SU S[        U     3-  n[        U5      eU[        U5      4$ )z
Convert the passed in OpOverload to its out variant. Raise an exception if
on return the op_overload is not guaranteed to be an out variant.

If a conversion is found, return the out variant OpOverload alongwith the name of out
arguments.
z#Expect a functionalish op, but get  z'Missing out variant for functional op: zf . Make sure you have loaded your custom operator library for compiler. E.g., custom_ops_generated_libz(
Found an out variant for operator name zE but its schema mismatched with functional op.
functional op schema:	z
out variant op schema:	)r    r-   r#   rK   r   rN   rO   r
   r   r`   r   r   r(   r   r$   )r   rA   out_varmsgs       r   to_out_variantre      sD    "+.F4V<<< 	...;;=J...F 
-V[[]O1VHEF	/
 	33:: 	;'11-k:*..{;7x  @f  g..#K0?@P@P@R?S T006x01Ek1R0SU
 30999r!   c                    [        U 5      nUR                  5       [        R                  :w  a(  [        R
                  " SUR                  5        35        g U [        ;  a  [        U 5        [        R                  U 5      nU$ )Nz(Expect an out variant op as input, got: )	r    rK   r   r0   r   r   r   r`   r   )r   rA   
scratch_ops      r   to_scratch_oprh     sf    !+.F {{}
&@PQ55;',00=J r!   c                 V    [        X5      n[        U5      nUc  gUR                  5       $ NF)r@   r    r-   r1   r8   r   rA   s       r   is_out_variantrl   &  s.    !"2=K!+.F~r!   c                 x    [        X5      n[        U5      nUc  gUR                  5       [        R                  :H  $ rj   )r@   r    rK   r   inplacerk   s       r   is_inplace_variantro   .  s6    !"2=K!+.F~;;=J....r!   )"__doc__rS   r   typingr   r   r   r<   
torch._opsr   torchgen.modelr   r   r	   __annotations__r
   r   r   r   rP   r   r    r   r$   r#   r7   r@   rE   r`   re   rh   boolrl   ro   rH   r!   r   <module>rv      s  "   ( (  ! 5
 BD d:~#=> C
 DF $z8J+??@ EFH T*hz.B"BC HFH T*hz.B"BC H
 DF d:x'??@ E88**nBj Xn5M Gj GU3Z GC^ Cc
 C S  U38_  	Fc 	FS 	FZ 	F5 5J 5[: [$ [|):
 ):uZs5K/L ):Xz hz.B &S C D / / / /r!   