U
    zhl                     @   s   d dl Z 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 e e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ed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                    sL   dd  || _  fdd|j D | _tdd | j  D | _i | _d S )Nc                 S   s   t | trt| jS | S N)
isinstancer   r   upper)v r   H/var/www/html/venv/lib/python3.8/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ks"d|j k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__)r   c              	   C   s   |  | jj}| jD ]6}t|jtr8d|jkrd|jkrtt 	 | j
|< qtt < t| jjj|}td| jjj |jt | j
d W 5 Q R X | j
S )Nr    set_indirectzget_bounds:
%sZinitial_env)swap_submodulesr   
submodulesr)   r   r!   strr	   r   unknownr*   r   Zset_ops_handlerr   r   Z
root_blockgraphlogdebugrunget_ops_handler)r+   r0   r%   interpreterr   r   r   
get_bounds0   s    
zBoundVars.get_bounds.)r0   r   c                    s   i  |  D ]}|dkr$j |< qd|krTjj| } fdd}|| |< qd|krt|tdd  }jj| }tj|}| |< qd|kst	||  |< q S )N	get_indexr    c                    s    fddS )Nc                    s    j| | S r   )r    r*   )maskvalue)resultr+   subblockr   r   <lambda>T   s       z<BoundVars.swap_submodules.<locals>.make_fn.<locals>.<lambda>r   r>   r=   r+   r@   r   make_fnS   s    z*BoundVars.swap_submodules.<locals>.make_fnr-   scan)
keysr:   r   Z	subblocksintlenZindirect_varsr   r-   AssertionError)r+   r0   keyr>   rB   idxvarZindirectr   rA   r   r/   C   s     
zBoundVars.swap_submodules)r>   envr;   r<   r0   r   c                 C   sN   t |j|}|jt |d dd |jjD }t|dks@t|j|d  S )Nr.   c                 S   s   g | ]}|j d kr|qS )output)r!   r$   r   r   r   
<listcomp>n   s     
 z-BoundVars.masked_subblock.<locals>.<listcomp>r
   r   )	r   r3   r6   r   r7   ZnodesrF   rG   rK   )r+   r>   rK   r;   r<   r0   interprL   r   r   r   r    d   s
    zBoundVars.masked_subblock)oldnewr   c                 C   s   t |tst|| j|< |S r   )r   r	   rG   r(   )r+   rO   rP   r   r   r   r-   t   s    
zBoundVars.set_indirect)namer   c                 C   s:   | j j| }| j|}|d kr,t|| j}|| j|< |S r   )r   Zindexing_exprsr(   getr   )r+   rQ   exprboundr   r   r   r:   y   s    
zBoundVars.get_index)__name__
__module____qualname____doc__r   r,   r   r   torchZfxNoder	   r   r9   r1   r   r   r/   r   r    r-   r:   r   r   r   r   r      s    	 #r   )loggingr"   	functoolsr   typingr   r   r   Zsympyr   rY   Ztorch.utils._sympy.value_rangesr   r   r	   Zirr   r   r   utilsr   r   Zvirtualizedr   	getLoggerrU   r4   r   r   r   r   r   <module>   s   
