
    3j3                     |   % 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
  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  \R>                  \ -  \!-  \"-  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   -  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overload	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    [/home/wildlama/miniconda3/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&   3   s(    %/UZZ%@%@;s!!IcIr"   c                   N    \ rS rSr% Sr\\S'   \R                  \S'   S r	S r
Srg)		TypedExpr7   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                  n[        U[        R                  5      (       a  UR                  SS9n[        U R                  5      " U5      n[        U R                  5      (       a~  [        R                  " U R                  5      R                  nU R                  R                  (       a  USUS-
  -  -   nUSU-  -  nU R                  R                  (       a  USUS-
  -  -
  nXl        g g )NT)identity   r   )r!   r*   r   r   r$   expandr	   r+   r
   torchiinfobits	is_signed)r.   r*   r7   s      r    __post_init__TypedExpr.__post_init__A   s    		""99D$

++{{D{1 ,T2D

++{{4::.33::''!q/1Dag~::''!q/1DI #r"   r*   N)__name__
__module____qualname____firstlineno____doc__	_ExprType__annotations__r5   r+   r/   r9   __static_attributes__ r"   r    r(   r(   7   s    1
O;;'r"   r(   c                      \ rS rSrSr\S\S\4S j5       r\S\\	-  \
-  S\R                  S\4S j5       r\S\R                   \-  S\R                  S\4S j5       r\  SS\S\R                  S
\R                  S	-  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\S	-  4S j5       r\S\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	)SymPyOpsQ   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   rD   )rH   s    r    r2   SymPyOps.identityY   s    r"   r+   c                     [        X5      $ r   r(   rH   r+   s     r    constantSymPyOps.constant]       &&r"   c                     [        X5      $ r   rM   rN   s     r    
index_exprSymPyOps.index_expra   rQ   r"   N	src_dtypeuse_compute_typesc                 .    [        U R                  U5      $ r   )r(   r*   )rH   r+   rU   rV   s       r    to_dtypeSymPyOps.to_dtypee   s     U++r"   xc                 T    [        [        U R                  5      U R                  5      $ r   )r(   absr*   r+   rZ   s    r    r\   SymPyOps.absn   s    QVVagg..r"   c                 \    [        U R                  U R                  -  U R                  5      $ r   r(   r*   r+   r]   s    r    squareSymPyOps.squarer   s    !&&!''22r"   yc                     [         R                  " U R                  UR                  5      n[        U R                  UR                  -   U5      $ r   r5   promote_typesr+   r(   r*   rZ   rc   result_types      r    addSymPyOps.addv   5    ))!''177;!&&+66r"   c                     [         R                  " U R                  UR                  5      n[        U R                  UR                  -
  U5      $ r   re   rg   s      r    subSymPyOps.sub{   rk   r"   c                     [         R                  " U R                  UR                  5      n[        U R                  UR                  -  U5      $ r   re   rg   s      r    mulSymPyOps.mul   rk   r"   c                 D    [        U R                  * U R                  5      $ r   r`   r]   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   )r5   rf   r+   r
   NotImplementedr(   r   r*   rg   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   )r5   rf   r+   r
   rv   r   r*   r   SOner(   )rZ   rc   rh   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   )r5   rf   r+   r
   rv   r   sympifyr*   is_nonnegativeis_positiver   rz   r{   r(   )rZ   rc   rh   x_expry_exprr|   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   )r5   rf   r+   r(   r   Minr*   rg   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   )r5   rf   r+   r(   r   Maxr*   rg   s      r    maximumSymPyOps.maximum   r   r"   rD   )NF)r<   r=   r>   r?   r@   staticmethodr   r2   r   r   r   r5   r+   r(   rO   r   r$   rS   rX   r\   ra   ri   rm   rp   rs   rw   r}   r   r   r   rC   rD   r"   r    rF   rF   Q   s        'ed* '5;; '9 ' ' '%**s* '5;; '9 ' '  )-"'	,,{{, ;;%,  	,
 
, , /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 39t+; 3 3 Y 9 T1A  " A9 A Ay A A A9 A Ay A Ar"   rF   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   rH   Fis_symbolicr*   rI   c                     [        U SS9$ )NTr   )r   r;   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   rH   r(   r-   s    r    r9   IndexPropVar.__post_init__   s1    ##z$**i'H'H 	
<	
H'H#r"   rD   N)r<   r=   r>   r?   r   rB   r   r   r   r(   r   r9   rC   rD   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\\-  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\\-  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_rangesrI   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)
r.   r   r   r   kvr   r   rZ   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   rO   rS   )r.   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   r.   s     r    	<genexpr>*IndexPropagation.unwrap.<locals>.<genexpr>   s     3AQ   !)	r   listr   r   r   r   rH   r*   r+   r.   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   rD   r.   r   r   r   s       r    fallbackIndexPropagation.fallback  s     r"   c                     g r   rD   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   )	r.   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[         [        -  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   rI   c                 H    [        U [        5      (       d  U $ U R                  $ r   )r   r   rH   )r   s    r    r   0IndexPropagation.propagate_sympy.<locals>.unwrap  s    a..77Nr"   )r   r   r   r   rF   rv   r/   r*   
is_integerr   r   )r.   r   r   r   r   r   r   r   r   r   new_expris_valid_exprs               r    propagate_sympy IndexPropagation.propagate_sympy  s    	cL( 	S 	
 (,,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>6  s     8-Q==-s   )
hasattrrF   r   r   r   valuesr   r   allr   )r.   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>J  s.      <DA K;q>A#567<s   )+)r   r   r   r   r   r   )r.   er   s      r    statically_true IndexPropagation.statically_true;  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*   r.   r   s    r    	wrap_expr5IndexPropagation.indirect_indexing.<locals>.wrap_exprb  sS    ''T	22K))$(33$;& 4$;==r"   r   check_bounds)lowerr%   r   )r   r   r   r   r   rH   r*   r   r   r   dict)
r.   r   r   r   wrap_negr*   r   can_prove_lowercan_prove_upperindirect_vars
   ` `       r    r   "IndexPropagation.indirect_indexingR  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)r<   r=   r>   r?   r@   r   r   r   Symbolr$   r   r5   r+   r   r   r   r   r   r   r   r   strr   r   r   r   r   r   r   rC   rD   r"   r    r   r      s	   BB %,,

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

":;	B
 
B23UZZ 3 3 3l* 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6 +\!+ + 	+ 
+ +r"   r   )-r@   r   collections.abcr   dataclassesr   typingr   r   r   r   r   r5   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   rA   r!   r&   r(   rF   r   r   r   rB   r   rD   r"   r    <module>r     s   ,  $ ! 4 4   ? I I D ' + "  JJ$t+	/i /JY J   2cA cAL 
 
 
 *E2H,II It~ tr"   