o
    "j7                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZmZ ddlm	Z	 ddl
mZmZmZmZmZ ddlmZ ddlmZ g Zd	d
 Zdd Ze dZe dZe dZdd Z	d!ddZdd Zdd Zdd Zd"ddZ d#ddZ!dd  Z"dS )$    N)StringIO)_C_ops_legacy_C_ops   )check_variable_and_dtype)OpProtoHolderVariableconvert_np_dtype_to_dtype_corein_dygraph_mode)LayerHelper)framework_pb2c                 C   s    t dd| }t dd| S )a	  
    Formatting.
    Args:
       name: The name/alias
    This function takes in a name and converts it to a standard format of
    group1_group2. Where as per the regular expression, group1 can have
    alphabets and numbers and group2 has capital alphabets.
    z(.)([A-Z][a-z]+)z\1_\2z([a-z0-9])([A-Z]))resublower)names1 r   l/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/base/layers/layer_function_generator.py	_convert_$   s   	r   c                 C   s   t j| S N)r   ZAttrTypeName)tpr   r   r   _type_to_str_1   s   r   z\$\$([^\$]+)\$\$z\$([^\$]+)\$z!!([^!]+)!!c                 C   s   t d| S )Nz
:math:`\1`)_two_dollar_pattern_r   )textr   r   r   escape_math:   s   r   c                 C   s  t | tjs
tdt }|t| j |d | jD ]1}dt	|j
 }|| |d |t|j |jrA|d |jrI|d |d qt }|d |d	 |d
 |rn|D ]}|| qf| jD ]2}|j
|v ryqq|d ||j
 |d |t|j |d |t|j |d qq|dur|D ]}	|	 }	|d ||	 |d qt| jdkr|d |d | jD ]}
|
js nq|t	|
j
 |d |t|
j | S )z
    Generate docstring by OpProto
    Args:
        op_proto (framework_pb2.OpProto): a protobuf message typed OpProto
    Returns:
        str: the document string
    z)OpProto should be `framework_pb2.OpProto`z
Args:
z    z (Tensor): z  Duplicatable.z  Optional.
Z
use_mkldnnZis_testZ	use_cudnnz (z): Nr   z

Returns:
)
isinstancer   ZOpProto	TypeErrorr   writer   commentinputsr   r   
duplicableZdispensabler   Zgenerated_op_attr_namesaddattrsr   typestriplenoutputsintermediategetvalue)op_protoadditional_args_linesZskip_attrs_setbuf
each_inputZ
line_beginZ
skip_attrst	each_attrlineeach_optr   r   r   _generate_doc_string_B   sb   



















r4   c                    s   t  dd jD }dd jD }t|dkr%tdd |d jr.td|D ]
}|jr:td	d
q0|d jdd |D fdd  fdd}|_t	|_
|S )zRegister the Python layer for an Operator.
    Args:
       op_type: The name of the operator to be created.
    This function takes in the operator type (sigmoid, mean , average etc) and
    creates the operator functionality.
    c                 S   s   g | ]}|j s|qS r   r*   .0outputr   r   r   
<listcomp>   
    z%generate_layer_fn.<locals>.<listcomp>c                 S   s   g | ]}|j r|qS r   r5   r6   r   r   r   r9      r:      z0Only one non intermediate output operator can bezautomatically generated. r   z6Only non duplicable op can be automatically generated.z0The op can be automatically generated only when z(all intermediate ops are not duplicable.c                 S   s   g | ]}|j qS r   )r   r6   r   r   r   r9      s    c           	         s  d}| j D ][}t|j}||g }t|tst|ts|g}t|dkr7t|dkr,q|d g}|dd }|D ]&}t|tsHt	d  d|du rP|j
}q9||j
kr_t	d ||j
q9q|du r|d}|r}t|tjjsyt|}|S |}|S tjjj}|S )z^
        This function performs the sanity check for dtype and
        instance type.
        Nr   r;   z	input of z must be variablez+operator {} must input same dtype. {} vs {}dtype)r"   r   r   popr   listtupler(   r   
ValueErrorr<   formatgetr
   ZVarDescZVarTyper	   ZFP32)	r,   argskwargsr<   iptr   valZeachZ	arg_dtypeop_typer   r   infer_and_check_dtype   sD   






z0generate_layer_fn.<locals>.infer_and_check_dtypec                     s  t fi |} g| R i |}i }jD ]5}t|j}||g }t|ts2t|ts2|g}t|dkrHt| dkrH| d }| dd  } |||j< qi }|tg }	|	rht|	ttfre|	d n|	}
n|j	|d}
|
g|< D ]}|j	|dg||< qu|j
|||d ||
S )Nr   r;   r<   )r&   r"   r)   r%   )r   r"   r   r   r=   r   r>   r?   r(   "create_variable_for_type_inference	append_opZappend_activation)rC   rD   helperr<   r"   rE   r   rF   r)   outZout_varrI   Zintermediate_output_namesZo_namer,   rH   r   r   func   s2   





