o
    "jj                     @   s   d dl Z d dlmZ d dlmZ d dlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZmZ dd	lmZmZmZmZmZmZmZmZmZmZmZmZ g Zd
d ZG dd dejZ G dd deZ!dS )    N)defaultdict)unique_name)gast   )BaseTransformerForLoopTuplePreTransformerForNodeVisitor)	ARGS_NAME)NodeVarTypeStaticAnalysisVisitor)FOR_BODY_PREFIXFOR_CONDITION_PREFIXWHILE_BODY_PREFIXWHILE_CONDITION_PREFIXFunctionNameLivenessAnalysisGetterSetterHelperast_to_source_codecreate_get_args_nodecreate_name_strcreate_nonlocal_stmt_nodescreate_set_args_nodeget_attribute_full_namec              
   C   s\   t |}g }|D ]}|| qd}d|| |||t|t|}	t|	jd }
|
g}|S )a4  
    Returns a list of gast.Node which represents the calling of Paddle
    controlflow while_loop.

    Usually, the list just contain 1 statement such as:

    [a, b, c] = paddle.jit.dy2static.convert_while_loop(
            condition_name, body_name, [a, b, c])

    where a, b, c are in loop_var_names.

    However, if loop_var_names contains property such as foo.x, we cannot
    assign the property as output of convert_while_loop because Python
    property is a kind of read-only attribute. To handle the case, we replace
    the attributes which are output of convert_while_loop with generated
    variables, then if we know the attribute is not read-only at runtime, we
    assign the attribute. The created statements are like:

    [a, b, __attribute_variable_1] = paddle.jit.dy2static.convert_while_loop(
            condition_name, body_name, [a, b, foo.x])
    if not isinstance(getattr(type(foo), x, None), property): foo.x = __attribute_variable_1

    The number of above statements is not only 1, that's why the return type is
    a list of gast.Node.
    z
_jst.Whilez9{}({}, {}, {}, {}, return_name_ids={}, push_pop_names={})r   )listappendformatr   r   parsebody)Zcondition_nameZ	body_nameloop_var_namespush_pop_namesZgetter_nameZsetter_nameZassign_loop_var_namesnameZwhile_func_nameZwhile_node_strZ
while_noderet r!   f/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/jit/dy2static/loop_transformer.pycreate_while_nodes.   s$   )r#   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zd%ddZdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ ZdS )&NameVisitorz5
    Analysis name liveness for loop transformer
    c                 C   sx   t  | _g | _g | _h d| _tt | _tt| _tt | _	tt | _
d| _t  | _t|| _| j | _| | d S )N>   NoneFalseTrueF)setcurrent_seen_varscurrent_loopnodes_with_scopeblacklist_namesr   before_loop_body_varsr   in_loop_varswrite_in_loopcondition_varsin_condition	type_varsr   Zstatic_analysis_visitorZget_node_to_wrapper_mapnode_to_wrapper_mapvisit)self	root_noder!   r!   r"   __init__s   s   





zNameVisitor.__init__c                 C   s  t |tjtjfsJ dt }t }tt tt h}| j| }t	t
}|D ]}|| | |j q*t|}| ||}| |}	| j| }
| |
|}
| |
}| j|
 | }| ||}| ||}| j| }| |}| j| }| |}i }|D ]}| j| }|j|| |< q|	D ]K}||v r||vr||vrq|| q||v r|| || qd}|| D ]
}t |tjrd}qt || d tjr|r|| || q||fS )Nz Input node is not gast loop nodeFTr   )
isinstancer   WhileForr(   typeLoadAugLoadr.   r   r   _var_node_to_namer   ctx_remove_unnecessary_vars_var_nodes_to_namesr-   r)   r0   r/   r3   node_var_typeaddStore)r5   noder   create_var_namesZread_contextZin_loop_vars_listZvar_name_to_ctxsZvar_noder.   Zin_loop_name_strsr-   Zbefore_loop_name_strsZafter_loop_varsZafter_loop_name_strsr0   Zcondition_namesZ
write_varsZwrite_namesZname_to_typevarwrapperr   Z
is_createdr?   r!   r!   r"   get_loop_var_names   sr   











zNameVisitor.get_loop_var_namesc                 C   s   |  |r| | d S |j| jv r| | d S | j| tt tt	 tt
 h}| jD ]}| j| | t|j|v rL| j| | q3| jrX| j| | | | d S N)_is_call_func_name_nodegeneric_visitidr,   r)   rC   r;   r   rD   AugStoreDelr*   r.   r   r?   r/   r1   r0   )r5   rE   Zwrite_context	loop_noder!   r!   r"   
visit_Name   s&   






