
    ^j.                     @   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 d dl	m
Z
mZ d dlZd dlmZ d dlmZ d dlmZ  G d d	e j&                        Z G d
 de      Zdej,                  j.                  ede
f   z  dej,                  j.                  ede
f   z  fdZy)    N)Callable)FunctionType)Anycast)normalize_source_lines)Tracer)Graphc                       e Zd ZdZej
                  j                  dedefd       Zde	j                  de	j                  fdZde	j                  de	j                  f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
    fnreturnc                    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k7  rt%        dt#        |             |	|d      }dt&        dt(        t*        t,        f   dt&        fd	} |||j                  
      S )N exec   zExpected 1 new key, got r   fglobalsr   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__)r   r   gs      i/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/torch/fx/experimental/rewriter.pychange_func_globalsz1AST_Rewriter.rewrite.<locals>.change_func_globals6   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AssertionErrorr   dictstrobject)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;>?x=A #;CM?!KLL"8A;/		&*3;&7		$ #;GGr#   nodec                    t        j                  dd      }t        |t         j                        st	        dt        |             |j                  }t        |t         j                        st	        dt        |             |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)modezExpected ast.Expression, got zExpected ast.Call, got r   N)valuekind)rH   )r)   r*   
isinstance
Expressionr3   typebodyCallmsgConstanttestargsExprcopy_location)r7   rD   n	call_noderO   expr_wrappers         r!   visit_Assertz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   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)funcrR   keywords)targetsrH   )r)   AssigntargetrN   NameLoadrH   
annotation)r7   rD   s     r!   visit_AnnAssignzAST_Rewriter.visit_AnnAssign`   sQ     zz[[M((XX<jj$//2	
 	
r#   N)r   
__module____qualname____doc__torch_dynamodisabler   rC   r)   AssertrS   rX   	AnnAssignr`   re    r#   r!   r   r      sn     ]](H, (H< (H (HT5 5 5,
CMM 
cjj 
r#   r   c                   x     e Zd Z	 ddej                  j
                  edef   z  dee	ef   dz  de
f fdZ xZS )RewritingTracerNroot.concrete_argsr   c                 6    t         |   t        |      |      S N)supertrace_rewrite)r7   rq   rr   	__class__s      r!   rv   zRewritingTracer.traceu   s    
 w}Xd^];;r#   rt   )r   rf   rg   ri   nnModuler   r   r4   r5   r	   rv   __classcell__)rx   s   @r!   rp   rp   t   sQ     04<hhooc 22< CH~,< 
	< <r#   rp   r   .r   c                    t        | t        j                  j                        rBdt        j                  j                  dt        j                  j                  ffd |       S t	               j                  t        t        |             S )Nmr   c                      G fddt         j                  j                        }t               j	                  t        t        | j                              |_         ||       S )Nc                   T     e Zd Zdej                  j
                  ddf fdZ xZS )9_rewrite.<locals>.rewrite_module.<locals>.RewrittenModuleorigr   Nc                 D   t         |           |j                  j                         D ]t  \  }}t	        |t
        j                  j                        r)t        j                   |            | j                  |<   St        j                  |      | j                  |<   v y rt   )	ru   __init____dict__itemsrJ   ri   ry   rz   r   )r7   r   kvrx   rewrite_modules       r!   r   zB_rewrite.<locals>.rewrite_module.<locals>.RewrittenModule.__init__   sr    G$& $ 3 3 5 <1%a9/3yy9J/KDMM!,/3yy|DMM!,	<r#   )r   rf   rg   ri   ry   rz   r   r{   )rx   r   s   @r!   RewrittenModuler      s#    < <T < <r#   r   )ri   ry   rz   r   rC   r   r   forward)r}   r   r   s     r!   r   z _rewrite.<locals>.rewrite_module   sI    <%((// < '3n&<&<\199-'O# #1%%r#   )rJ   ri   ry   rz   r   rC   r   r   )r   r   s    @r!   rw   rw   }   sc     "ehhoo&	&ehhoo 	&%((// 	& b!! ~%%d<&<==r#   )r)   r   r   r$   r'   collections.abcr   typesr   typingr   r   ri   torch._sourcesr   torch.fx._symbolic_tracer   torch.fx.graphr	   NodeTransformerr   rp   ry   rz   rw   rn   r#   r!   <module>r      s    
     $    1 +  a
3&& a
H<f <>(38,,>
XX__xS))>r#   