o
    "jVT                     @   s   d dl Z d dlZd dlZd dlZd dlm  mZ d dl	mZ d dl
mZ d dlm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mZ g ZG d
d dZd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 )     N)core)convert_dtype)switch_to_static_graph)TranslatedLayer)layers   )logging_utils)func_to_source_codeparse_arg_and_kwargsparse_varargs_name	type_namec                   @   s   e Zd ZdZdddZdd Zdd Zed	d
 Zedd Z	dd Z
dd Zedd Zedd Zedd Zedd Zedd ZdS )FunctionSpecz8
    Wrapper class for a function for class method.
    Nc                 C   s   || _ |d u rd | _d | _n| || _tj| j| _t|\| _| _	t
|| _| jd urBtt|dd trD|  j|jj7  _d S d S d S )N__self__)_dygraph_function_input_spec_flat_input_spec_verify_input_specpaddleutilsflattenr
   
_arg_names_default_kwargsr   Zvarargs_name
isinstancegetattrr   r   Z_input_args_names)selffunction
input_spec r   c/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/jit/dy2static/function_spec.py__init__,   s   
zFunctionSpec.__init__c                 C   s   t | jt |k r/d| jjt | j| jt ||}|r+t|d r+|d7 }t|t|t	|}t
t |t | jD ]/}| j| }||v rS|||  ||= q=|| jvrdtd| jj||||| j|  q=t||fS )a  
        Moves kwargs with default value into arguments list to keep `args` contain the same length
        value as function definition.

        For example:

            Given function definition: `def foo(x, a=1, b=2)`,
            when calling it by `foo(23)`, the args is `[23]`, kwargs is `{a=1, b=2}`.
            In this function, it will return args with `[23, 1, 2]`, kwargs with `{}`

        Args:
            args(tuple): tuple of input arguments value of decorated function.
            kwargs(dict): dict of input keyword arguments value of decorated function.

        Return:
            New arguments tuple containing default kwargs value.
        zOThe decorated function `{}` requires {} arguments: {}, but received {} with {}.r   zP
	Maybe the function has more than one decorator, we don't support this for now.zS`{}()` requires `{}` arguments, but not found in input `args`: {} and `kwargs`: {}.)lenr   formatr   __name__inspectisclassNotImplementedError
ValueErrorlistrangeappendr   tuple)r   argskwargs	error_msgiarg_namer   r   r   unified_args_and_kwargs>   s:   

z$FunctionSpec.unified_args_and_kwargsc                    s   g }g }| j dur2|rtd| jj|t|t| j k r+tdt|t| j t|| j }n#t|| j}dd |	 D }tt
| |  fddt|D }t| j|}||fS )a  
        Converts input arguments into InputSpec.

        1. If specific input_spec, use them to construct feed layers.
        2. If input_spec is None, consider all Tensor and Numpy.ndarray as feed layers

        Args:
            args(tuple): tuple of input arguments value of function containing default kwargs value.
            kwargs(dict): kwargs arguments received by **kwargs.

        Return:
            Same nest structure with args and kwargs by replacing value with InputSpec.
        Nzc{} got unexpected keyword arguments: {}. Cannot trace the function when `input_spec` is specificed.zZRequires len(arguments) >= len(input_spec), but received len(args):{} < len(InputSpec): {}c                 S   s   g | ]}d | qS )zkwargs.r   ).0keyr   r   r   
<listcomp>       z3FunctionSpec.args_to_input_spec.<locals>.<listcomp>c                    s   i | ]	\}}| | qS r   r   )r1   idxr2   Zkwargs_list_with_specr   r   
<dictcomp>   s    z3FunctionSpec.args_to_input_spec.<locals>.<dictcomp>)r   r&   r!   r   r"   r    convert_to_input_spec$_replace_to_input_spec_with_new_namer   keysr'   values	enumeratereplace_spec_empty_name)r   r+   r,   args_with_specZkwargs_with_specZkwarg_namesr   r6   r   args_to_input_specs   s<   
	
zFunctionSpec.args_to_input_specc           	      C   s   t j|}g }t|< t|D ]/\}}t|t jjr:t	|dd}t jj
j|jp-d| |jt|jd}||_n|}|| qW d   n1 sLw   Y  t j||S )  
        Constructs feed layer by inputs with InputSpec information for main program.

        Args:
            input_with_spec(tuple): input arguments by replacing argument with InputSpec.
            main_program(Program): main program for inserting feed layer.
        stop_gradientFfeed_%s)nameshapedtypeN)r   r   r   	ir_staticZprogram_guardr<   r   static	InputSpecr   inputdatarC   rD   r   rE   rA   r)   pack_sequence_as)	r   input_with_specmain_programflat_input_specinputsr.   var_specrA   Z
feed_valuer   r   r   pir_to_static_inputs_with_spec   s"   	z+FunctionSpec.pir_to_static_inputs_with_specc           
   	   C   s   t j|}g }| }t|D ]+\}}t|t jjr4t|dd}|j	|j