zNameVisitor.visit_Namec                 C   sN   | j | | j|j t| j}| | | j   | j r%|| _d S d S rJ   )	r+   r   r,   rC   r   copyr)   rL   pop)r5   rE   Zbefore_func_seen_varsr!   r!   r"   visit_FunctionDef  s   


zNameVisitor.visit_FunctionDefc                 C   s&   d|j j }t| || j}||}|S )Nvisit_)	__class____name__getattrrL   )r5   rE   methodvisitorr    r!   r!   r"   r4     s   zNameVisitor.visitc                 C   sR   |  |rd S t|}	 |drd S | j| | jD ]
}| j| | qd S )Nzself.)rK   r   
startswithr)   rC   r*   r.   r   )r5   rE   Zattr_full_namerP   r!   r!   r"   visit_Attribute  s   


zNameVisitor.visit_Attributec                 C   sZ   | j | d| _| |j | |j d| _t| j| j|< | 	| | j 
  d S NTF)r*   r   r1   r4   targetiterrR   r)   r-   rL   rS   r5   rE   r!   r!   r"   	visit_For/  s   
zNameVisitor.visit_Forc                 C   sN   | j | d| _| |j d| _t| j| j|< | | | j 	  d S r]   )
r*   r   r1   r4   testrR   r)   r-   rL   rS   r`   r!   r!   r"   visit_While9  s   
zNameVisitor.visit_Whilec                 C   st   t |jtjr3|jjdkr3|jd }t |tjr)|jD ]}| j	t
|  qn
| j	t
|  | | d S )Nr8   r   )r8   funcr   NamerM   argsTupleeltsr2   rC   r   striprL   )r5   rE   Z	type_nodeelementr!   r!   r"   
visit_CallB  s   

zNameVisitor.visit_CallNc                 C   s:   t  }|D ]}|d u st|j|v r|| | q|S rJ   )r(   r;   r?   rC   r>   )r5   Znode_setZctx_filter_setr    rE   r!   r!   r"   rA   N  s   zNameVisitor._var_nodes_to_namesc                 C   s*   t |tjr	|jS t |tjrt|S d S rJ   )r8   r   re   rM   	Attributer   r`   r!   r!   r"   r>   U  s
   zNameVisitor._var_node_to_namec                 C   s0   t jt jt jt jh}|D ]	}||v r dS qdS r]   )r
   ZBOOLEANINTFLOATSTRING)r5   rB   Zbasic_typestr!   r!   r"   _node_var_type_is_basic[  s   z#NameVisitor._node_var_type_is_basicc                 C   s(   |  |}t|tjr|j|krdS dS r]   )_get_parent_noder8   r   Callrd   )r5   rE   parent_noder!   r!   r"   rK   g  s   
z#NameVisitor._is_call_func_name_nodec                 C   s   dS )NFr!   r`   r!   r!   r"   _is_global_or_nonlocalm  s   z"NameVisitor._is_global_or_nonlocalc                 C   s4   |  |}|d ur||krdS |  |}|d us	dS r]   )rr   )r5   Zancestor_noderE   rt   r!   r!   r"   _is_ancestor_nodep  s   

zNameVisitor._is_ancestor_nodec                 C   s&   | j |}|r|jr|jj}|S d S rJ   )r3   getparentrE   )r5   rE   Zwrapper_nodert   r!   r!   r"   rr   y  s   zNameVisitor._get_parent_nodec                    s   fdd}t  }t  }|D ]}t|tjsq| |}t|tjr'| |}t|tjrz|j}t|tjr:|j}	n|g}	|t |	B }dd |	D }
| |}g }t|tj	r^|
|j nt|tjrm||j|jg |D ]	 || |
O }qoqt|tjr||u rq| ||rq|j}t|tjr|j}	n|g}	|t |	B }qdd |D }|D ]}t|tjsq|j|v r|| j| vr|| q||B }|D ]}t| | jv r|| q|| S )a  
        Remove unnecessary vars from before_loop_vars, after_loop_vars or in_loop_vars about loop_node.
            1. Remove target vars of gast.For from before_loop_vars or after_loop_vars.
            2. Remove vars only in gast.comprehension.
            3. Remove vars that are type names, for example: "isinstance(x, var_type_name)"
        :param loop_vars: before_loop_vars, after_loop_vars or in_loop_vars of loop_node.
        :param loop_node: Current loop node.
        c                    sZ   t  }t| tjr j|v r||  t| D ]}t|tjr*|j|v r*|| q|S )zT
            Filter children with gast.Name type from node.(inclusivly)
            )r(   r8   r   re   rM   rC   walk)r6   target_var_namesZ
name_nodes
child_noderE   r!   r"   filter_name_nodes_from  s   



