o
    Ih%                     @   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    J/var/www/vscode/kcb/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   
var_rangesitemsreplacement_valsr   	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   r3   r5   r6   )r7   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initial_env)swap_submodulesr   
submodulesr5   r   r*   strr
   r   unknownr6   r   set_ops_handlerValueRangeAnalysisr   
root_blockgraphlogdebugrunget_ops_handler)r7   rA   r.   interpreterr    r    r!   
get_boundsA   s   



zBoundVars.get_boundsrA   .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)   r6   )maskvalue)resultr7   rO   r    r!   <lambda>g   s    z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r    rO   rR   r7   rT   r!   make_fnd   s   z*BoundVars.swap_submodules.<locals>.make_fnr=   scan)keysrN   r   	subblocksr   r   r   r
   r   r0   lenindirect_varsr   r=   )r7   rA   keyrO   rV   idxvarindirectr    rU   r!   r@   T   s(   
zBoundVars.swap_submodulesrO   envrP   rQ   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   rG   rJ   r   rK   nodesrZ   r`   )r7   rO   r`   rP   rQ   rA   interpra   r    r    r!   r)   w   s
   zBoundVars.masked_subblockoldnewc                 C   s   t |tsJ || j|< |S r   )r   r
   r3   )r7   re   rf   r    r    r!   r=      s   
zBoundVars.set_indirectnamec                 C   s:   | j j| }| j|}|d u rt|| j}|| j|< |S r   )r   indexing_exprsr3   getr   )r7   rg   exprboundr    r    r!   rN      s   
zBoundVars.get_index)r;   
__module____qualname____doc__r   r8   rB   r<   r   dicttorchfxNoder
   r   rM   r   r   r@   r   r)   r=   rN   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 )-rE   r   Nc                 C   s&   d| _ d}|D ]	}t| || j qd S )NrE   )xorlogical_and
logical_orlogical_not)rg   setattrbool_handler)r7   boolean_operatorsopr    r    r!   r8      s
   zValueRangeAnalysis.__init__argskwargsc                  O   s   t tjtjS r   )r
   sympyfalsetrue)r{   r|   r    r    r!   rx      s   zValueRangeAnalysis.bool_handlerrg   .c                 C      t  S r   r
   rC   )r7   rg   r{   r|   r    r    r!   _default   s   zValueRangeAnalysis._defaultindexc                 C   r   r   r   )r7   rg   r   r    r    r!   r'      s   zValueRangeAnalysis.loadrQ   modec                 C   s   d S r   r    )r7   rg   r   rQ   r   r    r    r!   store   s   zValueRangeAnalysis.storedtype	src_dtypereduction_typec                 C   r   r   r   )r7   r   r   r   rQ   r    r    r!   r(      s   zValueRangeAnalysis.reductionc                 C   s   t |tsJ | ||S r   )r   r
   to_dtype)clsr   r   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   r   r   c                 S   sF   |j rt| S | tt fv r| S zt| W S  ty"   |  Y S w r   )is_floating_pointr}   Floatr   Integer	TypeError)r   r   r    r    r!   cast   s   
z)ValueRangeAnalysis.to_dtype.<locals>.castr   )r
   wraprp   boolis_singletonloweris_boolr}   r   r~   r   r   r   r   )r   r   r   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!   rS      s   
 z+ValueRangeAnalysis.square.<locals>.<lambda>)r
   convex_min_zero_mapr   r    r    r!   square   s   zValueRangeAnalysis.squarec                 C   s   t | tjS r   )r
   decreasing_mapr+   negr   r    r    r!   r      s   zValueRangeAnalysis.negabc                 C   s&   |  ||}|t kr|S | |S r   )truedivr
   rC   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)r;   rl   rm   r8   staticmethodr   r
   rx   rB   tuplero   r   r}   r   r'   r   r   rp   r   r   r(   classmethodr   r   r   r   r   r   r   r   r    r    r    r!   rE      sj    
*

	) rE   )&loggingr+   	functoolsr   typingr   r   r   r   r}   r   rp   torch.utils._sympy.value_rangesr   r	   r
   utils._sympy.functionsr   utils._sympy.numbersr   r   r   r   r   ops_handlerr   r   r   utilsr   r   virtualizedr   	getLoggerr;   rH   r   rE   r    r    r    r!   <module>   s"    
}