
    sg                     8   d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZm	Z	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZ d dlZ G d de j*                        Z G d	 d
e      Zde	ej0                  j2                  e
f   de	ej0                  j2                  e
f   fdZy)    N)FunctionType)castUnionCallableDictOptionalAny)Tracer)Graph)normalize_source_linesc                   Z    e Zd ZdZej
                  j                  defd       Zd Z	d Z
y)AST_Rewriterax  
    Take a FunctionType object representing a `forward` method, then
    perform an AST rewrite to swap out nodes that are not symbolically
    traceable with a callsite to the FX alternative.

    To support swapping out an AST node, define a new `visit` method on
    that node. For more details, see:
    https://docs.python.org/3/library/ast.html#ast.NodeTransformer
    fnc                 P   t        j                  |      \  }}t        |      }dj                  |      }t	        j
                  |      }t        j                  |      }t        j                  | j                  |            }t        |dd      }t        j                  |j                        }	t        |	j                               }
t        ||	       t!        t        |	j                               |
z
        }t#        |      dk(  sJ |	|d      }d } |||j                        S )N exec   r   c                     t        | j                  || j                  | j                  | j                        }t        j                  ||       }t        j                  | j                        |_        |S )z?Based on https://stackoverflow.com/a/13503277/2988730 (@unutbu))nameargdefsclosure)	r   __code____name____defaults____closure__	functoolsupdate_wrappercopy__kwdefaults__)fglobalsgs      Q/var/www/html/venv/lib/python3.12/site-packages/torch/fx/experimental/rewriter.pychange_func_globalsz1AST_Rewriter.rewrite.<locals>.change_func_globals5   s]     

ZZA ((A.A#yy)9)9:AH    )r!   )inspectgetsourcelinesr   jointextwrapdedentastparsefix_missing_locationsvisitcompiler   __globals__setkeysr   listlen)selfr   sourcelines_sourcenormalized_str
source_astdest_astcodeglobals_dictkeys_beforenew_keysfn_compiledr$   s                 r#   rewritezAST_Rewriter.rewrite   s     !//3Q,[9%!0 YY~.
,,TZZ
-CD xV,yy0,++-.T< L--/0;>?8}!!!"8A;/	 #;GGr%   c                    t        j                  dd      }t        |t         j                        sJ |j                  }t        |t         j
                        sJ |j                  r|j                  nt        j                  dd      }|j                  |g|_	        t        j                  |      }t        j                  ||      S )z
        Swap out the Assert node (Python's `assert`) with a callsite to the
        symbolically-traceable torch._assert function
        ztorch._assert()eval)moder   N)valuekind)rE   )r+   r,   
isinstance
ExpressionbodyCallmsgConstanttestargsExprcopy_location)r5   noden	call_noderK   expr_wrappers         r#   visit_AssertzAST_Rewriter.visit_AssertF   s     II'f5!S^^,,,FF	)SXX...((dhh2D(I))S)	 xxi0   t44r%   c           
          t        j                  |j                  gt        j                  t        j                  dt        j
                               |j                  |j                  gg             S )a  
        Swap out Python's AnnAssign with an Assign node where the annotation function is called.
        Example:
             Original:
             y: Tensor_Type(1,2,3, Dyn) = f2(x)
            Output:
             y = annotate(f2(x),Tensor_Type((1,2,3,Dyn)))
        annotate)idctx)funcrN   keywords)targetsrE   )r+   AssigntargetrJ   NameLoadrE   
annotation)r5   rQ   s     r#   visit_AnnAssignzAST_Rewriter.visit_AnnAssignZ   sN     zz4;;-sxxZSXXZ8**doo.8= > 	>r%   N)r   
__module____qualname____doc__torch_dynamodisabler   rA   rU   rb    r%   r#   r   r      s:     ]]%H, %H %HN5(>r%   r   c                   p     e Zd Zddeej
                  j                  ef   dee	e
ef      def fdZ xZS )RewritingTracerrootconcrete_argsreturnc                 6    t         |   t        |      |      S N)supertrace_rewrite)r5   rl   rm   	__class__s      r#   rr   zRewritingTracer.tracei   s    w}Xd^];;r%   rp   )r   rc   rd   r   rf   nnModuler   r   r   strr	   r   rr   __classcell__)rt   s   @r#   rk   rk   h   sG    <% 9: <8TXY\^aYaTbKc <ot < <r%   rk   r   rn   c                     t        | t        j                  j                        r(dt        j                  j                  ffd |       S t	               j                  t        t        |             S )Nmc                      G fddt         j                  j                        }t               j	                  t        t        | j                              |_         ||       S )Nc                   "     e Zd Z fdZ xZS )9_rewrite.<locals>.rewrite_module.<locals>.RewrittenModulec                 D   t         |           |j                  j                         D ]t  \  }}t	        |t
        j                  j                        r)t        j                   |            | j                  |<   St        j                  |      | j                  |<   v y rp   )	rq   __init____dict__itemsrG   rf   ru   rv   r   )r5   origkvrt   rewrite_modules       r#   r   zB_rewrite.<locals>.rewrite_module.<locals>.RewrittenModule.__init__t   sr    G$& $ 3 3 5 <1%a9/3yy9J/KDMM!,/3yy|DMM!,	<r%   )r   rc   rd   r   rx   )rt   r   s   @r#   RewrittenModuler}   s   s    < <r%   r   )rf   ru   rv   r   rA   r   r   forward)rz   r   r   s     r#   r   z _rewrite.<locals>.rewrite_moduler   sG    <%((// < '3n&<&<T,PQPYPY=Z&[O#"1%%r%   )rG   rf   ru   rv   r   rA   r   r   )r   r   s    @r#   rs   rs   m   sR    "ehhoo&
	&uxx 
	& b!! ~%%d<&<==r%   )r+   r&   r)   r   r   typesr   typingr   r   r   r   r   r	   torch.fx._symbolic_tracer
   torch.fx.graphr   torch._sourcesr   rf   NodeTransformerr   rk   ru   rv   rs   ri   r%   r#   <module>r      s          = = +   1 V>3&& V>r<f <
>uxx01 >eEHHOOX<U6V >r%   