U
    yhC                     @   s   d dl Z d dlZd dlmZmZmZmZmZ er>d dlm	Z	 neZ	d dl
Z
d dlm  mZ d dl
mZ d dlmZ d dlmZ d dlmZ d dlmZ e eZe
jed	Zejee d
ddZ edddee	ee!ddddZ"dS )    N)AnyDictOptionalSetTYPE_CHECKING)ShapeEnv)fx)compatibility)lazy_format_graph_code)SymNode)GraphModuleZ
graph_code)nodereturnc                 C   s0   d| j kr| j d S d| j kr(| j d S dS dS )zx
    Get the example value key for a node, since dynamo uses "example_value"
    while non-strict export uses "val.
    example_valuevalN)metar    r   P/var/www/html/venv/lib/python3.8/site-packages/torch/fx/passes/runtime_assert.py_get_example_value   s
    



r   T)Zis_backward_compatibleF)gm	shape_envnameexportr   c                    s  t  }t  }| jjD ]jdkrhjtjjjj	krht
jdksFt|jd jd jd f jdkrjtjjjj	krt
jdkst|jd  qddlddlm mmmmm ddlm dd	lm |j | jtd
d  D sdS t !dt"d| |  g }t  }#dg D ](}|j$|krB|%| ||j$ qB|d< i t  }	d}
jD ]&jdkr q}
|	 q|
dkrt&t'j}
t   D ]"}|D ]}(|j$ qސqt)!d fdd}d
t*j}t+|dd D ]\	,|	kr^|	d  n|
j&| |	kr0t- }dk	r0
fdd}||fdd t.| }tj/r0t+|0 D ] \	}||	fdd qt+|1 D ] \	}||	fdd q||2 fdd |	kr||
}t3
D ]}|j&}qF,|j& |#dg  W 5 Q R X g }j45d }r|6 D ]R\}}|%|  fddt78||< t)!d||  q|D ]}#|g }||j9krX|rB| j:|krX;tjjjj	| j:f n;tj<| j:f |j=| }|> ?|sdd }||j@}||jA}| j:||f|krԈ;tjjjj	| j:f||j@||jAd  || qW 5 Q R X q:dS )!a  
    During tracing, we may have discovered that some data-dependent values
    had runtime assert on them; e.g., torch.empty(x.item()) induces a runtime
    that x.item() >= 0.  This asserts can happen unpredictably during fake
    tensor propagation, so we cannot conveniently insert them into the FX graph
    when they occur.  Instead, we accumulate them in the ShapeEnv, and in this
    pass insert them into the graph as proper tests.
    call_function   r   minmaxN)CallMethodKey cast_symbool_to_symint_guardlessConvertIntKeyDivideByKeyfree_symbolsInnerTensorKey)sympy_interp)PythonReferenceAnalysisc                 s   s   | ]
}|V  qd S Nr   ).0rasr   r   r   	<genexpr>_   s     z2insert_deferred_runtime_asserts.<locals>.<genexpr>z%sz$pre insert_deferred_runtime_asserts placeholderzneeded_symbols = %sc              
      s   | D ]}t d|j |j}|  }|rPt|td}|g | q |jj}	t
jjjj|d|j d| df qd S )Nzinserting runtime assert %s)keyz(Runtime assertion failed for expression z
 on node '')logdebugexprkeysr   str
setdefaultappendr   r   torchopsatenZ_assert_scalardefault)r(   raZfvsmissingi1res)r%   r"   graphras_by_symbolsymbol_to_proxyr$   r   r   add_runtime_asserts   s$    
  
z<insert_deferred_runtime_asserts.<locals>.add_runtime_assertsc                    sj   t | tjrft | jtrft | jj }jrf|krf|krft| |< t	
d||   d7  d S )Nsymbol_to_proxy[%s] = %sr   )
isinstancer4   ZSymIntr   r   r/   Symbolr   Proxyr-   r.   )Zsymintcbs)inserted_sym_nodesneeded_symbolsr>   sympyr   r   match_symbol   s    

z5insert_deferred_runtime_asserts.<locals>.match_symbolc                      s    S r&   r   r   r   r   r   <lambda>       z1insert_deferred_runtime_asserts.<locals>.<lambda>c                      s     tjjjjfS r&   )r   r4   r5   r6   sym_sizeintr   r<   ir   r   r   rK      s   
 c                      s     tjjjjfS r&   )r   r4   r5   r6   Z
sym_striderN   r   rO   r   r   rK      s   
 c                      s     tjjjjfS r&   )r   r4   r5   r6   Zsym_storage_offsetr7   r   )r<   r   r   r   rK      s   
 unbacked_bindingsc                    s  |dkr| S t |dkrt|d  rt|d tjr|d jdkrptjjj	j
| |d jf|dd  S |d jdkrtjjjj
| |d jf|dd  S |d j| |d jf|dd  S t|d  r|d j| f|dd  S t|d tjr>tj| |d jf|dd  S t|d rj| f|dd  S t|d rtj| |d jf|dd  S t|d rԈt| |d jf|dd  S td| d S )Nr      r   r   sizestridezunrecognized keypath )lenrB   pytreeZSequenceKeyr   r   r4   r5   r6   rM   rN   idxrT   Zcall_methodoperatorgetitemfloordivZdivisorgetattrZ
inner_nameAssertionError)r   keypath)r   r    r!   r#   r   gor<   r   r   r^      s    




 
 
 
 
 
 
z+insert_deferred_runtime_asserts.<locals>.gorA   c                 S   s&   z
t | W S  tk
r    Y d S X d S r&   )rN   	TypeError)rF   r   r   r   convertq  s    
z0insert_deferred_runtime_asserts.<locals>.convert)r   r   )Bsetr<   nodesoptargetr4   r5   r6   Zsym_constrain_ranger7   rU   argsr\   addkwargsZsym_constrain_range_for_sizerI   %torch.fx.experimental.symbolic_shapesr   r   r    r!   r"   r#   Ztorch.utils._sympy.interpr$   Ztorch.utils._sympy.referencer%   Zdeferred_runtime_assertscopyanyvaluesgraph_code_logr.   r
   popr/   r3   nextiterupdater-   list	enumerateZinserting_beforer   rB   ZTensorrS   rT   Zstorage_offsetranger   getitemsr   rD   Z	size_liker   r   Z_check_is_sizeZvar_to_rangeZ _default_unspecified_value_rangeissubsetlowerupper)r   r   r   r   Z,nodes_that_already_have_sym_constraint_rangeZ+nodes_that_already_have_sym_constraint_sizeZnew_rasZ	ras_exprsr(   ZplaceholdersZlast_placeholderr8   r?   rb   r   rJ   trF   Zlast_sym_node_ZdefsrQ   r]   Zi0Zvrr`   Zmin_valZmax_valr   )r   r    r!   r#   r%   r   r"   r^   r<   rP   rG   rH   r   r=   r>   rI   r$   r   insert_deferred_runtime_asserts%   s     








B)

 





	r{   )F)#loggingrX   typingr   r   r   r   r   rh   r   r4   Ztorch.utils._pytreeutilsZ_pytreerV   r   Ztorch.fx._compatibilityr	   Ztorch.fx._utilsr
   Ztorch.fx.experimental.sym_noder   Ztorch.fx.graph_moduler   	getLogger__name__r-   Z_loggingZgetArtifactLoggerrl   Noder1   r   boolr{   r   r   r   r   <module>   s0   
 