p)d| |j|jdd|d}	n|}	||	 qt j||S )r@   rA   FrB   T)rC   rD   rE   Zis_dataZneed_check_feedrA   )r   r   r   Zglobal_blockr<   r   rG   rH   r   Z
create_varrC   rD   rE   r)   rK   )
r   rL   rM   rN   rO   blockr.   rP   rA   Z
feed_layerr   r   r   to_static_inputs_with_spec   s"   	
z'FunctionSpec.to_static_inputs_with_specc                 C   s(   t |ttfstdt|t|S )zJ
        Verifies the `input_spec` and its element type is valid.
        zEThe type(input_spec) should be one of (tuple, list), but received {}.)r   r*   r'   	TypeErrorr!   r   )r   r   r   r   r   r      s   zFunctionSpec._verify_input_specc                 C   s   d | jjd| j| jS )Nz function: {}({}), input_spec: {},)r!   r   r"   joinr   r   r   r   r   r   __repr__   s
   
zFunctionSpec.__repr__c                 C      | j S N)r   rW   r   r   r   dygraph_function      zFunctionSpec.dygraph_functionc                 C   rY   rZ   )r   rW   r   r   r   	args_name  r\   zFunctionSpec.args_namec                 C   rY   rZ   )r   rW   r   r   r   r     r\   zFunctionSpec.input_specc                 C   rY   rZ   )r   rW   r   r   r   rN   
  r\   zFunctionSpec.flat_input_specc                 C   s
   t | jS rZ   )r	   r   rW   r   r   r   code  s   
zFunctionSpec.coderZ   )r"   
__module____qualname____doc__r   r0   r?   r   rQ   rS   r   rX   propertyr[   r]   r   rN   r^   r   r   r   r   r   '   s*    
5<





r   Tc                 C   j   t  }| dur3t| tjr*|r%|  }dd |D }t t||}|S | j}|S td	t
| |S )z
    Returns parameters of decorated layers. If set `include_sublayer` True,
    the parameters created in sub layers will be added.
    Nc                 S      g | ]}|j qS r   rC   )r1   pr   r   r   r3         z"get_parameters.<locals>.<listcomp><Type of `layer_instance` should be nn.Layer, but received {})collectionsOrderedDictr   r   Layer
parameterszip_parametersrT   r!   r   )layer_instanceinclude_sublayerparamsnamesr   r   r   get_parameters  s    
rs   c                 C   rc   )z
    Returns Variable buffers of decorated layers. If set `include_sublayer` True,
    the Variable buffers created in sub layers will be added.
    Nc                 S   rd   r   re   )r1   bufferr   r   r   r3   5  rg   zget_buffers.<locals>.<listcomp>rh   )ri   rj   r   r   rk   buffersrm   _buffersrT   r!   r   )ro   rp   ru   rr   r   r   r   get_buffers+  s    	rw   c                 C   s   g }t tj| D ]L\}}t|tjrtjj	|}d|_
