o
    Zh%                     @   s   d dl Z d dlZd dlmZ d dlmZmZmZmZ d dl	Z	d dl	m
Z
 d dlZd dlmZmZmZ ddlmZ ddlmZ d	d
lmZ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  e !e"Z#G dd dZ$G dd deeZ%dS )    N)partial)AnyCallableOptionalUnion)Expr)bound_sympySymPyValueRangeAnalysisValueRanges   PowByNatural)int_oo   )InterpreterShimLoopBodyLoopBodyBlock)DefaultHandlerReductionType	StoreMode)cache_on_selfdominated_nodes)Vc                   @   s  e Zd ZdZdeddfddZdefddZede	e
jjee f fd	d
Zde	eedef f de	eedee f f fddZdede	e
jjee f dedede	eedef f dee fddZdedee dee fddZdedee fddZdS )	BoundVarsa  
    Performs Value Range Analysis on LoopBody's fx graph by calling BoundVars.run()
    It exposes the ranges of the nodes in the `bounds` variable

    Note. A current limitation of this analysis is that it just works on a per-loop basis.
    We should be able to propagate the bounds between across the whole graph. This may benefit
    the case a bounded variable is returned by a kernel and fed into another.
    	loop_bodyreturnNc                    s^   dt ttf dtfdd || _ fdd|j D | _tdd | j D | _	i | _
d S )	Nvr   c                 S   s   t | tr
t| jS | S N)
isinstancer   r   upper)r    r    E/var/www/auris/lib/python3.10/site-packages/torch/_inductor/bounds.pyupper_bound&   s   z'BoundVars.__init__.<locals>.upper_boundc                    s(   i | ]\}}|t t d  |d qS )r   r   )r
   r   ).0kr   r"   r    r!   
<dictcomp>*   s    z&BoundVars.__init__.<locals>.<dictcomp>c                 s   s0    | ]}|j d dtjfv sd|j v r|V  qdS )load	reductionmasked_subblockN)targetoperatorgetitemr#   noder    r    r!   	<genexpr>/   s    
z%BoundVars.__init__.<locals>.<genexpr>)r   r   intr   Z
var_rangesitemsreplacement_valsr   Z	get_nodesunbounded_vars_bounds)selfr   r    r%   r!   __init__%   s   


zBoundVars.__init__c              
   C   s.   | j j d| j d| j d| j d| j d
S )Nz(loop_body=z,
 replacement_vals=z, 
unbounded_vars=z, 
_bounds=))	__class____name__r   r2   r3   r4   )r5   r    r    r!   __repr__8   s   
zBoundVars.__repr__c                 C   s   |  | jj}| jD ]}t|jtrd|jvr%d|jvr%tt 	 | j
|< q
tt % t| jjj|}td| jjj |jt | j
d W d    | j
S 1 sTw   Y  | j
S )Nr)   set_indirectzget_bounds:
%sZinitial_env)swap_submodulesr   
submodulesr3   r   r*   strr
   r   unknownr4   r   Zset_ops_handlerValueRangeAnalysisr   Z
root_blockgraphlogdebugrunget_ops_handler)r5   r>   r.   interpreterr    r    r!   
get_boundsA   s   



zBoundVars.get_boundsr>   .c                    s   i  |  D ]\}|dkrj |< qd|v r7jj| }dtdtttgtt f f fdd}|| |< qd|v rVt	|t
dd  }jj| }tj|}| |< qd|v s\J ||  |< q S )	N	get_indexr)   subblockr   c                    s    fddS )Nc                    s    j| | S r   )r)   r4   )maskvalue)resultr5   rJ   r    r!   <lambda>g   s    z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r    rJ   rM   r5   rO   r!   make_fnd   s   z*BoundVars.swap_submodules.<locals>.make_fnr;   scan)keysrI   r   Z	subblocksr   r   r   r
   r   r0   lenZindirect_varsr   r;   )r5   r>   keyrJ   rQ   idxvarZindirectr    rP   r!   r=   T   s(   
zBoundVars.swap_submodulesrJ   envrK   rL   c                 C   sN   t |j|}|jt |d dd |jjD }t|dks J |j|d  S )Nr<   c                 S   s   g | ]	}|j d kr|qS )output)r*   r-   r    r    r!   
<listcomp>   s    z-BoundVars.masked_subblock.<locals>.<listcomp>r   r   )r   rB   rE   r   rF   nodesrT   rX   )r5   rJ   rX   rK   rL   r>   ZinterprY   r    r    r!   r)   w   s
   zBoundVars.masked_subblockoldnewc                 C   s   t |tsJ || j|< |S r   )r   r
   r2   )r5   r\   r]   r    r    r!   r;      s   
