
    Vh\                     4   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 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ej.                  j0                  e	f   deej.                  j0                  e	f   fdZy)    N)FunctionType)AnyCallablecastOptionalUnion)normalize_source_lines)Tracer)Graphc                   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      N/home/dcms/DCMS/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)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)rD   )r*   r+   
isinstance
ExpressionbodyCallmsgConstanttestargsExprcopy_location)r4   noden	call_noderJ   expr_wrappers         r"   visit_AssertzAST_Rewriter.visit_AssertH   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)funcrM   keywords)targetsrD   )r*   AssigntargetrI   NameLoadrD   
annotation)r4   rP   s     r"   visit_AnnAssignzAST_Rewriter.visit_AnnAssign\   sQ     zz[[M((XX<jj$//2
 	
r$   N)r   
__module____qualname____doc__torch_dynamodisabler   r@   rT   ra    r$   r"   r   r      s:     ]]%H, %H %HN5(
r$   r   c                   r     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)r4   rk   rl   	__class__s      r"   rq   zRewritingTracer.tracep   s    
 w}Xd^];;r$   ro   )r   rb   rc   r   re   nnModuler   r   dictstrr   r   rq   __classcell__)rs   s   @r"   rj   rj   o   sM     37<EHHOOX-.<  S#X/< 
	< <r$   rj   r   rm   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 ro   )	rp   __init____dict__itemsrF   re   rt   ru   r   )r4   origkvrs   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   rb   rc   r   rx   )rs   r   s   @r"   RewrittenModuler}   ~   s    < <r$   r   )re   rt   ru   r   r@   r   r   forward)rz   r   r   s     r"   r   z _rewrite.<locals>.rewrite_module}   sI    <%((// < '3n&<&<\199-'O# #1%%r$   )rF   re   rt   ru   r   r@   r   r   )r   r   s    @r"   rr   rr   x   sR    "ehhoo&	&ehhoo 	& b!! ~%%d<&<==r$   )r*   r   r   r%   r(   typesr   typingr   r   r   r   r   re   torch._sourcesr	   torch.fx._symbolic_tracer
   torch.fx.graphr   NodeTransformerr   rj   rt   ru   rr   rh   r$   r"   <module>r      s          7 7  1 +  [
3&& [
|<f <>uxx01 >eEHHOOX<U6V >r$   