o
    j9:jJ&                     @   s   d dl Z d dlZd dlmZ d dlmZ d dl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)Callable)partial)Any)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                    sZ   dt tB 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   ]/home/nk/hobo-godmode/plappi-mvp/.venv/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>0   s    
z%BoundVars.__init__.<locals>.<genexpr>)
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   r1   r3   r4   )r5   r   r   r   __repr__9   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   
submodulesr3   r   r(   strr   r   unknownr4   r   set_ops_handlerValueRangeAnalysisr   
root_blockgraphlogdebugrunget_ops_handler)r5   r?   r,   interpreterr   r   r   
get_boundsB   s   



zBoundVars.get_boundsr?   .c                    s   i  |D ]\}|dkrj  |< qd|v r5jj| }dtdtttgtt f f fdd}|| |< qd|v rTt|t	dd  }jj
| }tj|}| |< qd|v sZJ ||  |< q S )	N	get_indexr'   subblockr   c                    s    fddS )Nc                    s    j| | S r   )r'   r4   )maskvalue)resultr5   rM   r   r   <lambda>h   s    z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r   rM   rP   r5   rR   r   make_fne      z*BoundVars.swap_submodules.<locals>.make_fnr;   scan)rL   r   	subblocksr   r   r   r   r   r.   lenindirect_varsr   r;   )r5   r?   keyrM   rT   idxvarindirectr   rS   r   r>   U   s(   
zBoundVars.swap_submodulesrM   envrN   rO   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   rE   rH   r   rI   nodesrX   r^   )r5   rM   r^   rN   rO   r?   interpr_   r   r   r   r'   x   s
   zBoundVars.masked_subblockoldnewc                 C   s   t |tsJ || j|< |S r   )r   r   r1   )r5   rc   rd   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_exprsr1   getr   )r5   re   exprboundr   r   r   rL      s   
zBoundVars.get_index)r9   
__module____qualname____doc__r   r6   r@   r:   r   dicttorchfxNoder   r   rK   r   r   r>   r   r'   r;   rL   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jdB 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 )-rC   r   Nc                 C   s&   d| _ d}|D ]	}t| || j qd S )NrC   )xorlogical_and
logical_orlogical_not)re   setattrbool_handler)r5   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)ry   rz   r   r   r   rv         zValueRangeAnalysis.bool_handlerre   .c                 C      t  S r   r   rA   )r5   re   ry   rz   r   r   r   _default   s   zValueRangeAnalysis._defaultindexc                 C   r   r   r   )r5   re   r   r   r   r   r%      s   zValueRangeAnalysis.loadrO   modec                 C   s   d S r   r   )r5   re   r   rO   r   r   r   r   store   s   zValueRangeAnalysis.storedtype	src_dtypereduction_typec                 C   r   r   r   )r5   r   r   r   rO   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   wraprn   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   rQ      s   
 z+ValueRangeAnalysis.square.<locals>.<lambda>)r   convex_min_zero_mapr   r   r   r   square   rU   zValueRangeAnalysis.squarec                 C   s   t | tjS r   )r   decreasing_mapr)   negr   r   r   r   r      r~   zValueRangeAnalysis.negabc                 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)r   Nr   )NT)r9   rj   rk   r6   staticmethodr   r   rv   r@   tuplerm   r   r{   r   r%   r   r   rn   r   r   r&   classmethodr   r   r   r   r   r   r   r   r   r   r   rC      sj    
*

	) rC   )%loggingr)   collections.abcr   	functoolsr   typingr   r{   r   rn   torch.utils._sympy.value_rangesr   r   r   utils._sympy.functionsr   utils._sympy.numbersr   r   r   r   r   ops_handlerr   r   r   utilsr   r   virtualizedr   	getLoggerr9   rF   r   rC   r   r   r   r   <module>   s$    
}