zDNameVisitor._remove_unnecessary_vars.<locals>.filter_name_nodes_fromc                 S      h | ]}|j qS r!   rM   .0rG   r!   r!   r"   	<setcomp>      z7NameVisitor._remove_unnecessary_vars.<locals>.<setcomp>c                 S   r~   r!   r   r   r!   r!   r"   r     r   )r(   r8   r   re   rr   rg   comprehensionr^   rh   ListCompr   eltDictCompextendkeyvaluer:   rv   rM   r0   rC   r   ri   r2   )r5   Z	loop_varsrP   r}   Zvars_of_list_generatorZtarget_vars_of_for_node	name_nodert   Ztarget_nodeZtarget_varsrz   Z	comp_nodeZ	elt_nodesZtarget_vars_name_strsrG   Zremoved_varsr!   r|   r"   r@     sp   






z$NameVisitor._remove_unnecessary_varsrJ   )rW   
__module____qualname____doc__r7   rI   rQ   rT   r4   r\   ra   rc   rk   rA   r>   rq   rK   ru   rv   rr   r@   r!   r!   r!   r"   r$   n   s&     [
	
	r$   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )LoopTransformerzP
    This class transforms python while/for statement into Static Graph Ast
    c                 C   s   || _ t| j  d S rJ   )rootr   )r5   r   r!   r!   r"   r7     s   zLoopTransformer.__init__c                 C   s   t | j  | | j d S rJ   )r   r   	transformr4   )r5   r!   r!   r"   r     s   zLoopTransformer.transformc                 C      |  | | |}|S rJ   )rL   get_while_stmt_nodesr5   rE   	new_stmtsr!   r!   r"   rc        

zLoopTransformer.visit_Whilec                 C   r   rJ   )rL   get_for_stmt_nodesr   r!   r!   r"   ra     r   zLoopTransformer.visit_Forc                 C   s   t |tsd S d}|t|k rWt || tjr-| || }||||d < |t|7 }n"t || tjrK| || }||||d < |t|7 }n|d7 }|t|k sd S d S )Nr   r   )r8   r   lenr   r9   r   r:   r   )r5   Z	body_listir   r!   r!   r"   replace_stmt_list  s   
z!LoopTransformer.replace_stmt_listc                 C   s  t |}| }|d u r|gS |\}}}|j |j }}t|j }	| r@|j}
|j	}|
| |jd ur@|
|j g }t||B }|  t|v rU|t t|}|| tjtttjg g d g d d g d|tj|dg g d d d}|| tjtttjg g d g d d g d|| g d d d}|| td d ||	}t| }t| }t|j|j||	|j|j}|||g || |S N)rf   posonlyargsvararg
kwonlyargskw_defaultskwargdefaults)r   )r   rf   r   decorator_listreturnstype_comment) r   r   pd_scopemodified_varscreated_varsr   variadic_length_varsZis_for_iteriter_var_nameiter_idx_namerC   Zenum_idx_namesortr	   remover   r   r   FunctionDefr   generater   	argumentsReturnr   r   r   r   unionr   r#   r   )r5   rE   Zcurrent_for_node_parserZstmts_tupleZ
init_stmtsZ	cond_stmtZ
body_stmtsr   rF   r   r   r   r   nonlocal_namesnonlocal_stmt_nodecondition_func_nodebody_func_nodehelperget_args_nodeset_args_nodewhile_loop_nodesr!   r!   r"   r   !  s   




	
	

z"LoopTransformer.get_for_stmt_nodesc                 C   s@  |j  |j  }}t|j  }g }t||B }|  t|v r'|t t|}t	j
ttt	jg g d g d d g d|t	j|jdg g d d d}|| |j}	t	j
ttt	jg g d g d d g d||	 g d d d}
||
 td d ||}t| }t| }t|j|
j|||j|j}|||g || |S r   )r   r   r   r   r   r   r	   r   r   r   r   r   r   r   r   r   rb   r   r   r   r   r   r   r   r#   r   r   )r5   rE   r   rF   r   r   r   r   r   Znew_bodyr   r   r   r   r   r!   r!   r"   r     sv   
	
	

z$LoopTransformer.get_while_stmt_nodesN)rW   r   r   r   r7   r   rc   ra   r   r   r   r!   r!   r!   r"   r     s    ur   )"rR   collectionsr   Zpaddle.baser   Zpaddle.utilsr   Zbase_transformerr   r   r   Zifelse_transformerr	   Zstatic_analysisr
   r   utilsr   r   r   r   r   r   r   r   r   r   r   r   __all__r#   NodeVisitorr$   r   r!   r!   r!   r"   <module>   s   8@   