n2t|tjjr4|j
}tjj|}||_
nt|tjjjtjjfrQ|j
}tj|j|j|j}||_
|| q
tj| |}|S )NT)r<   r   r   r   r   npndarrayrG   rH   
from_numpyrA   r   eagerTensorfrom_tensorbase	frameworkVariablepirValuerD   rE   rC   r)   rK   )r+   r>   r5   	input_varrA   r   r   r   _replace_value_with_input_specB  s(   r   c              	   C   sP  t | t |ks
J t tt |d }g }tt| |D ]\}\}}d}ttj|D ]p\}}	t|	tj	rBtj
j|	}
d|
_n1t|	tjjrW|	j}tj
j|	}
||
_nt|	tjjjrq|	j}tj
|	j|	j|	j}
||
_n|	}
t|	tj	tjjtjjjfrdt|| d| dt| |
_|d7 }||
 q-qtj| |}|S )Nr   r   Tz_jst..)r    strr<   rm   r   r   r   r   rx   ry   rG   rH   rz   rA   r   r{   r|   r}   r~   r   r   rD   rE   rC   zfillr)   rK   )r+   	arg_namesZorder_digitr>   orderargZname_prefixindexr5   Zorigin_inputr   rA   r   r   r   r9   Z  sB   &r9   c                    s  d fdd	}t  ttfr`g }| d t D ]\}}t| |}|| qtt krSt d D ]}t |tjj	t
jfrRtdt| q<|t d  |S t  tri }| d  D ]\}}	| v rt|	 | ||< qq|	||< qq|S t  tjjr	 tgd }
t |
tjjstd d	 j|
_t |
r j|
_|
S td
  d|
 d |
S  S )aD  
    Replaces tensor in structured `inputs` by InputSpec in `input_spec`.

    Args:
        inputs(list|dict): nested structure list or dict.
        input_spec(list|dict): same nested structure list or dict as inputs.


    Return:
        Same structure with inputs by replacing the element with specified InputSpec.
    Fc                    sb   t | t |urtdt | dt |  d|r-t| t|k r/tdtt d S d S )Nztype(input) should be z, but received r   zYRequires len(inputs) >= len(input_spec), but received len(inputs):{} < len(input_spec):{})typerT   r    r&   r!   )rI   speccheck_lengthr   rO   r   r   check_type_and_len  s   z1convert_to_input_spec.<locals>.check_type_and_lenTNzThe inputs constain `{}` without specificing InputSpec, its shape and dtype will be treated immutable. Please specific InputSpec information in `@to_static` if you expect them as mutable inputs.r   z1Give input spec into a non-tensorable arguments `z`.z=input spec is not compatitable with real inputs. input_spec: z , real_spec:  )F)r   r*   r'   r<   r8   r)   r    r   r{   r|   rx   ry   r   warnr!   r   extenddictitemsr   rG   rH   r   RuntimeErrorrC   spec_greaterrD   )rO   r   r   rL   r.   r   Zout_specZ
rest_inputrC   rI   Z	real_specr   r   r   r8     sZ   




r8   c                 C   sD   t |}| dt| }t|D ]\}}|| }t||||< q|S )ap  
    Adds default name according to argument name from decorated function
    if without specificing InputSpec.name

    The naming rule are as followed:
        1. If InputSpec.name is not None, do nothing.
        2. If each argument `x` corresponds to an InputSpec, using the argument name like `x`
        3. If the arguments `inputs` corresponds to a list(InputSpec), using name like `inputs_0`, `inputs_1`
        4. If the arguments `input_dic` corresponds to a dict(InputSpec), using key as name.

    For example:

        # case 1: foo(x, y)
        foo = to_static(foo, input_spec=[InputSpec([None, 10]), InputSpec([None])])
        print([in_var.name for in_var in foo.inputs])  # [x, y]

        # case 2: foo(inputs) where inputs is a list
        foo = to_static(foo, input_spec=[[InputSpec([None, 10]), InputSpec([None])]])
        print([in_var.name for in_var in foo.inputs])  # [inputs_0, inputs_1]

        # case 3: foo(inputs) where inputs is a dict
        foo = to_static(foo, input_spec=[{'x': InputSpec([None, 10]), 'y': InputSpec([None])}])
        print([in_var.name for in_var in foo.inputs])  # [x, y]
    N)r'   r    r<   _replace_spec_name)r]   rL   Zcandidate_arg_namesr.   r/   r   r   r   r   r=     s   r=   c                 C   s   t |tjjr|jdu r| |_|S t |ttfr4g }t|D ]\}}|  d| }|t	|| q|S t |t
rMi }| D ]\}}t	||||< q?|S |S )zM
    Replaces InputSpec.name with given `name` while not specificing it.
    N_)r   r   rG   rH   rC   r'   r*   r<   r)   r   r   r   )rC   r   Zprocessed_specsr.   r   new_namer2   r   r   r   r     s    

r   c                    sb   dd t j| D }|dd t j|D 7 }di   fddfdd|D }t|S )a  
    Generater hash spec with args/kwargs InputSpec names.
    Consider the following InputSpecs with same shape/dtype except for name:
      1. [InputSpec([3,3], 'float32', 'x'), InputSpec([3,3], 'float32', 'x')]
      2. [InputSpec([3,3], 'float32', 'x'), InputSpec([3,3], 'float32', 'y')]
    Under @to_static, we should generate two different program not just one, because
    the former has one input ('x'), but the latter has two input ('x', 'y').
    c                 S       g | ]}t |tjjr|jqS r   r   r   rG   rH   rC   r1   r   r   r   r   r3         z$_hash_spec_names.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r3     r   r   c                    s    | vr | <  d7  |  S )Nr   r   re   )r.   name_idsr   r   to_idx  s   z _hash_spec_names.<locals>.to_idxc                    s   g | ]} |qS r   r   )r1   rC   )r   r   r   r3   %  r4   )r   r   r   r*   )Z
args_specsZkwargs_specsZ
spec_namesvaluer   )r.   r   r   r   _hash_spec_names	  s   	


r   c                 C   s   dd }|| j |j S )Nc                 S   sB   t | t |kr
dS t| |D ]\}}|dkr||kr dS qdS )NFT)r    rm   )Zfirst_shapeZsecond_shapeZfirst_nZsecond_nr   r   r   _shape_greater+  s   z$spec_greater.<locals>._shape_greater)rD   )firstotherr   r   r   r   r   *  s   r   )T)$ri   r#   numpyrx   r   Zpaddle.pir.corer   r   rF   Zpaddle.baseZpaddle.base.data_feederr   Zpaddle.base.dygraph.baser   Zpaddle.jit.translated_layerr   Zpaddle.nn.layerr    r   r   r	   r
   r   r   __all__r   rs   rw   r   r9   r8   r=   r   r   r   r   r   r   r   <module>   s0    
m
&O#!