
    ɯwg2                     z   U d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
mZmZ ddlmZ ddlZddlZddlmZmZ ddlmZmZmZ ddlmZmZ d	d
lmZ d	dlmZ d	dlm Z  eejB                  e"e#e$f   Z%de%fdZ&de%fdZ'e G d d             Z( G d d      Z)e G d d             Z*ee*ed   f   Z+ee,d<    G d d      Z-y)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)	dataclass)AnyCallableDictLiteralOptionaloverloadTupleUnion)	TypeAlias)dtype_to_typeis_integer_dtype)FloorDivModularIndexingWhere)bound_sympyValueRanges   )evaluate_expr)generate_assert)Vvalc                     t        | t        j                        r| j                  S t        | t        t
        t        f      S N)
isinstancesympyBasic	is_numberintfloatboolr   s    f/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/torch/_inductor/index_propagation.py_is_constantr$   +   s.    #u{{#}}cC-..    c                 d    t        | t        j                        rt        |       j                  S | S r   )r   r   Exprr   upperr"   s    r#   upper_boundr)   1   s%    %/UZZ%@;s!!IcIr%   c                   F    e Zd ZU dZeed<   ej                  ed<   d Zd Z	y)	TypedExprz'A SymPy expression with associated typeexprdtypec                 ,    t        | j                        S r   )r$   r,   selfs    r#   is_constantzTypedExpr.is_constant<   s    DII&&r%   c                     t        | j                        r+ t        | j                        | j                        | _        y y r   )r$   r,   r   r-   r/   s    r#   __post_init__zTypedExpr.__post_init__?   s.    		"1djj1$))<DI #r%   N)
__name__
__module____qualname____doc__	_ExprType__annotations__torchr-   r1   r3    r%   r#   r+   r+   5   s    1
O;;'=r%   r+   c                   \   e Zd ZdZededefd       Zedeee	e
f   dej                  defd       Zedeej                   ef   dej                  defd       Ze	 	 ddedej                  d	eej                     d
e
def
d       Zededefd       Zededefd       Zedededefd       Zedededefd       Zedededefd       Zededefd       Zedededefd       Zedededee   fd       Zedededee   fd       Zedededefd       Zedededefd       Zy)SymPyOpszAn 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                     | S r   r;   )r>   s    r#   identityzSymPyOps.identityL   s    r%   r-   c                     t        | |      S r   r+   r>   r-   s     r#   constantzSymPyOps.constantP       &&r%   c                     t        | |      S r   rC   rD   s     r#   
index_exprzSymPyOps.index_exprT   rF   r%   N	src_dtypeuse_compute_typesc                 .    t        | j                  |      S r   )r+   r,   )r>   r-   rI   rJ   s       r#   to_dtypezSymPyOps.to_dtypeX   s     U++r%   xc                 T    t        t        | j                        | j                        S r   )r+   absr,   r-   rM   s    r#   rO   zSymPyOps.absa   s    QVVagg..r%   c                 \    t        | j                  | j                  z  | j                        S r   r+   r,   r-   rP   s    r#   squarezSymPyOps.squaree   s    !&&!''22r%   yc                     t        j                  | j                  |j                        }t        | j                  |j                  z   |      S r   r:   promote_typesr-   r+   r,   rM   rT   result_types      r#   addzSymPyOps.addi   5    ))!''177;!&&+66r%   c                     t        j                  | j                  |j                        }t        | j                  |j                  z
  |      S r   rV   rX   s      r#   subzSymPyOps.subn   r[   r%   c                     t        j                  | j                  |j                        }t        | j                  |j                  z  |      S r   rV   rX   s      r#   mulzSymPyOps.muls   r[   r%   c                 D    t        | j                   | j                        S r   rR   rP   s    r#   negzSymPyOps.negx   s    !&&!''**r%   c                     t        j                  | j                  |j                        }t        |      st        S t        t        | j                  |j                        |      S r   )r:   rW   r-   r   NotImplementedr+   r   r,   rX   s      r#   floordivzSymPyOps.floordiv|   sF    ))!''177;,!!!&&!&&1;??r%   c                     t        j                  | j                  |j                        }t        |      st        S t        | j                  t        j                  d      |j                        }t        ||      S Nr   )