zBoundVars.set_indirectnamec                 C   s:   | j j| }| j|}|d u rt|| j}|| j|< |S r   )r   Zindexing_exprsr2   getr   )r5   r^   exprboundr    r    r!   rI      s   
zBoundVars.get_index)r9   
__module____qualname____doc__r   r6   r?   r:   r   dicttorchZfxNoder
   r   rH   r   r   r=   r   r)   r;   rI   r    r    r    r!   r      s4    		 
#
r   c                   @   s  e Zd Zd*ddZedededee fddZd	ede	ed
f de
eef defddZd	edejdee fddZ	d+d	edejdededdf
ddZdejdejdededee f
ddZededejdee fddZe		d,dedejdeej dedee f
ddZededee fd d!Zededee fd"d#Zed$ed%edee fd&d'Zed$ed%edee fd(d)ZdS )-rA   r   Nc                 C   s&   d| _ d}|D ]	}t| || j qd S )NrA   )xorlogical_and
logical_orZlogical_not)r^   setattrbool_handler)r5   Zboolean_operatorsopr    r    r!   r6      s
   zValueRangeAnalysis.__init__argskwargsc                  O   s   t tjtjS r   )r
   sympyfalsetrue)rn   ro   r    r    r!   rl      s   zValueRangeAnalysis.bool_handlerr^   .c                 C      t  S r   r
   r@   )r5   r^   rn   ro   r    r    r!   _default   s   zValueRangeAnalysis._defaultindexc                 C   rs   r   rt   )r5   r^   rv   r    r    r!   r'      s   zValueRangeAnalysis.loadrL   modec                 C   s   d S r   r    )r5   r^   rv   rL   rw   r    r    r!   store   s   zValueRangeAnalysis.storedtype	src_dtypereduction_typec                 C   rs   r   rt   )r5   ry   rz   r{   rL   r    r    r!   r(      s   zValueRangeAnalysis.reductionc                 C   s   t |tsJ | ||S r   )r   r
   to_dtype)clsrv   ry   r    r    r!   
index_expr   s   zValueRangeAnalysis.index_exprTxuse_compute_typesc                 C   s   t | } |tjkr,|  rt | jdkS | jr| S d| vr%t tjS t tj	tjS dt
dtjdtjfdd}| jrZ|  rO| jrEdnd}t |||S t |d||d|S t || j||| j|S )Nr   r   ry   r   c                 S   sF   |j rt| S | tt fv r| S zt| W S  ty"   |  Y S w r   )Zis_floating_pointrp   Floatr   Integer	TypeError)r   ry   r    r    r!   cast   s   
z)ValueRangeAnalysis.to_dtype.<locals>.castr   )r
   wraprf   boolZis_singletonlowerZis_boolrp   rr   rq   r   ry   r   r   )r   ry   rz   r   r   valr    r    r!   r|      s    

zValueRangeAnalysis.to_dtypec                 C   s   t | dd S )Nc                 S   s
   t | dS )Nr   r   )yr    r    r!   rN      s   
 z+ValueRangeAnalysis.square.<locals>.<lambda>)r
   Zconvex_min_zero_mapr   r    r    r!   square   s   zValueRangeAnalysis.squarec                 C   s   t | tjS r   )r
   Zdecreasing_mapr+   negr   r    r    r!   r      s   zValueRangeAnalysis.negabc                 C   s&   |  ||}|t kr|S | |S r   )truedivr
   r@   trunc)r}   r   r   r   r    r    r!   truncdiv   s   
zValueRangeAnalysis.truncdivc                 C   s   |  || |S r   )addr   )r}   r   r   r    r    r!   sub  s   zValueRangeAnalysis.sub)r   Nr   )NT)r9   rb   rc   r6   staticmethodr   r
   rl   r?   tuplere   ru   rp   r   r'   r   rx   rf   ry   r   r(   classmethodr~   r   r   r|   r   r   r   r   r    r    r    r!   rA      sj    
*

	) rA   )&loggingr+   	functoolsr   typingr   r   r   r   rp   r   rf   Ztorch.utils._sympy.value_rangesr   r	   r
   Zutils._sympy.functionsr   Zutils._sympy.numbersr   r   r   r   r   Zops_handlerr   r   r   utilsr   r   Zvirtualizedr   	getLoggerr9   rC   r   rA   r    r    r    r!   <module>   s"    
}