a
    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eddddZedddZee	e
jjee f dd	d
Ze	eedef f e	eedee f f dddZee	e
jjee f eee	eedef f ee dddZeee ee dddZeee d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.
    N)	loop_bodyreturnc                    s\   t ttf td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    D/var/www/auris/lib/python3.9/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   s.   | ]&}|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__r   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 ]6}t|jtr8d|jvrd|jvrtt 	 | j
|< qtt F t| jjj|}td| jjj |jt | j
d W d    n1 s0    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    
2zBoundVars.get_bounds.)r?   r   c                    s   i  |  D ]}|dkr$j |< qd|v rljj| }ttttgtt f d fdd}|| |< qd|v rt	|t
dd  }jj| }tj|}| |< qd|v sJ ||  |< q S )N	get_indexr)   )subblockr   c                    s    fddS )Nc                    s    j| | S r   )r)   r4   )maskvalue)resultr5   rK   r    r!   <lambda>g   s   z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r    rK   rN   r5   rP   r!   make_fnd   s    z*BoundVars.swap_submodules.<locals>.make_fnr<   scan)keysrJ   r   Z	subblocksr   r   r   r
   r   r0   lenZindirect_varsr   r<   )r5   r?   keyrK   rR   idxvarZindirectr    rQ   r!   r>   T   s$    	
zBoundVars.swap_submodules)rK   envrL   rM   r?   r   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>       z-BoundVars.masked_subblock.<locals>.<listcomp>r   r   )r   rC   rF   r   rG   nodesrU   rY   )r5   rK   rY   rL   rM   r?   ZinterprZ   r    r    r!   r)   w   s
    zBoundVars.masked_subblock)oldnewr   c                 C   s   t |tsJ || j|< |S r   )r   r
   r2   )r5   r^   r_   r    r    r!   r<      s    
zBoundVars.set_indirect)namer   c                 C   s:   | j j| }| j|}|d u r,t|| j}|| j|< |S r   )r   Zindexing_exprsr2   getr   )r5   r`   exprboundr    r    r!   rJ      s    
zBoundVars.get_index)r:   
__module____qualname____doc__r   r6   r@   r;   r   dicttorchZfxNoder
   r   rI   r   r   r>   r   r)   r<   rJ   r    r    r    r!   r      s"   		 %r   c                   @   sP  e Zd ZddddZeeeee dddZee	edf e
eef ed	d
dZeejee dddZd&eejeeddddZejejeeee dddZeeejee dddZed'eejeej eee dddZeeee dddZeeee ddd Zeeeee d!d"d#Zeeeee d!d$d%ZdS )(rB   Nr7   c                 C   s&   d| _ d}|D ]}t| || j qd S )NrB   )xorlogical_and
logical_orZlogical_not)r`   setattrbool_handler)r5   Zboolean_operatorsopr    r    r!   r6      s    zValueRangeAnalysis.__init__)argskwargsr   c                  O   s   t tjtjS r   )r
   sympyfalsetrue)rp   rq   r    r    r!   rn      s    zValueRangeAnalysis.bool_handler.)r`   rp   rq   r   c                 C   s   t  S r   r
   rA   )r5   r`   rp   rq   r    r    r!   _default   s    zValueRangeAnalysis._default)r`   indexr   c                 C   s   t  S r   ru   )r5   r`   rw   r    r    r!   r'      s    zValueRangeAnalysis.load)r`   rw   rM   moder   c                 C   s   d S r   r    )r5   r`   rw   rM   rx   r    r    r!   store   s    zValueRangeAnalysis.store)dtype	src_dtypereduction_typerM   r   c                 C   s   t  S r   ru   )r5   rz   r{   r|   rM   r    r    r!   r(      s    zValueRangeAnalysis.reduction)rw   rz   r   c                 C   s   t |tsJ | ||S r   )r   r
   to_dtype)clsrw   rz   r    r    r!   
index_expr   s    zValueRangeAnalysis.index_exprT)xrz   r{   use_compute_typesr   c                 C   s   t | } |tjkrX|  r,t | jdkS | jr6| S d| vrJt tjS t tj	tjS t
tjtjddd}| jr|  r| jrdnd}t |||S t |d||d|S nt || j||| j|S d S )Nr   )r   rz   r   c                 S   sJ   |j rt| S | tt fv r"| S zt| W S  tyD   |  Y S 0 d S r   )Zis_floating_pointrr   ZFloatr   ZInteger	TypeError)r   rz   r    r    r!   cast   s    
z)ValueRangeAnalysis.to_dtype.<locals>.castr   )r
   wraprh   boolZis_singletonlowerZis_boolrr   rt   rs   r   rz   r   r   )r   rz   r{   r   r   valr    r    r!   r}      s     

zValueRangeAnalysis.to_dtype)r   r   c                 C   s   t | dd S )Nc                 S   s
   t | dS )Nr   r   )yr    r    r!   rO      r\   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br   c                 C   s&   |  ||}|t kr|S | |S r   )truedivr
   rA   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)N)NT)r:   rd   re   r6   staticmethodr   r
   rn   r@   tuplerg   rv   rr   r   r'   r   ry   rh   rz   r   r(   classmethodr   r   r   r}   r   r   r   r   r    r    r    r!   rB      sH   $ 
	  )rB   )&loggingr+   	functoolsr   typingr   r   r   r   rr   r   rh   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   	getLoggerr:   rD   r   rB   r    r    r    r!   <module>   s    
}