r:   rW   r-   r   rc   r   r,   r   Integerr+   )rM   rT   rY   result_exprs       r#   modzSymPyOps.mod   sV    ))!''177;,!!%affemmA.>Gk22r%   c                    t        j                  | j                  |j                        }t        |      st        S t        j                  | j                        }t        j                  |j                        }|j                  Y|j                  |j                  k(  r@t        | j                  t        j                  d      |j                        }t        ||      S t        S rf   )r:   rW   r-   r   rc   r   sympifyr,   is_nonnegativeis_positiver   rg   r+   )rM   rT   rY   x_expry_exprrh   s         r#   	remainderzSymPyOps.remainder   s    ))!''177;,!!qvv&qvv& !!-%%););;)!&&%--2BAFFKK[+66r%   c                     t        j                  | j                  |j                        }t        t	        j
                  | j                  |j                        |      S r   )r:   rW   r-   r+   r   Minr,   rX   s      r#   minimumzSymPyOps.minimum   <    ))!''177;1661662K@@r%   c                     t        j                  | j                  |j                        }t        t	        j
                  | j                  |j                        |      S r   )r:   rW   r-   r+   r   Maxr,   rX   s      r#   maximumzSymPyOps.maximum   rt   r%   )NF)r4   r5   r6   r7   staticmethodr   rA   r   r   r    r!   r:   r-   r+   rE   r   r'   rH   r   rL   rO   rS   rZ   r]   r_   ra   rd   ri   rp   rs   rw   r;   r%   r#   r=   r=   D   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%   r=   c                   F    e Zd ZU eed<   dZeed<   ededd fd       Z	d Z
y)	IndexPropVarr>   Fis_symbolicr,   r?   c                     t        | d      S )NTr{   )rz   )r,   s    r#   new_symboliczIndexPropVar.new_symbolic   s    Dd33r%   c                 `    | j                   r"t        | j                  t              sJ d       y y )Nz.Symbolic IndexPropVar must contain a TypedExpr)r{   r   r>   r+   r/   s    r#   r3   zIndexPropVar.__post_init__   s5    ##zJJ	(
 	<;	< 
 (
#r%   N)r4   r5   r6   r   r9   r{   r!   rx   r+   r~   r3   r;   r%   r#   rz   rz      s6    JK49 4 4 4<r%   rz   )IndexPropResult.r   c            	           e Zd ZdZdedeej                  ej                  f   deej                  ej                  f   ddfdZ	dej                  d	e
j                  defd
Zdeeef   defdZdefdZeded   deedf   deeef   defd       Zededeedf   deeef   defd       Zdedeedf   deeef   defdZdedeedf   deeef   defdZdededef   fdZd Z	 	 ddeeef   dededefdZy)IndexPropagationzOps 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_rangesr?   Nc                 r   || _         t        j                  j                  j                  | _        |j                         D ci c]  \  }}|t        dt        |      dz
          }}}t        t        j                  | j                  j                  j                         |j                                     | _        || _        g }|j                         D ]-  \  }}	|j                  d|k         |j                  ||	k         / t        |      | j                  j                         z   | _        y c c}}w )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   rM   ss
             r#   __init__zIndexPropagation.__init__   s	    ))33 ?J>O>O>Q
6:aA{1k!nq011
 
 "OODNN77==?ASASAUV

 $7 %%' 	!DAqMM!q&!MM!a% 	! Fmdnn&?&?&AA
s   #D3r,   r-   c                     t        |      r- t        |      |      }| j                  j                  ||      S | j                  j	                  ||      S r   )r$   r   r   rE   rH   )r0   r,   r-   r   s       r#   materialize_exprz!IndexPropagation.materialize_expr   sI    &-&t,C;;''U33{{%%dE22r%   ac                      t        |t        t        f      rt         fd|D              S t        |t              s|S |j                  r: j                  |j                  j                  |j                  j                        S |j                  S )Nc              3   @   K   | ]  }j                  |        y wr   )unwrap.0r   r0   s     r#   	<genexpr>z*IndexPropagation.unwrap.<locals>.<genexpr>   s     3AQ3   )	r   listr   rz   r{   r   r>   r,   r-   r0   r   s   ` r#   r   zIndexPropagation.unwrap   sf    a$'3333!\*H ==((qww}}EEwwr%   c                 n     t        |t        t        f      rt         fd|D              S t        |      S )Nc              3   @   K   | ]  }j                  |        y wr   )wrapr   s     r#   r   z(IndexPropagation.wrap.<locals>.<genexpr>   s     1!11r   )r   r   r   rz   r   s   ` r#   r   zIndexPropagation.wrap   s,    a$'1q111Ar%   nameindirect_indexingargs.kwargsc                      y r   r;   r0   r   r   r   s       r#   fallbackzIndexPropagation.fallback   s     	r%   c                      y r   r;   r   s       r#   r   zIndexPropagation.fallback   s     	r%   c                    |D cg c]  }| j                  |       }}|j                         D ci c]  \  }}|| j                  |       }}}| j                   t        | j                  |      |i |      S c c}w c c}}w r   )r   r   r   getattrr   )	r0   r   r   r   r   new_argsr   r   
new_kwargss	            r#   r   zIndexPropagation.fallback  sx     -11qDKKN114:LLNCDAqaQ'C
Cyy3d3XLLMM 2Cs
   A<Bc                    dt         t        t        f   dt        fd}|D cg c]
  } ||       }}|j                         D ci c]  \  }}| ||       }	}} t	        t
        |      |i |	}
