U
    9%e                     @   s   d dl Z d dlmZ d dlmZmZ d dlZd dlmZ d dl	m
Z
mZmZ ddl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)DictOptional)free_symbols)bound_sympyValueRangeAnalysisValueRanges   )InterpreterShimLoopBody)cache_on_selfdominated_nodes)Vc                   @   sJ   e Zd ZdZedddZedd Zdd Zd	d
 Z	dd Z
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_bodyc                 C   s@   || _ dd |j D | _tdd | j  D | _i | _d S )Nc                 S   s0   i | ](\}}|t |s$td |d nt|qS )r   r	   )r   r   r   ).0kv r   U/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/_inductor/bounds.py
<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__c              	   C   s   |  | jj}| jD ]2}t|jtr8d|jkrd|jkrt | j	|< qt
t * t| jjj|}|jt
 | j	d W 5 Q R X | j	S )Nr   set_indirectZinitial_env)swap_submodulesr   
submodulesr!   
isinstancer   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_boundsc                    s   i  |  D ]}|dkr$j |< qd|krNjj|  fdd |< qd|ksZtt|tdd  }jj| }tj	|}| |< q S )N	get_indexr   c                    s    j| | S N)r   r"   )maskvalueresultr#   subblockr   r   <lambda>B   s       z+BoundVars.swap_submodules.<locals>.<lambda>r%   )
keysr1   r   Z	subblocksAssertionErrorintlenZindirect_varsr   r%   )r#   r(   keyidxvarZindirectr   r5   r   r'   9   s    
zBoundVars.swap_submodulesc                 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>Q   s     
 z-BoundVars.masked_subblock.<locals>.<listcomp>r	   r   )	r
   r,   r-   r   r.   Znodesr<   r:   env)r#   r7   rB   r3   r4   r(   Zinterpr@   r   r   r   r   N   s
    zBoundVars.masked_subblockc                 C   s   t |tst|| j|< |S r2   )r)   r   r:   r    )r#   oldnewr   r   r   r%   W   s    
zBoundVars.set_indirectc                 C   s:   | j j| }| j|}|d kr,t|| j}|| j|< |S r2   )r   Zindexing_exprsr    getr   )r#   nameexprboundr   r   r   r1   \   s    
zBoundVars.get_indexN)__name__
__module____qualname____doc__r   r$   r   r0   r'   r   r%   r1   r   r   r   r   r      s   	
	r   )r   	functoolsr   typingr   r   ZtorchZ%torch.fx.experimental.symbolic_shapesr   Ztorch.utils._sympy.value_rangesr   r   r   Zirr
   r   utilsr   r   Zvirtualizedr   r   r   r   r   r   <module>   s   