
    7hD2                        % S r SSKrSSKJr  SSKJr  SSKJrJrJ	r	J
r
Jr  SSKJr  SSKrSSKrSSKJr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  S
SK J!r!  \\RD                  \#\$\%4   r&S\&4S jr'S\&4S jr(\ " S S5      5       r) " S S5      r*\ " S S5      5       r+\\+\,S   4   r-\\.S'    " S S\5      r/g)a  This file implements the IndexPropagation ops handler, which wraps an
underlying handler to add a limited form of constant propagation, as well as
propagation of sympy expressions downstream of ops.index_expr calls.

For example, say we have the IR:

    tmp0 = ops.index_expr(x, torch.int32)
    tmp1 = ops.constant(2, torch.int32)
    tmp2 = ops.mul(tmp0, tmp1)
    tmp3 = ops.indirect_indexing(tmp2, x_size)
    tmp4 = ops.load("buf0", tmp3)

The underlying handler would just see:

    ops.load("buf0", x * 2)

This is limited by the set of operators handled in the sympy expression
printers. So simple operations like minimum and maximum cannot be translated to
SymPy expressions yet, despite sympy.Min and sympy.Max existing.

    N)Sequence)	dataclass)AnyLiteralOptionaloverloadUnion)	TypeAlias)dtype_to_typeis_integer_dtype)FloorDivModularIndexingWhere)bound_sympyValueRanges   )DefaultHandler)statically_known_true)generate_assert)Vvalc                     [        U [        R                  5      (       a  U R                  $ [        U [        [
        [        45      $ N)
isinstancesympyBasic	is_numberintfloatboolr   s    [/var/www/fran/franai/venv/lib/python3.13/site-packages/torch/_inductor/index_propagation.py_is_constantr#   .   s1    #u{{##}}cC-..    c                 n    [        U [        R                  5      (       a  [        U 5      R                  $ U $ r   )r   r   Exprr   upperr!   s    r"   upper_boundr(   4   s(    %/UZZ%@%@;s!!IcIr$   c                   N    \ rS rSr% Sr\\S'   \R                  \S'   S r	S r
Srg)		TypedExpr8   z'A SymPy expression with associated typeexprdtypec                 ,    [        U R                  5      $ r   )r#   r,   selfs    r"   is_constantTypedExpr.is_constant?   s    DII&&r$   c                     [        U R                  5      (       a+  [        U R                  5      " U R                  5      U l        g g r   )r#   r,   r   r-   r/   s    r"   __post_init__TypedExpr.__post_init__B   s/    		""%djj1$))<DI #r$   r,   N)__name__
__module____qualname____firstlineno____doc__	_ExprType__annotations__torchr-   r1   r4   __static_attributes__ r$   r"   r*   r*   8   s    1
O;;'=r$   r*   c                      \ rS rSrSr\S\S\4S j5       r\S\\	\
\4   S\R                  S\4S j5       r\S\\R"                  \	4   S\R                  S\4S j5       r\  SS\S\R                  S
\\R                     S\S\4
S jj5       r\S\S\4S j5       r\S\S\4S j5       r\S\S\S\4S j5       r\S\S\S\4S j5       r\S\S\S\4S j5       r\S\S\4S j5       r\S\S\S\4S j5       r\S\S\S\\   4S j5       r\S\S\S\\   4S j5       r\S\S\S\4S j5       r\S\S\S\4S j5       rSr g	)SymPyOpsG   zAn ops handler where all IR values are SymPy expressions

When a value cannot be represented as a SymPy expression, the method is
either not defined, or returns NotImplemented

valuereturnc                     U $ r   r@   )rD   s    r"   identitySymPyOps.identityO   s    r$   r-   c                     [        X5      $ r   r*   rD   r-   s     r"   constantSymPyOps.constantS       &&r$   c                     [        X5      $ r   rJ   rK   s     r"   
index_exprSymPyOps.index_exprW   rN   r$   N	src_dtypeuse_compute_typesc                 .    [        U R                  U5      $ r   )r*   r,   )rD   r-   rR   rS   s       r"   to_dtypeSymPyOps.to_dtype[   s     U++r$   xc                 T    [        [        U R                  5      U R                  5      $ r   )r*   absr,   r-   rW   s    r"   rY   SymPyOps.absd   s    QVVagg..r$   c                 \    [        U R                  U R                  -  U R                  5      $ r   r*   r,   r-   rZ   s    r"   squareSymPyOps.squareh   s    !&&!''22r$   yc                     [         R                  " U R                  UR                  5      n[        U R                  UR                  -   U5      $ r   r>   promote_typesr-   r*   r,   rW   r`   result_types      r"   addSymPyOps.addl   5    ))!''177;!&&+66r$   c                     [         R                  " U R                  UR                  5      n[        U R                  UR                  -
  U5      $ r   rb   rd   s      r"   subSymPyOps.subq   rh   r$   c                     [         R                  " U R                  UR                  5      n[        U R                  UR                  -  U5      $ r   rb   rd   s      r"   mulSymPyOps.mulv   rh   r$   c                 D    [        U R                  * U R                  5      $ r   r]   rZ   s    r"   negSymPyOps.neg{   s    !&&!''**r$   c                     [         R                  " U R                  UR                  5      n[        U5      (       d  [        $ [        [        U R                  UR                  5      U5      $ r   )r>   rc   r-   r   NotImplementedr*   r   r,   rd   s      r"   floordivSymPyOps.floordiv   sI    ))!''177;,,!!!&&!&&1;??r$   c                    [         R                  " U R                  UR                  5      n[        U5      (       d  [        $ [        U R                  [        R                  R                  UR                  5      n[        X25      $ r   )r>   rc   r-   r   rs   r   r,   r   SOner*   )rW   r`   re   result_exprs       r"   modSymPyOps.mod   sV    ))!''177;,,!!%affeggkk166B22r$   c                    [         R                  " U R                  UR                  5      n[        U5      (       d  [        $ [
        R                  " U R                  5      n[
        R                  " UR                  5      nUR                  b^  UR                  UR                  :X  aD  [        U R                  [
        R                  R                  UR                  5      n[        XR5      $ [        $ r   )r>   rc   r-   r   rs   r   sympifyr,   is_nonnegativeis_positiver   rw   rx   r*   )rW   r`   re   x_expry_exprry   s         r"   	remainderSymPyOps.remainder   s    ))!''177;,,!!qvv&qvv& !!-%%););;)!&&%''++qvvFK[66r$   c                     [         R                  " U R                  UR                  5      n[        [        R
                  " U R                  UR                  5      U5      $ r   )r>   rc   r-   r*   r   Minr,   rd   s      r"   minimumSymPyOps.minimum   <    ))!''177;1661662K@@r$   c                     [         R                  " U R                  UR                  5      n[        [        R
                  " U R                  UR                  5      U5      $ r   )r>   rc   r-   r*   r   Maxr,   rd   s      r"   maximumSymPyOps.maximum   r   r$   r@   )NF)!r7   r8   r9   r:   r;   staticmethodr   rG   r	   r   r   r    r>   r-   r*   rL   r   r&   rP   r   rU   rY   r^   rf   rj   rm   rp   rt   rz   r   r   r   r?   r@   r$   r"   rB   rB   G   s        'c5$./ ' '	 ' ' '%

C0 ' ' ' '  ,0"'	,,{{, EKK(,  	,
 
, , /y /Y / / 3) 3	 3 3 7y 7Y 79 7 7 7y 7Y 79 7 7 7y 7Y 79 7 7 +y +Y + + @I @) @	 @ @ 3y 3Y 38I+> 3 3 Y 9 )1D  " A9 A Ay A A A9 A Ay A Ar$   rB   c                   P    \ rS rSr% \\S'   Sr\\S'   \S\	SS 4S j5       r
S rS	rg
)IndexPropVar   rD   Fis_symbolicr,   rE   c                     [        U SS9$ )NTr   )r   r6   s    r"   new_symbolicIndexPropVar.new_symbolic   s    Dd33r$   c                 t    U R                   (       a'  [        U R                  [        5      (       d   S5       eg g )Nz.Symbolic IndexPropVar must contain a TypedExpr)r   r   rD   r*   r/   s    r"   r4   IndexPropVar.__post_init__   s1    ##z$**i'H'H 	
<	
H'H#r$   r@   N)r7   r8   r9   r:   r   r=   r   r    r   r*   r   r4   r?   r@   r$   r"   r   r      s6    JK49 4 4 4
r$   r   )IndexPropResult.r   c            	           \ rS rSrSrS\S\\R                  \R                  4   S\\R                  \R                  4   SS4S jr
S	\R                  S
\R                  S\4S jrS\\\4   S\4S jrS\4S jr\S\S   S\\   S\\\4   S\4S j5       r\S\S\\   S\\\4   S\4S j5       rS\S\\   S\\\4   S\4S jrS\S\\   S\\\4   S\4S jrS\S\\S4   S\\\4   S\4S jrS r  SS\\\4   S\S\S\4S jjrSrg) IndexPropagation   zOps wrapper that tries to propagate constant and index_expr values through the computation.

This aims to maximize the compile time simplification possible, and convert
indirect indexing from arange into normal static indexing.

inneriter_rangesindirect_var_rangesrE   Nc                 t   Xl         [        R                  R                  R                  U l        UR                  5        VVs0 s H  u  pEU[        S[        U5      S-
  5      _M      nnn[        [        R                  " U R                  R                  R                  5       UR                  5       5      5      U l        X0l        / nUR                  5        H,  u  pUR                  SU:*  5        UR                  X:  5        M.     [        U5      U R                  R                  5       -   U l        g s  snnf )Nr   r   )_innerr   graphsizevars	shape_envitemsr   r(   tuple	itertoolschainvar_to_ranger   append
get_axiomsaxioms)
r0   r   r   r   kvr   r   rW   ss
             r"   __init__IndexPropagation.__init__   s     ))33 ?J>O>O>Q
>QdaA{1k!nq011>Q 	 
 "OODNN77==?ASASAUV

 $7 %%'DAMM!q&!MM!%  ( Fmdnn&?&?&AA
s   %D4r,   r-   c                     [        U5      (       a,  [        U5      " U5      nU R                  R                  X25      $ U R                  R	                  X5      $ r   )r#   r   r   rL   rP   )r0   r,   r-   r   s       r"   materialize_expr!IndexPropagation.materialize_expr   sF    &t,C;;''33{{%%d22r$   ac                 @  ^  [        U[        [        45      (       a  [        U 4S jU 5       5      $ [        U[        5      (       d  U$ UR                  (       a:  T R                  UR                  R                  UR                  R                  5      $ UR                  $ )Nc              3   F   >#    U  H  nTR                  U5      v   M     g 7fr   )unwrap.0r   r0   s     r"   	<genexpr>*IndexPropagation.unwrap.<locals>.<genexpr>   s     3AQ   !)	r   listr   r   r   r   rD   r,   r-   r0   r   s   ` r"   r   IndexPropagation.unwrap   sl    a$''3333!\**H ==((qww}}EEwwr$   c                 z   ^  [        U[        [        45      (       a  [        U 4S jU 5       5      $ [        U5      $ )Nc              3   F   >#    U  H  nTR                  U5      v   M     g 7fr   )wrapr   s     r"   r   (IndexPropagation.wrap.<locals>.<genexpr>   s     1q!1qr   )r   r   r   r   r   s   ` r"   r   IndexPropagation.wrap   s/    a$''1q111Ar$   nameindirect_indexingargskwargsc                     g r   r@   r0   r   r   r   s       r"   fallbackIndexPropagation.fallback   s     r$   c                     g r   r@   r   s       r"   r   r     s     r$   c                    U Vs/ s H  o@R                  U5      PM     nnUR                  5        VVs0 s H  u  pgX`R                  U5      _M     nnnU R                  [        U R                  U5      " U0 UD65      $ s  snf s  snnf r   )r   r   r   getattrr   )	r0   r   r   r   r   new_argsr   r   
new_kwargss	            r"   r   r     sq     -11DqKKND14:LLNCNDAaQ'N
Cyyd3XLLMM 2Cs
   A?Bc                    S[         [        [        4   S[        4S jnU Vs/ s H
  oT" U5      PM     nnUR                  5        VVs0 s H  u  pxXt" U5      _M     n	nn[	        [
        U5      " U0 U	D6n
U
[        L=(       a-    U
R                  5       =(       d    U
R                  R                  nU(       d  U R                  XU5      $ [        R                  U
5      $ s  snf s  snnf )Nr   rE   c                 H    [        U [        5      (       d  U $ U R                  $ r   )r   r   rD   )r   s    r"   r   0IndexPropagation.propagate_sympy.<locals>.unwrap  s    a..77Nr$   )r	   r   r   r   r   rB   rs   r1   r,   
is_integerr   r   )r0   r   r   r   r   r   r   r   r   r   new_expris_valid_exprs               r"   propagate_sympy IndexPropagation.propagate_sympy  s    	eC-. 	3 	
 (,,t!F1It,/5||~>~tqal~
>8T*HC
C 6 
   ">hmm&>&> 	
 ==V44((22 ->s   C 	C%.c                 f   [        [        U5      (       d  U R                  XU5      $ [        R                  " X#R                  5       5       Vs/ s H  n[        U[        5      (       d  M  UPM     nn[        S U 5       5      (       d  U R                  XU5      $ U R                  XU5      $ s  snf )Nc              3   8   #    U  H  oR                   v   M     g 7fr   r   )r   r   s     r"   r   ,IndexPropagation._default.<locals>.<genexpr>,  s     8-Q==-s   )
hasattrrB   r   r   r   valuesr   r   allr   )r0   r   r   r   r   var_argumentss         r"   _defaultIndexPropagation._default#  s    x&&==V44 __T==?;
;!\* ; 	 

 8-888==V44##D77
s   B.+B.c                     / U R                   QS U R                  R                  5        5       Q7n[        U R                  XR
                  U5      $ )ai  
Given some iter_ranges, return a function that given an expression, returns whether
it is true or false using value ranges, guard knowledge and runtime_asserts.

FIXME I think this may not be entirely right, as we may not be able to use all runtime_asserts
      If this is an issue, just use guards in `self.axioms`.

      The proper way of handling this would be to have a global shape_env that adds
      runtime_asserts as they happen in the code. Then, it should be used in SimplifyIndexing
      to perform wrap_expr and in CSEProxy.check_bounds to elide upper / lower bounds also
      for indirect_indexing
c              3   Z   #    U  H!  u  pU[        S [        U5      S-
  5      4v   M#     g7f)r   r   N)r   r(   )r   r   r   s      r"   r   3IndexPropagation.statically_true.<locals>.<genexpr>@  s.      <DA K;q>A#567<s   )+)r   r   r   r   r   r   )r0   er   s      r"   statically_true IndexPropagation.statically_true1  sQ    

 44::<
 %T^^Q\RRr$   indexsizecheckc           	        ^ ^ [        U[        5      (       a  UR                  (       a  [        R                  " UR
                  R                  5      nU U4S jnT R                  SU:*  5      =(       d    T R                  T* U:*  5      nT R                  UT:  5      nU(       a  U" U5      n[        U5      (       a'  T R                  SUT4[        U(       + U(       + S95        U$ T R                  SUTX440 5      R
                  n	U	$ )Nc                    > TR                  SU :*  5      (       a  U $ TR                  U S:  5      (       a  U T-   $ [        U S:  U T-   U 5      $ )Nr   )r   r   )r,   r0   r   s    r"   	wrap_expr5IndexPropagation.indirect_indexing.<locals>.wrap_exprW  sS    ''T	22K))$(33$;& 4$;==r$   r   check_bounds)lowerr'   r   )r   r   r   r   r}   rD   r,   r   r   r   dict)
r0   r   r   r   wrap_negr,   r   can_prove_lowercan_prove_upperindirect_vars
   ` `       r"   r   "IndexPropagation.indirect_indexingG  s     e\**u/@/@ ==!1!12D> #2219= AUAUBO #224$;?O u%%"4L?2o:MN
 K}}%u!?

% 	 r$   )r   r   r   r   r   )TT)r7   r8   r9   r:   r;   r   r   r   Symbolr&   r   r>   r-   r   r	   r   r   r   r   r   r   r   strr   r   r   r   r   r    r   r?   r@   r$   r"   r   r      s   BB %,,

23B "%,,

":;	B
 
B23UZZ 3 3 3c</0 S  
 )* sm S#X	
 
  '}6:38n	 NN'}N6:38nN	N33'}36:38n3	3*8S 8c3h 8c3h 8TW 8S4 +S,&'+ + 	+ 
+ +r$   r   )0r;   r   collections.abcr   dataclassesr   typingr   r   r   r   r	   typing_extensionsr
   r   r>   torch._prims_commonr   r   torch.utils._sympy.functionsr   r   r   torch.utils._sympy.value_rangesr   r   ops_handlerr   r   r   utilsr   virtualizedr   r&   r   r   r    r<   r#   r(   r*   rB   r   r   r   r=   r   r@   r$   r"   <module>r     s   ,  $ ! : : '   ? I I D ' + "  %**eS$./	/i /JY J = = =cA cAL 
 
 
 #<7M1N#NO Os~ sr$   