o
    ߗi                     @   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	m
Z
 d dl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dS )    N)partial)AnyCallableDictUnion)Expr)bound_sympyValueRangeAnalysisValueRanges   )InterpreterShimLoopBodyLoopBodyBlock)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   T/home/ubuntu/transcripts/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>'   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   r,   r.   r/   )r0   r   r   r   __repr__0   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   
submodulesr.   r   r#   strr
   r   unknownr/   r   set_ops_handlerr	   r   
root_blockgraphlogdebugrunget_ops_handler)r0   r:   r'   interpreterr   r   r   
get_bounds9   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"   r/   )maskvalue)resultr0   rG   r   r   <lambda>_   s    z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r   rG   rJ   r0   rL   r   make_fn\   s   z*BoundVars.swap_submodules.<locals>.make_fnr6   scan)keysrF   r   	subblocksr   r   r   r
   r   r)   lenindirect_varsr   r6   )r0   r:   keyrG   rN   idxvarindirectr   rM   r   r9   L   s(   
zBoundVars.swap_submodulesrG   envrH   rI   c                 C   sN   t |j|}|jt |d dd |jjD }t|dks J |j|d  S )Nr7   c                 S   s   g | ]	}|j d kr|qS )output)r#   r&   r   r   r   
<listcomp>y   s    z-BoundVars.masked_subblock.<locals>.<listcomp>r   r   )r   r?   rB   r   rC   nodesrR   rX   )r0   rG   rX   rH   rI   r:   interprY   r   r   r   r"   o   s
   zBoundVars.masked_subblockoldnewc                 C   s   t |tsJ || j|< |S r   )r   r
   r,   )r0   r]   r^   r   r   r   r6      s   
zBoundVars.set_indirectnamec                 C   s:   | j j| }| j|}|d u rt|| j}|| j|< |S r   )r   indexing_exprsr,   getr   )r0   r_   exprboundr   r   r   rF      s   
zBoundVars.get_index)r4   
__module____qualname____doc__r   r1   r;   r5   r   r   torchfxNoder
   r   rE   r   r   r9   r   r"   r6   rF   r   r   r   r   r      s4    		 
#
r   )loggingr$   	functoolsr   typingr   r   r   r   sympyr   rg   torch.utils._sympy.value_rangesr   r	   r
   r   r   r   r   utilsr   r   virtualizedr   	getLoggerr4   r@   r   r   r   r   r   <module>   s    