zgenerate_layer_fn.<locals>.func)r   instanceget_op_protor)   r(   r@   r#   r   __name__r4   __doc__)rH   Znot_intermediate_outputsZintermediate_outputsr8   rP   r   rO   r   generate_layer_fn   s<   

) 
rU   c                    s6   t   }d fdd	} |_t|dgd|_|S )zRegister the Python layer for an Operator without Attribute.
    Args:
       op_type: The name of the operator to be created.
    This function takes in the operator type (sigmoid, exp , tanh etc) and
    creates the operator functionality.
    Nc                    s   t  rtt rtt }|| S t  r"tt r"tt }|| S  dvr0t| dg d  n	t| dg d  t fi t }|j| j	d}|j
 d| id|id |S )	N)absexpZsquarex)float16float32float64uint16)Zint32Zint64rY   rZ   r[   Z	complex64Z
complex128r\   rJ   XZOut)r&   r"   r)   )r   hasattrr   getattrr   r   r   localsrK   r<   rL   )rX   r   oprM   r8   rG   r   r   rP     s(   


z$generate_activation_fn.<locals>.funczname (str, optional): Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.)r-   r   )r   rQ   rR   rS   r4   rT   )rH   r,   rP   r   rG   r   generate_activation_fn   s   %rb   c                    s4    dd d fdd	} |_ d|_|S )a  Register the Python layer for an Inplace Operator without Attribute.
    Args:
       inplace_op_type: The name of the inplace operator to be created.
    This function takes in the inplace operator type (exp_ , ceil_ etc) and
    creates the operator functionality.
    Nc                    st   t  rtt }|| S td  ddlm} | r3t| dr3| j	r3t
d | j| j| jt| |S )NzPIn static mode, {}() is the same as {}() and does not perform inplace operation.r   )in_to_static_modeis_view_vara  Sorry about what's happend. In to_static mode, {}'s output variable {} is a viewed Tensor in dygraph. This will result in inconsistent calculation behavior between dynamic and static graphs. You must find the location of the strided API be called, and call {} = {}.assign().)r   r_   r   warningswarnrA   Zdygraph.baserd   r^   re   r@   r   Znamebrb   )rX   r   ra   rd   inplace_op_typeZorigin_op_typer   r   rP   :  s*   
z!generate_inplace_fn.<locals>.funcz
Inplace version of ``{}`` API, the output Tensor will be inplaced with input ``x``.
Please refer to :ref:`api_paddle_base_layers_{}`.
r   )rS   rA   rT   )ri   rP   r   rh   r   generate_inplace_fn1  s   rj    c                    s    fdd}|S )Nc                    s   t t | j  | _| S r   )r4   r   rQ   rR   rS   rT   )rP   r!   r   r   __impl__^  s   zautodoc.<locals>.__impl__r   )r!   rm   r   rl   r   autodoc]  s   	rn   c                    s   dd  fdd}|S )a  
    Decorator of layer function. It will use the docstring from the layer
    function as the template. The template arguments are:
    * ${comment}: The operator comment written in CPP.
    * ${{name}_comment}: The comment of ${name} written with AddAttr, AddOutput,
        and AddInput. The ${name} is Python snake style. i.e., xxx_xxx.
    * ${{name}_type}: The type of ${name}.
    Returns:
        Decorated function.
    c                 S   s
   |  dS )N.)rstrip)msgr   r   r   trim_ending_dotv  s   
z$templatedoc.<locals>.trim_ending_dotc                    sP   d u r| j }n }t |}t| j}|jd}d}|D ]!}|	 }t
|dkr8|t|7 }|d7 }q!t
|dkrB|d7 }q!d|i}|jD ]}t|j}	|j||	 d< d||	 d	< qL|jD ]}
t|
j}	|
j||	 d< t|
j||	 d	< qh|jD ]}t|j}|j|| d< d|| d	< q||| _| S )
Nr   rk   r    z

    
    r!   _commentr   _type)rS   r   rQ   rR   stringTemplaterT   r!   splitr'   r(   r   r"   r   r   r%   r   r&   r)   
substitute)rP   Zop_type_namer,   tmplZcomment_linesr!   r2   rC   r/   Z
input_namer1   r3   Zoutput_namerH   rr   r   r   rm   y  s<   






ztemplatedoc.<locals>.__impl__r   )rH   rm   r   r{   r   templatedocj  s   #r|   c                 C   s   | j | | _ dS )z
    Append sample code for dynamically generated functions.
    Args:
       func: The function of the function to be append sample code to.
       sample_code: sample code session in rst format.
    N)rT   )rP   Zsample_coder   r   r   add_sample_code  s   r}   )NN)rk   r   )#r   rv   rf   ior   Zpaddler   r   Zdata_feederr   Z	frameworkr   r   r	   r
   r   Zlayer_helperr   protor   __all__r   r   compiler   Z_single_dollar_pattern_Z_two_bang_pattern_r   r4   rU   rb   rj   rn   r|   r}   r   r   r   r   <module>   s0   


	
Er8
,
5