o
    I&i                     @   s   d dl Z d dlmZ d dl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 G d
d dZdS )    N)partial)AnyCallableDict)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edeej	j
ef fddZd	eeed
ef f deeed
ef f fddZdedeej	j
ef deded	eeed
ef f defddZdededefddZded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                 C   s@   || _ dd |j D | _tdd | j  D | _i | _d S )Nc                 S   s8   i | ]\}}|t |ts|jrtd |d nt|qS )r   r
   )
isinstanceintZ	is_numberr	   r   ).0kv r   AC:\wamp64\www\opt\env\Lib\site-packages\torch/_inductor/bounds.py
<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 )loadZ	reductionmasked_subblockN)targetoperatorgetitemr   noder   r   r   	<genexpr>!   s    
z%BoundVars.__init__.<locals>.<genexpr>)r   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}| jD ]}t|jtrd|jvr#d|jvr#t | j	|< q
t
t  t| jjj|}|jt
 | j	d W d    | j	S 1 sIw   Y  | j	S )Nr   set_indirectZinitial_env)swap_submodulesr   
submodulesr&   r   r   strr	   unknownr'   r   Zset_ops_handlerr   r   Z
root_blockgraphrunget_ops_handler)r(   r-   r"   interpreterr   r   r   
get_bounds*   s   



zBoundVars.get_boundsr-   .c                    s   i  |  D ]D}|dkrj |< qd|v r*jj| } fdd}|| |< qd|v s0J t|tdd  }jj| }tj|}| |< q S )N	get_indexr   c                    s    fddS )Nc                    s    j| | S N)r   r'   )maskvalue)resultr(   subblockr   r   <lambda>M   s    z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r   r:   r9   r(   r<   r   make_fnL   s   z*BoundVars.swap_submodules.<locals>.make_fnr*   )	keysr5   r   Z	subblocksr   lenZindirect_varsr   r*   )r(   r-   keyr:   r>   idxvarZindirectr   r=   r   r,   <   s   
zBoundVars.swap_submodulesr:   envr7   r8   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>f   s    z-BoundVars.masked_subblock.<locals>.<listcomp>r
   r   )r   r0   r1   r   r2   nodesr@   rD   )r(   r:   rD   r7   r8   r-   ZinterprE   r   r   r   r   \   s
   zBoundVars.masked_subblockoldnewc                 C   s   t |tsJ || j|< |S r6   )r   r	   r%   )r(   rH   rI   r   r   r   r*   l   s   
zBoundVars.set_indirectnamec                 C   s:   | j j| }| j|}|d u rt|| j}|| j|< |S r6   )r   Zindexing_exprsr%   getr   )r(   rJ   exprboundr   r   r   r5   q   s   
zBoundVars.get_index)__name__
__module____qualname____doc__r   r)   r   r   torchZfxNoder	   r4   r.   r   r   r,   r   r   r   r*   r5   r   r   r   r   r      s2    	
 
r   )r   	functoolsr   typingr   r   r   Zsympyr   rR   Ztorch.utils._sympy.value_rangesr   r   r	   Zirr   r   r   utilsr   r   Zvirtualizedr   r   r   r   r   r   <module>   s    