
    N j]                     >   S SK r S SKrS SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
JrJrJr  S SKrS SKJr  S SKJr  S SKJr   " S S	\ R*                  5      r " S
 S\5      rS\\R0                  R2                  \4   S\\R0                  R2                  \4   4S jrg)    N)Callable)FunctionType)AnycastOptionalUnion)normalize_source_lines)Tracer)Graphc                   d    \ rS rSrSr\R                  R                  S\4S j5       r	S r
S rSrg)	AST_Rewriter   a\  
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                 x   [         R                  " U5      u  p#[        U5      nSR                  U5      n[        R
                  " U5      n[        R                  " U5      n[        R                  " U R                  U5      5      n[        USS5      n[        R                  " UR                  5      n	[        U	R                  5       5      n
[        X5        [!        [        U	R                  5       5      U
-
  5      n[#        U5      S:w  a  [%        S[#        U5       35      eXS      nS nU" XR                  S9$ )N exec   zExpected 1 new key, got r   c                     [        U R                  UU R                  U R                  U R                  S9n[
        R                  " X 5      n[        R                  " U R                  5      Ul        U$ )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      o/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/torch/fx/experimental/rewriter.pychange_func_globals1AST_Rewriter.rewrite.<locals>.change_func_globals8   s[     

ZZ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AssertionError)selfr   sourcelines_sourcenormalized_str
source_astdest_astcodeglobals_dictkeys_beforenew_keysfn_compiledr$   s                 r#   rewriteAST_Rewriter.rewrite!   s    !//3,[9%!0 YY~.
,,TZZ
-CD xV,yy0,++-.T L--/0;>?x=A #;CM?!KLL"A;/	  #;GGr&   c                    [         R                  " SSS9n[        U[         R                  5      (       d  [	        S[        U5       35      eUR                  n[        U[         R                  5      (       d  [	        S[        U5       35      eUR                  (       a  UR                  O[         R                  " SSS9nUR                  U/Ul        [         R                  " US	9n[         R                  " XQ5      $ )
zs
Swap out the Assert node (Python's `assert`) with a callsite to the
symbolically-traceable torch._assert function
ztorch._assert()eval)modezExpected ast.Expression, got zExpected ast.Call, got r   N)valuekind)rH   )r,   r-   
isinstance
Expressionr6   typebodyCallmsgConstanttestargsExprcopy_location)r7   noden	call_noderO   expr_wrappers         r#   visit_AssertAST_Rewriter.visit_AssertJ   s     II'f5!S^^,, #@a	!JKKFF	)SXX.. #:4	?:K!LMM((dhh2D(I))S)	 xxi0   44r&   c           
          [         R                  " UR                  /[         R                  " [         R                  " S[         R
                  " 5       S9UR                  UR                  // S9S9$ )z
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)funcrR   keywords)targetsrH   )r,   AssigntargetrN   NameLoadrH   
annotation)r7   rU   s     r#   visit_AnnAssignAST_Rewriter.visit_AnnAssign`   sQ     zz[[M((XX<jj$//2
 	
r&    N)r   
__module____qualname____firstlineno____doc__torch_dynamodisabler   rC   rY   rg   __static_attributes__ri   r&   r#   r   r      s:     ]]&H, &H &HP5,
r&   r   c                      ^  \ rS rSr SS\\R                  R                  \4   S\	\
\\4      S\4U 4S jjjrSrU =r$ )RewritingTracers   rootconcrete_argsreturnc                 6   > [         TU ]  [        U5      U5      $ N)supertrace_rewrite)r7   ru   rv   	__class__s      r#   r{   RewritingTracer.tracet   s    
 w}Xd^];;r&   ri   ry   )r   rj   rk   rl   r   rn   nnModuler   r   dictstrr   r   r{   rq   __classcell__)r}   s   @r#   rs   rs   s   sM     37<EHHOOX-.<  S#X/< 
	< <r&   rs   r   rw   c                    ^ [        U [        R                  R                  5      (       a*  S[        R                  R                  4U4S jjmT" U 5      $ [	        5       R                  [        [        U 5      5      $ )Nmc                    >  " U4S jS[         R                  R                  5      n[        5       R	                  [        [        U R                  5      5      Ul        U" U 5      $ )Nc                   ,   >^  \ rS rSrU U4S jrSrU =r$ )9_rewrite.<locals>.rewrite_module.<locals>.RewrittenModule   c                 V  > [         TU ]  5         UR                  R                  5        H|  u  p#[	        U[
        R                  R                  5      (       a+  [        R                  " T" U5      5      U R                  U'   MY  [        R                  " U5      U R                  U'   M~     g ry   )	rz   __init____dict__itemsrJ   rn   r   r   r   )r7   origkvr}   rewrite_modules       r#   r   B_rewrite.<locals>.rewrite_module.<locals>.RewrittenModule.__init__   sn    G$& $ 3 3 5%a99/3yy9J/KDMM!,/3yy|DMM!,	 !6r&   ri   )r   rj   rk   rl   r   rq   r   )r}   r   s   @r#   RewrittenModuler      s    < <r&   r   )rn   r   r   r   rC   r   r   forward)r   r   r   s     r#   r    _rewrite.<locals>.rewrite_module   sI    <%((// < '3n&<&<\199-'O# #1%%r&   )rJ   rn   r   r   r   rC   r   r   )r   r   s    @r#   r|   r|   |   sU    "ehhoo&&	&ehhoo 	& b!! ~%%d<&<==r&   )r,   r   r   r'   r*   collections.abcr   typesr   typingr   r   r   r   rn   torch._sourcesr	   torch.fx._symbolic_tracer
   torch.fx.graphr   NodeTransformerr   rs   r   r   r|   ri   r&   r#   <module>r      s         $  - -  1 +  ^
3&& ^
B<f <>uxx01 >eEHHOOX<U6V >r&   