o
    "il                     @   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dedd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                    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   T/home/ubuntu/SoloSpeech/.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   
var_rangesitemsreplacement_valsr   	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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)r.   r4   r&   interpreterr   r   r   
get_bounds0   s   



zBoundVars.get_boundsr4   .c                    s   i  |  D ]O}|dkrj |< qd|v r*jj| } fdd}|| |< qd|v rIt|tdd  }jj| }tj|}| |< qd|v sOJ ||  |< 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   rD   rC   r.   rF   r   make_fnS   s   z*BoundVars.swap_submodules.<locals>.make_fnr0   scan)	keysr@   r   	subblocksintlenindirect_varsr   r0   )r.   r4   keyrD   rH   idxvarindirectr   rG   r   r3   C   s    
zBoundVars.swap_submodulesrD   envrA   rB   c                 C   sN   t |j|}|jt |d dd |jjD }t|dks J |j|d  S )Nr1   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   r9   r<   r   r=   nodesrM   rS   )r.   rD   rS   rA   rB   r4   interprT   r   r   r   r!   d   s
   zBoundVars.masked_subblockoldnewc                 C   s   t |tsJ || j|< |S r   )r   r	   r*   )r.   rX   rY   r   r   r   r0   t   s   
zBoundVars.set_indirectnamec                 C   s:   | j j| }| j|}|d u rt|| j}|| j|< |S r   )r   indexing_exprsr*   getr   )r.   rZ   exprboundr   r   r   r@   y   s   
zBoundVars.get_index)__name__
__module____qualname____doc__r   r/   r   r   torchfxNoder	   r   r?   r5   r   r   r3   r   r!   r0   r@   r   r   r   r   r      s2    	 
!
r   )loggingr#   	functoolsr   typingr   r   r   sympyr   rc   torch.utils._sympy.value_rangesr   r   r	   irr   r   r   utilsr   r   virtualizedr   	getLoggerr_   r:   r   r   r   r   r   <module>   s   
