
    ϑiRM                       S SK J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  SSKJrJr  SrS	rS
rSrSrSrSrSrSrSrSrSrSrSrSrSrSr S r! " S S\RD                  5      r#S r$S r%S r&S r'S  r(S! r)S" r*S# r+S$ r,\RZ                  " 5       S%4S& jr.S' r/S( r0S) r1 " S* S+5      r2 " S, S-\RD                  5      r3g).    )annotationsN)unique_name)ast_to_source_code)gast   )PADDLE_MODULE_PREFIXis_api_in_module_helperget_argsset_args__argstrue_fnfalse_fn__for_loop_var_index__for_loop_iter_tuple__for_loop_iter_target__for_loop_iter_iterator__for_loop_iter_tuple_index__for_loop_var_len__for_loop_iter_var__for_loop_iter_zipwhile_condition
while_bodyfor_loop_conditionfor_loop_bodyc                F     U R                  U5      $ ! [         a     gf = fN)index
ValueError)
array_listitems     g/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/jit/dy2static/transformers/utils.pyindex_in_listr#   3   s*    %% s    
  c                  $    \ rS rSrSrS rS rSrg)BaseNodeVisitor;   z
Implement customized NodeVisitor inherited from gast.NodeVisitor.
Ancestor nodes are traced to easily support more operations of currently
visited node.
c                    / U l         g Nancestor_nodesselfs    r"   __init__BaseNodeVisitor.__init__B   s
         c                    U R                   R                  U5        SUR                  R                  -   n[	        XU R
                  5      nU" U5      nU R                   R                  5         U$ )zVisit a node.visit_)r*   append	__class____name__getattrgeneric_visitpop)r,   nodemethodvisitorrets        r"   visitBaseNodeVisitor.visitE   s\    ""4(DNN333$(:(:;dm!
r/   r)   N)r4   
__module____qualname____firstlineno____doc__r-   r<   __static_attributes__ r/   r"   r%   r%   ;   s    !r/   r%   c                X    U  SU  S3n[         R                  " U5      R                  S   $ )Nz = _jst.UndefinedVar('z')r   )r   parsebody)name	func_codes     r"   create_undefined_varrI   P   s/    &.tfB7I::i %%a((r/   c                    [        U[        5      (       d   eU  SU 3n[        R                  " U5      R                  S   $ )z)
Create a assign stmt for name = value .
z = r   )
isinstanceboolr   rE   rF   )rG   valuer8   s      r"   create_bool_noderN   U   sA     eT""""V3ugD::d  ##r/   c                    0 n[         R                  " U 5       H$  n[         R                  " U5       H  nX!U'   M	     M&     U$ r(   )r   walkiter_child_nodes)root	to_parentr8   childs       r"   get_parent_mappingrU   ^   s>    *,I		$**40E#e 1   r/   c           	         U (       d  gU  Vs/ s H$  nSR                  UR                  SS5      5      PM&     nnSR                  SR                  U5      5      $ s  snf )z 
Return "('x', 'y')" for [x, y]
Nonez'{}''z\'z({}, ),)formatreplacejoin)name_idsrG   	names_strs      r"   create_name_strr_   f   sP     EMNXTt||C78XIN??388I.// Os   +Ac           
        [         R                   " U 5      n U(       a-  U R                  [        R                  " [	        U5      S95        O#U R                  [        R                  " SS95        [        R
                  " UUU / SS/ S9nU$ )z\
Wrapper all statements of nodes into one ast.FunctionDef, which can be
called by ast.Call.
)rM   N)rG   argsrF   decorator_listreturnstype_commenttype_params)copyr2   r   Returngenerate_name_nodeFunctionDef)nodesrG   
input_argsreturn_name_idsfunc_def_nodes        r"   create_function_def_nodern   q   sr    
 IIeET[['9/'JKLT[[t,-$$M r/   c                p    [        U [        R                  " 5       S9n[        R                  " U/USS9nX#4$ )zL
Creates a `gast.Assign` node by given name_id as target and node as value.
)ctxN)targetsrM   rd   )rh   r   StoreAssign)rG   r8   rq   assign_nodes       r"   create_assign_noderu      s:     !4::<8G++	K
 r/   c                   S n[        U [        [        45      (       d   e[        U 5      nU (       d  U" 5       $ U/ :X  a  SnO[	        US   5      nSnUR                  [        R                  " [        5      USR                  U 5      S9n[        R                  " [        R                  " U5      5      R                  S   $ )zg
Create get_args function as follows:

    def get_args_0():
        nonlocal x, y
        return x, y
c                     S[         R                  " [        5       S3n [        R                  " [
        R                  " U 5      5      R                  S   $ )N
        def z():
            return
        r   )r   generateGET_ARGS_FUNC_PREFIXr   rE   textwrapdedentrF   func_defs    r"   
empty_node(create_get_args_node.<locals>.empty_node   sJ    !!"678 9	 zz(//(3499!<<r/   
r   zK
    def {func_name}():
        {nonlocal_vars}
        return {vars},
    rY   )	func_namenonlocal_varsvars)rK   listtuplecreate_nonlocal_stmt_nodesr   rZ   r   ry   rz   r\   r   rE   r{   r|   rF   namesr   r8   r   templater~   s         r"   create_get_args_noder      s    = edE]++++%e,D|rz*473H
 &&';<#XXe_  H
 ::hooh/055a88r/   c                   S n[        U [        [        45      (       d   e[        U 5      nU (       d  U" 5       $ U/ :X  a  SnO[	        US   5      nSnUR                  [        R                  " [        5      [        USR                  U 5      S9n[        R                  " [        R                  " U5      5      R                  S   $ )zo
Create set_args function as follows:

    def set_args_0(__args):
        nonlocal x, y
        x, y = __args
c                     S[         R                  " [        5       S[         S3n [        R
                  " [        R                  " U 5      5      R                  S   $ )Nrx   (z):
            pass
        r   )	r   ry   SET_ARGS_FUNC_PREFIX	ARGS_NAMEr   rE   r{   r|   rF   r}   s    r"   r   (create_set_args_node.<locals>.empty_node   sQ    !!"678) E	 zz(//(3499!<<r/   r   r   zS
    def {func_name}({args}):
        {nonlocal_vars}
        {vars}, = {args}
    rY   )r   ra   r   r   )rK   r   r   r   r   rZ   r   ry   r   r   r\   r   rE   r{   r|   rF   r   s         r"   create_set_args_noder      s    = edE]++++%e,D|rz*473H
 &&';<#XXe_	  H ::hooh/055a88r/   c                T   [        U [        [        45      (       d   e[        [        S U 5      5      n[        [        S U5      5      n[	        XR
                  S9n U (       d  / $ SR                  SR                  U 5      5      n[        R                  " U5      R                  S   /$ )Nc                    SU ;  $ N.rC   ns    r"   <lambda>,create_nonlocal_stmt_nodes.<locals>.<lambda>       3a<r/   c                    SU ;  $ )N[rC   r   s    r"   r   r      r   r/   )keyznonlocal {}rY   r   )rK   r   r   filtersortedr   rZ   r\   r   rE   rF   )r   mappedrH   s      r"   r   r      s    edE]++++&/78F&/89FLLE 	$$SXXe_5IJJy!&&q)**r/   Fc                N  ^ [        U [        5      (       a  U /n [        U [        [        [        45      (       d  [        S[        U 5       35      eU4S jnU  Vs/ s H
  oC" U5      PM     nn[        U5      S:X  a  U(       d  US   nU$ [        R                  " UTS9nU$ s  snf )aQ  
If name_ids is list or tuple or set with multiple strings, this function
generates gast.Tuple of gast.Name.
If the name_ids is single string or contains only 1 string, this function
returns gast.Name if gen_tuple_if_single==False else returns gast.Tuple
with only one gast.Name

This function is used at several gast.Return statements.
z4name_ids must be list or tuple or set, but received c                   > SU ;  a  [         R                  " U TS S S9$ [         R                  " U 5      R                  S   R                  $ )Nr   )idrp   
annotationrd   r   )r   NamerE   rF   rM   )rG   rp   s    r"   create_node_for_name0generate_name_node.<locals>.create_node_for_name   sF    d?99ST  zz$$$Q'---r/      r   )eltsrp   )
rK   strr   r   set	TypeErrortypelenr   Tuple)r]   rp   gen_tuple_if_singler   name_id
gast_names	name_nodes    `     r"   rh   rh      s     (C  :huc 233B4>BRS
 	
. @HHxG&w/xJH
:!$7qM	  JJJC8	 Is   B"c                    [        U [        R                  5      (       d   S5       e[        U 5      R	                  5       $ )Nz3Input non-Attribute node to get attribute full name)rK   r   	Attributer   stripr8   s    r"   get_attribute_full_namer     s9    dDNN++ =+ d#))++r/   c                   [        U [        R                  5      (       d   S5       eU R                  n[        U[        R                  5      (       a-  UR                  n[        U[        R                  5      (       a  M-  [	        U5      R                  5       n SS KnSS KJs  J	n  SSKJ
n  [        UUUS.n[        X75      n[        X5      $ ! [         a     gf = f)Nz(Input non-Call node for is_api_in_moduler   )	to_tensor)nppaddle_jstr   F)rK   r   Callfuncr   r   r   paddle.jit.dy2staticjit	dy2staticr   r   evalr	   	Exception)	r8   module_prefix	func_nodefunc_strr   r   r   globalsfns	            r"   is_api_in_moduler     s    dDII&& 2& 		I
Y		
*
*NN	 Y		
*
* "),224H++$ "	
 ($&r99 s   3C 
CCc                "    [        U [        5      $ r(   )r   r   r   s    r"   is_paddle_apir   3  s    D"677r/   c                  V    \ rS rSrS rS rS rS rS rS r	S r
S	 rS
 rS rS rSrg)	NameScopei7  c                    [        5       U l        [        5       U l        [        5       U l        SU l        [        5       U l        [        5       U l        [        5       U l        g)a   
A NameScope is a object which manager all the variable names.
only FunctionDef and Controlflow node will have a namescope property.

type can be "function" and "controlflow"

we don't analyze the read only variable because they don't affect the analysis.
N)r   r   	nonlocalsra   fatherw_varscreatedpush_pop_varsr+   s    r"   r-   NameScope.__init__8  sD     uE	eu !Ur/   c                    Xl         g r(   )r   )r,   r   s     r"   
set_fatherNameScope.set_fatherK  s    r/   c                    U R                   U R                  -
  U R                  -
  U R                  -
  n[	        [        S U5      5      $ )zGvars existing in current scope.
they must not contain qualified names.
c                    SU ;  $ r   rC   )xs    r"   r   (NameScope.existed_vars.<locals>.<lambda>S  s    CqLr/   )r   r   r   ra   r   r   )r,   
local_varss     r"   existed_varsNameScope.existed_varsN  s;     [[4<</$..@499L
60*=>>r/   c                    U R                   $ r(   )r   r+   s    r"   created_varsNameScope.created_varsU  s    ||r/   c                    U R                   $ r(   )r   r+   s    r"   modified_varsNameScope.modified_varsX  s    {{r/   c           
         / nU R                    Hb  nU R                  U5      (       a8  U R                  U5      (       a"  [        R                  " SU SU SU S35        MQ  UR                  U5        Md     [        U5      $ )z
At present, we do not support global append, such as

import numpy as np
a = []
def func():
    a.append() # global names `a`, we will raise a warning.
    p.append(a, 1) # global names `np`, we will raise a warning.
zFind variable `z$` defined in global scope and call `z.append() or zJ.pop()`, which will be ignored and never be transferred into tensor array.)r   _is_simple_nameis_global_varwarningswarnr2   r   )r,   non_global_push_pop_namesvars      r"   variadic_length_varsNameScope.variadic_length_vars\  s     %'!%%C##C((T-?-?-D-D%cU +""%mC5 9%& *005 & ,--r/   c                p    U R                   nU R                  R                  U-  4nX R                   U-
  S.$ )N)globalnonlocal)r   r   global_vars)r,   valid_namestmps      r"   control_flow_varsNameScope.control_flow_varss  s4    kk{{&&46;;+<==r/   c                    SU;   d  SU;   a  gg)Nr   r   FTrC   r,   rG   s     r"   r   NameScope._is_simple_namex  s    $;#+r/   c                    U R                  U5      (       d   S5       eU nUb>  XR                  ;   a  gXR                  UR                  -  ;   a  gUR                  nUb  M>  g)z
Return whether the name is a var created in global scope.
Search from bottom to top. If it is not created or modified,
it means global vars; otherwise, it means local vars.
Only valid after FunctionNameLivenessAnalysis visitor.
z5is_global_var accept a simple name, but get `{name}`.TF)r   r   r   r   r   )r,   rG   ancestors      r"   r   NameScope.is_global_var}  so     ##D)) 	
C	
) "'''**X__<=H " r/   c                .    U R                  U5      (       + $ r(   )r   r   s     r"   is_local_varNameScope.is_local_var  s    %%d+++r/   c                :   U =R                   UR                   -  sl         U =R                  UR                  -  sl        U =R                  UR                  -  sl        U =R                  UR                  -  sl        U =R                  UR                  -  sl        g r(   )r   r   ra   r   r   )r,   
name_scopes     r"   
merge_fromNameScope.merge_from  sg    
****...		Z__$	z(((j666r/   )ra   r   r   r   r   r   r   N)r4   r>   r?   r@   r-   r   r   r   r   r   r   r   r   r   r  rB   rC   r/   r"   r   r   7  s9    #&?..>

&,7r/   r   c                      \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rSrg)FunctionNameLivenessAnalysisi  a  analyze the liveness of a function.

every variables stored in this scope will be collected,
in addition with global/nonlocal information and
push_pop information.

1. global variable is stored in node.var_globals.
2. nonlocal variable is stored in node.var_nonlocals.
3. arguments is stored in node.var_args.
4. if a variable's push and pop attribute is called,
   it will be collected in push_pop_vars. They are
   used for transformation to tensor_array.
   NOTE: push_pop_vars **may not** in w_vars.
   a.push(0) don't modify the variable a, but the content
   of a.

For example:

def func(*args, **kargs):
    a = 12
    global i,j
    nonlocal x,y
    print(a)
    i = k
    b = []
    c = [1,2,3]
    for m in range(10):
        q = 12
        b.push(1)
        c.pop()

After this visitor we have:
# node is the FunctionDef node with name: "func"
node.pd_scope = NameScope(
    globals = ['i', 'j'],
    nonlocals = ['x', 'y'],
    args = ['args', 'kargs'],
    wr_vars = ['a', 'i', 'q', 'm', 'c', 'b']
    push_pop_vars = ['b', 'c']
)
c                4    / U l         U R                  U5        g r(   )scope_node_stackr<   )r,   	root_nodes     r"   r-   %FunctionNameLivenessAnalysis.__init__  s     "

9r/   c                "    [        5       Ul        g r(   )r   pd_scoper,   r8   s     r"   _reset_name_scope.FunctionNameLivenessAnalysis._reset_name_scope  s    !r/   c                Z    [        US5      (       d  [        5       Ul        UR                  $ )Nr  )hasattrr   r  r  s     r"   _get_name_scope,FunctionNameLivenessAnalysis._get_name_scope  s"    tZ((%KDM}}r/   c                >    U R                  U R                  S   5      $ r   )r  r  r+   s    r"   _current_name_scope0FunctionNameLivenessAnalysis._current_name_scope  s    ##D$9$9"$=>>r/   c                r    [        U R                  5      S:X  a  g U R                  U R                  S   5      $ )Nr   )r   r  r  r+   s    r"   _father_name_scope/FunctionNameLivenessAnalysis._father_name_scope  s4    t$$%*##D$9$9"$=>>r/   c                    [        U R                  5      S:X  a  g U R                  SS S2    H5  n[        U[        R                  5      (       d  M$  U R                  U5      s  $    g )Nr   r  r   )r   r  rK   r   ri   r  r  s     r"   _nearest_function_scope4FunctionNameLivenessAnalysis._nearest_function_scope  sW    t$$%*))"&b&1D$ 0 011++D11 2r/   c                    g)z[ i for i in range(10) ]
In this case, `i` will not created in FunctionScope.
We don't collect `i` by not calling generic_visit.
NrC   r  s     r"   visit_ListComp+FunctionNameLivenessAnalysis.visit_ListComp  s    
 	r/   c                    g)zthe same as ListComp.NrC   r  s     r"   visit_DictComp+FunctionNameLivenessAnalysis.visit_DictComp  s    r/   c                "   U R                  U5        [        R                  [        R                  [        R                  4n[        UR                  U5      (       a4  U R                  5       R                  R                  UR                  5        g g r(   )r6   r   rr   AugStoreDelrK   rp   r  r   addr   r,   r8   write_contexts      r"   
visit_Name'FunctionNameLivenessAnalysis.visit_Name  s_    4 T]]DHH=dhh..$$&--11$'': /r/   c                H   ^ ^ UU 4S jnUU 4S jnT R                  TX#5        g )Nc                 |   > TR                  5       =R                  [        TR                  T 5      5      -  sl        g r(   )r  ra   r   _get_argument_namesr8   r,   s   r"   pre_func@FunctionNameLivenessAnalysis.visit_FunctionDef.<locals>.pre_func  s2    $$&++s((.0 +r/   c                   >^ [         [         [        [        [        [        /mUU4S jn TR                  5       (       a  U " 5       (       aw  TR                  5       =R                  TR                  5       R                  -  sl        TR                  5       =R                  TR                  5       R                  -  sl        ggg)zNOTE: why we need merge w_vars and push_pop_vars here ?
because we do ifelse_transformer after loop_transformer. Loops will changed into functions. but we know this function will be called in if. so we add w_vars to father function scope.
c                 \   > T H%  n TR                   R                  U 5      (       d  M%    g   g)NTF)rG   
startswith)prefixcontrol_flow_function_defr8   s    r"   is_control_flow_def_nodecFunctionNameLivenessAnalysis.visit_FunctionDef.<locals>.post_func.<locals>.is_control_flow_def_node  s*    7Fyy++F33# 8 r/   N)	WHILE_BODY_PREFIXFOR_CONDITION_PREFIXFOR_BODY_PREFIXTRUE_FUNC_PREFIXFALSE_FUNC_PREFIXr  r   r  r   )r7  r6  r8   r,   s    @r"   	post_funcAFunctionNameLivenessAnalysis.visit_FunctionDef.<locals>.post_func  s    
 "!$ !)% &&((-E-G-G'')00,,.550 '')77,,.<<7	 .H(r/   _visit_scope_noder,   r8   r0  r>  s   ``  r"   visit_FunctionDef.FunctionNameLivenessAnalysis.visit_FunctionDef  s    	
	6 	tX9r/   c                D   U R                  U5        U R                  R                  U5        U R                  5       R	                  U R                  5       5        U(       a  U" 5         U R                  U5        U(       a  U" 5         U R                  R                  5         g)zAscope node main visit logic.
pre_func and post_func is callbacks
N)r  r  r2   r  r   r  r6   r7   rB  s       r"   rA  .FunctionNameLivenessAnalysis._visit_scope_node  sv     	t$$$T*  "--d.J.J.LMJ4 K!!#r/   c                H   ^ ^ UU 4S jnUU 4S jnT R                  TX25        g )Nc                   > TR                  5       R                  TR                  5       5        TR                  5       R                  TR                  5       5        TR                  5       R	                  5       T R
                  -
  TR                  5       l        TR                  5       =R                  TR                  5       R                  -  sl        g r(   )r  r  r  r  r   before_createdr   r/  s   r"   r>  GFunctionNameLivenessAnalysis._visit_controlflow_node.<locals>.post_func%  s    ##%001I1I1KL((*55((* ,,.;;=%%& $$&.
 ((*22((*222r/   c                 L   > TR                  5       R                  5       T l        g r(   )r  r   rI  r/  s   r"   r0  FFunctionNameLivenessAnalysis._visit_controlflow_node.<locals>.pre_func3  s    "&">">"@"M"M"ODr/   r@  )r,   r8   r>  r0  s   ``  r"   _visit_controlflow_node4FunctionNameLivenessAnalysis._visit_controlflow_node$  s     		P 	tX9r/   c                &    U R                  U5        g r(   rM  r  s     r"   	visit_For&FunctionNameLivenessAnalysis.visit_For8      $$T*r/   c                &    U R                  U5        g r(   rP  r  s     r"   visit_While(FunctionNameLivenessAnalysis.visit_While;  rS  r/   c                &    U R                  U5        g r(   rP  r  s     r"   visit_If%FunctionNameLivenessAnalysis.visit_If>  rS  r/   c                p    U R                  5       =R                  [        UR                  5      -  sl        g r(   )r  r   r   r   r  s     r"   visit_Global)FunctionNameLivenessAnalysis.visit_GlobalA  s$      "**c$**o=*r/   c                p    U R                  5       =R                  [        UR                  5      -  sl        g r(   )r  r   r   r   r  s     r"   visit_Nonlocal+FunctionNameLivenessAnalysis.visit_NonlocalD  s$      ",,DJJ?,r/   c                @   U R                  U5        [        R                  [        R                  [        R                  4n[        UR                  U5      (       aC  [        U5      R                  5       nU R                  5       R                  R                  U5        g g r(   )r6   r   rr   r%  r&  rK   rp   r   r   r  r   r'  )r,   r8   r)  rG   s       r"   visit_Attribute,FunctionNameLivenessAnalysis.visit_AttributeG  sn    4 T]]DHH=dhh..%d+113D$$&--11$7 /r/   c                J   U R                  U5        [        R                  [        R                  [        R                  4n[        UR                  U5      (       a  [        UR                  [        R                  5      (       a7  UR                  n[        UR                  [        R                  5      (       a  M7  [        UR                  [        R                  5      (       a>  U R                  5       R                  R                  UR                  R                  5        g g g r(   )r6   r   rr   r%  r&  rK   rp   rM   	Subscriptr   r  r   r'  r   r(  s      r"   visit_Subscript,FunctionNameLivenessAnalysis.visit_SubscriptN  s    4 T]]DHH=dhh..TZZ88zz TZZ88$**dii00((*1155djjmmD 1 /r/   c                d   U R                  U5        [        UR                  [        R                  5      (       d  g SS/nUR                  R
                  U;  a  g [        UR                  R                  5      R                  5       nU R                  5       R                  R                  U5        g )Nr2   r7   )r6   rK   r   r   r   attrr   rM   r   r  r   r'  )r,   r8   variadic_length_methodrG   s       r"   
visit_Call'FunctionNameLivenessAnalysis.visit_CallW  s    4 $))T^^44"*E!299>>!77!$))//288:  "0044T:r/   c                n   [        U[        R                  5      (       d   S5       e[        UR                  R                  5      nUR                  UR                  R                  5        UR                  UR                  R                  5        U Vs/ s H  o3c  M  UR                  PM     nnU$ s  snf )zmget all arguments name in the functiondef node.
this node is local to the function and shouldn't
be created.
z&Input node is not function define node)	rK   r   ri   r   ra   r2   varargkwargr   )r,   r8   r   is       r"   r.  0FunctionNameLivenessAnalysis._get_argument_namesb  s    
 $ 0 011 	
4	
1 TYY^^$TYY%%&TYY__%$6u!u6 7s   B2B2)r  N)r4   r>   r?   r@   rA   r-   r  r  r  r  r  r  r"  r*  rC  rA  rM  rQ  rU  rX  r[  r^  ra  re  rj  r.  rB   rC   r/   r"   r  r    st    (T$
??
2;!:F$:(+++>@8E	;r/   r  )4
__future__r   rf   r{   r   numpyr   paddle.baser   paddle.jit.dy2static.ast_utilsr   paddle.utilsr   utilsr   r	   rz   r   r   r<  r=  FOR_ITER_INDEX_PREFIXFOR_ITER_TUPLE_PREFIXFOR_ITER_TARGET_PREFIXFOR_ITER_ITERATOR_PREFIXFOR_ITER_TUPLE_INDEX_PREFIXFOR_ITER_VAR_LEN_PREFIXFOR_ITER_VAR_NAME_PREFIXFOR_ITER_ZIP_TO_LIST_PREFIXWHILE_CONDITION_PREFIXr9  r:  r;  r#   NodeVisitorr%   rI   rN   rU   r_   rn   ru   r   r   r   Loadrh   r   r   r   r   r  rC   r/   r"   <module>r     s   #     # =  A! ! 	  . / 1 5 ; . 0 3 *   + !d&& *)
$0.
 "9J#9L+ &*YY[e @,<8a7 a7HS4#3#3 Sr/   