|
t        uxr( |
j                         xs |
j                  j                  }|s| j                  |||      S t        j                  |
      S c c}w c c}}w )Nr   r?   c                 >    t        | t              s| S | j                  S r   )r   rz   r>   )r   s    r#   r   z0IndexPropagation.propagate_sympy.<locals>.unwrap  s    a.77Nr%   )r   r   rz   r   r   r=   rc   r1   r,   
is_integerr   r~   )r0   r   r   r   r   r   r   r   r   r   new_expris_valid_exprs               r#   propagate_sympyz IndexPropagation.propagate_sympy  s    	eC-. 	3 	
 (,,!F1I,,/5||~>tq!al>
>*78T*HC
C 6 
   " (}}''	 	 ==tV44((22 ->s   CCc                 <     dt         dt         dt        f fd}|S )Nr   r   r?   c                  F   t        t              sj                  | |      S t        j                  | |j                               D cg c]  }t        |t              r| }}t        d |D              sj                  | |      S j                  | |      S c c}w )Nc              3   4   K   | ]  }|j                     y wr   r}   )r   r   s     r#   r   z>IndexPropagation.__getattr__.<locals>.inner.<locals>.<genexpr>-  s     <q}}<s   )
hasattrr=   r   r   r   valuesr   rz   allr   )r   r   r   var_argumentsr   r0   s       r#   r   z+IndexPropagation.__getattr__.<locals>.inner$  s    8T*}}T488 #v}}?a. M 
 <m<<}}T488''dF;;s   B)r   r   )r0   r   r   s   `` r#   __getattr__zIndexPropagation.__getattr__#  s$    	< 	< 	< 	< r%   c                     g | j                   d | j                  j                         D        }t        | j                  || j
                  |      S )a  
        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 shuld be used in SimplifyIndexing
              to perform wrap_expr and in CSEProxy.check_bounds to elide upper / lower bounds also
              for indirect_indexing
        c              3   V   K   | ]!  \  }}|t        d t        |      dz
        f # yw)r   r   N)r   r)   )r   r   r   s      r#   r   z3IndexPropagation.statically_true.<locals>.<genexpr>C  s1      Aq K;q>A#567s   '))r   r   r   r   r   r   )r0   er   s      r#   statically_truez IndexPropagation.statically_true4  sS    

 44::<
 T^^Q\JJr%   indexsizecheckc                     t        |t              r|j                  rt        j                  |j
                  j                        } fd} j                  d|k        xs  j                   |k        } j                  |k        }|r ||      }t        |      r" j                  d|ft        | |              |S  j                  d|||fi       j
                  }	|	S )Nc                     j                  d| k        r| S j                  | dk        r| z   S t        | dk  | z   |       S )Nr   )r   r   )r,   r0   r   s    r#   	wrap_exprz5IndexPropagation.indirect_indexing.<locals>.wrap_exprZ  sM    ''T	2K))$(3$;& 4$;==r%   r   check_bounds)lowerr(   r   )r   rz   r{   r   rk   r>   r,   r   r   r   dict)
r0   r   r   r   wrap_negr,   r   can_prove_lowercan_prove_upperindirect_vars
   ` `       r#   r   z"IndexPropagation.indirect_indexingJ  s     e\*u/@/@ ==!1!12D> #2219= AUAUBO #224$;?O u%"4L?2o:MN
 K}}%uh!?

% 	 r%   )TT)r4   r5   r6   r7   r   r   r   Symbolr'   r   r:   r-   r   r   rz   r   r   r   r	   r   r
   strr   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  
 )* CHo S#X	
 
  $S#X8<S#X	 
NN$S#XN8<S#XN	N33$S#X38<S#X3	3, o1E(F "K4 +S,&'+ + 	+ 
+r%   r   ).r7   r   dataclassesr   typingr   r   r   r   r   r	   r
   r   typing_extensionsr   r   r:   torch._prims_commonr   r   torch.utils._sympy.functionsr   r   r   torch.utils._sympy.value_rangesr   r   r   r   utilsr   virtualizedr   r'   r    r   r!   r8   r$   r)   r+   r=   rz   r   r9   r   r;   r%   r#   <module>r      s   *  ! Q Q Q '   ? I I D # "  %**eS$./	/i /JY J = = =cA cAL < < < #<7M1N#NO Oy yr%   